bcachefs: traverse all iterators on transaction restart

Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
This commit is contained in:
Kent Overstreet 2019-03-28 00:07:24 -04:00 committed by Kent Overstreet
parent e1120a4c8d
commit bf7b87a4a9
3 changed files with 23 additions and 19 deletions

View 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 @@ static int btree_iter_traverse_error(struct btree_iter *iter, int 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: */
for (i = 0; i < nr_sorted; i++) {
iter = &trans->iters[sorted[i]];
@ -1003,12 +1008,11 @@ static int btree_iter_traverse_error(struct btree_iter *iter, int ret)
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)

View 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);

View 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;
}
/*