]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
bcachefs: Fix set_should_be_locked() call in peek_slot()
authorKent Overstreet <kent.overstreet@linux.dev>
Wed, 14 May 2025 01:14:17 +0000 (21:14 -0400)
committerKent Overstreet <kent.overstreet@linux.dev>
Wed, 14 May 2025 21:05:19 +0000 (17:05 -0400)
set_should_be_locked() needs to be called before peek_key_cache(), which
traverses other paths and may do a trans unlock/relock.

This fixes an assertion pop in path_peek_slot(), when the path we're
using is unexpectedly not uptodate.

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

index 9c9bc7b6c712792ea0972c9d169fdc015158b3c5..a873ec1baf581cad2cf6a6561b094dbe63683571 100644 (file)
@@ -2749,7 +2749,7 @@ struct bkey_s_c bch2_btree_iter_peek_slot(struct btree_trans *trans, struct btre
        ret = trans_maybe_inject_restart(trans, _RET_IP_);
        if (unlikely(ret)) {
                k = bkey_s_c_err(ret);
-               goto out_no_locked;
+               goto out;
        }
 
        /* extents can't span inode numbers: */
@@ -2769,13 +2769,15 @@ struct bkey_s_c bch2_btree_iter_peek_slot(struct btree_trans *trans, struct btre
        ret = bch2_btree_path_traverse(trans, iter->path, iter->flags);
        if (unlikely(ret)) {
                k = bkey_s_c_err(ret);
-               goto out_no_locked;
+               goto out;
        }
 
        struct btree_path *path = btree_iter_path(trans, iter);
        if (unlikely(!btree_path_node(path, path->level)))
                return bkey_s_c_null;
 
+       btree_path_set_should_be_locked(trans, path);
+
        if ((iter->flags & BTREE_ITER_cached) ||
            !(iter->flags & (BTREE_ITER_is_extents|BTREE_ITER_filter_snapshots))) {
                k = bkey_s_c_null;
@@ -2796,12 +2798,12 @@ struct bkey_s_c bch2_btree_iter_peek_slot(struct btree_trans *trans, struct btre
                        if (!bkey_err(k))
                                iter->k = *k.k;
                        /* We're not returning a key from iter->path: */
-                       goto out_no_locked;
+                       goto out;
                }
 
-               k = bch2_btree_path_peek_slot(trans->paths + iter->path, &iter->k);
+               k = bch2_btree_path_peek_slot(btree_iter_path(trans, iter), &iter->k);
                if (unlikely(!k.k))
-                       goto out_no_locked;
+                       goto out;
 
                if (unlikely(k.k->type == KEY_TYPE_whiteout &&
                             (iter->flags & BTREE_ITER_filter_snapshots) &&
@@ -2839,7 +2841,7 @@ struct bkey_s_c bch2_btree_iter_peek_slot(struct btree_trans *trans, struct btre
                }
 
                if (unlikely(bkey_err(k)))
-                       goto out_no_locked;
+                       goto out;
 
                next = k.k ? bkey_start_pos(k.k) : POS_MAX;
 
@@ -2861,8 +2863,6 @@ struct bkey_s_c bch2_btree_iter_peek_slot(struct btree_trans *trans, struct btre
                }
        }
 out:
-       btree_path_set_should_be_locked(trans, btree_iter_path(trans, iter));
-out_no_locked:
        bch2_btree_iter_verify_entry_exit(iter);
        bch2_btree_iter_verify(trans, iter);
        ret = bch2_btree_iter_verify_ret(trans, iter, k);