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.c40
1 files changed, 34 insertions, 6 deletions
diff --git a/libbcachefs/btree_iter.c b/libbcachefs/btree_iter.c
index c365a2af..321fe306 100644
--- a/libbcachefs/btree_iter.c
+++ b/libbcachefs/btree_iter.c
@@ -912,6 +912,27 @@ static void btree_iter_prefetch(struct btree_iter *iter)
btree_node_unlock(iter, iter->level);
}
+static noinline void btree_node_mem_ptr_set(struct btree_iter *iter,
+ unsigned plevel, struct btree *b)
+{
+ struct btree_iter_level *l = &iter->l[plevel];
+ bool locked = btree_node_locked(iter, plevel);
+ struct bkey_packed *k;
+ struct bch_btree_ptr_v2 *bp;
+
+ if (!bch2_btree_node_relock(iter, plevel))
+ return;
+
+ k = bch2_btree_node_iter_peek_all(&l->iter, l->b);
+ BUG_ON(k->type != KEY_TYPE_btree_ptr_v2);
+
+ bp = (void *) bkeyp_val(&l->b->format, k);
+ bp->mem_ptr = (unsigned long)b;
+
+ if (!locked)
+ btree_node_unlock(iter, plevel);
+}
+
static __always_inline int btree_iter_down(struct btree_iter *iter)
{
struct bch_fs *c = iter->trans->c;
@@ -933,6 +954,10 @@ static __always_inline int btree_iter_down(struct btree_iter *iter)
mark_btree_node_locked(iter, level, lock_type);
btree_iter_node_set(iter, b);
+ if (tmp.k.k.type == KEY_TYPE_btree_ptr_v2 &&
+ unlikely(b != btree_node_mem_ptr(&tmp.k)))
+ btree_node_mem_ptr_set(iter, level + 1, b);
+
if (iter->flags & BTREE_ITER_PREFETCH)
btree_iter_prefetch(iter);
@@ -1756,6 +1781,8 @@ int bch2_trans_iter_put(struct btree_trans *trans,
if (IS_ERR_OR_NULL(iter))
return 0;
+ BUG_ON(trans->iters + iter->idx != iter);
+
ret = btree_iter_err(iter);
if (!(trans->iters_touched & (1ULL << iter->idx)) &&
@@ -2080,16 +2107,11 @@ void bch2_trans_reset(struct btree_trans *trans, unsigned flags)
bch2_trans_unlink_iters(trans);
- if (flags & TRANS_RESET_ITERS)
- trans->iters_live = 0;
-
trans->iters_touched &= trans->iters_live;
trans->need_reset = 0;
trans->nr_updates = 0;
-
- if (flags & TRANS_RESET_MEM)
- trans->mem_top = 0;
+ trans->mem_top = 0;
if (trans->fs_usage_deltas) {
trans->fs_usage_deltas->used = 0;
@@ -2108,6 +2130,12 @@ void bch2_trans_init(struct btree_trans *trans, struct bch_fs *c,
{
memset(trans, 0, offsetof(struct btree_trans, iters_onstack));
+ /*
+ * reallocating iterators currently completely breaks
+ * bch2_trans_iter_put():
+ */
+ expected_nr_iters = BTREE_ITER_MAX;
+
trans->c = c;
trans->ip = _RET_IP_;
trans->size = ARRAY_SIZE(trans->iters_onstack);