diff options
Diffstat (limited to 'libbcachefs/btree_iter.c')
-rw-r--r-- | libbcachefs/btree_iter.c | 21 |
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); } |