diff options
author | Kent Overstreet <kent.overstreet@gmail.com> | 2018-03-22 03:35:13 -0400 |
---|---|---|
committer | Kent Overstreet <kent.overstreet@gmail.com> | 2018-03-22 04:12:02 -0400 |
commit | 919a34d47a68f3e5f00a7ce5efb67748ec31bd62 (patch) | |
tree | 9ba1ddcc86c6998318ea2c1209ac50b51492d18f | |
parent | ef097245223f66434a6b0d3156fd27ef842f5342 (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; |