summaryrefslogtreecommitdiff
path: root/libbcachefs/btree_iter.c
diff options
context:
space:
mode:
Diffstat (limited to 'libbcachefs/btree_iter.c')
-rw-r--r--libbcachefs/btree_iter.c21
1 files changed, 15 insertions, 6 deletions
diff --git a/libbcachefs/btree_iter.c b/libbcachefs/btree_iter.c
index cc5bcbb2..465aadba 100644
--- a/libbcachefs/btree_iter.c
+++ b/libbcachefs/btree_iter.c
@@ -1290,16 +1290,19 @@ struct bkey_s_c bch2_btree_iter_peek_slot(struct btree_iter *iter)
struct bkey_s_c bch2_btree_iter_next_slot(struct btree_iter *iter)
{
+ iter->pos = btree_type_successor(iter->btree_id, iter->k.p);
+
if (unlikely(iter->uptodate != BTREE_ITER_UPTODATE)) {
- struct bkey_s_c k;
+ /*
+ * XXX: when we just need to relock we should be able to avoid
+ * calling traverse, but we need to kill BTREE_ITER_NEED_PEEK
+ * for that to work
+ */
+ btree_iter_set_dirty(iter, BTREE_ITER_NEED_TRAVERSE);
- k = bch2_btree_iter_peek_slot(iter);
- if (btree_iter_err(k))
- return k;
+ return bch2_btree_iter_peek_slot(iter);
}
- iter->pos = btree_type_successor(iter->btree_id, iter->k.p);
-
if (!bkey_deleted(&iter->k))
__btree_iter_advance(&iter->l[0]);
@@ -1318,6 +1321,8 @@ void __bch2_btree_iter_init(struct btree_iter *iter, struct bch_fs *c,
iter->c = c;
iter->pos = pos;
+ bkey_init(&iter->k);
+ iter->k.p = pos;
iter->flags = flags;
iter->uptodate = BTREE_ITER_NEED_TRAVERSE;
iter->btree_id = btree_id;
@@ -1330,6 +1335,10 @@ void __bch2_btree_iter_init(struct btree_iter *iter, struct bch_fs *c,
iter->l[iter->level].b = BTREE_ITER_NOT_END;
iter->next = iter;
+ if (unlikely((flags & BTREE_ITER_IS_EXTENTS) &&
+ !bkey_cmp(pos, POS_MAX)))
+ iter->uptodate = BTREE_ITER_END;
+
prefetch(c->btree_roots[btree_id].b);
}