Commit bf7b87a4 authored by Kent Overstreet's avatar Kent Overstreet Committed by Kent Overstreet

bcachefs: traverse all iterators on transaction restart

Signed-off-by: default avatarKent Overstreet <kent.overstreet@linux.dev>
parent e1120a4c
...@@ -954,9 +954,9 @@ static void btree_iter_up(struct btree_iter *iter) ...@@ -954,9 +954,9 @@ static void btree_iter_up(struct btree_iter *iter)
int __must_check __bch2_btree_iter_traverse(struct btree_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; struct bch_fs *c = trans->c;
u8 sorted[BTREE_ITER_MAX]; u8 sorted[BTREE_ITER_MAX];
unsigned i, nr_sorted = 0; unsigned i, nr_sorted = 0;
...@@ -973,10 +973,7 @@ static int btree_iter_traverse_error(struct btree_iter *iter, int ret) ...@@ -973,10 +973,7 @@ static int btree_iter_traverse_error(struct btree_iter *iter, int ret)
retry_all: retry_all:
bch2_btree_trans_unlock(trans); bch2_btree_trans_unlock(trans);
if (ret != -ENOMEM && ret != -EINTR) if (unlikely(ret == -ENOMEM)) {
goto io_error;
if (ret == -ENOMEM) {
struct closure cl; struct closure cl;
closure_init_stack(&cl); closure_init_stack(&cl);
...@@ -987,6 +984,14 @@ static int btree_iter_traverse_error(struct btree_iter *iter, int ret) ...@@ -987,6 +984,14 @@ static int btree_iter_traverse_error(struct btree_iter *iter, int ret)
} while (ret); } 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: */ /* Now, redo traversals in correct order: */
for (i = 0; i < nr_sorted; i++) { for (i = 0; i < nr_sorted; i++) {
iter = &trans->iters[sorted[i]]; iter = &trans->iters[sorted[i]];
...@@ -1003,12 +1008,11 @@ static int btree_iter_traverse_error(struct btree_iter *iter, int ret) ...@@ -1003,12 +1008,11 @@ static int btree_iter_traverse_error(struct btree_iter *iter, int ret)
out: out:
bch2_btree_cache_cannibalize_unlock(c); bch2_btree_cache_cannibalize_unlock(c);
return ret; return ret;
io_error: }
BUG_ON(ret != -EIO);
iter->flags |= BTREE_ITER_ERROR; int bch2_btree_iter_traverse_all(struct btree_trans *trans)
iter->l[iter->level].b = BTREE_ITER_NOT_END; {
goto out; return __btree_iter_traverse_all(trans, NULL, 0);
} }
static unsigned btree_iter_up_until_locked(struct btree_iter *iter, 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) ...@@ -1096,7 +1100,7 @@ int __must_check bch2_btree_iter_traverse(struct btree_iter *iter)
ret = __bch2_btree_iter_traverse(iter); ret = __bch2_btree_iter_traverse(iter);
if (unlikely(ret)) 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)); BUG_ON(ret == -EINTR && !btree_trans_has_multiple_iters(iter->trans));
...@@ -1923,6 +1927,8 @@ void __bch2_trans_begin(struct btree_trans *trans) ...@@ -1923,6 +1927,8 @@ void __bch2_trans_begin(struct btree_trans *trans)
trans->iters_unlink_on_commit = 0; trans->iters_unlink_on_commit = 0;
trans->nr_updates = 0; trans->nr_updates = 0;
trans->mem_top = 0; trans->mem_top = 0;
bch2_btree_iter_traverse_all(trans);
} }
void bch2_trans_init(struct btree_trans *trans, struct bch_fs *c) void bch2_trans_init(struct btree_trans *trans, struct bch_fs *c)
......
...@@ -135,6 +135,7 @@ void bch2_btree_iter_node_drop(struct btree_iter *, struct btree *); ...@@ -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 *); void bch2_btree_iter_reinit_node(struct btree_iter *, struct btree *);
int __must_check bch2_btree_iter_traverse(struct btree_iter *); 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_peek_node(struct btree_iter *);
struct btree *bch2_btree_iter_next_node(struct btree_iter *, unsigned); struct btree *bch2_btree_iter_next_node(struct btree_iter *, unsigned);
......
...@@ -708,16 +708,13 @@ int bch2_trans_commit_error(struct btree_trans *trans, ...@@ -708,16 +708,13 @@ int bch2_trans_commit_error(struct btree_trans *trans,
} }
if (ret == -EINTR) { if (ret == -EINTR) {
trans_for_each_update_iter(trans, i) { int ret2 = bch2_btree_iter_traverse_all(trans);
int ret2 = bch2_btree_iter_traverse(i->iter);
if (ret2) { if (ret2) {
trans_restart(" (traverse)"); trans_restart(" (traverse)");
return ret2; return ret2;
} }
BUG_ON(i->iter->uptodate > BTREE_ITER_NEED_PEEK);
}
/* /*
* BTREE_ITER_ATOMIC means we have to return -EINTR if we * BTREE_ITER_ATOMIC means we have to return -EINTR if we
* dropped locks: * dropped locks:
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment