summaryrefslogtreecommitdiff
path: root/fs/bcachefs/btree_key_cache.c
diff options
context:
space:
mode:
authorKent Overstreet <kent.overstreet@linux.dev>2023-01-25 18:15:39 +0300
committerKent Overstreet <kent.overstreet@linux.dev>2023-10-23 00:09:47 +0300
commit6f90e6b28180cb567b0abdb753ccac4c7d840cb2 (patch)
tree51a4a861f52468b0e1bc1a4f252397d221715e9a /fs/bcachefs/btree_key_cache.c
parent1617d56dc9bc3d9fd56824e8e488e88acbba152f (diff)
downloadlinux-6f90e6b28180cb567b0abdb753ccac4c7d840cb2.tar.xz
bcachefs: Fix a livelock in key cache fill path
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>
Diffstat (limited to 'fs/bcachefs/btree_key_cache.c')
-rw-r--r--fs/bcachefs/btree_key_cache.c11
1 files changed, 10 insertions, 1 deletions
diff --git a/fs/bcachefs/btree_key_cache.c b/fs/bcachefs/btree_key_cache.c
index c118d1b8241f..4833cb4c7cf5 100644
--- a/fs/bcachefs/btree_key_cache.c
+++ b/fs/bcachefs/btree_key_cache.c
@@ -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);