summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--drivers/md/bcache/alloc.c5
-rw-r--r--drivers/md/bcache/bcache.h4
-rw-r--r--drivers/md/bcache/btree.c6
-rw-r--r--drivers/md/bcache/extents.c6
-rw-r--r--drivers/md/bcache/journal.c2
-rw-r--r--drivers/md/bcache/super.c12
-rw-r--r--drivers/md/bcache/sysfs.c38
-rw-r--r--drivers/md/bcache/sysfs.h21
-rw-r--r--drivers/md/bcache/util.h11
9 files changed, 76 insertions, 29 deletions
diff --git a/drivers/md/bcache/alloc.c b/drivers/md/bcache/alloc.c
index b7e1065413d6..aba5b8ea25aa 100644
--- a/drivers/md/bcache/alloc.c
+++ b/drivers/md/bcache/alloc.c
@@ -733,7 +733,7 @@ int bch_bucket_alloc_set(struct cache_set *c, enum alloc_reserve reserve,
int i, ret;
mutex_lock(&c->bucket_lock);
- BUG_ON(!n || n > c->sb.nr_in_set || n > MAX_CACHES_PER_SET);
+ BUG_ON(!n || n > BKEY_EXTENT_PTRS_MAX);
bkey_init(k);
memset(caches_used, 0, sizeof(caches_used));
@@ -915,7 +915,8 @@ retry:
goto found;
spin_unlock(&c->open_buckets_lock);
- b = bch_open_bucket_alloc(c, RESERVE_NONE, c->data_replicas,
+ b = bch_open_bucket_alloc(c, RESERVE_NONE,
+ CACHE_SET_DATA_REPLICAS_WANT(&c->sb),
tier_idx, cl);
spin_lock(&c->open_buckets_lock);
diff --git a/drivers/md/bcache/bcache.h b/drivers/md/bcache/bcache.h
index b81f9071da0f..7b78492d07f8 100644
--- a/drivers/md/bcache/bcache.h
+++ b/drivers/md/bcache/bcache.h
@@ -856,10 +856,6 @@ struct cache_set {
unsigned tiering_enabled:1;
unsigned tiering_percent;
unsigned btree_scan_ratelimit;
-
- /* number of caches to replicate data on */
- unsigned short meta_replicas;
- unsigned short data_replicas;
};
struct bbio {
diff --git a/drivers/md/bcache/btree.c b/drivers/md/bcache/btree.c
index 2396a686d69c..cb0489214ca3 100644
--- a/drivers/md/bcache/btree.c
+++ b/drivers/md/bcache/btree.c
@@ -1295,7 +1295,8 @@ static struct btree *bch_btree_node_alloc(struct cache_set *c,
retry:
if (bch_bucket_alloc_set(c, reserve, &k.key,
- c->meta_replicas, 0, NULL))
+ CACHE_SET_META_REPLICAS_WANT(&c->sb),
+ 0, NULL))
goto err;
SET_KEY_SIZE(&k.key, c->btree_pages * PAGE_SECTORS);
@@ -1473,7 +1474,8 @@ u8 __bch_btree_mark_key(struct cache_set *c, int level, struct bkey *k)
{
uint8_t stale = 0;
unsigned replicas_found = 0, replicas_needed = level
- ? c->meta_replicas : c->data_replicas;
+ ? CACHE_SET_META_REPLICAS_WANT(&c->sb)
+ : CACHE_SET_DATA_REPLICAS_WANT(&c->sb);
struct cache *ca;
struct bucket *g;
int i;
diff --git a/drivers/md/bcache/extents.c b/drivers/md/bcache/extents.c
index ff9db154ddda..58c1f7daea67 100644
--- a/drivers/md/bcache/extents.c
+++ b/drivers/md/bcache/extents.c
@@ -534,7 +534,8 @@ static void bch_add_sectors(struct bkey *k,
u64 offset,
int sectors)
{
- unsigned replicas_found = 0, replicas_needed = c->data_replicas;
+ unsigned replicas_found = 0, replicas_needed =
+ CACHE_SET_DATA_REPLICAS_WANT(&c->sb);
struct cache *ca;
int i;
@@ -821,7 +822,8 @@ static bool bch_extent_debug_invalid(struct btree_keys *bk, struct bkey *k)
return true;
}
- replicas_needed = KEY_CACHED(k) ? 0 : c->data_replicas;
+ replicas_needed = KEY_CACHED(k) ? 0
+ : CACHE_SET_DATA_REPLICAS_WANT(&c->sb);
rcu_read_lock();
diff --git a/drivers/md/bcache/journal.c b/drivers/md/bcache/journal.c
index 1e38e2cbcfdb..25567a0d2643 100644
--- a/drivers/md/bcache/journal.c
+++ b/drivers/md/bcache/journal.c
@@ -634,7 +634,7 @@ static void journal_reclaim(struct cache_set *c)
bch_set_extent_ptrs(k, bch_extent_ptrs(k) + 1);
- if (bch_extent_ptrs(k) == c->meta_replicas)
+ if (bch_extent_ptrs(k) == CACHE_SET_META_REPLICAS_WANT(&c->sb))
break;
}
diff --git a/drivers/md/bcache/super.c b/drivers/md/bcache/super.c
index cec6e2037841..7cc5f0c3c2e6 100644
--- a/drivers/md/bcache/super.c
+++ b/drivers/md/bcache/super.c
@@ -174,6 +174,16 @@ static const char *validate_super(struct bcache_superblock *disk_sb,
if (sb->keys < bch_journal_buckets_offset(sb))
goto err;
+ err = "Invalid number of metadata replicas";
+ if (!CACHE_SET_META_REPLICAS_WANT(sb) ||
+ CACHE_SET_META_REPLICAS_WANT(sb) >= BKEY_EXTENT_PTRS_MAX)
+ goto err;
+
+ err = "Invalid number of data replicas";
+ if (!CACHE_SET_DATA_REPLICAS_WANT(sb) ||
+ CACHE_SET_DATA_REPLICAS_WANT(sb) >= BKEY_EXTENT_PTRS_MAX)
+ goto err;
+
err = "Invalid checksum type";
if (CACHE_SB_CSUM_TYPE(sb) >= BCH_CSUM_NR)
goto err;
@@ -1579,8 +1589,6 @@ static struct cache_set *bch_cache_set_alloc(struct cache *ca)
c->btree_scan_ratelimit = 30;
- c->meta_replicas = 1;
- c->data_replicas = 1;
c->copy_gc_enabled = 1;
c->tiering_enabled = 1;
c->tiering_percent = 10;
diff --git a/drivers/md/bcache/sysfs.c b/drivers/md/bcache/sysfs.c
index 1c42dda99bcc..66ae1b53d8c9 100644
--- a/drivers/md/bcache/sysfs.c
+++ b/drivers/md/bcache/sysfs.c
@@ -364,8 +364,7 @@ STORE(__bch_flash_dev)
sysfs_strtoul(data_csum, d->data_csum);
if (attr == &sysfs_size) {
- uint64_t v;
- strtoi_h_or_return(buf, v);
+ u64 v = strtoi_h_or_return(buf);
mutex_lock(&d->inode_lock);
@@ -582,8 +581,10 @@ SHOW(__bch_cache_set)
sysfs_print(btree_scan_ratelimit, c->btree_scan_ratelimit);
sysfs_print(tiering_percent, c->tiering_percent);
- sysfs_printf(meta_replicas, "%u", c->meta_replicas);
- sysfs_printf(data_replicas, "%u", c->data_replicas);
+ sysfs_printf(meta_replicas, "%llu",
+ CACHE_SET_META_REPLICAS_WANT(&c->sb));
+ sysfs_printf(data_replicas, "%llu",
+ CACHE_SET_DATA_REPLICAS_WANT(&c->sb));
if (!test_bit(CACHE_SET_RUNNING, &c->flags))
return -EPERM;
@@ -692,10 +693,25 @@ STORE(__bch_cache_set)
sysfs_pd_controller_store(tiering, &c->tiering_pd);
- sysfs_strtoul_clamp(meta_replicas,
- c->meta_replicas, 1, BKEY_EXTENT_PTRS_MAX);
- sysfs_strtoul_clamp(data_replicas,
- c->data_replicas, 1, BKEY_EXTENT_PTRS_MAX);
+ if (attr == &sysfs_meta_replicas) {
+ unsigned v = strtoul_restrict_or_return(buf, 1,
+ BKEY_EXTENT_PTRS_MAX - 1);
+
+ if (v != CACHE_SET_META_REPLICAS_WANT(&c->sb)) {
+ SET_CACHE_SET_META_REPLICAS_WANT(&c->sb, v);
+ bcache_write_super(c);
+ }
+ }
+
+ if (attr == &sysfs_data_replicas) {
+ unsigned v = strtoul_restrict_or_return(buf, 1,
+ BKEY_EXTENT_PTRS_MAX - 1);
+
+ if (v != CACHE_SET_DATA_REPLICAS_WANT(&c->sb)) {
+ SET_CACHE_SET_DATA_REPLICAS_WANT(&c->sb, v);
+ bcache_write_super(c);
+ }
+ }
if (!test_bit(CACHE_SET_RUNNING, &c->flags))
return -EPERM;
@@ -718,11 +734,9 @@ STORE(__bch_cache_set)
}
if (attr == &sysfs_flash_vol_create) {
- int r;
- u64 v;
+ u64 v = strtoi_h_or_return(buf);
+ int r = bch_flash_dev_create(c, v);
- strtoi_h_or_return(buf, v);
- r = bch_flash_dev_create(c, v);
if (r)
return r;
}
diff --git a/drivers/md/bcache/sysfs.h b/drivers/md/bcache/sysfs.h
index 0526fe92a683..bfb25afd1499 100644
--- a/drivers/md/bcache/sysfs.h
+++ b/drivers/md/bcache/sysfs.h
@@ -1,6 +1,8 @@
#ifndef _BCACHE_SYSFS_H_
#define _BCACHE_SYSFS_H_
+#include "util.h"
+
#define KTYPE(type) \
struct kobj_type type ## _ktype = { \
.release = type ## _release, \
@@ -94,12 +96,23 @@ do { \
_v; \
})
-#define strtoi_h_or_return(cp, v) \
-do { \
- int _r = strtoi_h(cp, &v); \
+#define strtoul_restrict_or_return(cp, min, max) \
+({ \
+ unsigned long _v = 0; \
+ int _r = strtoul_safe_restrict(cp, _v, min, max); \
if (_r) \
return _r; \
-} while (0)
+ _v; \
+})
+
+#define strtoi_h_or_return(cp) \
+({ \
+ u64 _v; \
+ int _r = strtoi_h(cp, &_v); \
+ if (_r) \
+ return _r; \
+ _v; \
+})
#define sysfs_hatoi(file, var) \
do { \
diff --git a/drivers/md/bcache/util.h b/drivers/md/bcache/util.h
index bd21ae32d3f9..a6557479fb91 100644
--- a/drivers/md/bcache/util.h
+++ b/drivers/md/bcache/util.h
@@ -359,6 +359,17 @@ static inline int bch_strtoul_h(const char *cp, long *res)
_r; \
})
+#define strtoul_safe_restrict(cp, var, min, max) \
+({ \
+ unsigned long _v; \
+ int _r = kstrtoul(cp, 10, &_v); \
+ if (!_r && _v >= min && _v <= max) \
+ var = _v; \
+ else \
+ _r = -EINVAL; \
+ _r; \
+})
+
#define snprint(buf, size, var) \
snprintf(buf, size, \
__builtin_types_compatible_p(typeof(var), int) \