diff options
-rw-r--r-- | fs/bcachefs/btree_iter.c | 25 | ||||
-rw-r--r-- | fs/bcachefs/btree_iter.h | 2 |
2 files changed, 17 insertions, 10 deletions
diff --git a/fs/bcachefs/btree_iter.c b/fs/bcachefs/btree_iter.c index 2c28e65fdeb5..94ba43626cde 100644 --- a/fs/bcachefs/btree_iter.c +++ b/fs/bcachefs/btree_iter.c @@ -1654,19 +1654,19 @@ static struct btree_path *have_path_at_pos(struct btree_trans *trans, struct btr return NULL; } -static bool have_node_at_pos(struct btree_trans *trans, struct btree_path *path) +static struct btree_path *have_node_at_pos(struct btree_trans *trans, struct btree_path *path) { struct btree_path *next; next = prev_btree_path(trans, path); - if (next && path_l(next)->b == path_l(path)->b) - return true; + if (next && next->level == path->level && path_l(next)->b == path_l(path)->b) + return next; next = next_btree_path(trans, path); - if (next && path_l(next)->b == path_l(path)->b) - return true; + if (next && next->level == path->level && path_l(next)->b == path_l(path)->b) + return next; - return false; + return NULL; } static inline void __bch2_path_free(struct btree_trans *trans, struct btree_path *path) @@ -1693,11 +1693,20 @@ void bch2_path_put(struct btree_trans *trans, struct btree_path *path, bool inte (dup = have_path_at_pos(trans, path))) { dup->preserve = true; path->preserve = false; + goto free; } if (!path->preserve && - have_node_at_pos(trans, path)) - __bch2_path_free(trans, path); + (dup = have_node_at_pos(trans, path))) + goto free; + return; +free: + if (path->should_be_locked && + !btree_node_locked(dup, path->level)) + return; + + dup->should_be_locked |= path->should_be_locked; + __bch2_path_free(trans, path); } noinline __cold diff --git a/fs/bcachefs/btree_iter.h b/fs/bcachefs/btree_iter.h index 64a3969db263..c71e42a782d6 100644 --- a/fs/bcachefs/btree_iter.h +++ b/fs/bcachefs/btree_iter.h @@ -253,8 +253,6 @@ static inline void bch2_btree_iter_set_pos(struct btree_iter *iter, struct bpos iter->k.p.offset = iter->pos.offset = new_pos.offset; iter->k.p.snapshot = iter->pos.snapshot = new_pos.snapshot; iter->k.size = 0; - if (iter->path->ref == 1) - iter->path->should_be_locked = false; } static inline void bch2_btree_iter_set_pos_to_extent_start(struct btree_iter *iter) |