]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
bcachefs: Free iterator if we have duplicate
authorKent Overstreet <kent.overstreet@gmail.com>
Mon, 23 Aug 2021 21:19:17 +0000 (17:19 -0400)
committerKent Overstreet <kent.overstreet@linux.dev>
Sun, 22 Oct 2023 21:09:10 +0000 (17:09 -0400)
This helps - but does not fully fix - the outstanding "transaction
iterator overflow" bugs.

Signed-off-by: Kent Overstreet <kent.overstreet@gmail.com>
fs/bcachefs/btree_iter.c
fs/bcachefs/btree_update_leaf.c

index f38f231fb2963e34ffd9b00359b7c989f6c7926c..c97569450741fdfa59d1208c5361dd55330b9db2 100644 (file)
@@ -2204,6 +2204,22 @@ static inline void __bch2_trans_iter_free(struct btree_trans *trans,
        btree_trans_verify_sorted_refs(trans);
 }
 
+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)
 {
@@ -2217,8 +2233,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);
index 179091e4c5617514d978ae4ceca36d8e8c3e50ce..cfb691fa65cf41df12a56b4ff0d50beb2e806d93 100644 (file)
@@ -1040,6 +1040,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);