aboutsummaryrefslogtreecommitdiff
path: root/fs
diff options
context:
space:
mode:
authorGravatar Kent Overstreet <kent.overstreet@linux.dev> 2023-02-17 20:50:55 -0500
committerGravatar Kent Overstreet <kent.overstreet@linux.dev> 2023-10-22 17:09:53 -0400
commit2c7dd446d91681e90396c82e20c703b93f8daa2f (patch)
tree14cc13b3e4ba7844d4e8bb5cb9058a23fd517526 /fs
parentbcachefs: Don't invalidate open buckets (diff)
downloadlinux-2c7dd446d91681e90396c82e20c703b93f8daa2f.tar.gz
linux-2c7dd446d91681e90396c82e20c703b93f8daa2f.tar.bz2
linux-2c7dd446d91681e90396c82e20c703b93f8daa2f.zip
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 <kent.overstreet@linux.dev>
Diffstat (limited to 'fs')
-rw-r--r--fs/bcachefs/alloc_foreground.c29
-rw-r--r--fs/bcachefs/alloc_foreground.h2
-rw-r--r--fs/bcachefs/ec.c13
-rw-r--r--fs/bcachefs/ec.h2
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);