summaryrefslogtreecommitdiff
path: root/fs/bcachefs/ec.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/bcachefs/ec.c')
-rw-r--r--fs/bcachefs/ec.c38
1 files changed, 14 insertions, 24 deletions
diff --git a/fs/bcachefs/ec.c b/fs/bcachefs/ec.c
index 71956ee86a9c..687c3ba98095 100644
--- a/fs/bcachefs/ec.c
+++ b/fs/bcachefs/ec.c
@@ -1720,7 +1720,8 @@ err:
static int new_stripe_alloc_buckets(struct btree_trans *trans,
struct alloc_request *req,
- struct ec_stripe_head *h, struct ec_stripe_new *s)
+ struct ec_stripe_head *h, struct ec_stripe_new *s,
+ struct closure *cl)
{
struct bch_fs *c = trans->c;
struct open_bucket *ob;
@@ -1770,7 +1771,7 @@ static int new_stripe_alloc_buckets(struct btree_trans *trans,
req->nr_effective = nr_have_parity;
req->data_type = BCH_DATA_parity;
- ret = bch2_bucket_alloc_set_trans(trans, req, &h->parity_stripe);
+ ret = bch2_bucket_alloc_set_trans(trans, req, &h->parity_stripe, cl);
open_bucket_for_each(c, &req->ptrs, ob, i) {
j = find_next_zero_bit(s->blocks_gotten,
@@ -1793,7 +1794,7 @@ static int new_stripe_alloc_buckets(struct btree_trans *trans,
req->nr_effective = nr_have_data;
req->data_type = BCH_DATA_user;
- ret = bch2_bucket_alloc_set_trans(trans, req, &h->block_stripe);
+ ret = bch2_bucket_alloc_set_trans(trans, req, &h->block_stripe, cl);
open_bucket_for_each(c, &req->ptrs, ob, i) {
j = find_next_zero_bit(s->blocks_gotten,
@@ -1925,7 +1926,7 @@ static int __bch2_ec_stripe_head_reuse(struct btree_trans *trans, struct ec_stri
}
bch2_trans_iter_exit(trans, &lru_iter);
if (!ret)
- return bch_err_throw(c, stripe_alloc_blocked);
+ ret = bch_err_throw(c, stripe_alloc_blocked);
if (ret == 1)
ret = 0;
if (ret)
@@ -1997,7 +1998,8 @@ err:
struct ec_stripe_head *bch2_ec_stripe_head_get(struct btree_trans *trans,
struct alloc_request *req,
- unsigned algo)
+ unsigned algo,
+ struct closure *cl)
{
struct bch_fs *c = trans->c;
unsigned redundancy = req->nr_replicas - 1;
@@ -2039,18 +2041,12 @@ struct ec_stripe_head *bch2_ec_stripe_head_get(struct btree_trans *trans,
if (s->have_existing_stripe)
goto alloc_existing;
-
/* First, try to allocate a full stripe: */
enum bch_watermark saved_watermark = BCH_WATERMARK_stripe;
- unsigned saved_flags = req->flags | BCH_WRITE_alloc_nowait;
- swap(req->watermark, saved_watermark);
- swap(req->flags, saved_flags);
-
- ret = new_stripe_alloc_buckets(trans, req, h, s) ?:
+ swap(req->watermark, saved_watermark);
+ ret = new_stripe_alloc_buckets(trans, req, h, s, NULL) ?:
__bch2_ec_stripe_head_reserve(trans, h, s);
-
- swap(req->watermark, saved_watermark);
- swap(req->flags, saved_flags);
+ swap(req->watermark, saved_watermark);
if (!ret)
goto allocate_buf;
@@ -2066,25 +2062,19 @@ struct ec_stripe_head *bch2_ec_stripe_head_get(struct btree_trans *trans,
ret = __bch2_ec_stripe_head_reuse(trans, h, s);
if (!ret)
break;
- if (waiting ||
- (req->flags & BCH_WRITE_alloc_nowait) ||
- ret != -BCH_ERR_stripe_alloc_blocked)
+ if (waiting || !cl || ret != -BCH_ERR_stripe_alloc_blocked)
goto err;
if (req->watermark == BCH_WATERMARK_copygc) {
- /* Don't self-deadlock copygc */
- swap(req->flags, saved_flags);
- ret = new_stripe_alloc_buckets(trans, req, h, s) ?:
+ ret = new_stripe_alloc_buckets(trans, req, h, s, NULL) ?:
__bch2_ec_stripe_head_reserve(trans, h, s);
- swap(req->flags, saved_flags);
-
if (ret)
goto err;
goto allocate_buf;
}
/* XXX freelist_wait? */
- closure_wait(&c->freelist_wait, req->cl);
+ closure_wait(&c->freelist_wait, cl);
waiting = true;
}
@@ -2095,7 +2085,7 @@ alloc_existing:
* Retry allocating buckets, with the watermark for this
* particular write:
*/
- ret = new_stripe_alloc_buckets(trans, req, h, s);
+ ret = new_stripe_alloc_buckets(trans, req, h, s, cl);
if (ret)
goto err;