mirror of
https://github.com/torvalds/linux.git
synced 2024-11-25 21:51:40 +00:00
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
@ -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 New Issue
Block a user