summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--fs/bcachefs/alloc_foreground.c27
1 files changed, 10 insertions, 17 deletions
diff --git a/fs/bcachefs/alloc_foreground.c b/fs/bcachefs/alloc_foreground.c
index 1ecd635852a9..df7a28cd8491 100644
--- a/fs/bcachefs/alloc_foreground.c
+++ b/fs/bcachefs/alloc_foreground.c
@@ -710,7 +710,6 @@ int bch2_bucket_alloc_set_trans(struct btree_trans *trans,
struct dev_stripe_state *stripe)
{
struct bch_fs *c = trans->c;
- struct closure *cl = NULL;
int ret = 0;
BUG_ON(req->nr_effective >= req->nr_replicas);
@@ -722,8 +721,7 @@ int bch2_bucket_alloc_set_trans(struct btree_trans *trans,
retry_blocking:
bch2_dev_alloc_list(c, stripe, &req->devs_may_alloc, &req->devs_sorted);
- if (req->devs_sorted.nr == 1)
- req->will_retry_target_devices = false;
+ req->will_retry_target_devices = req->devs_sorted.nr > 1;
darray_for_each(req->devs_sorted, i) {
req->ca = bch2_dev_tryget_noerror(c, *i);
@@ -740,31 +738,26 @@ retry_blocking:
bch2_dev_stripe_increment_inlined(req->ca, stripe, &req->usage);
bch2_dev_put(req->ca);
- if (IS_ERR(ob)) {
+ if (IS_ERR(ob)) { /* don't squash error */
ret = PTR_ERR(ob);
- if (bch2_err_matches(ret, BCH_ERR_transaction_restart) || cl)
- break;
+ if (bch2_err_matches(ret, BCH_ERR_transaction_restart) ||
+ bch2_err_matches(ret, BCH_ERR_operation_blocked) ||
+ bch2_err_matches(ret, BCH_ERR_open_buckets_empty))
+ return ret;
continue;
}
- ret = add_new_bucket(c, req, ob);
- if (ret)
- break;
+ if (add_new_bucket(c, req, ob))
+ return 0;
}
- if (ret == 1)
- return 0;
-
- if (ret &&
- !bch2_err_matches(ret, BCH_ERR_transaction_restart) &&
+ if (bch2_err_matches(ret, BCH_ERR_freelist_empty) &&
req->will_retry_target_devices) {
req->will_retry_target_devices = false;
goto retry_blocking;
}
- if (ret)
- return ret;
- return bch_err_throw(c, insufficient_devices);
+ return ret ?: bch_err_throw(c, insufficient_devices);
}
/* Allocate from stripes: */