bcachefs: traverse all iterators on transaction restart
authorKent Overstreet <kent.overstreet@gmail.com>
Thu, 28 Mar 2019 04:07:24 +0000 (00:07 -0400)
committerKent Overstreet <kent.overstreet@linux.dev>
Sun, 22 Oct 2023 21:08:19 +0000 (17:08 -0400)
Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
fs/bcachefs/btree_iter.c
fs/bcachefs/btree_iter.h
fs/bcachefs/btree_update_leaf.c

index fef5b04440b3a0de22cfbcc14e627fcc43c332d7..c8122be210295b6076b7d1e40ac7c940046d6c93 100644 (file)
@@ -954,9 +954,9 @@ static void btree_iter_up(struct btree_iter *iter)
 
 int __must_check __bch2_btree_iter_traverse(struct btree_iter *);
 
-static int btree_iter_traverse_error(struct btree_iter *iter, int ret)
+static int __btree_iter_traverse_all(struct btree_trans *trans,
+                                    struct btree_iter *iter, int ret)
 {
-       struct btree_trans *trans = iter->trans;
        struct bch_fs *c = trans->c;
        u8 sorted[BTREE_ITER_MAX];
        unsigned i, nr_sorted = 0;
@@ -973,10 +973,7 @@ static int btree_iter_traverse_error(struct btree_iter *iter, int ret)
 retry_all:
        bch2_btree_trans_unlock(trans);
 
-       if (ret != -ENOMEM && ret != -EINTR)
-               goto io_error;
-
-       if (ret == -ENOMEM) {
+       if (unlikely(ret == -ENOMEM)) {
                struct closure cl;
 
                closure_init_stack(&cl);
@@ -987,6 +984,14 @@ retry_all:
                } while (ret);
        }
 
+       if (unlikely(ret == -EIO)) {
+               iter->flags |= BTREE_ITER_ERROR;
+               iter->l[iter->level].b = BTREE_ITER_NOT_END;
+               goto out;
+       }
+
+       BUG_ON(ret && ret != -EINTR);
+
        /* Now, redo traversals in correct order: */
        for (i = 0; i < nr_sorted; i++) {
                iter = &trans->iters[sorted[i]];
@@ -1003,12 +1008,11 @@ retry_all:
 out:
        bch2_btree_cache_cannibalize_unlock(c);
        return ret;
-io_error:
-       BUG_ON(ret != -EIO);
+}
 
-       iter->flags |= BTREE_ITER_ERROR;
-       iter->l[iter->level].b = BTREE_ITER_NOT_END;
-       goto out;
+int bch2_btree_iter_traverse_all(struct btree_trans *trans)
+{
+       return __btree_iter_traverse_all(trans, NULL, 0);
 }
 
 static unsigned btree_iter_up_until_locked(struct btree_iter *iter,
@@ -1096,7 +1100,7 @@ int __must_check bch2_btree_iter_traverse(struct btree_iter *iter)
 
        ret = __bch2_btree_iter_traverse(iter);
        if (unlikely(ret))
-               ret = btree_iter_traverse_error(iter, ret);
+               ret = __btree_iter_traverse_all(iter->trans, iter, ret);
 
        BUG_ON(ret == -EINTR && !btree_trans_has_multiple_iters(iter->trans));
 
@@ -1923,6 +1927,8 @@ void __bch2_trans_begin(struct btree_trans *trans)
        trans->iters_unlink_on_commit   = 0;
        trans->nr_updates               = 0;
        trans->mem_top                  = 0;
+
+       bch2_btree_iter_traverse_all(trans);
 }
 
 void bch2_trans_init(struct btree_trans *trans, struct bch_fs *c)
index 800320966ff14c382fa300fec05ec4f12eed4336..291c805e3cc5ba7ea314795acbc1637c5d1387c0 100644 (file)
@@ -135,6 +135,7 @@ void bch2_btree_iter_node_drop(struct btree_iter *, struct btree *);
 void bch2_btree_iter_reinit_node(struct btree_iter *, struct btree *);
 
 int __must_check bch2_btree_iter_traverse(struct btree_iter *);
+int bch2_btree_iter_traverse_all(struct btree_trans *);
 
 struct btree *bch2_btree_iter_peek_node(struct btree_iter *);
 struct btree *bch2_btree_iter_next_node(struct btree_iter *, unsigned);
index 8b043d3c19adcfe2d638587c59f2e4f64253ed3e..a8ac68b94e25ed69638662456bb1cdd5d453153b 100644 (file)
@@ -708,14 +708,11 @@ int bch2_trans_commit_error(struct btree_trans *trans,
        }
 
        if (ret == -EINTR) {
-               trans_for_each_update_iter(trans, i) {
-                       int ret2 = bch2_btree_iter_traverse(i->iter);
-                       if (ret2) {
-                               trans_restart(" (traverse)");
-                               return ret2;
-                       }
+               int ret2 = bch2_btree_iter_traverse_all(trans);
 
-                       BUG_ON(i->iter->uptodate > BTREE_ITER_NEED_PEEK);
+               if (ret2) {
+                       trans_restart(" (traverse)");
+                       return ret2;
                }
 
                /*