diff options
-rw-r--r-- | drivers/md/bcache/opts.c | 27 | ||||
-rw-r--r-- | drivers/md/bcache/opts.h | 16 | ||||
-rw-r--r-- | drivers/md/bcache/sysfs.c | 22 | ||||
-rw-r--r-- | include/uapi/linux/bcache.h | 20 |
4 files changed, 47 insertions, 38 deletions
diff --git a/drivers/md/bcache/opts.c b/drivers/md/bcache/opts.c index 523b395d65a3..249dd5d91a98 100644 --- a/drivers/md/bcache/opts.c +++ b/drivers/md/bcache/opts.c @@ -44,7 +44,7 @@ const char * const bch_str_hash_types[] = { }; enum bch_opts { -#define CACHE_SET_OPT(_name, _bits, _options, _sb_opt, _perm) \ +#define CACHE_SET_OPT(_name, _choices, _min, _max, _sb_opt, _perm) \ Opt_##_name, CACHE_SET_VISIBLE_OPTS() @@ -56,7 +56,7 @@ enum bch_opts { struct bch_option { const char *name; const char * const *opts; - unsigned long max; + unsigned long min, max; }; struct bch_opt_result { @@ -78,6 +78,7 @@ static int parse_bool_opt(const struct bch_option *opt, const char *s) static int parse_uint_opt(const struct bch_option *opt, const char *s) { unsigned long v; + int ret; if (strncmp(opt->name, s, strlen(opt->name))) return -1; @@ -89,7 +90,14 @@ static int parse_uint_opt(const struct bch_option *opt, const char *s) s++; - return kstrtoul(s, 10, &v) ?: v < opt->max ? v : -ERANGE; + ret = kstrtoul(s, 10, &v); + if (ret) + return ret; + + if (v < opt->min || v >= opt->max) + return -ERANGE; + + return 0; } static int parse_string_opt(const struct bch_option *opt, const char *s) @@ -110,11 +118,12 @@ static int parse_string_opt(const struct bch_option *opt, const char *s) static struct bch_opt_result parse_one_opt(const char *opt) { static const struct bch_option opt_table[] = { -#define CACHE_SET_OPT(_name, _options, _nr_opts, _sb_opt, _perm) \ +#define CACHE_SET_OPT(_name, _choices, _min, _max, _sb_opt, _perm) \ [Opt_##_name] = { \ .name = #_name, \ - .opts = _options, \ - .max = _nr_opts, \ + .opts = _choices, \ + .min = _min, \ + .max = _max, \ }, CACHE_SET_VISIBLE_OPTS() #undef CACHE_SET_OPT @@ -151,9 +160,9 @@ int bch_parse_options(struct cache_set_opts *opts, int flags, char *options) struct bch_opt_result res = parse_one_opt(p); switch (res.opt) { -#define CACHE_SET_OPT(_name, _options, _nr_opts, _sb_opt, _perm)\ - case Opt_##_name: \ - opts->_name = res.val; \ +#define CACHE_SET_OPT(_name, _choices, _min, _max, _sb_opt, _perm) \ + case Opt_##_name: \ + opts->_name = res.val; \ break; CACHE_SET_VISIBLE_OPTS() diff --git a/drivers/md/bcache/opts.h b/drivers/md/bcache/opts.h index 87a1a290babe..bd490aa91b79 100644 --- a/drivers/md/bcache/opts.h +++ b/drivers/md/bcache/opts.h @@ -30,24 +30,24 @@ LE64_BITMASK(NO_SB_OPT, struct cache_sb, flags, 0, 0); #define CACHE_SET_VISIBLE_OPTS() \ CACHE_SET_OPT(verbose_recovery, \ - bch_bool_opt, 2, \ + bch_bool_opt, 0, 2, \ NO_SB_OPT, false) \ CACHE_SET_OPT(posix_acl, \ - bch_bool_opt, 2, \ + bch_bool_opt, 0, 2, \ NO_SB_OPT, false) \ CACHE_SET_OPT(journal_flush_disabled, \ - bch_bool_opt, 2, \ + bch_bool_opt, 0, 2, \ NO_SB_OPT, true) \ CACHE_SET_SB_OPTS() #define CACHE_SET_OPTS() \ CACHE_SET_OPT(read_only, \ - bch_bool_opt, 2, \ + bch_bool_opt, 0, 2, \ NO_SB_OPT, 0) \ CACHE_SET_VISIBLE_OPTS() struct cache_set_opts { -#define CACHE_SET_OPT(_name, _opts, _nr_opts, _sb_opt, _perm) \ +#define CACHE_SET_OPT(_name, _choices, _min, _max, _sb_opt, _perm)\ s8 _name; CACHE_SET_OPTS() @@ -69,7 +69,7 @@ static inline struct cache_set_opts cache_set_opts_empty(void) static inline struct cache_set_opts cache_superblock_opts(struct cache_sb *sb) { return (struct cache_set_opts) { -#define CACHE_SET_OPT(_name, _options, _nr_opts, _sb_opt, _perm)\ +#define CACHE_SET_OPT(_name, _choices, _min, _max, _sb_opt, _perm)\ ._name = _sb_opt##_BITS ? _sb_opt(sb) : 0, CACHE_SET_OPTS() @@ -80,8 +80,8 @@ static inline struct cache_set_opts cache_superblock_opts(struct cache_sb *sb) static inline void cache_set_opts_apply(struct cache_set_opts *dst, struct cache_set_opts src) { -#define CACHE_SET_OPT(_name, _options, _nr_opts, _sb_opt, _perm)\ - BUILD_BUG_ON(_nr_opts > S8_MAX); \ +#define CACHE_SET_OPT(_name, _choices, _min, _max, _sb_opt, _perm)\ + BUILD_BUG_ON(_max > S8_MAX); \ if (src._name >= 0) \ dst->_name = src._name; diff --git a/drivers/md/bcache/sysfs.c b/drivers/md/bcache/sysfs.c index 02961774496d..61d01bfd66a6 100644 --- a/drivers/md/bcache/sysfs.c +++ b/drivers/md/bcache/sysfs.c @@ -166,10 +166,10 @@ read_attribute(tier); BCH_DEBUG_PARAMS() #undef BCH_DEBUG_PARAM -#define CACHE_SET_OPT(_name, _options, _nr_opts, _sb_opt, _writeable) \ +#define CACHE_SET_OPT(_name, _choices, _min, _max, _sb_opt, _perm) \ static struct attribute sysfs_opt_##_name = { \ .name = #_name, \ - .mode = S_IRUGO|(_writeable ? S_IWUSR : 0) \ + .mode = S_IRUGO|(_perm ? S_IWUSR : 0) \ }; CACHE_SET_VISIBLE_OPTS() @@ -967,12 +967,12 @@ SHOW(bch_cache_set_opts_dir) { struct cache_set *c = container_of(kobj, struct cache_set, opts_dir); -#define CACHE_SET_OPT(_name, _options, _nr_opts, _sb_opt, _perm) \ +#define CACHE_SET_OPT(_name, _choices, _min, _max, _sb_opt, _perm) \ if (attr == &sysfs_opt_##_name) \ - return _options == bch_bool_opt || _options == bch_uint_opt\ + return _choices == bch_bool_opt || _choices == bch_uint_opt\ ? snprintf(buf, PAGE_SIZE, "%i\n", c->opts._name)\ : bch_snprint_string_list(buf, PAGE_SIZE, \ - _options, c->opts._name);\ + _choices, c->opts._name);\ CACHE_SET_VISIBLE_OPTS() #undef CACHE_SET_OPT @@ -984,12 +984,12 @@ STORE(bch_cache_set_opts_dir) { struct cache_set *c = container_of(kobj, struct cache_set, opts_dir); -#define CACHE_SET_OPT(_name, _options, _nr_opts, _sb_opt, _perm) \ +#define CACHE_SET_OPT(_name, _choices, _min, _max, _sb_opt, _perm) \ if (attr == &sysfs_opt_##_name) { \ - ssize_t v = (_options == bch_bool_opt || \ - _options == bch_uint_opt) \ - ? strtoul_restrict_or_return(buf, 0, _nr_opts - 1)\ - : bch_read_string_list(buf, _options); \ + ssize_t v = (_choices == bch_bool_opt || \ + _choices == bch_uint_opt) \ + ? strtoul_restrict_or_return(buf, _min, _max - 1)\ + : bch_read_string_list(buf, _choices); \ \ if (v < 0) \ return v; \ @@ -1015,7 +1015,7 @@ static void bch_cache_set_opts_dir_release(struct kobject *k) } static struct attribute *bch_cache_set_opts_dir_files[] = { -#define CACHE_SET_OPT(_name, _options, _nr_opts, _sb_opt, _perm) \ +#define CACHE_SET_OPT(_name, _choices, _min, _max, _sb_opt, _perm) \ &sysfs_opt_##_name, CACHE_SET_VISIBLE_OPTS() diff --git a/include/uapi/linux/bcache.h b/include/uapi/linux/bcache.h index bce0838f7760..0b04508c0a7b 100644 --- a/include/uapi/linux/bcache.h +++ b/include/uapi/linux/bcache.h @@ -785,7 +785,7 @@ LE64_BITMASK(CACHE_INODE_32BIT, struct cache_sb, flags, 56, 57); /* options: */ /** - * CACHE_SET_OPT(name, nr_bits, choices, sb_option, sysfs_writeable) + * CACHE_SET_OPT(name, choices, min, max, sb_option, sysfs_writeable) * * @name - name of mount option, sysfs attribute, and struct cache_set_opts * member @@ -796,7 +796,7 @@ LE64_BITMASK(CACHE_INODE_32BIT, struct cache_sb, flags, 56, 57); * Booleans are special cased; if @choices is bch_bool_opt the mount * options name and noname will work as expected. * - * @nr_opts - i.e. 2 for booleans + * @min, @max * * @sb_option - name of corresponding superblock option * @@ -806,41 +806,41 @@ LE64_BITMASK(CACHE_INODE_32BIT, struct cache_sb, flags, 56, 57); #define CACHE_SET_SB_OPTS() \ CACHE_SET_OPT(errors, \ bch_error_actions, \ - BCH_NR_ERROR_ACTIONS, \ + 0, BCH_NR_ERROR_ACTIONS, \ CACHE_ERROR_ACTION, \ true) \ CACHE_SET_OPT(metadata_replicas, \ bch_uint_opt, \ - BCH_REPLICAS_MAX, \ + 0, BCH_REPLICAS_MAX, \ CACHE_SET_META_REPLICAS_WANT, \ false) \ CACHE_SET_OPT(data_replicas, \ bch_uint_opt, \ - BCH_REPLICAS_MAX, \ + 0, BCH_REPLICAS_MAX, \ CACHE_SET_DATA_REPLICAS_WANT, \ false) \ CACHE_SET_OPT(metadata_checksum, \ bch_csum_types, \ - BCH_CSUM_NR, \ + 0, BCH_CSUM_NR, \ CACHE_META_PREFERRED_CSUM_TYPE, \ true) \ CACHE_SET_OPT(data_checksum, \ bch_csum_types, \ - BCH_CSUM_NR, \ + 0, BCH_CSUM_NR, \ CACHE_DATA_PREFERRED_CSUM_TYPE, \ true) \ CACHE_SET_OPT(compression, \ bch_compression_types, \ - BCH_COMPRESSION_NR, \ + 0, BCH_COMPRESSION_NR, \ CACHE_COMPRESSION_TYPE, \ true) \ CACHE_SET_OPT(str_hash, \ bch_str_hash_types, \ - BCH_STR_HASH_NR, \ + 0, BCH_STR_HASH_NR, \ CACHE_SET_STR_HASH_TYPE, \ true) \ CACHE_SET_OPT(inodes_32bit, \ - bch_bool_opt, 2, \ + bch_bool_opt, 0, 2, \ CACHE_INODE_32BIT, \ true) \ |