diff options
-rw-r--r-- | drivers/md/bcache/alloc.c | 5 | ||||
-rw-r--r-- | drivers/md/bcache/bcache.h | 4 | ||||
-rw-r--r-- | drivers/md/bcache/btree.c | 6 | ||||
-rw-r--r-- | drivers/md/bcache/extents.c | 6 | ||||
-rw-r--r-- | drivers/md/bcache/journal.c | 2 | ||||
-rw-r--r-- | drivers/md/bcache/super.c | 12 | ||||
-rw-r--r-- | drivers/md/bcache/sysfs.c | 38 | ||||
-rw-r--r-- | drivers/md/bcache/sysfs.h | 21 | ||||
-rw-r--r-- | drivers/md/bcache/util.h | 11 |
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) \ |