diff options
author | Al Viro <viro@zeniv.linux.org.uk> | 2019-12-18 06:02:31 +0100 |
---|---|---|
committer | Al Viro <viro@zeniv.linux.org.uk> | 2020-02-07 20:48:38 +0100 |
commit | 328de5287b10abc967c517461cf2948bd8a5b4e9 (patch) | |
tree | a6f015793241358f6d0b7a258c0d7f5114e029bc /fs | |
parent | fs_parse: handle optional arguments sanely (diff) | |
download | linux-328de5287b10abc967c517461cf2948bd8a5b4e9.tar.xz linux-328de5287b10abc967c517461cf2948bd8a5b4e9.zip |
turn fs_param_is_... into functions
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Diffstat (limited to 'fs')
-rw-r--r-- | fs/fs_parser.c | 228 | ||||
-rw-r--r-- | fs/nfs/fs_context.c | 2 |
2 files changed, 125 insertions, 105 deletions
diff --git a/fs/fs_parser.c b/fs/fs_parser.c index db940fac84c3..7e6fb43f9541 100644 --- a/fs/fs_parser.c +++ b/fs/fs_parser.c @@ -48,7 +48,7 @@ EXPORT_SYMBOL(lookup_constant); static inline bool is_flag(const struct fs_parameter_spec *p) { - return p->type == fs_param_is_flag; + return p->type == NULL; } static const struct fs_parameter_spec *fs_lookup_key( @@ -106,8 +106,6 @@ int __fs_parse(struct p_log *log, struct fs_parse_result *result) { const struct fs_parameter_spec *p; - const struct constant_table *e; - int ret = -ENOPARAM, b; result->uint_64 = 0; @@ -121,96 +119,17 @@ int __fs_parse(struct p_log *log, /* Try to turn the type we were given into the type desired by the * parameter and give an error if we can't. */ - switch (p->type) { - case __fs_param_wasnt_defined: - return -EINVAL; - case fs_param_is_flag: + if (is_flag(p)) { if (param->type != fs_value_is_flag) return inval_plog(log, "Unexpected value for '%s'", param->key); result->boolean = !result->negated; - goto okay; - case fs_param_is_bool: - if (param->type != fs_value_is_string) - goto bad_value; - b = lookup_constant(bool_names, param->string, -1); - if (b == -1) - goto bad_value; - result->boolean = b; - goto okay; - case fs_param_is_u32: - if (param->type != fs_value_is_string) - goto bad_value; - ret = kstrtouint(param->string, 0, &result->uint_32); - goto maybe_okay; - case fs_param_is_u32_octal: - if (param->type != fs_value_is_string) - goto bad_value; - ret = kstrtouint(param->string, 8, &result->uint_32); - goto maybe_okay; - case fs_param_is_u32_hex: - if (param->type != fs_value_is_string) - goto bad_value; - ret = kstrtouint(param->string, 16, &result->uint_32); - goto maybe_okay; - case fs_param_is_s32: - if (param->type != fs_value_is_string) - goto bad_value; - ret = kstrtoint(param->string, 0, &result->int_32); - goto maybe_okay; - case fs_param_is_u64: - if (param->type != fs_value_is_string) - goto bad_value; - ret = kstrtoull(param->string, 0, &result->uint_64); - goto maybe_okay; - case fs_param_is_enum: - if (param->type != fs_value_is_string) - goto bad_value; - e = __lookup_constant(p->data, param->string); - if (e) { - result->uint_32 = e->value; - goto okay; - } - goto bad_value; - case fs_param_is_string: - if (param->type != fs_value_is_string || !*param->string) - goto bad_value; - goto okay; - case fs_param_is_blob: - if (param->type != fs_value_is_blob) - goto bad_value; - goto okay; - case fs_param_is_fd: { - switch (param->type) { - case fs_value_is_string: - ret = kstrtouint(param->string, 0, &result->uint_32); - break; - case fs_value_is_file: - result->uint_32 = param->dirfd; - ret = 0; - default: - goto bad_value; - } - - if (result->uint_32 > INT_MAX) - goto bad_value; - goto maybe_okay; + } else { + int ret = p->type(log, p, param, result); + if (ret) + return ret; } - case fs_param_is_blockdev: - case fs_param_is_path: - goto okay; - default: - BUG(); - } - -maybe_okay: - if (ret < 0) - goto bad_value; -okay: return p->opt; - -bad_value: - return inval_plog(log, "Bad value for '%s'", param->key); } EXPORT_SYMBOL(__fs_parse); @@ -270,6 +189,124 @@ out: } EXPORT_SYMBOL(fs_lookup_param); +int fs_param_bad_value(struct p_log *log, struct fs_parameter *param) +{ + return inval_plog(log, "Bad value for '%s'", param->key); +} + +int fs_param_is_bool(struct p_log *log, const struct fs_parameter_spec *p, + struct fs_parameter *param, struct fs_parse_result *result) +{ + int b; + if (param->type != fs_value_is_string) + return fs_param_bad_value(log, param); + b = lookup_constant(bool_names, param->string, -1); + if (b == -1) + return fs_param_bad_value(log, param); + result->boolean = b; + return 0; +} +EXPORT_SYMBOL(fs_param_is_bool); + +int fs_param_is_u32(struct p_log *log, const struct fs_parameter_spec *p, + struct fs_parameter *param, struct fs_parse_result *result) +{ + int base = (unsigned long)p->data; + if (param->type != fs_value_is_string || + kstrtouint(param->string, base, &result->uint_32) < 0) + return fs_param_bad_value(log, param); + return 0; +} +EXPORT_SYMBOL(fs_param_is_u32); + +int fs_param_is_s32(struct p_log *log, const struct fs_parameter_spec *p, + struct fs_parameter *param, struct fs_parse_result *result) +{ + if (param->type != fs_value_is_string || + kstrtoint(param->string, 0, &result->int_32) < 0) + return fs_param_bad_value(log, param); + return 0; +} +EXPORT_SYMBOL(fs_param_is_s32); + +int fs_param_is_u64(struct p_log *log, const struct fs_parameter_spec *p, + struct fs_parameter *param, struct fs_parse_result *result) +{ + if (param->type != fs_value_is_string || + kstrtoull(param->string, 0, &result->uint_64) < 0) + return fs_param_bad_value(log, param); + return 0; +} +EXPORT_SYMBOL(fs_param_is_u64); + +int fs_param_is_enum(struct p_log *log, const struct fs_parameter_spec *p, + struct fs_parameter *param, struct fs_parse_result *result) +{ + const struct constant_table *c; + if (param->type != fs_value_is_string) + return fs_param_bad_value(log, param); + c = __lookup_constant(p->data, param->string); + if (!c) + return fs_param_bad_value(log, param); + result->uint_32 = c->value; + return 0; +} +EXPORT_SYMBOL(fs_param_is_enum); + +int fs_param_is_string(struct p_log *log, const struct fs_parameter_spec *p, + struct fs_parameter *param, struct fs_parse_result *result) +{ + if (param->type != fs_value_is_string || !*param->string) + return fs_param_bad_value(log, param); + return 0; +} +EXPORT_SYMBOL(fs_param_is_string); + +int fs_param_is_blob(struct p_log *log, const struct fs_parameter_spec *p, + struct fs_parameter *param, struct fs_parse_result *result) +{ + if (param->type != fs_value_is_blob) + return fs_param_bad_value(log, param); + return 0; +} +EXPORT_SYMBOL(fs_param_is_blob); + +int fs_param_is_fd(struct p_log *log, const struct fs_parameter_spec *p, + struct fs_parameter *param, struct fs_parse_result *result) +{ + switch (param->type) { + case fs_value_is_string: + if (kstrtouint(param->string, 0, &result->uint_32) < 0) + break; + if (result->uint_32 <= INT_MAX) + return 0; + break; + case fs_value_is_file: + result->uint_32 = param->dirfd; + if (result->uint_32 <= INT_MAX) + return 0; + break; + default: + break; + } + return fs_param_bad_value(log, param); +} +EXPORT_SYMBOL(fs_param_is_fd); + +int fs_param_is_blockdev(struct p_log *log, const struct fs_parameter_spec *p, + struct fs_parameter *param, struct fs_parse_result *result) +{ + return 0; +} +EXPORT_SYMBOL(fs_param_is_blockdev); + +int fs_param_is_path(struct p_log *log, const struct fs_parameter_spec *p, + struct fs_parameter *param, struct fs_parse_result *result) +{ + return 0; +} +EXPORT_SYMBOL(fs_param_is_path); + #ifdef CONFIG_VALIDATE_FS_PARSER /** * validate_constant_table - Validate a constant table @@ -334,23 +371,6 @@ bool fs_validate_description(const char *name, pr_notice("*** VALIDATE %s ***\n", name); for (param = desc; param->name; param++) { - enum fs_parameter_type t = param->type; - - /* Check that the type is in range */ - if (t == __fs_param_wasnt_defined || - t >= nr__fs_parameter_type) { - pr_err("VALIDATE %s: PARAM[%s] Bad type %u\n", - name, param->name, t); - good = false; - } else if (t == fs_param_is_enum) { - const struct constant_table *e = param->data; - if (!e || !e->name) { - pr_err("VALIDATE %s: PARAM[%s] enum with no values\n", - name, param->name); - good = false; - } - } - /* Check for duplicate parameter names */ for (p2 = desc; p2 < param; p2++) { if (strcmp(param->name, p2->name) == 0) { diff --git a/fs/nfs/fs_context.c b/fs/nfs/fs_context.c index c87cdedbdd0c..e1b938457ab9 100644 --- a/fs/nfs/fs_context.c +++ b/fs/nfs/fs_context.c @@ -129,7 +129,7 @@ static const struct fs_parameter_spec nfs_fs_parameters[] = { fsparam_flag_no("fsc", Opt_fscache_flag), fsparam_string("fsc", Opt_fscache), fsparam_flag ("hard", Opt_hard), - __fsparam(fs_param_is_flag, "intr", Opt_intr, + __fsparam(NULL, "intr", Opt_intr, fs_param_neg_with_no|fs_param_deprecated, NULL), fsparam_enum ("local_lock", Opt_local_lock, nfs_param_enums_local_lock), fsparam_flag_no("lock", Opt_lock), |