aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--fs/bcachefs/btree_iter.c25
-rw-r--r--fs/bcachefs/btree_iter.h2
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)