summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKent Overstreet <kent.overstreet@linux.dev>2022-09-27 18:56:57 -0400
committerKent Overstreet <kent.overstreet@linux.dev>2022-10-03 23:55:52 -0400
commit8ce10d733352e2995295cd01bcd263304fbecd59 (patch)
tree4a648bf5b0cfab093f2644c19868402bc265b348
parent1c05040a0f0890bcc1ec4e19065f022bf71b281b (diff)
bcachefs: Fix bch2_btree_path_up_until_good_node()
There was a rare bug when path->locks_want was nonzero, but not BTREE_MAX_DEPTH, where we'd return on a valid node that wasn't locked - oops. Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
-rw-r--r--fs/bcachefs/btree_iter.c6
1 files changed, 4 insertions, 2 deletions
diff --git a/fs/bcachefs/btree_iter.c b/fs/bcachefs/btree_iter.c
index 44e0724061b7..a7ff5df4869d 100644
--- a/fs/bcachefs/btree_iter.c
+++ b/fs/bcachefs/btree_iter.c
@@ -1040,7 +1040,7 @@ static inline unsigned btree_path_up_until_good_node(struct btree_trans *trans,
int check_pos)
{
unsigned i, l = path->level;
-
+again:
while (btree_path_node(path, l) &&
!btree_path_good_node(trans, path, l, check_pos))
__btree_path_set_level_up(trans, path, l++);
@@ -1049,9 +1049,11 @@ static inline unsigned btree_path_up_until_good_node(struct btree_trans *trans,
for (i = l + 1;
i < path->locks_want && btree_path_node(path, i);
i++)
- if (!bch2_btree_node_relock(trans, path, i))
+ if (!bch2_btree_node_relock(trans, path, i)) {
while (l <= i)
__btree_path_set_level_up(trans, path, l++);
+ goto again;
+ }
return l;
}