bcachefs: Fix a livelock in key cache fill path
authorKent Overstreet <kent.overstreet@linux.dev>
Wed, 25 Jan 2023 15:15:39 +0000 (10:15 -0500)
committerKent Overstreet <kent.overstreet@linux.dev>
Sun, 22 Oct 2023 21:09:47 +0000 (17:09 -0400)
We weren't setting path->uptodate before calling
bch2_btree_key_cache_fill() - which causes __bch2_btree_path_upgrade()
to fail.

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

index c118d1b..4833cb4 100644 (file)
@@ -487,6 +487,8 @@ retry:
        path->l[0].lock_seq     = ck->c.lock.state.seq;
        path->l[0].b            = (void *) ck;
 fill:
+       path->uptodate = BTREE_ITER_UPTODATE;
+
        if (!ck->valid && !(flags & BTREE_ITER_CACHED_NOFILL)) {
                /*
                 * Using the underscore version because we haven't set
@@ -502,16 +504,23 @@ fill:
                ret = btree_key_cache_fill(trans, path, ck);
                if (ret)
                        goto err;
+
+               ret = bch2_btree_path_relock(trans, path, _THIS_IP_);
+               if (ret)
+                       goto err;
+
+               path->uptodate = BTREE_ITER_UPTODATE;
        }
 
        if (!test_bit(BKEY_CACHED_ACCESSED, &ck->flags))
                set_bit(BKEY_CACHED_ACCESSED, &ck->flags);
 
-       path->uptodate = BTREE_ITER_UPTODATE;
        BUG_ON(btree_node_locked_type(path, 0) != btree_lock_want(path, 0));
+       BUG_ON(path->uptodate);
 
        return ret;
 err:
+       path->uptodate = BTREE_ITER_NEED_TRAVERSE;
        if (!bch2_err_matches(ret, BCH_ERR_transaction_restart)) {
                btree_node_unlock(trans, path, 0);
                path->l[0].b = ERR_PTR(ret);