forked from mirrors/linux
		
	bcachefs: Fix BCH_TRANS_COMMIT_skip_accounting_apply
This was added to avoid double-counting accounting keys in journal replay. But applied incorrectly (easily done since it applies to the transaction commit, not a particular update), it leads to skipping in-mem accounting for real accounting updates, and failure to give them a version number - which leads to journal replay becoming very confused the next time around. Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
This commit is contained in:
		
							parent
							
								
									f8911ad88d
								
							
						
					
					
						commit
						a3581ca35d
					
				
					 1 changed files with 18 additions and 14 deletions
				
			
		|  | @ -700,27 +700,31 @@ bch2_trans_commit_write_locked(struct btree_trans *trans, unsigned flags, | ||||||
| 
 | 
 | ||||||
| 	struct jset_entry *entry = trans->journal_entries; | 	struct jset_entry *entry = trans->journal_entries; | ||||||
| 
 | 
 | ||||||
| 	if (likely(!(flags & BCH_TRANS_COMMIT_skip_accounting_apply))) { | 	percpu_down_read(&c->mark_lock); | ||||||
| 		percpu_down_read(&c->mark_lock); |  | ||||||
| 
 | 
 | ||||||
| 		for (entry = trans->journal_entries; | 	for (entry = trans->journal_entries; | ||||||
| 		     entry != (void *) ((u64 *) trans->journal_entries + trans->journal_entries_u64s); | 	     entry != (void *) ((u64 *) trans->journal_entries + trans->journal_entries_u64s); | ||||||
| 		     entry = vstruct_next(entry)) | 	     entry = vstruct_next(entry)) | ||||||
| 			if (jset_entry_is_key(entry) && entry->start->k.type == KEY_TYPE_accounting) { | 		if (entry->type == BCH_JSET_ENTRY_write_buffer_keys && | ||||||
| 				struct bkey_i_accounting *a = bkey_i_to_accounting(entry->start); | 		    entry->start->k.type == KEY_TYPE_accounting) { | ||||||
|  | 			BUG_ON(!trans->journal_res.ref); | ||||||
| 
 | 
 | ||||||
| 				a->k.bversion = journal_pos_to_bversion(&trans->journal_res, | 			struct bkey_i_accounting *a = bkey_i_to_accounting(entry->start); | ||||||
| 								(u64 *) entry - (u64 *) trans->journal_entries); | 
 | ||||||
| 				BUG_ON(bversion_zero(a->k.bversion)); | 			a->k.bversion = journal_pos_to_bversion(&trans->journal_res, | ||||||
|  | 							(u64 *) entry - (u64 *) trans->journal_entries); | ||||||
|  | 			BUG_ON(bversion_zero(a->k.bversion)); | ||||||
|  | 
 | ||||||
|  | 			if (likely(!(flags & BCH_TRANS_COMMIT_skip_accounting_apply))) { | ||||||
| 				ret = bch2_accounting_mem_mod_locked(trans, accounting_i_to_s_c(a), BCH_ACCOUNTING_normal); | 				ret = bch2_accounting_mem_mod_locked(trans, accounting_i_to_s_c(a), BCH_ACCOUNTING_normal); | ||||||
| 				if (ret) | 				if (ret) | ||||||
| 					goto revert_fs_usage; | 					goto revert_fs_usage; | ||||||
| 			} | 			} | ||||||
| 		percpu_up_read(&c->mark_lock); | 		} | ||||||
|  | 	percpu_up_read(&c->mark_lock); | ||||||
| 
 | 
 | ||||||
| 		/* XXX: we only want to run this if deltas are nonzero */ | 	/* XXX: we only want to run this if deltas are nonzero */ | ||||||
| 		bch2_trans_account_disk_usage_change(trans); | 	bch2_trans_account_disk_usage_change(trans); | ||||||
| 	} |  | ||||||
| 
 | 
 | ||||||
| 	trans_for_each_update(trans, i) | 	trans_for_each_update(trans, i) | ||||||
| 		if (btree_node_type_has_atomic_triggers(i->bkey_type)) { | 		if (btree_node_type_has_atomic_triggers(i->bkey_type)) { | ||||||
|  |  | ||||||
		Loading…
	
		Reference in a new issue
	
	 Kent Overstreet
						Kent Overstreet