diff options
author | Kent Overstreet <kent.overstreet@gmail.com> | 2018-03-22 03:35:13 -0400 |
---|---|---|
committer | Kent Overstreet <kent.overstreet@gmail.com> | 2018-05-22 00:44:18 -0400 |
commit | ac32c4573cbe13fe8db1cc5043d7c84dc2fa93ac (patch) | |
tree | 8afbcc7944002a410446b1606dd883a60e98bd14 | |
parent | 5b38dc5a617c75d77332cfbbfda696e9a87d80bc (diff) |
bcachefs: fix bch2_btree_iter_next_slot() for extents
when the iterator is not uptodate, bch2_btree_iter_peek_slot() will
_not_ necessarily return the same key it returned last time - it'll
return the key at iter->pos, but for extents the key it returns won't
necessarily have the same _end_ at the same position as the key it
returned last time.
-rw-r--r-- | fs/bcachefs/btree_iter.c | 17 |
1 files changed, 11 insertions, 6 deletions
diff --git a/fs/bcachefs/btree_iter.c b/fs/bcachefs/btree_iter.c index cc5bcbb28a50..893fde807c89 100644 --- a/fs/bcachefs/btree_iter.c +++ b/fs/bcachefs/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; |