summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKent Overstreet <kent.overstreet@linux.dev>2022-12-02 12:45:37 -0500
committerKent Overstreet <kent.overstreet@linux.dev>2022-12-02 12:45:37 -0500
commit2a961219e335c7866f364c6114a29d277eefee7c (patch)
tree68142bf8c14455fcc39fdc171fa23dafec673132
parent06de518acea81278abe3565ecc825e05b5259d2c (diff)
bcachefs: Fix a btree iter assertion pop
This fixes a (harmless) broken invariant in __bch2_btree_path_set_pos(): iterators to interior nodes should point to the first non whiteout. Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
-rw-r--r--fs/bcachefs/btree_iter.c23
1 files changed, 16 insertions, 7 deletions
diff --git a/fs/bcachefs/btree_iter.c b/fs/bcachefs/btree_iter.c
index 0d280e60e1e3..f9ccc216216c 100644
--- a/fs/bcachefs/btree_iter.c
+++ b/fs/bcachefs/btree_iter.c
@@ -1249,7 +1249,7 @@ __bch2_btree_path_set_pos(struct btree_trans *trans,
struct btree_path *path, struct bpos new_pos,
bool intent, unsigned long ip, int cmp)
{
- unsigned l = path->level;
+ unsigned level = path->level;
EBUG_ON(trans->restarted);
EBUG_ON(!path->ref);
@@ -1267,10 +1267,12 @@ __bch2_btree_path_set_pos(struct btree_trans *trans,
goto out;
}
- l = btree_path_up_until_good_node(trans, path, cmp);
+ level = btree_path_up_until_good_node(trans, path, cmp);
- if (btree_path_node(path, l)) {
- BUG_ON(!btree_node_locked(path, l));
+ if (btree_path_node(path, level)) {
+ struct btree_path_level *l = &path->l[level];
+
+ BUG_ON(!btree_node_locked(path, level));
/*
* We might have to skip over many keys, or just a few: try
* advancing the node iterator, and if we have to skip over too
@@ -1278,11 +1280,18 @@ __bch2_btree_path_set_pos(struct btree_trans *trans,
* is expensive).
*/
if (cmp < 0 ||
- !btree_path_advance_to_pos(path, &path->l[l], 8))
- __btree_path_level_init(path, l);
+ !btree_path_advance_to_pos(path, l, 8))
+ bch2_btree_node_iter_init(&l->iter, l->b, &path->pos);
+
+ /*
+ * Iterators to interior nodes should always be pointed at the first non
+ * whiteout:
+ */
+ if (unlikely(level))
+ bch2_btree_node_iter_peek(&l->iter, l->b);
}
- if (unlikely(l != path->level)) {
+ if (unlikely(level != path->level)) {
btree_path_set_dirty(path, BTREE_ITER_NEED_TRAVERSE);
__bch2_btree_path_unlock(trans, path);
}