bcachefs: bch2_btree_path_peek_slot_exact()
authorKent Overstreet <kent.overstreet@linux.dev>
Tue, 20 Dec 2022 16:13:19 +0000 (11:13 -0500)
committerKent Overstreet <kent.overstreet@linux.dev>
Sun, 22 Oct 2023 21:09:47 +0000 (17:09 -0400)
When we start using the key cache for inodes again, it'll be possible
for bch2_btree_path_peek_slot() to return a key in a different snapshot
with a key cache path.

This isn't what we want when triggers are checking what they're
overwriting, so introduce a new helper for the commit path.

Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
fs/bcachefs/btree_update_leaf.c

index 323f2942b11d7005a4e7bbce363f04177d49846b..62b0aa55c7527b55dcbb62fe46a3c8c2f6f71675 100644 (file)
 #include <linux/prefetch.h>
 #include <linux/sort.h>
 
+/*
+ * bch2_btree_path_peek_slot() for a cached iterator might return a key in a
+ * different snapshot:
+ */
+struct bkey_s_c bch2_btree_path_peek_slot_exact(struct btree_path *path, struct bkey *u)
+{
+       struct bkey_s_c k = bch2_btree_path_peek_slot(path, u);
+
+       if (k.k && bpos_eq(path->pos, k.k->p))
+               return k;
+
+       bkey_init(u);
+       u->p = path->pos;
+       return (struct bkey_s_c) { u, NULL };
+}
+
 static int __must_check
 bch2_trans_update_by_path(struct btree_trans *, struct btree_path *,
                          struct bkey_i *, enum btree_update_flags);
@@ -1505,7 +1521,7 @@ bch2_trans_update_by_path_trace(struct btree_trans *trans, struct btree_path *pa
                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_v = bch2_btree_path_peek_slot_exact(path, &i->old_k).v;
                i->old_btree_u64s = !bkey_deleted(&i->old_k) ? i->old_k.u64s : 0;
 
                if (unlikely(trans->journal_replay_not_finished)) {