summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKent Overstreet <kent.overstreet@gmail.com>2020-12-15 12:53:30 -0500
committerKent Overstreet <kent.overstreet@gmail.com>2020-12-17 14:08:26 -0500
commit369468267c93e7c7f4277aec398d5eee882b1b3b (patch)
tree632552f898134e7dd02e40cee88c082d3a5de04a
parent34881783a2bdfa44308d9e2d06b0d79b7453b547 (diff)
bcachefs: Use separate new stripes for copygc and non-copygc
Allocations for copygc have to be kept separate from everything else, so that copygc doesn't get starved. Signed-off-by: Kent Overstreet <kent.overstreet@gmail.com>
-rw-r--r--fs/bcachefs/alloc_foreground.c4
-rw-r--r--fs/bcachefs/alloc_types.h1
-rw-r--r--fs/bcachefs/ec.c27
-rw-r--r--fs/bcachefs/ec.h3
4 files changed, 23 insertions, 12 deletions
diff --git a/fs/bcachefs/alloc_foreground.c b/fs/bcachefs/alloc_foreground.c
index 0c5c69d643f6..6d016592fbe1 100644
--- a/fs/bcachefs/alloc_foreground.c
+++ b/fs/bcachefs/alloc_foreground.c
@@ -486,7 +486,9 @@ 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, cl);
+ h = bch2_ec_stripe_head_get(c, target, 0, nr_replicas - 1,
+ wp == &c->copygc_write_point,
+ cl);
if (IS_ERR(h))
return -PTR_ERR(h);
if (!h)
diff --git a/fs/bcachefs/alloc_types.h b/fs/bcachefs/alloc_types.h
index 20705460bb0a..61938ed64605 100644
--- a/fs/bcachefs/alloc_types.h
+++ b/fs/bcachefs/alloc_types.h
@@ -89,7 +89,6 @@ struct write_point {
u64 last_used;
unsigned long write_point;
enum bch_data_type type;
- bool is_ec;
/* calculated based on how many pointers we're actually going to use: */
unsigned sectors_free;
diff --git a/fs/bcachefs/ec.c b/fs/bcachefs/ec.c
index 903b81744c8f..c0ff0e0120d1 100644
--- a/fs/bcachefs/ec.c
+++ b/fs/bcachefs/ec.c
@@ -1158,7 +1158,8 @@ static int ec_new_stripe_alloc(struct bch_fs *c, struct ec_stripe_head *h)
static struct ec_stripe_head *
ec_new_stripe_head_alloc(struct bch_fs *c, unsigned target,
- unsigned algo, unsigned redundancy)
+ unsigned algo, unsigned redundancy,
+ bool copygc)
{
struct ec_stripe_head *h;
struct bch_dev *ca;
@@ -1174,6 +1175,7 @@ ec_new_stripe_head_alloc(struct bch_fs *c, unsigned target,
h->target = target;
h->algo = algo;
h->redundancy = redundancy;
+ h->copygc = copygc;
rcu_read_lock();
h->devs = target_rw_devs(c, BCH_DATA_user, target);
@@ -1205,9 +1207,10 @@ void bch2_ec_stripe_head_put(struct bch_fs *c, struct ec_stripe_head *h)
}
struct ec_stripe_head *__bch2_ec_stripe_head_get(struct bch_fs *c,
- unsigned target,
- unsigned algo,
- unsigned redundancy)
+ unsigned target,
+ unsigned algo,
+ unsigned redundancy,
+ bool copygc)
{
struct ec_stripe_head *h;
@@ -1218,12 +1221,13 @@ struct ec_stripe_head *__bch2_ec_stripe_head_get(struct bch_fs *c,
list_for_each_entry(h, &c->ec_stripe_head_list, list)
if (h->target == target &&
h->algo == algo &&
- h->redundancy == redundancy) {
+ h->redundancy == redundancy &&
+ h->copygc == copygc) {
mutex_lock(&h->lock);
goto found;
}
- h = ec_new_stripe_head_alloc(c, target, algo, redundancy);
+ h = ec_new_stripe_head_alloc(c, target, algo, redundancy, copygc);
found:
mutex_unlock(&c->ec_stripe_head_lock);
return h;
@@ -1268,7 +1272,9 @@ new_stripe_alloc_buckets(struct bch_fs *c, struct ec_stripe_head *h,
h->redundancy,
&nr_have,
&have_cache,
- RESERVE_NONE,
+ h->copygc
+ ? RESERVE_MOVINGGC
+ : RESERVE_NONE,
0,
cl);
if (ret)
@@ -1284,7 +1290,9 @@ new_stripe_alloc_buckets(struct bch_fs *c, struct ec_stripe_head *h,
nr_data,
&nr_have,
&have_cache,
- RESERVE_NONE,
+ h->copygc
+ ? RESERVE_MOVINGGC
+ : RESERVE_NONE,
0,
cl);
if (ret)
@@ -1353,6 +1361,7 @@ struct ec_stripe_head *bch2_ec_stripe_head_get(struct bch_fs *c,
unsigned target,
unsigned algo,
unsigned redundancy,
+ bool copygc,
struct closure *cl)
{
struct ec_stripe_head *h;
@@ -1361,7 +1370,7 @@ struct ec_stripe_head *bch2_ec_stripe_head_get(struct bch_fs *c,
s64 idx;
int ret;
- h = __bch2_ec_stripe_head_get(c, target, algo, redundancy);
+ h = __bch2_ec_stripe_head_get(c, target, algo, redundancy, copygc);
if (!h) {
bch_err(c, "no stripe head");
return NULL;
diff --git a/fs/bcachefs/ec.h b/fs/bcachefs/ec.h
index 3f1999bae6d4..97a263cf9c87 100644
--- a/fs/bcachefs/ec.h
+++ b/fs/bcachefs/ec.h
@@ -122,6 +122,7 @@ struct ec_stripe_head {
unsigned target;
unsigned algo;
unsigned redundancy;
+ bool copygc;
struct bch_devs_mask devs;
unsigned nr_active_devs;
@@ -147,7 +148,7 @@ 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 *,
- unsigned, unsigned, unsigned, struct closure *);
+ unsigned, unsigned, unsigned, bool, struct closure *);
void bch2_stripes_heap_update(struct bch_fs *, struct stripe *, size_t);
void bch2_stripes_heap_del(struct bch_fs *, struct stripe *, size_t);