summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKent Overstreet <kent.overstreet@gmail.com>2018-03-22 03:35:13 -0400
committerKent Overstreet <kent.overstreet@gmail.com>2018-03-22 04:12:02 -0400
commit919a34d47a68f3e5f00a7ce5efb67748ec31bd62 (patch)
tree9ba1ddcc86c6998318ea2c1209ac50b51492d18f
parentef097245223f66434a6b0d3156fd27ef842f5342 (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.c17
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;