From 2c7dd446d91681e90396c82e20c703b93f8daa2f Mon Sep 17 00:00:00 2001 From: Kent Overstreet Date: Fri, 17 Feb 2023 20:50:55 -0500 Subject: [PATCH] bcachefs: Erasure coding now uses bch2_bucket_alloc_trans This code predates plumbing btree_trans through the bucket allocation path: switching to it fixes a deadlock due to using multiple btree_trans at the same time, which we never want to do. Signed-off-by: Kent Overstreet --- fs/bcachefs/alloc_foreground.c | 29 ++++++----------------------- fs/bcachefs/alloc_foreground.h | 2 +- fs/bcachefs/ec.c | 13 +++++++------ fs/bcachefs/ec.h | 2 +- 4 files changed, 15 insertions(+), 31 deletions(-) diff --git a/fs/bcachefs/alloc_foreground.c b/fs/bcachefs/alloc_foreground.c index 9e1c236d57b8..2eab63b90664 100644 --- a/fs/bcachefs/alloc_foreground.c +++ b/fs/bcachefs/alloc_foreground.c @@ -713,7 +713,7 @@ static void add_new_bucket(struct bch_fs *c, ob_push(c, ptrs, ob); } -static int bch2_bucket_alloc_set_trans(struct btree_trans *trans, +int bch2_bucket_alloc_set_trans(struct btree_trans *trans, struct open_buckets *ptrs, struct dev_stripe_state *stripe, struct bch_devs_mask *devs_may_alloc, @@ -779,24 +779,6 @@ static int bch2_bucket_alloc_set_trans(struct btree_trans *trans, return ret; } -int bch2_bucket_alloc_set(struct bch_fs *c, - struct open_buckets *ptrs, - struct dev_stripe_state *stripe, - struct bch_devs_mask *devs_may_alloc, - unsigned nr_replicas, - unsigned *nr_effective, - bool *have_cache, - enum alloc_reserve reserve, - unsigned flags, - struct closure *cl) -{ - return bch2_trans_do(c, NULL, NULL, 0, - bch2_bucket_alloc_set_trans(&trans, ptrs, stripe, - devs_may_alloc, nr_replicas, - nr_effective, have_cache, reserve, - flags, cl)); -} - /* Allocate from stripes: */ /* @@ -805,7 +787,7 @@ int bch2_bucket_alloc_set(struct bch_fs *c, * it's to a device we don't want: */ -static int bucket_alloc_from_stripe(struct bch_fs *c, +static int bucket_alloc_from_stripe(struct btree_trans *trans, struct open_buckets *ptrs, struct write_point *wp, struct bch_devs_mask *devs_may_alloc, @@ -817,6 +799,7 @@ static int bucket_alloc_from_stripe(struct bch_fs *c, unsigned flags, struct closure *cl) { + struct bch_fs *c = trans->c; struct dev_alloc_list devs_sorted; struct ec_stripe_head *h; struct open_bucket *ob; @@ -832,11 +815,11 @@ static int bucket_alloc_from_stripe(struct bch_fs *c, if (ec_open_bucket(c, ptrs)) return 0; - h = bch2_ec_stripe_head_get(c, target, 0, nr_replicas - 1, + h = bch2_ec_stripe_head_get(trans, target, 0, nr_replicas - 1, wp == &c->copygc_write_point, cl); if (IS_ERR(h)) - return -PTR_ERR(h); + return PTR_ERR(h); if (!h) return 0; @@ -942,7 +925,7 @@ static int open_bucket_add_buckets(struct btree_trans *trans, } if (!ec_open_bucket(c, ptrs)) { - ret = bucket_alloc_from_stripe(c, ptrs, wp, &devs, + ret = bucket_alloc_from_stripe(trans, ptrs, wp, &devs, target, erasure_code, nr_replicas, nr_effective, have_cache, flags, _cl); diff --git a/fs/bcachefs/alloc_foreground.h b/fs/bcachefs/alloc_foreground.h index 26e986f2385b..ba7a87afda0e 100644 --- a/fs/bcachefs/alloc_foreground.h +++ b/fs/bcachefs/alloc_foreground.h @@ -150,7 +150,7 @@ static inline bool bch2_bucket_is_open_safe(struct bch_fs *c, unsigned dev, u64 return ret; } -int bch2_bucket_alloc_set(struct bch_fs *, struct open_buckets *, +int bch2_bucket_alloc_set_trans(struct btree_trans *, struct open_buckets *, struct dev_stripe_state *, struct bch_devs_mask *, unsigned, unsigned *, bool *, enum alloc_reserve, unsigned, struct closure *); diff --git a/fs/bcachefs/ec.c b/fs/bcachefs/ec.c index 879df8bd1f51..ca3e4a18e28a 100644 --- a/fs/bcachefs/ec.c +++ b/fs/bcachefs/ec.c @@ -1294,9 +1294,10 @@ found: return h; } -static int new_stripe_alloc_buckets(struct bch_fs *c, struct ec_stripe_head *h, +static int new_stripe_alloc_buckets(struct btree_trans *trans, struct ec_stripe_head *h, struct closure *cl) { + struct bch_fs *c = trans->c; struct bch_devs_mask devs = h->devs; struct open_bucket *ob; struct open_buckets buckets; @@ -1319,7 +1320,7 @@ static int new_stripe_alloc_buckets(struct bch_fs *c, struct ec_stripe_head *h, buckets.nr = 0; if (nr_have_parity < h->s->nr_parity) { - ret = bch2_bucket_alloc_set(c, &buckets, + ret = bch2_bucket_alloc_set_trans(trans, &buckets, &h->parity_stripe, &devs, h->s->nr_parity, @@ -1348,7 +1349,7 @@ static int new_stripe_alloc_buckets(struct bch_fs *c, struct ec_stripe_head *h, buckets.nr = 0; if (nr_have_data < h->s->nr_data) { - ret = bch2_bucket_alloc_set(c, &buckets, + ret = bch2_bucket_alloc_set_trans(trans, &buckets, &h->block_stripe, &devs, h->s->nr_data, @@ -1464,13 +1465,14 @@ static int __bch2_ec_stripe_head_reserve(struct bch_fs *c, h->s->nr_parity, 0); } -struct ec_stripe_head *bch2_ec_stripe_head_get(struct bch_fs *c, +struct ec_stripe_head *bch2_ec_stripe_head_get(struct btree_trans *trans, unsigned target, unsigned algo, unsigned redundancy, bool copygc, struct closure *cl) { + struct bch_fs *c = trans->c; struct ec_stripe_head *h; int ret; bool needs_stripe_new; @@ -1509,7 +1511,7 @@ struct ec_stripe_head *bch2_ec_stripe_head_get(struct bch_fs *c, } if (!h->s->allocated) { - ret = new_stripe_alloc_buckets(c, h, cl); + ret = new_stripe_alloc_buckets(trans, h, cl); if (ret) goto err; @@ -1517,7 +1519,6 @@ struct ec_stripe_head *bch2_ec_stripe_head_get(struct bch_fs *c, } return h; - err: bch2_ec_stripe_head_put(c, h); return ERR_PTR(ret); diff --git a/fs/bcachefs/ec.h b/fs/bcachefs/ec.h index d47da7d86fe7..37d42e2a4505 100644 --- a/fs/bcachefs/ec.h +++ b/fs/bcachefs/ec.h @@ -200,7 +200,7 @@ void bch2_ec_bucket_cancel(struct bch_fs *, struct open_bucket *); int bch2_ec_stripe_new_alloc(struct bch_fs *, struct ec_stripe_head *); void bch2_ec_stripe_head_put(struct bch_fs *, struct ec_stripe_head *); -struct ec_stripe_head *bch2_ec_stripe_head_get(struct bch_fs *, +struct ec_stripe_head *bch2_ec_stripe_head_get(struct btree_trans *, unsigned, unsigned, unsigned, bool, struct closure *); void bch2_stripes_heap_update(struct bch_fs *, struct stripe *, size_t);