bcachefs: Stash a copy of key being overwritten in btree_insert_entry

We currently need to call bch2_btree_path_peek_slot() multiple times in
the transaction commit path - and some of those need to be updated to
also check the keys from journal replay, too. Let's consolidate this and
stash the key being overwritten in btree_insert_entry.

Signed-off-by: Kent Overstreet <kent.overstreet@gmail.com>
This commit is contained in:
Kent Overstreet 2022-02-24 11:02:58 -05:00 committed by Kent Overstreet
parent ce91abd60b
commit 2e63e18066
4 changed files with 27 additions and 33 deletions

View File

@ -1987,6 +1987,7 @@ inline struct bkey_s_c bch2_btree_path_peek_slot(struct btree_path *path, struct
if (unlikely(!ck->valid))
goto hole;
*u = ck->k->k;
k = bkey_i_to_s_c(ck->k);
}

View File

@ -339,12 +339,20 @@ struct btree_insert_entry {
unsigned flags;
u8 bkey_type;
enum btree_id btree_id:8;
u8 level;
u8 level:4;
bool cached:1;
bool insert_trigger_run:1;
bool overwrite_trigger_run:1;
/*
* @old_k may be a key from the journal; @old_btree_u64s always refers
* to the size of the key being overwritten in the btree:
*/
u8 old_btree_u64s;
struct bkey_i *k;
struct btree_path *path;
/* key being overwritten: */
struct bkey old_k;
const struct bch_val *old_v;
unsigned long ip_allocated;
};

View File

@ -653,7 +653,6 @@ static inline int do_bch2_trans_commit(struct btree_trans *trans,
{
struct bch_fs *c = trans->c;
struct btree_insert_entry *i;
struct bkey_s_c old;
int ret, u64s_delta = 0;
trans_for_each_update(trans, i) {
@ -671,22 +670,11 @@ static inline int do_bch2_trans_commit(struct btree_trans *trans,
}
trans_for_each_update(trans, i) {
struct bkey u;
/*
* peek_slot() doesn't yet work on iterators that point to
* interior nodes:
*/
if (i->cached || i->level)
if (i->cached)
continue;
old = bch2_btree_path_peek_slot(i->path, &u);
ret = bkey_err(old);
if (unlikely(ret))
return ret;
u64s_delta += !bkey_deleted(&i->k->k) ? i->k->k.u64s : 0;
u64s_delta -= !bkey_deleted(old.k) ? old.k->u64s : 0;
u64s_delta -= i->old_btree_u64s;
if (!same_leaf_as_next(trans, i)) {
if (u64s_delta <= 0) {
@ -1432,11 +1420,19 @@ int __must_check bch2_trans_update_by_path(struct btree_trans *trans, struct btr
}
bch2_path_put(trans, i->path, true);
*i = n;
} else
i->flags = n.flags;
i->cached = n.cached;
i->k = n.k;
i->path = n.path;
i->ip_allocated = n.ip_allocated;
} else {
array_insert_item(trans->updates, trans->nr_updates,
i - trans->updates, n);
i->old_v = bch2_btree_path_peek_slot(path, &i->old_k).v;
i->old_btree_u64s = !bkey_deleted(&i->old_k) ? i->old_k.u64s : 0;
}
__btree_path_get(n.path, true);
return 0;
}

View File

@ -1322,25 +1322,14 @@ void fs_usage_apply_warn(struct btree_trans *trans,
should_not_have_added, disk_res_sectors);
trans_for_each_update(trans, i) {
struct bkey_s_c old = { &i->old_k, i->old_v };
pr_err("while inserting");
bch2_bkey_val_to_text(&PBUF(buf), c, bkey_i_to_s_c(i->k));
pr_err("%s", buf);
pr_err(" %s", buf);
pr_err("overlapping with");
if (!i->cached) {
struct bkey u;
struct bkey_s_c k = bch2_btree_path_peek_slot(i->path, &u);
bch2_bkey_val_to_text(&PBUF(buf), c, k);
pr_err("%s", buf);
} else {
struct bkey_cached *ck = (void *) i->path->l[0].b;
if (ck->valid) {
bch2_bkey_val_to_text(&PBUF(buf), c, bkey_i_to_s_c(ck->k));
pr_err("%s", buf);
}
}
bch2_bkey_val_to_text(&PBUF(buf), c, old);
pr_err(" %s", buf);
}
__WARN();
}