]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
bcachefs: Stash a copy of key being overwritten in btree_insert_entry
authorKent Overstreet <kent.overstreet@gmail.com>
Thu, 24 Feb 2022 16:02:58 +0000 (11:02 -0500)
committerKent Overstreet <kent.overstreet@linux.dev>
Sun, 22 Oct 2023 21:09:23 +0000 (17:09 -0400)
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>
fs/bcachefs/btree_iter.c
fs/bcachefs/btree_types.h
fs/bcachefs/btree_update_leaf.c
fs/bcachefs/buckets.c

index e057c9b15ee0e66273f15baa59f3425cc85270f3..75815a1e90ec314e5e74e2a9e190132bb4aaff00 100644 (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);
        }
 
index 9828bdd924aff783de5fb56ed9a511fb3b7e62a6..587307ff5321f70e10d220ba3a14b1c65c0ccce0 100644 (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;
 };
 
index cfcaa58f728c71c4c354541b802da5a9aa566f21..5dd86c41c631f5ecc99725403e3e0cd876251daa 100644 (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;
 }
index ae576031522309d713b48cee8a99bda570488f92..7ca1087b5bb3faca100d9a2ff104c95093746d28 100644 (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();
 }