summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKent Overstreet <kent.overstreet@gmail.com>2019-06-10 11:31:07 -0400
committerKent Overstreet <kent.overstreet@gmail.com>2019-06-10 11:34:21 -0400
commit98ce6c3477743ee65f1816168bd28f0c247b8e26 (patch)
tree8e7ed43505c9e731daa27bcd9876824bd1276ed4
parent0dfe3030cb29c317d926350c1b184903f1803680 (diff)
bcachefs: Fix promoting to cache devices (durability = 0)bcachefs-v5.0
-rw-r--r--fs/bcachefs/alloc_foreground.c78
-rw-r--r--fs/bcachefs/io.c14
2 files changed, 55 insertions, 37 deletions
diff --git a/fs/bcachefs/alloc_foreground.c b/fs/bcachefs/alloc_foreground.c
index 7fb1e5a4ca69..181dcc51741f 100644
--- a/fs/bcachefs/alloc_foreground.c
+++ b/fs/bcachefs/alloc_foreground.c
@@ -376,6 +376,25 @@ void bch2_dev_stripe_increment(struct bch_fs *c, struct bch_dev *ca,
#define BUCKET_MAY_ALLOC_PARTIAL (1 << 0)
#define BUCKET_ALLOC_USE_DURABILITY (1 << 1)
+static void add_new_bucket(struct bch_fs *c,
+ struct open_buckets *ptrs,
+ struct bch_devs_mask *devs_may_alloc,
+ unsigned *nr_effective,
+ bool *have_cache,
+ unsigned flags,
+ struct open_bucket *ob)
+{
+ unsigned durability =
+ bch_dev_bkey_exists(c, ob->ptr.dev)->mi.durability;
+
+ __clear_bit(ob->ptr.dev, devs_may_alloc->d);
+ *nr_effective += (flags & BUCKET_ALLOC_USE_DURABILITY)
+ ? durability : 1;
+ *have_cache |= !durability;
+
+ ob_push(c, ptrs, ob);
+}
+
static int bch2_bucket_alloc_set(struct bch_fs *c,
struct open_buckets *ptrs,
struct dev_stripe_state *stripe,
@@ -391,7 +410,7 @@ static int bch2_bucket_alloc_set(struct bch_fs *c,
bch2_dev_alloc_list(c, stripe, devs_may_alloc);
struct bch_dev *ca;
bool alloc_failure = false;
- unsigned i, durability;
+ unsigned i;
BUG_ON(*nr_effective >= nr_replicas);
@@ -421,14 +440,8 @@ static int bch2_bucket_alloc_set(struct bch_fs *c,
continue;
}
- durability = (flags & BUCKET_ALLOC_USE_DURABILITY)
- ? ca->mi.durability : 1;
-
- __clear_bit(ca->dev_idx, devs_may_alloc->d);
- *nr_effective += durability;
- *have_cache |= !durability;
-
- ob_push(c, ptrs, ob);
+ add_new_bucket(c, ptrs, devs_may_alloc,
+ nr_effective, have_cache, flags, ob);
bch2_dev_stripe_increment(c, ca, stripe);
@@ -523,7 +536,8 @@ static void bucket_alloc_from_stripe(struct bch_fs *c,
unsigned erasure_code,
unsigned nr_replicas,
unsigned *nr_effective,
- bool *have_cache)
+ bool *have_cache,
+ unsigned flags)
{
struct dev_alloc_list devs_sorted;
struct ec_stripe_head *h;
@@ -563,11 +577,8 @@ got_bucket:
ob->ec_idx = ec_idx;
ob->ec = h->s;
- __clear_bit(ob->ptr.dev, devs_may_alloc->d);
- *nr_effective += ca->mi.durability;
- *have_cache |= !ca->mi.durability;
-
- ob_push(c, ptrs, ob);
+ add_new_bucket(c, ptrs, devs_may_alloc,
+ nr_effective, have_cache, flags, ob);
atomic_inc(&h->s->pin);
out_put_head:
bch2_ec_stripe_head_put(h);
@@ -582,6 +593,7 @@ static void get_buckets_from_writepoint(struct bch_fs *c,
unsigned nr_replicas,
unsigned *nr_effective,
bool *have_cache,
+ unsigned flags,
bool need_ec)
{
struct open_buckets ptrs_skip = { .nr = 0 };
@@ -596,11 +608,9 @@ static void get_buckets_from_writepoint(struct bch_fs *c,
(ca->mi.durability ||
(wp->type == BCH_DATA_USER && !*have_cache)) &&
(ob->ec || !need_ec)) {
- __clear_bit(ob->ptr.dev, devs_may_alloc->d);
- *nr_effective += ca->mi.durability;
- *have_cache |= !ca->mi.durability;
-
- ob_push(c, ptrs, ob);
+ add_new_bucket(c, ptrs, devs_may_alloc,
+ nr_effective, have_cache,
+ flags, ob);
} else {
ob_push(c, &ptrs_skip, ob);
}
@@ -618,17 +628,15 @@ static int open_bucket_add_buckets(struct bch_fs *c,
unsigned *nr_effective,
bool *have_cache,
enum alloc_reserve reserve,
+ unsigned flags,
struct closure *_cl)
{
struct bch_devs_mask devs;
struct open_bucket *ob;
struct closure *cl = NULL;
- unsigned i, flags = BUCKET_ALLOC_USE_DURABILITY;
+ unsigned i;
int ret;
- if (wp->type == BCH_DATA_USER)
- flags |= BUCKET_MAY_ALLOC_PARTIAL;
-
rcu_read_lock();
devs = target_rw_devs(c, wp->type, target);
rcu_read_unlock();
@@ -643,21 +651,21 @@ static int open_bucket_add_buckets(struct bch_fs *c,
if (erasure_code) {
get_buckets_from_writepoint(c, ptrs, wp, &devs,
nr_replicas, nr_effective,
- have_cache, true);
+ have_cache, flags, true);
if (*nr_effective >= nr_replicas)
return 0;
bucket_alloc_from_stripe(c, ptrs, wp, &devs,
target, erasure_code,
nr_replicas, nr_effective,
- have_cache);
+ have_cache, flags);
if (*nr_effective >= nr_replicas)
return 0;
}
get_buckets_from_writepoint(c, ptrs, wp, &devs,
nr_replicas, nr_effective,
- have_cache, false);
+ have_cache, flags, false);
if (*nr_effective >= nr_replicas)
return 0;
@@ -862,9 +870,13 @@ struct write_point *bch2_alloc_sectors_start(struct bch_fs *c,
struct open_bucket *ob;
struct open_buckets ptrs;
unsigned nr_effective, write_points_nr;
+ unsigned ob_flags = 0;
bool have_cache;
int ret, i;
+ if (!(flags & BCH_WRITE_ONLY_SPECIFIED_DEVS))
+ ob_flags |= BUCKET_ALLOC_USE_DURABILITY;
+
BUG_ON(!nr_replicas || !nr_replicas_required);
retry:
ptrs.nr = 0;
@@ -874,6 +886,9 @@ retry:
wp = writepoint_find(c, write_point.v);
+ if (wp->type == BCH_DATA_USER)
+ ob_flags |= BUCKET_MAY_ALLOC_PARTIAL;
+
/* metadata may not allocate on cache devices: */
if (wp->type != BCH_DATA_USER)
have_cache = true;
@@ -882,19 +897,22 @@ retry:
ret = open_bucket_add_buckets(c, &ptrs, wp, devs_have,
target, erasure_code,
nr_replicas, &nr_effective,
- &have_cache, reserve, cl);
+ &have_cache, reserve,
+ ob_flags, cl);
} else {
ret = open_bucket_add_buckets(c, &ptrs, wp, devs_have,
target, erasure_code,
nr_replicas, &nr_effective,
- &have_cache, reserve, NULL);
+ &have_cache, reserve,
+ ob_flags, NULL);
if (!ret)
goto alloc_done;
ret = open_bucket_add_buckets(c, &ptrs, wp, devs_have,
0, erasure_code,
nr_replicas, &nr_effective,
- &have_cache, reserve, cl);
+ &have_cache, reserve,
+ ob_flags, cl);
}
alloc_done:
BUG_ON(!ret && nr_effective < nr_replicas);
diff --git a/fs/bcachefs/io.c b/fs/bcachefs/io.c
index dc922a9140b1..72a7dfe239a8 100644
--- a/fs/bcachefs/io.c
+++ b/fs/bcachefs/io.c
@@ -1003,23 +1003,23 @@ static inline bool should_promote(struct bch_fs *c, struct bkey_s_c k,
struct bch_io_opts opts,
unsigned flags)
{
- if (!opts.promote_target)
+ if (!bkey_extent_is_data(k.k))
return false;
if (!(flags & BCH_READ_MAY_PROMOTE))
return false;
- if (percpu_ref_is_dying(&c->writes))
- return false;
-
- if (!bkey_extent_is_data(k.k))
+ if (!opts.promote_target)
return false;
- if (bch2_extent_has_target(c, bkey_s_c_to_extent(k), opts.promote_target))
+ if (bch2_extent_has_target(c, bkey_s_c_to_extent(k),
+ opts.promote_target))
return false;
- if (bch2_target_congested(c, opts.promote_target))
+ if (bch2_target_congested(c, opts.promote_target)) {
+ /* XXX trace this */
return false;
+ }
if (rhashtable_lookup_fast(&c->promote_table, &pos,
bch_promote_params))