summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKent Overstreet <kent.overstreet@linux.dev>2025-05-27 03:03:35 -0400
committerKent Overstreet <kent.overstreet@linux.dev>2025-07-05 12:42:45 -0400
commitaa7b73cc80040e67f8655326cc1fff90facf8f05 (patch)
tree51b37ac3b0902ffffe5c3e8fa1975dbf3a15e7b1
parent342812ffec0ba9c6e7708c21398283f4e7f7d339 (diff)
bcachefs: bch2_bucket_alloc_set_trans() now tries first nonblocking
Prep work for more slimming down of the allocation path Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
-rw-r--r--fs/bcachefs/alloc_foreground.c41
1 files changed, 19 insertions, 22 deletions
diff --git a/fs/bcachefs/alloc_foreground.c b/fs/bcachefs/alloc_foreground.c
index 23a9fbb36f49..a6bce46c696a 100644
--- a/fs/bcachefs/alloc_foreground.c
+++ b/fs/bcachefs/alloc_foreground.c
@@ -706,13 +706,19 @@ static int add_new_bucket(struct bch_fs *c,
inline int bch2_bucket_alloc_set_trans(struct btree_trans *trans,
struct alloc_request *req,
struct dev_stripe_state *stripe,
- struct closure *cl)
+ struct closure *_cl)
{
struct bch_fs *c = trans->c;
+ struct closure *cl = NULL;
int ret = 0;
BUG_ON(req->nr_effective >= req->nr_replicas);
+ /*
+ * Try nonblocking first, so that if one device is full we'll try from
+ * other devices:
+ */
+retry_blocking:
bch2_dev_alloc_list(c, stripe, &req->devs_may_alloc, &req->devs_sorted);
darray_for_each(req->devs_sorted, i) {
@@ -745,6 +751,14 @@ inline int bch2_bucket_alloc_set_trans(struct btree_trans *trans,
if (ret == 1)
return 0;
+
+ if (ret &&
+ !bch2_err_matches(ret, BCH_ERR_transaction_restart) &&
+ cl != _cl) {
+ cl = _cl;
+ goto retry_blocking;
+ }
+
if (ret)
return ret;
return bch_err_throw(c, insufficient_devices);
@@ -889,11 +903,10 @@ unlock:
static int __open_bucket_add_buckets(struct btree_trans *trans,
struct alloc_request *req,
- struct closure *_cl)
+ struct closure *cl)
{
struct bch_fs *c = trans->c;
struct open_bucket *ob;
- struct closure *cl = NULL;
unsigned i;
int ret;
@@ -914,25 +927,9 @@ static int __open_bucket_add_buckets(struct btree_trans *trans,
if (ret)
return ret;
- if (req->ec) {
- ret = bucket_alloc_from_stripe(trans, req, _cl);
- } else {
-retry_blocking:
- /*
- * Try nonblocking first, so that if one device is full we'll try from
- * other devices:
- */
- ret = bch2_bucket_alloc_set_trans(trans, req, &req->wp->stripe, cl);
- if (ret &&
- !bch2_err_matches(ret, BCH_ERR_transaction_restart) &&
- !bch2_err_matches(ret, BCH_ERR_insufficient_devices) &&
- !cl && _cl) {
- cl = _cl;
- goto retry_blocking;
- }
- }
-
- return ret;
+ return req->ec
+ ? bucket_alloc_from_stripe(trans, req, cl)
+ : bch2_bucket_alloc_set_trans(trans, req, &req->wp->stripe, cl);
}
static int open_bucket_add_buckets(struct btree_trans *trans,