diff options
author | Kent Overstreet <kent.overstreet@linux.dev> | 2025-05-27 03:03:35 -0400 |
---|---|---|
committer | Kent Overstreet <kent.overstreet@linux.dev> | 2025-07-05 16:37:12 -0400 |
commit | ef68e668e4e9babdbe0fe969e060d345f67b4c05 (patch) | |
tree | 6f5ed8777500d681e6c32a846eaffed06a803062 | |
parent | 342812ffec0ba9c6e7708c21398283f4e7f7d339 (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.c | 51 |
1 files changed, 21 insertions, 30 deletions
diff --git a/fs/bcachefs/alloc_foreground.c b/fs/bcachefs/alloc_foreground.c index 23a9fbb36f49..cfb4935495b8 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) { @@ -738,16 +744,18 @@ inline int bch2_bucket_alloc_set_trans(struct btree_trans *trans, 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) - return ret; - return bch_err_throw(c, insufficient_devices); + if (ret && + !bch2_err_matches(ret, BCH_ERR_transaction_restart) && + cl != _cl) { + cl = _cl; + goto retry_blocking; + } + + return ret ?: bch_err_throw(c, insufficient_devices); } /* Allocate from stripes: */ @@ -889,11 +897,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 +921,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, |