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

bcachefs: Change btree_iter_traverse_error() to not use iter->next

Signed-off-by: default avatarKent Overstreet <kent.overstreet@linux.dev>
parent 0f238367
...@@ -956,10 +956,22 @@ int __must_check __bch2_btree_iter_traverse(struct btree_iter *); ...@@ -956,10 +956,22 @@ 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_error(struct btree_iter *iter, int ret)
{ {
struct bch_fs *c = iter->trans->c; struct btree_trans *trans = iter->trans;
struct btree_iter *linked, *sorted_iters, **i; struct bch_fs *c = trans->c;
u8 sorted[BTREE_ITER_MAX];
unsigned i, nr_sorted = 0;
trans_for_each_iter(trans, iter)
sorted[nr_sorted++] = iter - trans->iters;
#define btree_iter_cmp_by_idx(_l, _r) \
btree_iter_cmp(&trans->iters[_l], &trans->iters[_r])
bubble_sort(sorted, nr_sorted, btree_iter_cmp_by_idx);
#undef btree_iter_cmp_by_idx
retry_all: retry_all:
bch2_btree_iter_unlock(iter); bch2_btree_trans_unlock(trans);
if (ret != -ENOMEM && ret != -EINTR) if (ret != -ENOMEM && ret != -EINTR)
goto io_error; goto io_error;
...@@ -975,48 +987,19 @@ static int btree_iter_traverse_error(struct btree_iter *iter, int ret) ...@@ -975,48 +987,19 @@ static int btree_iter_traverse_error(struct btree_iter *iter, int ret)
} while (ret); } while (ret);
} }
/*
* Linked iters are normally a circular singly linked list - break cycle
* while we sort them:
*/
linked = iter->next;
iter->next = NULL;
sorted_iters = NULL;
while (linked) {
iter = linked;
linked = linked->next;
i = &sorted_iters;
while (*i && btree_iter_cmp(iter, *i) > 0)
i = &(*i)->next;
iter->next = *i;
*i = iter;
}
/* Make list circular again: */
iter = sorted_iters;
while (iter->next)
iter = iter->next;
iter->next = sorted_iters;
/* Now, redo traversals in correct order: */ /* Now, redo traversals in correct order: */
for (i = 0; i < nr_sorted; i++) {
iter = &trans->iters[sorted[i]];
iter = sorted_iters; do {
do { ret = __bch2_btree_iter_traverse(iter);
retry: } while (ret == -EINTR);
ret = __bch2_btree_iter_traverse(iter);
if (unlikely(ret)) {
if (ret == -EINTR)
goto retry;
goto retry_all;
}
iter = iter->next; if (ret)
} while (iter != sorted_iters); goto retry_all;
}
ret = btree_trans_has_multiple_iters(iter->trans) ? -EINTR : 0; ret = btree_trans_has_multiple_iters(trans) ? -EINTR : 0;
out: out:
bch2_btree_cache_cannibalize_unlock(c); bch2_btree_cache_cannibalize_unlock(c);
return ret; return ret;
......
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