From: Kent Overstreet Date: Thu, 28 Mar 2019 04:07:24 +0000 (-0400) Subject: bcachefs: traverse all iterators on transaction restart X-Git-Url: http://git.maquefel.me/?a=commitdiff_plain;h=bf7b87a4a92fac3e97228ce94c35d4f78c85417e;p=linux.git bcachefs: traverse all iterators on transaction restart Signed-off-by: Kent Overstreet --- diff --git a/fs/bcachefs/btree_iter.c b/fs/bcachefs/btree_iter.c index fef5b04440b3a..c8122be210295 100644 --- a/fs/bcachefs/btree_iter.c +++ b/fs/bcachefs/btree_iter.c @@ -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) diff --git a/fs/bcachefs/btree_iter.h b/fs/bcachefs/btree_iter.h index 800320966ff14..291c805e3cc5b 100644 --- a/fs/bcachefs/btree_iter.h +++ b/fs/bcachefs/btree_iter.h @@ -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); diff --git a/fs/bcachefs/btree_update_leaf.c b/fs/bcachefs/btree_update_leaf.c index 8b043d3c19adc..a8ac68b94e25e 100644 --- a/fs/bcachefs/btree_update_leaf.c +++ b/fs/bcachefs/btree_update_leaf.c @@ -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; } /*