diff options
-rw-r--r-- | fs/bcachefs/btree_iter.c | 21 | ||||
-rw-r--r-- | fs/bcachefs/btree_update_leaf.c | 1 |
2 files changed, 20 insertions, 2 deletions
diff --git a/fs/bcachefs/btree_iter.c b/fs/bcachefs/btree_iter.c index 1da314b6e5a6..302b8539bf0e 100644 --- a/fs/bcachefs/btree_iter.c +++ b/fs/bcachefs/btree_iter.c @@ -2196,6 +2196,22 @@ static inline void __bch2_trans_iter_free(struct btree_trans *trans, trans->iters_touched &= ~(1ULL << idx); } +static bool have_iter_at_pos(struct btree_trans *trans, + struct btree_iter *iter) +{ + struct btree_iter *n; + + n = prev_btree_iter(trans, iter); + if (n && !btree_iter_cmp(n, iter)) + return true; + + n = next_btree_iter(trans, iter); + if (n && !btree_iter_cmp(n, iter)) + return true; + + return false; +} + int bch2_trans_iter_put(struct btree_trans *trans, struct btree_iter *iter) { @@ -2209,8 +2225,9 @@ int bch2_trans_iter_put(struct btree_trans *trans, ret = btree_iter_err(iter); - if (!(trans->iters_touched & (1ULL << iter->idx)) && - !(iter->flags & BTREE_ITER_KEEP_UNTIL_COMMIT)) + if (!(iter->flags & BTREE_ITER_KEEP_UNTIL_COMMIT) && + (!(trans->iters_touched & (1ULL << iter->idx)) || + have_iter_at_pos(trans, iter))) __bch2_trans_iter_free(trans, iter->idx); trans->iters_live &= ~(1ULL << iter->idx); diff --git a/fs/bcachefs/btree_update_leaf.c b/fs/bcachefs/btree_update_leaf.c index 7e9909e2dcaf..bfb568025a2a 100644 --- a/fs/bcachefs/btree_update_leaf.c +++ b/fs/bcachefs/btree_update_leaf.c @@ -1019,6 +1019,7 @@ int bch2_trans_update(struct btree_trans *trans, struct btree_iter *iter, n.iter = bch2_trans_get_iter(trans, n.btree_id, n.k->k.p, BTREE_ITER_INTENT| BTREE_ITER_NOT_EXTENTS); + n.iter->flags |= BTREE_ITER_KEEP_UNTIL_COMMIT; ret = bch2_btree_iter_traverse(n.iter); bch2_trans_iter_put(trans, n.iter); |