From 0f89589a8c6f1033cb847a606517998efb0da8ee Mon Sep 17 00:00:00 2001 From: Al Viro Date: Tue, 17 Dec 2019 14:15:04 -0500 Subject: Pass consistent param->type to fs_parse() As it is, vfs_parse_fs_string() makes "foo" and "foo=" indistinguishable; both get fs_value_is_string for ->type and NULL for ->string. To make it even more unpleasant, that combination is impossible to produce with fsconfig(). Much saner rules would be "foo" => fs_value_is_flag, NULL "foo=" => fs_value_is_string, "" "foo=bar" => fs_value_is_string, "bar" All cases are distinguishable, all results are expressable by fsconfig(), ->has_value checks are much simpler that way (to the point of the field being useless) and quite a few regressions go away (gfs2 has no business accepting -o nodebug=, for example). Partially based upon patches from Miklos. Signed-off-by: Al Viro --- drivers/block/rbd.c | 7 ++----- fs/fs_context.c | 5 +++-- fs/fs_parser.c | 23 +++++++++++------------ include/linux/fs_parser.h | 1 - 4 files changed, 16 insertions(+), 20 deletions(-) diff --git a/drivers/block/rbd.c b/drivers/block/rbd.c index 2b184563cd32..9fc686be81ca 100644 --- a/drivers/block/rbd.c +++ b/drivers/block/rbd.c @@ -6433,7 +6433,7 @@ static int rbd_parse_options(char *options, struct rbd_parse_opts_ctx *pctx) if (*key) { struct fs_parameter param = { .key = key, - .type = fs_value_is_string, + .type = fs_value_is_flag, }; char *value = strchr(key, '='); size_t v_len = 0; @@ -6443,14 +6443,11 @@ static int rbd_parse_options(char *options, struct rbd_parse_opts_ctx *pctx) continue; *value++ = 0; v_len = strlen(value); - } - - - if (v_len > 0) { param.string = kmemdup_nul(value, v_len, GFP_KERNEL); if (!param.string) return -ENOMEM; + param.type = fs_value_is_string; } param.size = v_len; diff --git a/fs/fs_context.c b/fs/fs_context.c index 138b5b4d621d..9097421cbba5 100644 --- a/fs/fs_context.c +++ b/fs/fs_context.c @@ -175,14 +175,15 @@ int vfs_parse_fs_string(struct fs_context *fc, const char *key, struct fs_parameter param = { .key = key, - .type = fs_value_is_string, + .type = fs_value_is_flag, .size = v_size, }; - if (v_size > 0) { + if (value) { param.string = kmemdup_nul(value, v_size, GFP_KERNEL); if (!param.string) return -ENOMEM; + param.type = fs_value_is_string; } ret = vfs_parse_fs_param(fc, ¶m); diff --git a/fs/fs_parser.c b/fs/fs_parser.c index d1930adce68d..07ae041b83a8 100644 --- a/fs/fs_parser.c +++ b/fs/fs_parser.c @@ -85,7 +85,6 @@ int fs_parse(struct fs_context *fc, const struct fs_parameter_enum *e; int ret = -ENOPARAM, b; - result->has_value = !!param->string; result->negated = false; result->uint_64 = 0; @@ -95,7 +94,7 @@ int fs_parse(struct fs_context *fc, * "xxx" takes the "no"-form negative - but only if there * wasn't an value. */ - if (result->has_value) + if (param->type != fs_value_is_flag) goto unknown_parameter; if (param->key[0] != 'n' || param->key[1] != 'o' || !param->key[2]) goto unknown_parameter; @@ -127,14 +126,18 @@ int fs_parse(struct fs_context *fc, case fs_param_is_u64: case fs_param_is_enum: case fs_param_is_string: - if (param->type != fs_value_is_string) - goto bad_value; - if (!result->has_value) { + if (param->type == fs_value_is_string) { + if (p->flags & fs_param_v_optional) + break; + if (!*param->string) + goto bad_value; + break; + } + if (param->type == fs_value_is_flag) { if (p->flags & fs_param_v_optional) goto okay; - goto bad_value; } - /* Fall through */ + goto bad_value; default: break; } @@ -144,8 +147,7 @@ int fs_parse(struct fs_context *fc, */ switch (p->type) { case fs_param_is_flag: - if (param->type != fs_value_is_flag && - (param->type != fs_value_is_string || result->has_value)) + if (param->type != fs_value_is_flag) return invalf(fc, "%s: Unexpected value for '%s'", desc->name, param->key); result->boolean = true; @@ -206,9 +208,6 @@ int fs_parse(struct fs_context *fc, case fs_param_is_fd: { switch (param->type) { case fs_value_is_string: - if (!result->has_value) - goto bad_value; - ret = kstrtouint(param->string, 0, &result->uint_32); break; case fs_value_is_file: diff --git a/include/linux/fs_parser.h b/include/linux/fs_parser.h index dee140db6240..45323203128b 100644 --- a/include/linux/fs_parser.h +++ b/include/linux/fs_parser.h @@ -72,7 +72,6 @@ struct fs_parameter_description { */ struct fs_parse_result { bool negated; /* T if param was "noxxx" */ - bool has_value; /* T if value supplied to param */ union { bool boolean; /* For spec_bool */ int int_32; /* For spec_s32/spec_enum */ -- cgit v1.2.3 From 2710c957a8ef4fb00f21acb306e3bd6bcf80c81f Mon Sep 17 00:00:00 2001 From: Al Viro Date: Fri, 6 Sep 2019 22:12:08 -0400 Subject: fs_parse: get rid of ->enums Don't do a single array; attach them to fsparam_enum() entry instead. And don't bother trying to embed the names into those - it actually loses memory, with no real speedup worth mentioning. Simplifies validation as well. Signed-off-by: Al Viro --- fs/afs/super.c | 19 ++++++------- fs/ceph/super.c | 11 ++++---- fs/fs_parser.c | 72 ++++++----------------------------------------- fs/gfs2/ops_fstype.c | 38 +++++++++++++++---------- fs/jffs2/super.c | 21 +++++++------- fs/nfs/fs_context.c | 62 ++++++++++++++++++++-------------------- include/linux/fs_parser.h | 38 ++++++++++++------------- mm/shmem.c | 21 +++++++------- net/ceph/ceph_common.c | 2 +- 9 files changed, 119 insertions(+), 165 deletions(-) diff --git a/fs/afs/super.c b/fs/afs/super.c index 7f8a9b3137bf..42bf63b82007 100644 --- a/fs/afs/super.c +++ b/fs/afs/super.c @@ -73,26 +73,25 @@ enum afs_param { Opt_source, }; +static const struct fs_parameter_enum afs_param_flock[] = { + {"local", afs_flock_mode_local }, + {"openafs", afs_flock_mode_openafs }, + {"strict", afs_flock_mode_strict }, + {"write", afs_flock_mode_write }, + {} +}; + static const struct fs_parameter_spec afs_param_specs[] = { fsparam_flag ("autocell", Opt_autocell), fsparam_flag ("dyn", Opt_dyn), - fsparam_enum ("flock", Opt_flock), + fsparam_enum ("flock", Opt_flock, afs_param_flock), fsparam_string("source", Opt_source), {} }; -static const struct fs_parameter_enum afs_param_enums[] = { - { Opt_flock, "local", afs_flock_mode_local }, - { Opt_flock, "openafs", afs_flock_mode_openafs }, - { Opt_flock, "strict", afs_flock_mode_strict }, - { Opt_flock, "write", afs_flock_mode_write }, - {} -}; - static const struct fs_parameter_description afs_fs_parameters = { .name = "kAFS", .specs = afs_param_specs, - .enums = afs_param_enums, }; /* diff --git a/fs/ceph/super.c b/fs/ceph/super.c index 29a795f975df..0f7c8913bb20 100644 --- a/fs/ceph/super.c +++ b/fs/ceph/super.c @@ -163,9 +163,9 @@ enum ceph_recover_session_mode { ceph_recover_session_clean }; -static const struct fs_parameter_enum ceph_mount_param_enums[] = { - { Opt_recover_session, "no", ceph_recover_session_no }, - { Opt_recover_session, "clean", ceph_recover_session_clean }, +static const struct fs_parameter_enum ceph_param_recover[] = { + { "no", ceph_recover_session_no }, + { "clean", ceph_recover_session_clean }, {} }; @@ -180,7 +180,7 @@ static const struct fs_parameter_spec ceph_mount_param_specs[] = { fsparam_flag_no ("dcache", Opt_dcache), fsparam_flag_no ("dirstat", Opt_dirstat), __fsparam (fs_param_is_string, "fsc", Opt_fscache, - fs_param_neg_with_no | fs_param_v_optional), + fs_param_neg_with_no | fs_param_v_optional, NULL), fsparam_flag_no ("ino32", Opt_ino32), fsparam_string ("mds_namespace", Opt_mds_namespace), fsparam_flag_no ("poolperm", Opt_poolperm), @@ -189,7 +189,7 @@ static const struct fs_parameter_spec ceph_mount_param_specs[] = { fsparam_flag_no ("rbytes", Opt_rbytes), fsparam_u32 ("readdir_max_bytes", Opt_readdir_max_bytes), fsparam_u32 ("readdir_max_entries", Opt_readdir_max_entries), - fsparam_enum ("recover_session", Opt_recover_session), + fsparam_enum ("recover_session", Opt_recover_session, ceph_param_recover), fsparam_flag_no ("require_active_mds", Opt_require_active_mds), fsparam_u32 ("rsize", Opt_rsize), fsparam_string ("snapdirname", Opt_snapdirname), @@ -201,7 +201,6 @@ static const struct fs_parameter_spec ceph_mount_param_specs[] = { static const struct fs_parameter_description ceph_mount_parameters = { .name = "ceph", .specs = ceph_mount_param_specs, - .enums = ceph_mount_param_enums, }; struct ceph_parse_opts_ctx { diff --git a/fs/fs_parser.c b/fs/fs_parser.c index 07ae041b83a8..34275191697f 100644 --- a/fs/fs_parser.c +++ b/fs/fs_parser.c @@ -189,9 +189,8 @@ int fs_parse(struct fs_context *fc, goto maybe_okay; case fs_param_is_enum: - for (e = desc->enums; e->name[0]; e++) { - if (e->opt == p->opt && - strcmp(e->name, param->string) == 0) { + for (e = p->data; e->name; e++) { + if (strcmp(e->name, param->string) == 0) { result->uint_32 = e->value; goto okay; } @@ -359,10 +358,8 @@ bool validate_constant_table(const struct constant_table *tbl, size_t tbl_size, bool fs_validate_description(const struct fs_parameter_description *desc) { const struct fs_parameter_spec *param, *p2; - const struct fs_parameter_enum *e; const char *name = desc->name; - unsigned int nr_params = 0; - bool good = true, enums = false; + bool good = true; pr_notice("*** VALIDATE %s ***\n", name); @@ -383,7 +380,12 @@ bool fs_validate_description(const struct fs_parameter_description *desc) name, param->name, t); good = false; } else if (t == fs_param_is_enum) { - enums = true; + const struct fs_parameter_enum *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 */ @@ -395,63 +397,7 @@ bool fs_validate_description(const struct fs_parameter_description *desc) } } } - - nr_params = param - desc->specs; - } - - if (desc->enums) { - if (!nr_params) { - pr_err("VALIDATE %s: Enum table but no parameters\n", - name); - good = false; - goto no_enums; - } - if (!enums) { - pr_err("VALIDATE %s: Enum table but no enum-type values\n", - name); - good = false; - goto no_enums; - } - - for (e = desc->enums; e->name[0]; e++) { - /* Check that all entries in the enum table have at - * least one parameter that uses them. - */ - for (param = desc->specs; param->name; param++) { - if (param->opt == e->opt && - param->type != fs_param_is_enum) { - pr_err("VALIDATE %s: e[%tu] enum val for %s\n", - name, e - desc->enums, param->name); - good = false; - } - } - } - - /* Check that all enum-type parameters have at least one enum - * value in the enum table. - */ - for (param = desc->specs; param->name; param++) { - if (param->type != fs_param_is_enum) - continue; - for (e = desc->enums; e->name[0]; e++) - if (e->opt == param->opt) - break; - if (!e->name[0]) { - pr_err("VALIDATE %s: PARAM[%s] enum with no values\n", - name, param->name); - good = false; - } - } - } else { - if (enums) { - pr_err("VALIDATE %s: enum-type values, but no enum table\n", - name); - good = false; - goto no_enums; - } } - -no_enums: return good; } #endif /* CONFIG_VALIDATE_FS_PARSER */ diff --git a/fs/gfs2/ops_fstype.c b/fs/gfs2/ops_fstype.c index e8b7b0ce8404..0df8f2df9491 100644 --- a/fs/gfs2/ops_fstype.c +++ b/fs/gfs2/ops_fstype.c @@ -1271,6 +1271,13 @@ enum opt_quota { Opt_quota_on, }; +static const struct fs_parameter_enum gfs2_param_quota[] = { + {"off", Opt_quota_off }, + {"account", Opt_quota_account }, + {"on", Opt_quota_on }, + {} +}; + static const unsigned int opt_quota_values[] = { [Opt_quota_off] = GFS2_QUOTA_OFF, [Opt_quota_account] = GFS2_QUOTA_ACCOUNT, @@ -1282,11 +1289,23 @@ enum opt_data { Opt_data_ordered = GFS2_DATA_ORDERED, }; +static const struct fs_parameter_enum gfs2_param_data[] = { + {"writeback", Opt_data_writeback }, + {"ordered", Opt_data_ordered }, + {} +}; + enum opt_errors { Opt_errors_withdraw = GFS2_ERRORS_WITHDRAW, Opt_errors_panic = GFS2_ERRORS_PANIC, }; +static const struct fs_parameter_enum gfs2_param_errors[] = { + {"withdraw", Opt_errors_withdraw }, + {"panic", Opt_errors_panic }, + {} +}; + static const struct fs_parameter_spec gfs2_param_specs[] = { fsparam_string ("lockproto", Opt_lockproto), fsparam_string ("locktable", Opt_locktable), @@ -1300,11 +1319,11 @@ static const struct fs_parameter_spec gfs2_param_specs[] = { fsparam_flag ("upgrade", Opt_upgrade), fsparam_flag_no("acl", Opt_acl), fsparam_flag_no("suiddir", Opt_suiddir), - fsparam_enum ("data", Opt_data), + fsparam_enum ("data", Opt_data, gfs2_param_data), fsparam_flag ("meta", Opt_meta), fsparam_flag_no("discard", Opt_discard), fsparam_s32 ("commit", Opt_commit), - fsparam_enum ("errors", Opt_errors), + fsparam_enum ("errors", Opt_errors, gfs2_param_errors), fsparam_s32 ("statfs_quantum", Opt_statfs_quantum), fsparam_s32 ("statfs_percent", Opt_statfs_percent), fsparam_s32 ("quota_quantum", Opt_quota_quantum), @@ -1312,25 +1331,14 @@ static const struct fs_parameter_spec gfs2_param_specs[] = { fsparam_flag_no("rgrplvb", Opt_rgrplvb), fsparam_flag_no("loccookie", Opt_loccookie), /* quota can be a flag or an enum so it gets special treatment */ - __fsparam(fs_param_is_enum, "quota", Opt_quota, fs_param_neg_with_no|fs_param_v_optional), - {} -}; - -static const struct fs_parameter_enum gfs2_param_enums[] = { - { Opt_quota, "off", Opt_quota_off }, - { Opt_quota, "account", Opt_quota_account }, - { Opt_quota, "on", Opt_quota_on }, - { Opt_data, "writeback", Opt_data_writeback }, - { Opt_data, "ordered", Opt_data_ordered }, - { Opt_errors, "withdraw", Opt_errors_withdraw }, - { Opt_errors, "panic", Opt_errors_panic }, + __fsparam(fs_param_is_enum, "quota", Opt_quota, + fs_param_neg_with_no|fs_param_v_optional, gfs2_param_quota), {} }; static const struct fs_parameter_description gfs2_fs_parameters = { .name = "gfs2", .specs = gfs2_param_specs, - .enums = gfs2_param_enums, }; /* Parse a single mount parameter */ diff --git a/fs/jffs2/super.c b/fs/jffs2/super.c index 0e6406c4f362..ecd1a13a35d8 100644 --- a/fs/jffs2/super.c +++ b/fs/jffs2/super.c @@ -167,27 +167,26 @@ enum { Opt_rp_size, }; -static const struct fs_parameter_spec jffs2_param_specs[] = { - fsparam_enum ("compr", Opt_override_compr), - fsparam_u32 ("rp_size", Opt_rp_size), - {} -}; - -static const struct fs_parameter_enum jffs2_param_enums[] = { - { Opt_override_compr, "none", JFFS2_COMPR_MODE_NONE }, +static const struct fs_parameter_enum jffs2_param_compr[] = { + {"none", JFFS2_COMPR_MODE_NONE }, #ifdef CONFIG_JFFS2_LZO - { Opt_override_compr, "lzo", JFFS2_COMPR_MODE_FORCELZO }, + {"lzo", JFFS2_COMPR_MODE_FORCELZO }, #endif #ifdef CONFIG_JFFS2_ZLIB - { Opt_override_compr, "zlib", JFFS2_COMPR_MODE_FORCEZLIB }, + {"zlib", JFFS2_COMPR_MODE_FORCEZLIB }, #endif {} }; +static const struct fs_parameter_spec jffs2_param_specs[] = { + fsparam_enum ("compr", Opt_override_compr, jffs2_param_compr), + fsparam_u32 ("rp_size", Opt_rp_size), + {} +}; + const struct fs_parameter_description jffs2_fs_parameters = { .name = "jffs2", .specs = jffs2_param_specs, - .enums = jffs2_param_enums, }; static int jffs2_parse_param(struct fs_context *fc, struct fs_parameter *param) diff --git a/fs/nfs/fs_context.c b/fs/nfs/fs_context.c index 2c6dc1b6cc92..01c76885f54e 100644 --- a/fs/nfs/fs_context.c +++ b/fs/nfs/fs_context.c @@ -83,6 +83,34 @@ enum nfs_param { Opt_wsize, }; +enum { + Opt_local_lock_all, + Opt_local_lock_flock, + Opt_local_lock_none, + Opt_local_lock_posix, +}; + +static const struct fs_parameter_enum nfs_param_enums_local_lock[] = { + { "all", Opt_local_lock_all }, + { "flock", Opt_local_lock_flock }, + { "none", Opt_local_lock_none }, + {} +}; + +enum { + Opt_lookupcache_all, + Opt_lookupcache_none, + Opt_lookupcache_positive, +}; + +static const struct fs_parameter_enum nfs_param_enums_lookupcache[] = { + { "all", Opt_lookupcache_all }, + { "none", Opt_lookupcache_none }, + { "pos", Opt_lookupcache_positive }, + { "positive", Opt_lookupcache_positive }, + {} +}; + static const struct fs_parameter_spec nfs_param_specs[] = { fsparam_flag_no("ac", Opt_ac), fsparam_u32 ("acdirmax", Opt_acdirmax), @@ -98,13 +126,13 @@ static const struct fs_parameter_spec nfs_param_specs[] = { fsparam_flag_no("cto", Opt_cto), fsparam_flag ("fg", Opt_fg), __fsparam(fs_param_is_string, "fsc", Opt_fscache, - fs_param_neg_with_no|fs_param_v_optional), + fs_param_neg_with_no|fs_param_v_optional, NULL), fsparam_flag ("hard", Opt_hard), __fsparam(fs_param_is_flag, "intr", Opt_intr, - fs_param_neg_with_no|fs_param_deprecated), - fsparam_enum ("local_lock", Opt_local_lock), + 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), - fsparam_enum ("lookupcache", Opt_lookupcache), + fsparam_enum ("lookupcache", Opt_lookupcache, nfs_param_enums_lookupcache), fsparam_flag_no("migration", Opt_migration), fsparam_u32 ("minorversion", Opt_minorversion), fsparam_string("mountaddr", Opt_mountaddr), @@ -145,35 +173,9 @@ static const struct fs_parameter_spec nfs_param_specs[] = { {} }; -enum { - Opt_local_lock_all, - Opt_local_lock_flock, - Opt_local_lock_none, - Opt_local_lock_posix, -}; - -enum { - Opt_lookupcache_all, - Opt_lookupcache_none, - Opt_lookupcache_positive, -}; - -static const struct fs_parameter_enum nfs_param_enums[] = { - { Opt_local_lock, "all", Opt_local_lock_all }, - { Opt_local_lock, "flock", Opt_local_lock_flock }, - { Opt_local_lock, "none", Opt_local_lock_none }, - { Opt_local_lock, "posix", Opt_local_lock_posix }, - { Opt_lookupcache, "all", Opt_lookupcache_all }, - { Opt_lookupcache, "none", Opt_lookupcache_none }, - { Opt_lookupcache, "pos", Opt_lookupcache_positive }, - { Opt_lookupcache, "positive", Opt_lookupcache_positive }, - {} -}; - static const struct fs_parameter_description nfs_fs_parameters = { .name = "nfs", .specs = nfs_param_specs, - .enums = nfs_param_enums, }; enum { diff --git a/include/linux/fs_parser.h b/include/linux/fs_parser.h index 45323203128b..498cba1bbf6e 100644 --- a/include/linux/fs_parser.h +++ b/include/linux/fs_parser.h @@ -53,18 +53,17 @@ struct fs_parameter_spec { #define fs_param_neg_with_no 0x0002 /* "noxxx" is negative param */ #define fs_param_neg_with_empty 0x0004 /* "xxx=" is negative param */ #define fs_param_deprecated 0x0008 /* The param is deprecated */ + const void *data; }; struct fs_parameter_enum { - u8 opt; /* Option number (as fs_parameter_spec::opt) */ - char name[14]; + const char *name; u8 value; }; struct fs_parameter_description { const char name[16]; /* Name for logging purposes */ const struct fs_parameter_spec *specs; /* List of param specifications */ - const struct fs_parameter_enum *enums; /* Enum values */ }; /* @@ -114,33 +113,34 @@ static inline bool fs_validate_description(const struct fs_parameter_description * work, but any such case is probably a sign that new helper is needed. * Helpers will remain stable; low-level implementation may change. */ -#define __fsparam(TYPE, NAME, OPT, FLAGS) \ +#define __fsparam(TYPE, NAME, OPT, FLAGS, DATA) \ { \ .name = NAME, \ .opt = OPT, \ .type = TYPE, \ - .flags = FLAGS \ + .flags = FLAGS, \ + .data = DATA \ } -#define fsparam_flag(NAME, OPT) __fsparam(fs_param_is_flag, NAME, OPT, 0) +#define fsparam_flag(NAME, OPT) __fsparam(fs_param_is_flag, NAME, OPT, 0, NULL) #define fsparam_flag_no(NAME, OPT) \ __fsparam(fs_param_is_flag, NAME, OPT, \ - fs_param_neg_with_no) -#define fsparam_bool(NAME, OPT) __fsparam(fs_param_is_bool, NAME, OPT, 0) -#define fsparam_u32(NAME, OPT) __fsparam(fs_param_is_u32, NAME, OPT, 0) + fs_param_neg_with_no, NULL) +#define fsparam_bool(NAME, OPT) __fsparam(fs_param_is_bool, NAME, OPT, 0, NULL) +#define fsparam_u32(NAME, OPT) __fsparam(fs_param_is_u32, NAME, OPT, 0, NULL) #define fsparam_u32oct(NAME, OPT) \ - __fsparam(fs_param_is_u32_octal, NAME, OPT, 0) + __fsparam(fs_param_is_u32_octal, NAME, OPT, 0, NULL) #define fsparam_u32hex(NAME, OPT) \ - __fsparam(fs_param_is_u32_hex, NAME, OPT, 0) -#define fsparam_s32(NAME, OPT) __fsparam(fs_param_is_s32, NAME, OPT, 0) -#define fsparam_u64(NAME, OPT) __fsparam(fs_param_is_u64, NAME, OPT, 0) -#define fsparam_enum(NAME, OPT) __fsparam(fs_param_is_enum, NAME, OPT, 0) + __fsparam(fs_param_is_u32_hex, NAME, OPT, 0, NULL) +#define fsparam_s32(NAME, OPT) __fsparam(fs_param_is_s32, NAME, OPT, 0, NULL) +#define fsparam_u64(NAME, OPT) __fsparam(fs_param_is_u64, NAME, OPT, 0, NULL) +#define fsparam_enum(NAME, OPT, array) __fsparam(fs_param_is_enum, NAME, OPT, 0, array) #define fsparam_string(NAME, OPT) \ - __fsparam(fs_param_is_string, NAME, OPT, 0) -#define fsparam_blob(NAME, OPT) __fsparam(fs_param_is_blob, NAME, OPT, 0) -#define fsparam_bdev(NAME, OPT) __fsparam(fs_param_is_blockdev, NAME, OPT, 0) -#define fsparam_path(NAME, OPT) __fsparam(fs_param_is_path, NAME, OPT, 0) -#define fsparam_fd(NAME, OPT) __fsparam(fs_param_is_fd, NAME, OPT, 0) + __fsparam(fs_param_is_string, NAME, OPT, 0, NULL) +#define fsparam_blob(NAME, OPT) __fsparam(fs_param_is_blob, NAME, OPT, 0, NULL) +#define fsparam_bdev(NAME, OPT) __fsparam(fs_param_is_blockdev, NAME, OPT, 0, NULL) +#define fsparam_path(NAME, OPT) __fsparam(fs_param_is_path, NAME, OPT, 0, NULL) +#define fsparam_fd(NAME, OPT) __fsparam(fs_param_is_fd, NAME, OPT, 0, NULL) #endif /* _LINUX_FS_PARSER_H */ diff --git a/mm/shmem.c b/mm/shmem.c index 8793e8cc1a48..1c02c6c20f45 100644 --- a/mm/shmem.c +++ b/mm/shmem.c @@ -3381,9 +3381,19 @@ enum shmem_param { Opt_uid, }; +static const struct fs_parameter_enum shmem_param_enums_huge[] = { + {"never", SHMEM_HUGE_NEVER }, + {"always", SHMEM_HUGE_ALWAYS }, + {"within_size", SHMEM_HUGE_WITHIN_SIZE }, + {"advise", SHMEM_HUGE_ADVISE }, + {"deny", SHMEM_HUGE_DENY }, + {"force", SHMEM_HUGE_FORCE }, + {} +}; + static const struct fs_parameter_spec shmem_param_specs[] = { fsparam_u32 ("gid", Opt_gid), - fsparam_enum ("huge", Opt_huge), + fsparam_enum ("huge", Opt_huge, shmem_param_enums_huge), fsparam_u32oct("mode", Opt_mode), fsparam_string("mpol", Opt_mpol), fsparam_string("nr_blocks", Opt_nr_blocks), @@ -3393,18 +3403,9 @@ static const struct fs_parameter_spec shmem_param_specs[] = { {} }; -static const struct fs_parameter_enum shmem_param_enums[] = { - { Opt_huge, "never", SHMEM_HUGE_NEVER }, - { Opt_huge, "always", SHMEM_HUGE_ALWAYS }, - { Opt_huge, "within_size", SHMEM_HUGE_WITHIN_SIZE }, - { Opt_huge, "advise", SHMEM_HUGE_ADVISE }, - {} -}; - const struct fs_parameter_description shmem_fs_parameters = { .name = "tmpfs", .specs = shmem_param_specs, - .enums = shmem_param_enums, }; static int shmem_parse_one(struct fs_context *fc, struct fs_parameter *param) diff --git a/net/ceph/ceph_common.c b/net/ceph/ceph_common.c index a9d6c97b5b0d..c2d0b5c47b5f 100644 --- a/net/ceph/ceph_common.c +++ b/net/ceph/ceph_common.c @@ -283,7 +283,7 @@ static const struct fs_parameter_spec ceph_param_specs[] = { fsparam_u32 ("osd_request_timeout", Opt_osd_request_timeout), fsparam_u32 ("osdkeepalive", Opt_osdkeepalivetimeout), __fsparam (fs_param_is_s32, "osdtimeout", Opt_osdtimeout, - fs_param_deprecated), + fs_param_deprecated, NULL), fsparam_string ("secret", Opt_secret), fsparam_flag_no ("share", Opt_share), fsparam_flag_no ("tcp_nodelay", Opt_tcp_nodelay), -- cgit v1.2.3 From 5eede625297f4d21dc12ea7a7418fd21672f131d Mon Sep 17 00:00:00 2001 From: Al Viro Date: Mon, 16 Dec 2019 13:33:32 -0500 Subject: fold struct fs_parameter_enum into struct constant_table no real difference now Signed-off-by: Al Viro --- fs/afs/super.c | 2 +- fs/ceph/super.c | 2 +- fs/fs_parser.c | 4 ++-- fs/gfs2/ops_fstype.c | 6 +++--- fs/jffs2/super.c | 2 +- fs/nfs/fs_context.c | 4 ++-- include/linux/fs_parser.h | 5 ----- mm/shmem.c | 2 +- 8 files changed, 11 insertions(+), 16 deletions(-) diff --git a/fs/afs/super.c b/fs/afs/super.c index 42bf63b82007..8d71d10761b7 100644 --- a/fs/afs/super.c +++ b/fs/afs/super.c @@ -73,7 +73,7 @@ enum afs_param { Opt_source, }; -static const struct fs_parameter_enum afs_param_flock[] = { +static const struct constant_table afs_param_flock[] = { {"local", afs_flock_mode_local }, {"openafs", afs_flock_mode_openafs }, {"strict", afs_flock_mode_strict }, diff --git a/fs/ceph/super.c b/fs/ceph/super.c index 0f7c8913bb20..2bad9bc1fd70 100644 --- a/fs/ceph/super.c +++ b/fs/ceph/super.c @@ -163,7 +163,7 @@ enum ceph_recover_session_mode { ceph_recover_session_clean }; -static const struct fs_parameter_enum ceph_param_recover[] = { +static const struct constant_table ceph_param_recover[] = { { "no", ceph_recover_session_no }, { "clean", ceph_recover_session_clean }, {} diff --git a/fs/fs_parser.c b/fs/fs_parser.c index 34275191697f..d032ac4a758d 100644 --- a/fs/fs_parser.c +++ b/fs/fs_parser.c @@ -82,7 +82,7 @@ int fs_parse(struct fs_context *fc, struct fs_parse_result *result) { const struct fs_parameter_spec *p; - const struct fs_parameter_enum *e; + const struct constant_table *e; int ret = -ENOPARAM, b; result->negated = false; @@ -380,7 +380,7 @@ bool fs_validate_description(const struct fs_parameter_description *desc) name, param->name, t); good = false; } else if (t == fs_param_is_enum) { - const struct fs_parameter_enum *e = param->data; + 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); diff --git a/fs/gfs2/ops_fstype.c b/fs/gfs2/ops_fstype.c index 0df8f2df9491..16230e496fdb 100644 --- a/fs/gfs2/ops_fstype.c +++ b/fs/gfs2/ops_fstype.c @@ -1271,7 +1271,7 @@ enum opt_quota { Opt_quota_on, }; -static const struct fs_parameter_enum gfs2_param_quota[] = { +static const struct constant_table gfs2_param_quota[] = { {"off", Opt_quota_off }, {"account", Opt_quota_account }, {"on", Opt_quota_on }, @@ -1289,7 +1289,7 @@ enum opt_data { Opt_data_ordered = GFS2_DATA_ORDERED, }; -static const struct fs_parameter_enum gfs2_param_data[] = { +static const struct constant_table gfs2_param_data[] = { {"writeback", Opt_data_writeback }, {"ordered", Opt_data_ordered }, {} @@ -1300,7 +1300,7 @@ enum opt_errors { Opt_errors_panic = GFS2_ERRORS_PANIC, }; -static const struct fs_parameter_enum gfs2_param_errors[] = { +static const struct constant_table gfs2_param_errors[] = { {"withdraw", Opt_errors_withdraw }, {"panic", Opt_errors_panic }, {} diff --git a/fs/jffs2/super.c b/fs/jffs2/super.c index ecd1a13a35d8..1e54f736865d 100644 --- a/fs/jffs2/super.c +++ b/fs/jffs2/super.c @@ -167,7 +167,7 @@ enum { Opt_rp_size, }; -static const struct fs_parameter_enum jffs2_param_compr[] = { +static const struct constant_table jffs2_param_compr[] = { {"none", JFFS2_COMPR_MODE_NONE }, #ifdef CONFIG_JFFS2_LZO {"lzo", JFFS2_COMPR_MODE_FORCELZO }, diff --git a/fs/nfs/fs_context.c b/fs/nfs/fs_context.c index 01c76885f54e..c0ddeecadfac 100644 --- a/fs/nfs/fs_context.c +++ b/fs/nfs/fs_context.c @@ -90,7 +90,7 @@ enum { Opt_local_lock_posix, }; -static const struct fs_parameter_enum nfs_param_enums_local_lock[] = { +static const struct constant_table nfs_param_enums_local_lock[] = { { "all", Opt_local_lock_all }, { "flock", Opt_local_lock_flock }, { "none", Opt_local_lock_none }, @@ -103,7 +103,7 @@ enum { Opt_lookupcache_positive, }; -static const struct fs_parameter_enum nfs_param_enums_lookupcache[] = { +static const struct constant_table nfs_param_enums_lookupcache[] = { { "all", Opt_lookupcache_all }, { "none", Opt_lookupcache_none }, { "pos", Opt_lookupcache_positive }, diff --git a/include/linux/fs_parser.h b/include/linux/fs_parser.h index 498cba1bbf6e..5c91a0ac4446 100644 --- a/include/linux/fs_parser.h +++ b/include/linux/fs_parser.h @@ -56,11 +56,6 @@ struct fs_parameter_spec { const void *data; }; -struct fs_parameter_enum { - const char *name; - u8 value; -}; - struct fs_parameter_description { const char name[16]; /* Name for logging purposes */ const struct fs_parameter_spec *specs; /* List of param specifications */ diff --git a/mm/shmem.c b/mm/shmem.c index 1c02c6c20f45..90c7737bcce2 100644 --- a/mm/shmem.c +++ b/mm/shmem.c @@ -3381,7 +3381,7 @@ enum shmem_param { Opt_uid, }; -static const struct fs_parameter_enum shmem_param_enums_huge[] = { +static const struct constant_table shmem_param_enums_huge[] = { {"never", SHMEM_HUGE_NEVER }, {"always", SHMEM_HUGE_ALWAYS }, {"within_size", SHMEM_HUGE_WITHIN_SIZE }, -- cgit v1.2.3 From 34264ae3fa22429ec4fd9151602342d1f21486eb Mon Sep 17 00:00:00 2001 From: Al Viro Date: Mon, 16 Dec 2019 13:45:41 -0500 Subject: don't bother with explicit length argument for __lookup_constant() Have the arrays of constant_table self-terminated (by NULL ->name in the final entry). Simplifies lookup_constant() and allows to reuse the search for enum params as well. Signed-off-by: Al Viro --- fs/fs_context.c | 2 ++ fs/fs_parser.c | 33 ++++++++++++++++++--------------- include/linux/fs_parser.h | 4 +--- 3 files changed, 21 insertions(+), 18 deletions(-) diff --git a/fs/fs_context.c b/fs/fs_context.c index 9097421cbba5..ea97a2411e83 100644 --- a/fs/fs_context.c +++ b/fs/fs_context.c @@ -45,6 +45,7 @@ static const struct constant_table common_set_sb_flag[] = { { "posixacl", SB_POSIXACL }, { "ro", SB_RDONLY }, { "sync", SB_SYNCHRONOUS }, + { }, }; static const struct constant_table common_clear_sb_flag[] = { @@ -53,6 +54,7 @@ static const struct constant_table common_clear_sb_flag[] = { { "nomand", SB_MANDLOCK }, { "rw", SB_RDONLY }, { "silent", SB_SILENT }, + { }, }; static const char *const forbidden_sb_flag[] = { diff --git a/fs/fs_parser.c b/fs/fs_parser.c index d032ac4a758d..065ce6c22587 100644 --- a/fs/fs_parser.c +++ b/fs/fs_parser.c @@ -20,27 +20,31 @@ static const struct constant_table bool_names[] = { { "no", false }, { "true", true }, { "yes", true }, + { }, }; +static const struct constant_table * +__lookup_constant(const struct constant_table *tbl, const char *name) +{ + for ( ; tbl->name; tbl++) + if (strcmp(name, tbl->name) == 0) + return tbl; + return NULL; +} + /** * lookup_constant - Look up a constant by name in an ordered table * @tbl: The table of constants to search. - * @tbl_size: The size of the table. * @name: The name to look up. * @not_found: The value to return if the name is not found. */ -int __lookup_constant(const struct constant_table *tbl, size_t tbl_size, - const char *name, int not_found) +int lookup_constant(const struct constant_table *tbl, const char *name, int not_found) { - unsigned int i; + const struct constant_table *p = __lookup_constant(tbl, name); - for (i = 0; i < tbl_size; i++) - if (strcmp(name, tbl[i].name) == 0) - return tbl[i].value; - - return not_found; + return p ? p->value : not_found; } -EXPORT_SYMBOL(__lookup_constant); +EXPORT_SYMBOL(lookup_constant); static const struct fs_parameter_spec *fs_lookup_key( const struct fs_parameter_description *desc, @@ -189,11 +193,10 @@ int fs_parse(struct fs_context *fc, goto maybe_okay; case fs_param_is_enum: - for (e = p->data; e->name; e++) { - if (strcmp(e->name, param->string) == 0) { - result->uint_32 = e->value; - goto okay; - } + e = __lookup_constant(p->data, param->string); + if (e) { + result->uint_32 = e->value; + goto okay; } goto bad_value; diff --git a/include/linux/fs_parser.h b/include/linux/fs_parser.h index 5c91a0ac4446..14bdaacf1218 100644 --- a/include/linux/fs_parser.h +++ b/include/linux/fs_parser.h @@ -83,9 +83,7 @@ extern int fs_lookup_param(struct fs_context *fc, bool want_bdev, struct path *_path); -extern int __lookup_constant(const struct constant_table tbl[], size_t tbl_size, - const char *name, int not_found); -#define lookup_constant(t, n, nf) __lookup_constant(t, ARRAY_SIZE(t), (n), (nf)) +extern int lookup_constant(const struct constant_table tbl[], const char *name, int not_found); #ifdef CONFIG_VALIDATE_FS_PARSER extern bool validate_constant_table(const struct constant_table *tbl, size_t tbl_size, -- cgit v1.2.3 From aa1918f9491442a007a0cbe41a31539233209777 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Tue, 17 Dec 2019 20:09:08 -0500 Subject: get rid of fs_value_is_filename_empty Its behaviour is identical to that of fs_value_is_filename. It makes no sense, anyway - LOOKUP_EMPTY affects nothing whatsoever once the pathname has been imported from userland. And both fs_value_is_filename and fs_value_is_filename_empty carry an already imported pathname. Signed-off-by: Al Viro --- Documentation/filesystems/mount_api.txt | 1 - fs/fs_parser.c | 3 --- fs/fsopen.c | 16 +++++----------- include/linux/fs_context.h | 1 - 4 files changed, 5 insertions(+), 16 deletions(-) diff --git a/Documentation/filesystems/mount_api.txt b/Documentation/filesystems/mount_api.txt index 00ff0cfccfa7..b96e73591327 100644 --- a/Documentation/filesystems/mount_api.txt +++ b/Documentation/filesystems/mount_api.txt @@ -427,7 +427,6 @@ returned. fs_value_is_string, Value is a string fs_value_is_blob, Value is a binary blob fs_value_is_filename, Value is a filename* + dirfd - fs_value_is_filename_empty, Value is a filename* + dirfd + AT_EMPTY_PATH fs_value_is_file, Value is an open file (file*) If there is a value, that value is stored in a union in the struct in one diff --git a/fs/fs_parser.c b/fs/fs_parser.c index 065ce6c22587..dc5c6737c280 100644 --- a/fs/fs_parser.c +++ b/fs/fs_parser.c @@ -268,9 +268,6 @@ int fs_lookup_param(struct fs_context *fc, return PTR_ERR(f); put_f = true; break; - case fs_value_is_filename_empty: - flags = LOOKUP_EMPTY; - /* Fall through */ case fs_value_is_filename: f = param->name; put_f = false; diff --git a/fs/fsopen.c b/fs/fsopen.c index 043ffa8dc263..c822d8924ca9 100644 --- a/fs/fsopen.c +++ b/fs/fsopen.c @@ -321,6 +321,7 @@ SYSCALL_DEFINE5(fsconfig, struct fs_context *fc; struct fd f; int ret; + int lookup_flags = 0; struct fs_parameter param = { .type = fs_value_is_undefined, @@ -409,19 +410,12 @@ SYSCALL_DEFINE5(fsconfig, goto out_key; } break; + case FSCONFIG_SET_PATH_EMPTY: + lookup_flags = LOOKUP_EMPTY; + /* fallthru */ case FSCONFIG_SET_PATH: param.type = fs_value_is_filename; - param.name = getname_flags(_value, 0, NULL); - if (IS_ERR(param.name)) { - ret = PTR_ERR(param.name); - goto out_key; - } - param.dirfd = aux; - param.size = strlen(param.name->name); - break; - case FSCONFIG_SET_PATH_EMPTY: - param.type = fs_value_is_filename_empty; - param.name = getname_flags(_value, LOOKUP_EMPTY, NULL); + param.name = getname_flags(_value, lookup_flags, NULL); if (IS_ERR(param.name)) { ret = PTR_ERR(param.name); goto out_key; diff --git a/include/linux/fs_context.h b/include/linux/fs_context.h index e5c14e2c53d3..c7c69640a6c6 100644 --- a/include/linux/fs_context.h +++ b/include/linux/fs_context.h @@ -54,7 +54,6 @@ enum fs_value_type { fs_value_is_string, /* Value is a string */ fs_value_is_blob, /* Value is a binary blob */ fs_value_is_filename, /* Value is a filename* + dirfd */ - fs_value_is_filename_empty, /* Value is a filename* + dirfd + AT_EMPTY_PATH */ fs_value_is_file, /* Value is a file* */ }; -- cgit v1.2.3 From fbc2d1686dc5c2e403091f3c25ca2bc16f88cccb Mon Sep 17 00:00:00 2001 From: Al Viro Date: Fri, 20 Dec 2019 21:06:08 -0500 Subject: get rid of cg_invalf() pointless alias for invalf()... Signed-off-by: Al Viro --- kernel/cgroup/cgroup-v1.c | 26 ++++++++++++-------------- 1 file changed, 12 insertions(+), 14 deletions(-) diff --git a/kernel/cgroup/cgroup-v1.c b/kernel/cgroup/cgroup-v1.c index 09f3a413f6f8..77eb72b704a6 100644 --- a/kernel/cgroup/cgroup-v1.c +++ b/kernel/cgroup/cgroup-v1.c @@ -18,8 +18,6 @@ #include -#define cg_invalf(fc, fmt, ...) invalf(fc, fmt, ## __VA_ARGS__) - /* * pidlists linger the following amount before being destroyed. The goal * is avoiding frequent destruction in the middle of consecutive read calls @@ -924,7 +922,7 @@ int cgroup1_parse_param(struct fs_context *fc, struct fs_parameter *param) ctx->subsys_mask |= (1 << i); return 0; } - return cg_invalf(fc, "cgroup1: Unknown subsys name '%s'", param->key); + return invalf(fc, "cgroup1: Unknown subsys name '%s'", param->key); } if (opt < 0) return opt; @@ -952,7 +950,7 @@ int cgroup1_parse_param(struct fs_context *fc, struct fs_parameter *param) case Opt_release_agent: /* Specifying two release agents is forbidden */ if (ctx->release_agent) - return cg_invalf(fc, "cgroup1: release_agent respecified"); + return invalf(fc, "cgroup1: release_agent respecified"); ctx->release_agent = param->string; param->string = NULL; break; @@ -962,9 +960,9 @@ int cgroup1_parse_param(struct fs_context *fc, struct fs_parameter *param) return -ENOENT; /* Can't specify an empty name */ if (!param->size) - return cg_invalf(fc, "cgroup1: Empty name"); + return invalf(fc, "cgroup1: Empty name"); if (param->size > MAX_CGROUP_ROOT_NAMELEN - 1) - return cg_invalf(fc, "cgroup1: Name too long"); + return invalf(fc, "cgroup1: Name too long"); /* Must match [\w.-]+ */ for (i = 0; i < param->size; i++) { char c = param->string[i]; @@ -972,11 +970,11 @@ int cgroup1_parse_param(struct fs_context *fc, struct fs_parameter *param) continue; if ((c == '.') || (c == '-') || (c == '_')) continue; - return cg_invalf(fc, "cgroup1: Invalid name"); + return invalf(fc, "cgroup1: Invalid name"); } /* Specifying two names is forbidden */ if (ctx->name) - return cg_invalf(fc, "cgroup1: name respecified"); + return invalf(fc, "cgroup1: name respecified"); ctx->name = param->string; param->string = NULL; break; @@ -1011,7 +1009,7 @@ static int check_cgroupfs_options(struct fs_context *fc) if (ctx->all_ss) { /* Mutually exclusive option 'all' + subsystem name */ if (ctx->subsys_mask) - return cg_invalf(fc, "cgroup1: subsys name conflicts with all"); + return invalf(fc, "cgroup1: subsys name conflicts with all"); /* 'all' => select all the subsystems */ ctx->subsys_mask = enabled; } @@ -1021,7 +1019,7 @@ static int check_cgroupfs_options(struct fs_context *fc) * empty hierarchies must have a name). */ if (!ctx->subsys_mask && !ctx->name) - return cg_invalf(fc, "cgroup1: Need name or subsystem set"); + return invalf(fc, "cgroup1: Need name or subsystem set"); /* * Option noprefix was introduced just for backward compatibility @@ -1029,11 +1027,11 @@ static int check_cgroupfs_options(struct fs_context *fc) * the cpuset subsystem. */ if ((ctx->flags & CGRP_ROOT_NOPREFIX) && (ctx->subsys_mask & mask)) - return cg_invalf(fc, "cgroup1: noprefix used incorrectly"); + return invalf(fc, "cgroup1: noprefix used incorrectly"); /* Can't specify "none" and some subsystems */ if (ctx->subsys_mask && ctx->none) - return cg_invalf(fc, "cgroup1: none used incorrectly"); + return invalf(fc, "cgroup1: none used incorrectly"); return 0; } @@ -1063,7 +1061,7 @@ int cgroup1_reconfigure(struct fs_context *fc) /* Don't allow flags or name to change at remount */ if ((ctx->flags ^ root->flags) || (ctx->name && strcmp(ctx->name, root->name))) { - cg_invalf(fc, "option or name mismatch, new: 0x%x \"%s\", old: 0x%x \"%s\"", + errorf(fc, "option or name mismatch, new: 0x%x \"%s\", old: 0x%x \"%s\"", ctx->flags, ctx->name ?: "", root->flags, root->name); ret = -EINVAL; goto out_unlock; @@ -1180,7 +1178,7 @@ static int cgroup1_root_to_use(struct fs_context *fc) * can't create new one without subsys specification. */ if (!ctx->subsys_mask && !ctx->none) - return cg_invalf(fc, "cgroup1: No subsys list or none specified"); + return invalf(fc, "cgroup1: No subsys list or none specified"); /* Hierarchies may only be created in the initial cgroup namespace. */ if (ctx->ns != &init_cgroup_ns) -- cgit v1.2.3 From 9f09f649ca3350cdb49c81f7d5ac6e64a4d7e1a1 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Fri, 20 Dec 2019 22:10:36 -0500 Subject: teach logfc() to handle prefices, give it saner calling conventions Signed-off-by: Al Viro --- fs/fs_context.c | 63 +++++++++++++--------------------------------- include/linux/fs_context.h | 16 +++++++----- 2 files changed, 27 insertions(+), 52 deletions(-) diff --git a/fs/fs_context.c b/fs/fs_context.c index ea97a2411e83..fb6329c21384 100644 --- a/fs/fs_context.c +++ b/fs/fs_context.c @@ -388,64 +388,33 @@ EXPORT_SYMBOL(vfs_dup_fs_context); * @fc: The filesystem context to log to. * @fmt: The format of the buffer. */ -void logfc(struct fs_context *fc, const char *fmt, ...) +void logfc(struct fc_log *log, const char *prefix, char level, const char *fmt, ...) { - static const char store_failure[] = "OOM: Can't store error string"; - struct fc_log *log = fc ? fc->log : NULL; - const char *p; va_list va; - char *q; - u8 freeable; + struct va_format vaf = {.fmt = fmt, .va = &va}; va_start(va, fmt); - if (!strchr(fmt, '%')) { - p = fmt; - goto unformatted_string; - } - if (strcmp(fmt, "%s") == 0) { - p = va_arg(va, const char *); - goto unformatted_string; - } - - q = kvasprintf(GFP_KERNEL, fmt, va); -copied_string: - if (!q) - goto store_failure; - freeable = 1; - goto store_string; - -unformatted_string: - if ((unsigned long)p >= (unsigned long)__start_rodata && - (unsigned long)p < (unsigned long)__end_rodata) - goto const_string; - if (log && within_module_core((unsigned long)p, log->owner)) - goto const_string; - q = kstrdup(p, GFP_KERNEL); - goto copied_string; - -store_failure: - p = store_failure; -const_string: - q = (char *)p; - freeable = 0; -store_string: if (!log) { - switch (fmt[0]) { + switch (level) { case 'w': - printk(KERN_WARNING "%s\n", q + 2); + printk(KERN_WARNING "%s%s%pV\n", prefix ? prefix : "", + prefix ? ": " : "", &vaf); break; case 'e': - printk(KERN_ERR "%s\n", q + 2); + printk(KERN_ERR "%s%s%pV\n", prefix ? prefix : "", + prefix ? ": " : "", &vaf); break; default: - printk(KERN_NOTICE "%s\n", q + 2); + printk(KERN_NOTICE "%s%s%pV\n", prefix ? prefix : "", + prefix ? ": " : "", &vaf); break; } - if (freeable) - kfree(q); } else { unsigned int logsize = ARRAY_SIZE(log->buffer); u8 index; + char *q = kasprintf(GFP_KERNEL, "%c %s%s%pV\n", level, + prefix ? prefix : "", + prefix ? ": " : "", &vaf); index = log->head & (logsize - 1); BUILD_BUG_ON(sizeof(log->head) != sizeof(u8) || @@ -457,9 +426,11 @@ store_string: log->tail++; } - log->buffer[index] = q; - log->need_free &= ~(1 << index); - log->need_free |= freeable << index; + log->buffer[index] = q ? q : "OOM: Can't store error string"; + if (q) + log->need_free |= 1 << index; + else + log->need_free &= ~(1 << index); log->head++; } va_end(va); diff --git a/include/linux/fs_context.h b/include/linux/fs_context.h index c7c69640a6c6..d18ff422e942 100644 --- a/include/linux/fs_context.h +++ b/include/linux/fs_context.h @@ -181,9 +181,13 @@ struct fc_log { char *buffer[8]; }; -extern __attribute__((format(printf, 2, 3))) -void logfc(struct fs_context *fc, const char *fmt, ...); +extern __attribute__((format(printf, 4, 5))) +void logfc(struct fc_log *log, const char *prefix, char level, const char *fmt, ...); +#define __logfc(fc, l, fmt, ...) ({ \ + struct fs_context *__fc = (fc); \ + logfc(__fc ? __fc->log : NULL, NULL, \ + l, fmt, ## __VA_ARGS__);}) /** * infof - Store supplementary informational message * @fc: The context in which to log the informational message @@ -192,7 +196,7 @@ void logfc(struct fs_context *fc, const char *fmt, ...); * Store the supplementary informational message for the process if the process * has enabled the facility. */ -#define infof(fc, fmt, ...) ({ logfc(fc, "i "fmt, ## __VA_ARGS__); }) +#define infof(fc, fmt, ...) __logfc(fc, 'i', fmt, ## __VA_ARGS__) /** * warnf - Store supplementary warning message @@ -202,7 +206,7 @@ void logfc(struct fs_context *fc, const char *fmt, ...); * Store the supplementary warning message for the process if the process has * enabled the facility. */ -#define warnf(fc, fmt, ...) ({ logfc(fc, "w "fmt, ## __VA_ARGS__); }) +#define warnf(fc, fmt, ...) __logfc(fc, 'w', fmt, ## __VA_ARGS__) /** * errorf - Store supplementary error message @@ -212,7 +216,7 @@ void logfc(struct fs_context *fc, const char *fmt, ...); * Store the supplementary error message for the process if the process has * enabled the facility. */ -#define errorf(fc, fmt, ...) ({ logfc(fc, "e "fmt, ## __VA_ARGS__); }) +#define errorf(fc, fmt, ...) __logfc(fc, 'e', fmt, ## __VA_ARGS__) /** * invalf - Store supplementary invalid argument error message @@ -222,6 +226,6 @@ void logfc(struct fs_context *fc, const char *fmt, ...); * Store the supplementary error message for the process if the process has * enabled the facility and return -EINVAL. */ -#define invalf(fc, fmt, ...) ({ errorf(fc, fmt, ## __VA_ARGS__); -EINVAL; }) +#define invalf(fc, fmt, ...) (errorf(fc, fmt, ## __VA_ARGS__), -EINVAL) #endif /* _LINUX_FS_CONTEXT_H */ -- cgit v1.2.3 From 3fbb8d5554a1481d9c5f54ee7dc59f416650efb1 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Fri, 20 Dec 2019 23:43:32 -0500 Subject: struct p_log, variants of warnf() et.al. taking that one instead primitives for prefixed logging Signed-off-by: Al Viro --- drivers/block/rbd.c | 1 + include/linux/fs_context.h | 11 +++++++++++ 2 files changed, 12 insertions(+) diff --git a/drivers/block/rbd.c b/drivers/block/rbd.c index 9fc686be81ca..1dd758e8f955 100644 --- a/drivers/block/rbd.c +++ b/drivers/block/rbd.c @@ -6353,6 +6353,7 @@ static int rbd_parse_param(struct fs_parameter *param, { struct rbd_options *opt = pctx->opts; struct fs_parse_result result; + struct p_log log = {.prefix = "rbd"}; int token, ret; ret = ceph_parse_param(param, pctx->copts, NULL); diff --git a/include/linux/fs_context.h b/include/linux/fs_context.h index d18ff422e942..6a7eeb252084 100644 --- a/include/linux/fs_context.h +++ b/include/linux/fs_context.h @@ -73,6 +73,11 @@ struct fs_parameter { int dirfd; }; +struct p_log { + const char *prefix; + struct fc_log *log; +}; + /* * Filesystem context for holding the parameters used in the creation or * reconfiguration of a superblock. @@ -188,6 +193,8 @@ void logfc(struct fc_log *log, const char *prefix, char level, const char *fmt, struct fs_context *__fc = (fc); \ logfc(__fc ? __fc->log : NULL, NULL, \ l, fmt, ## __VA_ARGS__);}) +#define __plog(p, l, fmt, ...) logfc((p)->log, (p)->prefix, \ + l, fmt, ## __VA_ARGS__) /** * infof - Store supplementary informational message * @fc: The context in which to log the informational message @@ -197,6 +204,7 @@ void logfc(struct fc_log *log, const char *prefix, char level, const char *fmt, * has enabled the facility. */ #define infof(fc, fmt, ...) __logfc(fc, 'i', fmt, ## __VA_ARGS__) +#define info_plog(p, fmt, ...) __plog(p, 'i', fmt, ## __VA_ARGS__) /** * warnf - Store supplementary warning message @@ -207,6 +215,7 @@ void logfc(struct fc_log *log, const char *prefix, char level, const char *fmt, * enabled the facility. */ #define warnf(fc, fmt, ...) __logfc(fc, 'w', fmt, ## __VA_ARGS__) +#define warn_plog(p, fmt, ...) __plog(p, 'w', fmt, ## __VA_ARGS__) /** * errorf - Store supplementary error message @@ -217,6 +226,7 @@ void logfc(struct fc_log *log, const char *prefix, char level, const char *fmt, * enabled the facility. */ #define errorf(fc, fmt, ...) __logfc(fc, 'e', fmt, ## __VA_ARGS__) +#define error_plog(p, fmt, ...) __plog(p, 'e', fmt, ## __VA_ARGS__) /** * invalf - Store supplementary invalid argument error message @@ -227,5 +237,6 @@ void logfc(struct fc_log *log, const char *prefix, char level, const char *fmt, * enabled the facility and return -EINVAL. */ #define invalf(fc, fmt, ...) (errorf(fc, fmt, ## __VA_ARGS__), -EINVAL) +#define inval_plog(p, fmt, ...) (error_plog(p, fmt, ## __VA_ARGS__), -EINVAL) #endif /* _LINUX_FS_CONTEXT_H */ -- cgit v1.2.3 From 2c3f3dc315565941262e980029c0f74ad118231a Mon Sep 17 00:00:00 2001 From: Al Viro Date: Fri, 20 Dec 2019 23:43:32 -0500 Subject: switch rbd and libceph to p_log-based primitives Signed-off-by: Al Viro --- drivers/block/rbd.c | 14 ++++++-------- net/ceph/ceph_common.c | 26 ++++++++++++++------------ 2 files changed, 20 insertions(+), 20 deletions(-) diff --git a/drivers/block/rbd.c b/drivers/block/rbd.c index 1dd758e8f955..596a1188d0c3 100644 --- a/drivers/block/rbd.c +++ b/drivers/block/rbd.c @@ -6363,10 +6363,9 @@ static int rbd_parse_param(struct fs_parameter *param, token = fs_parse(NULL, &rbd_parameters, param, &result); dout("%s fs_parse '%s' token %d\n", __func__, param->key, token); if (token < 0) { - if (token == -ENOPARAM) { - return invalf(NULL, "rbd: Unknown parameter '%s'", - param->key); - } + if (token == -ENOPARAM) + return inval_plog(&log, "Unknown parameter '%s'", + param->key); return token; } @@ -6379,9 +6378,8 @@ static int rbd_parse_param(struct fs_parameter *param, case Opt_alloc_size: if (result.uint_32 < SECTOR_SIZE) goto out_of_range; - if (!is_power_of_2(result.uint_32)) { - return invalf(NULL, "rbd: alloc_size must be a power of 2"); - } + if (!is_power_of_2(result.uint_32)) + return inval_plog(&log, "alloc_size must be a power of 2"); opt->alloc_size = result.uint_32; break; case Opt_lock_timeout: @@ -6417,7 +6415,7 @@ static int rbd_parse_param(struct fs_parameter *param, return 0; out_of_range: - return invalf(NULL, "rbd: %s out of range", param->key); + return inval_plog(&log, "%s out of range", param->key); } /* diff --git a/net/ceph/ceph_common.c b/net/ceph/ceph_common.c index c2d0b5c47b5f..a3f4f00f2b72 100644 --- a/net/ceph/ceph_common.c +++ b/net/ceph/ceph_common.c @@ -337,7 +337,7 @@ EXPORT_SYMBOL(ceph_destroy_options); /* get secret from key store */ static int get_secret(struct ceph_crypto_key *dst, const char *name, - struct fs_context *fc) + struct p_log *log) { struct key *ukey; int key_err; @@ -351,19 +351,19 @@ static int get_secret(struct ceph_crypto_key *dst, const char *name, key_err = PTR_ERR(ukey); switch (key_err) { case -ENOKEY: - errorf(fc, "libceph: Failed due to key not found: %s", + error_plog(log, "Failed due to key not found: %s", name); break; case -EKEYEXPIRED: - errorf(fc, "libceph: Failed due to expired key: %s", + error_plog(log, "Failed due to expired key: %s", name); break; case -EKEYREVOKED: - errorf(fc, "libceph: Failed due to revoked key: %s", + error_plog(log, "Failed due to revoked key: %s", name); break; default: - errorf(fc, "libceph: Failed due to key error %d: %s", + error_plog(log, "Failed due to key error %d: %s", key_err, name); } err = -EPERM; @@ -385,13 +385,14 @@ out: int ceph_parse_mon_ips(const char *buf, size_t len, struct ceph_options *opt, struct fs_context *fc) { + struct p_log log = {.prefix = "libceph", .log = fc ? fc->log : NULL}; int ret; /* ip1[:port1][,ip2[:port2]...] */ ret = ceph_parse_ips(buf, buf + len, opt->mon_addr, CEPH_MAX_MON, &opt->num_mon); if (ret) { - errorf(fc, "libceph: Failed to parse monitor IPs: %d", ret); + error_plog(&log, "Failed to parse monitor IPs: %d", ret); return ret; } @@ -404,6 +405,7 @@ int ceph_parse_param(struct fs_parameter *param, struct ceph_options *opt, { struct fs_parse_result result; int token, err; + struct p_log log = {.prefix = "libceph", .log = fc ? fc->log : NULL}; token = fs_parse(fc, &ceph_parameters, param, &result); dout("%s fs_parse '%s' token %d\n", __func__, param->key, token); @@ -417,7 +419,7 @@ int ceph_parse_param(struct fs_parameter *param, struct ceph_options *opt, &opt->my_addr, 1, NULL); if (err) { - errorf(fc, "libceph: Failed to parse ip: %d", err); + error_plog(&log, "Failed to parse ip: %d", err); return err; } opt->flags |= CEPH_OPT_MYIP; @@ -426,7 +428,7 @@ int ceph_parse_param(struct fs_parameter *param, struct ceph_options *opt, case Opt_fsid: err = parse_fsid(param->string, &opt->fsid); if (err) { - errorf(fc, "libceph: Failed to parse fsid: %d", err); + error_plog(&log, "Failed to parse fsid: %d", err); return err; } opt->flags |= CEPH_OPT_FSID; @@ -445,7 +447,7 @@ int ceph_parse_param(struct fs_parameter *param, struct ceph_options *opt, return -ENOMEM; err = ceph_crypto_key_unarmor(opt->key, param->string); if (err) { - errorf(fc, "libceph: Failed to parse secret: %d", err); + error_plog(&log, "Failed to parse secret: %d", err); return err; } break; @@ -456,10 +458,10 @@ int ceph_parse_param(struct fs_parameter *param, struct ceph_options *opt, opt->key = kzalloc(sizeof(*opt->key), GFP_KERNEL); if (!opt->key) return -ENOMEM; - return get_secret(opt->key, param->string, fc); + return get_secret(opt->key, param->string, &log); case Opt_osdtimeout: - warnf(fc, "libceph: Ignoring osdtimeout"); + warn_plog(&log, "Ignoring osdtimeout"); break; case Opt_osdkeepalivetimeout: /* 0 isn't well defined right now, reject it */ @@ -530,7 +532,7 @@ int ceph_parse_param(struct fs_parameter *param, struct ceph_options *opt, return 0; out_of_range: - return invalf(fc, "libceph: %s out of range", param->key); + return inval_plog(&log, "%s out of range", param->key); } EXPORT_SYMBOL(ceph_parse_param); -- cgit v1.2.3 From 7f5d38141e309bb4ba995d9726928af85a299c50 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Fri, 20 Dec 2019 23:52:55 -0500 Subject: new primitive: __fs_parse() fs_parse() analogue taking p_log instead of fs_context. fs_parse() turned into a wrapper, callers in ceph_common and rbd switched to __fs_parse(). As the result, fs_parse() never gets NULL fs_context and neither do fs_context-based logging primitives Signed-off-by: Al Viro --- drivers/block/rbd.c | 2 +- fs/fs_parser.c | 21 +++++++++++++++------ include/linux/fs_context.h | 6 ++---- include/linux/fs_parser.h | 4 ++++ net/ceph/ceph_common.c | 2 +- 5 files changed, 23 insertions(+), 12 deletions(-) diff --git a/drivers/block/rbd.c b/drivers/block/rbd.c index 596a1188d0c3..47e82f076a12 100644 --- a/drivers/block/rbd.c +++ b/drivers/block/rbd.c @@ -6360,7 +6360,7 @@ static int rbd_parse_param(struct fs_parameter *param, if (ret != -ENOPARAM) return ret; - token = fs_parse(NULL, &rbd_parameters, param, &result); + token = __fs_parse(&log, &rbd_parameters, param, &result); dout("%s fs_parse '%s' token %d\n", __func__, param->key, token); if (token < 0) { if (token == -ENOPARAM) diff --git a/fs/fs_parser.c b/fs/fs_parser.c index dc5c6737c280..dadb6582874d 100644 --- a/fs/fs_parser.c +++ b/fs/fs_parser.c @@ -80,7 +80,7 @@ static const struct fs_parameter_spec *fs_lookup_key( * unknown parameters are okay and -EINVAL if there was a conversion issue or * the parameter wasn't recognised and unknowns aren't okay. */ -int fs_parse(struct fs_context *fc, +int __fs_parse(struct p_log *log, const struct fs_parameter_description *desc, struct fs_parameter *param, struct fs_parse_result *result) @@ -113,8 +113,7 @@ int fs_parse(struct fs_context *fc, } if (p->flags & fs_param_deprecated) - warnf(fc, "%s: Deprecated parameter '%s'", - desc->name, param->key); + warn_plog(log, "Deprecated parameter '%s'", param->key); if (result->negated) goto okay; @@ -152,8 +151,8 @@ int fs_parse(struct fs_context *fc, switch (p->type) { case fs_param_is_flag: if (param->type != fs_value_is_flag) - return invalf(fc, "%s: Unexpected value for '%s'", - desc->name, param->key); + return inval_plog(log, "Unexpected value for '%s'", + param->key); result->boolean = true; goto okay; @@ -238,10 +237,20 @@ okay: return p->opt; bad_value: - return invalf(fc, "%s: Bad value for '%s'", desc->name, param->key); + return inval_plog(log, "Bad value for '%s'", param->key); unknown_parameter: return -ENOPARAM; } +EXPORT_SYMBOL(__fs_parse); + +int fs_parse(struct fs_context *fc, + const struct fs_parameter_description *desc, + struct fs_parameter *param, + struct fs_parse_result *result) +{ + struct p_log log = {.prefix = desc->name, .log = fc->log}; + return __fs_parse(&log, desc, param, result); +} EXPORT_SYMBOL(fs_parse); /** diff --git a/include/linux/fs_context.h b/include/linux/fs_context.h index 6a7eeb252084..41f37d33e358 100644 --- a/include/linux/fs_context.h +++ b/include/linux/fs_context.h @@ -189,10 +189,8 @@ struct fc_log { extern __attribute__((format(printf, 4, 5))) void logfc(struct fc_log *log, const char *prefix, char level, const char *fmt, ...); -#define __logfc(fc, l, fmt, ...) ({ \ - struct fs_context *__fc = (fc); \ - logfc(__fc ? __fc->log : NULL, NULL, \ - l, fmt, ## __VA_ARGS__);}) +#define __logfc(fc, l, fmt, ...) logfc((fc)->log, NULL, \ + l, fmt, ## __VA_ARGS__) #define __plog(p, l, fmt, ...) logfc((p)->log, (p)->prefix, \ l, fmt, ## __VA_ARGS__) /** diff --git a/include/linux/fs_parser.h b/include/linux/fs_parser.h index 14bdaacf1218..b0fba26a4ffe 100644 --- a/include/linux/fs_parser.h +++ b/include/linux/fs_parser.h @@ -74,6 +74,10 @@ struct fs_parse_result { }; }; +extern int __fs_parse(struct p_log *log, + const struct fs_parameter_description *desc, + struct fs_parameter *value, + struct fs_parse_result *result); extern int fs_parse(struct fs_context *fc, const struct fs_parameter_description *desc, struct fs_parameter *value, diff --git a/net/ceph/ceph_common.c b/net/ceph/ceph_common.c index a3f4f00f2b72..9f8bc962985d 100644 --- a/net/ceph/ceph_common.c +++ b/net/ceph/ceph_common.c @@ -407,7 +407,7 @@ int ceph_parse_param(struct fs_parameter *param, struct ceph_options *opt, int token, err; struct p_log log = {.prefix = "libceph", .log = fc ? fc->log : NULL}; - token = fs_parse(fc, &ceph_parameters, param, &result); + token = __fs_parse(&log, &ceph_parameters, param, &result); dout("%s fs_parse '%s' token %d\n", __func__, param->key, token); if (token < 0) return token; -- cgit v1.2.3 From c80c98f0dc5dc709b04254b5f30145c6ab8800a4 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Sat, 21 Dec 2019 00:06:01 -0500 Subject: ceph_parse_param(), ceph_parse_mon_ips(): switch to passing fc_log ... and now errorf() et.al. are never called with NULL fs_context, so we can get rid of conditional in those. Signed-off-by: Al Viro --- fs/ceph/super.c | 4 ++-- include/linux/ceph/libceph.h | 5 +++-- net/ceph/ceph_common.c | 8 ++++---- 3 files changed, 9 insertions(+), 8 deletions(-) diff --git a/fs/ceph/super.c b/fs/ceph/super.c index 2bad9bc1fd70..0fe0aa575585 100644 --- a/fs/ceph/super.c +++ b/fs/ceph/super.c @@ -250,7 +250,7 @@ static int ceph_parse_source(struct fs_parameter *param, struct fs_context *fc) dout("server path '%s'\n", fsopt->server_path); ret = ceph_parse_mon_ips(param->string, dev_name_end - dev_name, - pctx->copts, fc); + pctx->copts, fc->log); if (ret) return ret; @@ -268,7 +268,7 @@ static int ceph_parse_mount_param(struct fs_context *fc, unsigned int mode; int token, ret; - ret = ceph_parse_param(param, pctx->copts, fc); + ret = ceph_parse_param(param, pctx->copts, fc->log); if (ret != -ENOPARAM) return ret; diff --git a/include/linux/ceph/libceph.h b/include/linux/ceph/libceph.h index 8fe9b80e80a5..ec73ebc4827d 100644 --- a/include/linux/ceph/libceph.h +++ b/include/linux/ceph/libceph.h @@ -281,11 +281,12 @@ extern int ceph_check_fsid(struct ceph_client *client, struct ceph_fsid *fsid); extern void *ceph_kvmalloc(size_t size, gfp_t flags); struct fs_parameter; +struct fc_log; struct ceph_options *ceph_alloc_options(void); int ceph_parse_mon_ips(const char *buf, size_t len, struct ceph_options *opt, - struct fs_context *fc); + struct fc_log *l); int ceph_parse_param(struct fs_parameter *param, struct ceph_options *opt, - struct fs_context *fc); + struct fc_log *l); int ceph_print_client_options(struct seq_file *m, struct ceph_client *client, bool show_all); extern void ceph_destroy_options(struct ceph_options *opt); diff --git a/net/ceph/ceph_common.c b/net/ceph/ceph_common.c index 9f8bc962985d..d435d22999f5 100644 --- a/net/ceph/ceph_common.c +++ b/net/ceph/ceph_common.c @@ -383,9 +383,9 @@ out: } int ceph_parse_mon_ips(const char *buf, size_t len, struct ceph_options *opt, - struct fs_context *fc) + struct fc_log *l) { - struct p_log log = {.prefix = "libceph", .log = fc ? fc->log : NULL}; + struct p_log log = {.prefix = "libceph", .log = l}; int ret; /* ip1[:port1][,ip2[:port2]...] */ @@ -401,11 +401,11 @@ int ceph_parse_mon_ips(const char *buf, size_t len, struct ceph_options *opt, EXPORT_SYMBOL(ceph_parse_mon_ips); int ceph_parse_param(struct fs_parameter *param, struct ceph_options *opt, - struct fs_context *fc) + struct fc_log *l) { struct fs_parse_result result; int token, err; - struct p_log log = {.prefix = "libceph", .log = fc ? fc->log : NULL}; + struct p_log log = {.prefix = "libceph", .log = l}; token = __fs_parse(&log, &ceph_parameters, param, &result); dout("%s fs_parse '%s' token %d\n", __func__, param->key, token); -- cgit v1.2.3 From cc3c0b533ab9142eac2e291628fbfca3685f38cd Mon Sep 17 00:00:00 2001 From: Al Viro Date: Sat, 21 Dec 2019 00:16:49 -0500 Subject: add prefix to fs_context->log ... turning it into struct p_log embedded into fs_context. Initialize the prefix with fs_type->name, turning fs_parse() into a trivial inline wrapper for __fs_parse(). This makes fs_parameter_description->name completely unused. Signed-off-by: Al Viro --- fs/ceph/super.c | 4 ++-- fs/fs_context.c | 9 +++++---- fs/fs_parser.c | 10 ---------- fs/fsopen.c | 10 +++++----- include/linux/fs_context.h | 4 ++-- include/linux/fs_parser.h | 13 +++++++++---- 6 files changed, 23 insertions(+), 27 deletions(-) diff --git a/fs/ceph/super.c b/fs/ceph/super.c index 0fe0aa575585..4125de07221b 100644 --- a/fs/ceph/super.c +++ b/fs/ceph/super.c @@ -250,7 +250,7 @@ static int ceph_parse_source(struct fs_parameter *param, struct fs_context *fc) dout("server path '%s'\n", fsopt->server_path); ret = ceph_parse_mon_ips(param->string, dev_name_end - dev_name, - pctx->copts, fc->log); + pctx->copts, fc->log.log); if (ret) return ret; @@ -268,7 +268,7 @@ static int ceph_parse_mount_param(struct fs_context *fc, unsigned int mode; int token, ret; - ret = ceph_parse_param(param, pctx->copts, fc->log); + ret = ceph_parse_param(param, pctx->copts, fc->log.log); if (ret != -ENOPARAM) return ret; diff --git a/fs/fs_context.c b/fs/fs_context.c index fb6329c21384..fc9f6ef93b55 100644 --- a/fs/fs_context.c +++ b/fs/fs_context.c @@ -271,6 +271,7 @@ static struct fs_context *alloc_fs_context(struct file_system_type *fs_type, fc->fs_type = get_filesystem(fs_type); fc->cred = get_current_cred(); fc->net_ns = get_net(current->nsproxy->net_ns); + fc->log.prefix = fs_type->name; mutex_init(&fc->uapi_mutex); @@ -364,8 +365,8 @@ struct fs_context *vfs_dup_fs_context(struct fs_context *src_fc) get_net(fc->net_ns); get_user_ns(fc->user_ns); get_cred(fc->cred); - if (fc->log) - refcount_inc(&fc->log->usage); + if (fc->log.log) + refcount_inc(&fc->log.log->usage); /* Can't call put until we've called ->dup */ ret = fc->ops->dup(fc, src_fc); @@ -442,12 +443,12 @@ EXPORT_SYMBOL(logfc); */ static void put_fc_log(struct fs_context *fc) { - struct fc_log *log = fc->log; + struct fc_log *log = fc->log.log; int i; if (log) { if (refcount_dec_and_test(&log->usage)) { - fc->log = NULL; + fc->log.log = NULL; for (i = 0; i <= 7; i++) if (log->need_free & (1 << i)) kfree(log->buffer[i]); diff --git a/fs/fs_parser.c b/fs/fs_parser.c index dadb6582874d..4c410eef0173 100644 --- a/fs/fs_parser.c +++ b/fs/fs_parser.c @@ -243,16 +243,6 @@ unknown_parameter: } EXPORT_SYMBOL(__fs_parse); -int fs_parse(struct fs_context *fc, - const struct fs_parameter_description *desc, - struct fs_parameter *param, - struct fs_parse_result *result) -{ - struct p_log log = {.prefix = desc->name, .log = fc->log}; - return __fs_parse(&log, desc, param, result); -} -EXPORT_SYMBOL(fs_parse); - /** * fs_lookup_param - Look up a path referred to by a parameter * @fc: The filesystem context to log errors through. diff --git a/fs/fsopen.c b/fs/fsopen.c index c822d8924ca9..2fa3f241b762 100644 --- a/fs/fsopen.c +++ b/fs/fsopen.c @@ -25,7 +25,7 @@ static ssize_t fscontext_read(struct file *file, char __user *_buf, size_t len, loff_t *pos) { struct fs_context *fc = file->private_data; - struct fc_log *log = fc->log; + struct fc_log *log = fc->log.log; unsigned int logsize = ARRAY_SIZE(log->buffer); ssize_t ret; char *p; @@ -97,11 +97,11 @@ static int fscontext_create_fd(struct fs_context *fc, unsigned int o_flags) static int fscontext_alloc_log(struct fs_context *fc) { - fc->log = kzalloc(sizeof(*fc->log), GFP_KERNEL); - if (!fc->log) + fc->log.log = kzalloc(sizeof(*fc->log.log), GFP_KERNEL); + if (!fc->log.log) return -ENOMEM; - refcount_set(&fc->log->usage, 1); - fc->log->owner = fc->fs_type->owner; + refcount_set(&fc->log.log->usage, 1); + fc->log.log->owner = fc->fs_type->owner; return 0; } diff --git a/include/linux/fs_context.h b/include/linux/fs_context.h index 41f37d33e358..b2ad9b0a7af4 100644 --- a/include/linux/fs_context.h +++ b/include/linux/fs_context.h @@ -97,7 +97,7 @@ struct fs_context { struct user_namespace *user_ns; /* The user namespace for this mount */ struct net *net_ns; /* The network namespace for this mount */ const struct cred *cred; /* The mounter's credentials */ - struct fc_log *log; /* Logging buffer */ + struct p_log log; /* Logging buffer */ const char *source; /* The source name (eg. dev path) */ void *security; /* Linux S&M options */ void *s_fs_info; /* Proposed s_fs_info */ @@ -189,7 +189,7 @@ struct fc_log { extern __attribute__((format(printf, 4, 5))) void logfc(struct fc_log *log, const char *prefix, char level, const char *fmt, ...); -#define __logfc(fc, l, fmt, ...) logfc((fc)->log, NULL, \ +#define __logfc(fc, l, fmt, ...) logfc((fc)->log.log, NULL, \ l, fmt, ## __VA_ARGS__) #define __plog(p, l, fmt, ...) logfc((p)->log, (p)->prefix, \ l, fmt, ## __VA_ARGS__) diff --git a/include/linux/fs_parser.h b/include/linux/fs_parser.h index b0fba26a4ffe..37459124c1c1 100644 --- a/include/linux/fs_parser.h +++ b/include/linux/fs_parser.h @@ -78,10 +78,15 @@ extern int __fs_parse(struct p_log *log, const struct fs_parameter_description *desc, struct fs_parameter *value, struct fs_parse_result *result); -extern int fs_parse(struct fs_context *fc, - const struct fs_parameter_description *desc, - struct fs_parameter *value, - struct fs_parse_result *result); + +static inline int fs_parse(struct fs_context *fc, + const struct fs_parameter_description *desc, + struct fs_parameter *param, + struct fs_parse_result *result) +{ + return __fs_parse(&fc->log, desc, param, result); +} + extern int fs_lookup_param(struct fs_context *fc, struct fs_parameter *param, bool want_bdev, -- cgit v1.2.3 From 96cafb9ccb153f6a82ff2c9bde68916d9d65501e Mon Sep 17 00:00:00 2001 From: Eric Sandeen Date: Fri, 6 Dec 2019 10:45:01 -0600 Subject: fs_parser: remove fs_parameter_description name field Unused now. Signed-off-by: Eric Sandeen Acked-by: David Howells Signed-off-by: Al Viro --- Documentation/filesystems/mount_api.txt | 11 ++--------- arch/powerpc/platforms/cell/spufs/inode.c | 1 - arch/s390/hypfs/inode.c | 1 - arch/x86/kernel/cpu/resctrl/rdtgroup.c | 1 - drivers/block/rbd.c | 1 - drivers/usb/gadget/function/f_fs.c | 1 - fs/afs/super.c | 1 - fs/ceph/super.c | 1 - fs/filesystems.c | 3 ++- fs/fs_parser.c | 10 ++-------- fs/fuse/inode.c | 1 - fs/gfs2/ops_fstype.c | 1 - fs/hugetlbfs/inode.c | 1 - fs/jffs2/super.c | 1 - fs/nfs/fs_context.c | 1 - fs/proc/root.c | 1 - fs/ramfs/inode.c | 1 - fs/xfs/xfs_super.c | 1 - include/linux/fs_parser.h | 7 ++++--- kernel/bpf/inode.c | 1 - kernel/cgroup/cgroup-v1.c | 1 - kernel/cgroup/cgroup.c | 1 - mm/shmem.c | 1 - net/ceph/ceph_common.c | 1 - security/selinux/hooks.c | 3 +-- security/smack/smack_lsm.c | 1 - 26 files changed, 11 insertions(+), 44 deletions(-) diff --git a/Documentation/filesystems/mount_api.txt b/Documentation/filesystems/mount_api.txt index b96e73591327..87c14bbb2b35 100644 --- a/Documentation/filesystems/mount_api.txt +++ b/Documentation/filesystems/mount_api.txt @@ -518,7 +518,6 @@ Parameters are described using structures defined in linux/fs_parser.h. There's a core description struct that links everything together: struct fs_parameter_description { - const char name[16]; const struct fs_parameter_spec *specs; const struct fs_parameter_enum *enums; }; @@ -534,19 +533,13 @@ For example: }; static const struct fs_parameter_description afs_fs_parameters = { - .name = "kAFS", .specs = afs_param_specs, .enums = afs_param_enums, }; The members are as follows: - (1) const char name[16]; - - The name to be used in error messages generated by the parse helper - functions. - - (2) const struct fs_parameter_specification *specs; + (1) const struct fs_parameter_specification *specs; Table of parameter specifications, terminated with a null entry, where the entries are of type: @@ -625,7 +618,7 @@ The members are as follows: of arguments to specify the type and the flags for anything that doesn't match one of the above macros. - (6) const struct fs_parameter_enum *enums; + (2) const struct fs_parameter_enum *enums; Table of enum value names to integer mappings, terminated with a null entry. This is of type: diff --git a/arch/powerpc/platforms/cell/spufs/inode.c b/arch/powerpc/platforms/cell/spufs/inode.c index 9b1586b85152..36ce5d0ac675 100644 --- a/arch/powerpc/platforms/cell/spufs/inode.c +++ b/arch/powerpc/platforms/cell/spufs/inode.c @@ -592,7 +592,6 @@ static const struct fs_parameter_spec spufs_param_specs[] = { }; static const struct fs_parameter_description spufs_fs_parameters = { - .name = "spufs", .specs = spufs_param_specs, }; diff --git a/arch/s390/hypfs/inode.c b/arch/s390/hypfs/inode.c index 70139d0791b6..b3a6d13a63bf 100644 --- a/arch/s390/hypfs/inode.c +++ b/arch/s390/hypfs/inode.c @@ -216,7 +216,6 @@ static const struct fs_parameter_spec hypfs_param_specs[] = { }; static const struct fs_parameter_description hypfs_fs_parameters = { - .name = "hypfs", .specs = hypfs_param_specs, }; diff --git a/arch/x86/kernel/cpu/resctrl/rdtgroup.c b/arch/x86/kernel/cpu/resctrl/rdtgroup.c index 2e3b06d6bbc6..f145594e4d6a 100644 --- a/arch/x86/kernel/cpu/resctrl/rdtgroup.c +++ b/arch/x86/kernel/cpu/resctrl/rdtgroup.c @@ -2045,7 +2045,6 @@ static const struct fs_parameter_spec rdt_param_specs[] = { }; static const struct fs_parameter_description rdt_fs_parameters = { - .name = "rdt", .specs = rdt_param_specs, }; diff --git a/drivers/block/rbd.c b/drivers/block/rbd.c index 47e82f076a12..e87486920382 100644 --- a/drivers/block/rbd.c +++ b/drivers/block/rbd.c @@ -864,7 +864,6 @@ static const struct fs_parameter_spec rbd_param_specs[] = { }; static const struct fs_parameter_description rbd_parameters = { - .name = "rbd", .specs = rbd_param_specs, }; diff --git a/drivers/usb/gadget/function/f_fs.c b/drivers/usb/gadget/function/f_fs.c index 0bbccac94d6c..eda1972b70eb 100644 --- a/drivers/usb/gadget/function/f_fs.c +++ b/drivers/usb/gadget/function/f_fs.c @@ -1497,7 +1497,6 @@ static const struct fs_parameter_spec ffs_fs_param_specs[] = { }; static const struct fs_parameter_description ffs_fs_fs_parameters = { - .name = "kAFS", .specs = ffs_fs_param_specs, }; diff --git a/fs/afs/super.c b/fs/afs/super.c index 8d71d10761b7..862c806bc22f 100644 --- a/fs/afs/super.c +++ b/fs/afs/super.c @@ -90,7 +90,6 @@ static const struct fs_parameter_spec afs_param_specs[] = { }; static const struct fs_parameter_description afs_fs_parameters = { - .name = "kAFS", .specs = afs_param_specs, }; diff --git a/fs/ceph/super.c b/fs/ceph/super.c index 4125de07221b..497469149e4b 100644 --- a/fs/ceph/super.c +++ b/fs/ceph/super.c @@ -199,7 +199,6 @@ static const struct fs_parameter_spec ceph_mount_param_specs[] = { }; static const struct fs_parameter_description ceph_mount_parameters = { - .name = "ceph", .specs = ceph_mount_param_specs, }; diff --git a/fs/filesystems.c b/fs/filesystems.c index 9135646e41ac..77bf5f95362d 100644 --- a/fs/filesystems.c +++ b/fs/filesystems.c @@ -74,7 +74,8 @@ int register_filesystem(struct file_system_type * fs) int res = 0; struct file_system_type ** p; - if (fs->parameters && !fs_validate_description(fs->parameters)) + if (fs->parameters && + !fs_validate_description(fs->name, fs->parameters)) return -EINVAL; BUG_ON(strchr(fs->name, '.')); diff --git a/fs/fs_parser.c b/fs/fs_parser.c index 4c410eef0173..3ed1e49d8267 100644 --- a/fs/fs_parser.c +++ b/fs/fs_parser.c @@ -354,20 +354,14 @@ bool validate_constant_table(const struct constant_table *tbl, size_t tbl_size, * fs_validate_description - Validate a parameter description * @desc: The parameter description to validate. */ -bool fs_validate_description(const struct fs_parameter_description *desc) +bool fs_validate_description(const char *name, + const struct fs_parameter_description *desc) { const struct fs_parameter_spec *param, *p2; - const char *name = desc->name; bool good = true; pr_notice("*** VALIDATE %s ***\n", name); - if (!name[0]) { - pr_err("VALIDATE Parser: No name\n"); - name = "Unknown"; - good = false; - } - if (desc->specs) { for (param = desc->specs; param->name; param++) { enum fs_parameter_type t = param->type; diff --git a/fs/fuse/inode.c b/fs/fuse/inode.c index 16aec32f7f3d..5a01daadee7e 100644 --- a/fs/fuse/inode.c +++ b/fs/fuse/inode.c @@ -463,7 +463,6 @@ static const struct fs_parameter_spec fuse_param_specs[] = { }; static const struct fs_parameter_description fuse_fs_parameters = { - .name = "fuse", .specs = fuse_param_specs, }; diff --git a/fs/gfs2/ops_fstype.c b/fs/gfs2/ops_fstype.c index 16230e496fdb..8bc20425a830 100644 --- a/fs/gfs2/ops_fstype.c +++ b/fs/gfs2/ops_fstype.c @@ -1337,7 +1337,6 @@ static const struct fs_parameter_spec gfs2_param_specs[] = { }; static const struct fs_parameter_description gfs2_fs_parameters = { - .name = "gfs2", .specs = gfs2_param_specs, }; diff --git a/fs/hugetlbfs/inode.c b/fs/hugetlbfs/inode.c index a66e425884d1..c073f76478af 100644 --- a/fs/hugetlbfs/inode.c +++ b/fs/hugetlbfs/inode.c @@ -85,7 +85,6 @@ static const struct fs_parameter_spec hugetlb_param_specs[] = { }; static const struct fs_parameter_description hugetlb_fs_parameters = { - .name = "hugetlbfs", .specs = hugetlb_param_specs, }; diff --git a/fs/jffs2/super.c b/fs/jffs2/super.c index 1e54f736865d..f6fda79e98cf 100644 --- a/fs/jffs2/super.c +++ b/fs/jffs2/super.c @@ -185,7 +185,6 @@ static const struct fs_parameter_spec jffs2_param_specs[] = { }; const struct fs_parameter_description jffs2_fs_parameters = { - .name = "jffs2", .specs = jffs2_param_specs, }; diff --git a/fs/nfs/fs_context.c b/fs/nfs/fs_context.c index c0ddeecadfac..5f45e637e62a 100644 --- a/fs/nfs/fs_context.c +++ b/fs/nfs/fs_context.c @@ -174,7 +174,6 @@ static const struct fs_parameter_spec nfs_param_specs[] = { }; static const struct fs_parameter_description nfs_fs_parameters = { - .name = "nfs", .specs = nfs_param_specs, }; diff --git a/fs/proc/root.c b/fs/proc/root.c index 0b7c8dffc9ae..c44765447d05 100644 --- a/fs/proc/root.c +++ b/fs/proc/root.c @@ -48,7 +48,6 @@ static const struct fs_parameter_spec proc_param_specs[] = { }; static const struct fs_parameter_description proc_fs_parameters = { - .name = "proc", .specs = proc_param_specs, }; diff --git a/fs/ramfs/inode.c b/fs/ramfs/inode.c index d82636e8eb65..bb7ab562ff4d 100644 --- a/fs/ramfs/inode.c +++ b/fs/ramfs/inode.c @@ -187,7 +187,6 @@ static const struct fs_parameter_spec ramfs_param_specs[] = { }; const struct fs_parameter_description ramfs_fs_parameters = { - .name = "ramfs", .specs = ramfs_param_specs, }; diff --git a/fs/xfs/xfs_super.c b/fs/xfs/xfs_super.c index d9ae27ddf253..ee23a2bf1a81 100644 --- a/fs/xfs/xfs_super.c +++ b/fs/xfs/xfs_super.c @@ -107,7 +107,6 @@ static const struct fs_parameter_spec xfs_param_specs[] = { }; static const struct fs_parameter_description xfs_fs_parameters = { - .name = "xfs", .specs = xfs_param_specs, }; diff --git a/include/linux/fs_parser.h b/include/linux/fs_parser.h index 37459124c1c1..ac439ee50aab 100644 --- a/include/linux/fs_parser.h +++ b/include/linux/fs_parser.h @@ -57,7 +57,6 @@ struct fs_parameter_spec { }; struct fs_parameter_description { - const char name[16]; /* Name for logging purposes */ const struct fs_parameter_spec *specs; /* List of param specifications */ }; @@ -97,12 +96,14 @@ extern int lookup_constant(const struct constant_table tbl[], const char *name, #ifdef CONFIG_VALIDATE_FS_PARSER extern bool validate_constant_table(const struct constant_table *tbl, size_t tbl_size, int low, int high, int special); -extern bool fs_validate_description(const struct fs_parameter_description *desc); +extern bool fs_validate_description(const char *name, + const struct fs_parameter_description *desc); #else static inline bool validate_constant_table(const struct constant_table *tbl, size_t tbl_size, int low, int high, int special) { return true; } -static inline bool fs_validate_description(const struct fs_parameter_description *desc) +static inline bool fs_validate_description(const char *name, + const struct fs_parameter_description *desc) { return true; } #endif diff --git a/kernel/bpf/inode.c b/kernel/bpf/inode.c index ecf42bec38c0..9608aa48128d 100644 --- a/kernel/bpf/inode.c +++ b/kernel/bpf/inode.c @@ -593,7 +593,6 @@ static const struct fs_parameter_spec bpf_param_specs[] = { }; static const struct fs_parameter_description bpf_fs_parameters = { - .name = "bpf", .specs = bpf_param_specs, }; diff --git a/kernel/cgroup/cgroup-v1.c b/kernel/cgroup/cgroup-v1.c index 77eb72b704a6..c7b526f33621 100644 --- a/kernel/cgroup/cgroup-v1.c +++ b/kernel/cgroup/cgroup-v1.c @@ -898,7 +898,6 @@ static const struct fs_parameter_spec cgroup1_param_specs[] = { }; const struct fs_parameter_description cgroup1_fs_parameters = { - .name = "cgroup1", .specs = cgroup1_param_specs, }; diff --git a/kernel/cgroup/cgroup.c b/kernel/cgroup/cgroup.c index 735af8f15f95..d86d441d93ca 100644 --- a/kernel/cgroup/cgroup.c +++ b/kernel/cgroup/cgroup.c @@ -1823,7 +1823,6 @@ static const struct fs_parameter_spec cgroup2_param_specs[] = { }; static const struct fs_parameter_description cgroup2_fs_parameters = { - .name = "cgroup2", .specs = cgroup2_param_specs, }; diff --git a/mm/shmem.c b/mm/shmem.c index 90c7737bcce2..445d038a54b9 100644 --- a/mm/shmem.c +++ b/mm/shmem.c @@ -3404,7 +3404,6 @@ static const struct fs_parameter_spec shmem_param_specs[] = { }; const struct fs_parameter_description shmem_fs_parameters = { - .name = "tmpfs", .specs = shmem_param_specs, }; diff --git a/net/ceph/ceph_common.c b/net/ceph/ceph_common.c index d435d22999f5..f639e04d9c63 100644 --- a/net/ceph/ceph_common.c +++ b/net/ceph/ceph_common.c @@ -291,7 +291,6 @@ static const struct fs_parameter_spec ceph_param_specs[] = { }; static const struct fs_parameter_description ceph_parameters = { - .name = "libceph", .specs = ceph_param_specs, }; diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c index 116b4d644f68..54f34631bc16 100644 --- a/security/selinux/hooks.c +++ b/security/selinux/hooks.c @@ -2818,7 +2818,6 @@ static const struct fs_parameter_spec selinux_param_specs[] = { }; static const struct fs_parameter_description selinux_fs_parameters = { - .name = "SELinux", .specs = selinux_param_specs, }; @@ -7145,7 +7144,7 @@ static __init int selinux_init(void) else pr_debug("SELinux: Starting in permissive mode\n"); - fs_validate_description(&selinux_fs_parameters); + fs_validate_description("selinux", &selinux_fs_parameters); return 0; } diff --git a/security/smack/smack_lsm.c b/security/smack/smack_lsm.c index ecea41ce919b..646c0b4aa8c4 100644 --- a/security/smack/smack_lsm.c +++ b/security/smack/smack_lsm.c @@ -689,7 +689,6 @@ static const struct fs_parameter_spec smack_param_specs[] = { }; static const struct fs_parameter_description smack_fs_parameters = { - .name = "smack", .specs = smack_param_specs, }; -- cgit v1.2.3 From d7167b149943e38ad610191ecbb0800c78bbced9 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Sat, 7 Sep 2019 07:23:15 -0400 Subject: fs_parse: fold fs_parameter_desc/fs_parameter_spec The former contains nothing but a pointer to an array of the latter... Signed-off-by: Al Viro --- arch/powerpc/platforms/cell/spufs/inode.c | 10 ++---- arch/s390/hypfs/inode.c | 10 ++---- arch/x86/kernel/cpu/resctrl/rdtgroup.c | 10 ++---- drivers/base/devtmpfs.c | 4 +-- drivers/block/rbd.c | 8 ++--- drivers/usb/gadget/function/f_fs.c | 10 ++---- fs/afs/super.c | 12 +++---- fs/ceph/super.c | 8 ++--- fs/fs_parser.c | 53 +++++++++++++++---------------- fs/fuse/inode.c | 12 +++---- fs/gfs2/ops_fstype.c | 10 ++---- fs/hugetlbfs/inode.c | 10 ++---- fs/jffs2/super.c | 10 ++---- fs/nfs/fs_context.c | 12 +++---- fs/proc/root.c | 10 ++---- fs/ramfs/inode.c | 10 ++---- fs/xfs/xfs_super.c | 10 ++---- include/linux/fs.h | 4 +-- include/linux/fs_parser.h | 12 +++---- include/linux/ramfs.h | 4 ++- include/linux/shmem_fs.h | 3 +- kernel/bpf/inode.c | 10 ++---- kernel/cgroup/cgroup-internal.h | 4 +-- kernel/cgroup/cgroup-v1.c | 8 ++--- kernel/cgroup/cgroup.c | 12 +++---- mm/shmem.c | 12 +++---- net/ceph/ceph_common.c | 8 ++--- security/selinux/hooks.c | 10 ++---- security/smack/smack_lsm.c | 8 ++--- 29 files changed, 106 insertions(+), 198 deletions(-) diff --git a/arch/powerpc/platforms/cell/spufs/inode.c b/arch/powerpc/platforms/cell/spufs/inode.c index 36ce5d0ac675..25390569e24c 100644 --- a/arch/powerpc/platforms/cell/spufs/inode.c +++ b/arch/powerpc/platforms/cell/spufs/inode.c @@ -583,7 +583,7 @@ enum { Opt_uid, Opt_gid, Opt_mode, Opt_debug, }; -static const struct fs_parameter_spec spufs_param_specs[] = { +static const struct fs_parameter_spec spufs_fs_parameters[] = { fsparam_u32 ("gid", Opt_gid), fsparam_u32oct ("mode", Opt_mode), fsparam_u32 ("uid", Opt_uid), @@ -591,10 +591,6 @@ static const struct fs_parameter_spec spufs_param_specs[] = { {} }; -static const struct fs_parameter_description spufs_fs_parameters = { - .specs = spufs_param_specs, -}; - static int spufs_show_options(struct seq_file *m, struct dentry *root) { struct spufs_sb_info *sbi = spufs_get_sb_info(root->d_sb); @@ -622,7 +618,7 @@ static int spufs_parse_param(struct fs_context *fc, struct fs_parameter *param) kgid_t gid; int opt; - opt = fs_parse(fc, &spufs_fs_parameters, param, &result); + opt = fs_parse(fc, spufs_fs_parameters, param, &result); if (opt < 0) return opt; @@ -773,7 +769,7 @@ static struct file_system_type spufs_type = { .owner = THIS_MODULE, .name = "spufs", .init_fs_context = spufs_init_fs_context, - .parameters = &spufs_fs_parameters, + .parameters = spufs_fs_parameters, .kill_sb = kill_litter_super, }; MODULE_ALIAS_FS("spufs"); diff --git a/arch/s390/hypfs/inode.c b/arch/s390/hypfs/inode.c index b3a6d13a63bf..5c97f48cea91 100644 --- a/arch/s390/hypfs/inode.c +++ b/arch/s390/hypfs/inode.c @@ -209,16 +209,12 @@ static int hypfs_release(struct inode *inode, struct file *filp) enum { Opt_uid, Opt_gid, }; -static const struct fs_parameter_spec hypfs_param_specs[] = { +static const struct fs_parameter_spec hypfs_fs_parameters[] = { fsparam_u32("gid", Opt_gid), fsparam_u32("uid", Opt_uid), {} }; -static const struct fs_parameter_description hypfs_fs_parameters = { - .specs = hypfs_param_specs, -}; - static int hypfs_parse_param(struct fs_context *fc, struct fs_parameter *param) { struct hypfs_sb_info *hypfs_info = fc->s_fs_info; @@ -227,7 +223,7 @@ static int hypfs_parse_param(struct fs_context *fc, struct fs_parameter *param) kgid_t gid; int opt; - opt = fs_parse(fc, &hypfs_fs_parameters, param, &result); + opt = fs_parse(fc, hypfs_fs_parameters, param, &result); if (opt < 0) return opt; @@ -454,7 +450,7 @@ static struct file_system_type hypfs_type = { .owner = THIS_MODULE, .name = "s390_hypfs", .init_fs_context = hypfs_init_fs_context, - .parameters = &hypfs_fs_parameters, + .parameters = hypfs_fs_parameters, .kill_sb = hypfs_kill_super }; diff --git a/arch/x86/kernel/cpu/resctrl/rdtgroup.c b/arch/x86/kernel/cpu/resctrl/rdtgroup.c index f145594e4d6a..9891b4648de4 100644 --- a/arch/x86/kernel/cpu/resctrl/rdtgroup.c +++ b/arch/x86/kernel/cpu/resctrl/rdtgroup.c @@ -2037,24 +2037,20 @@ enum rdt_param { nr__rdt_params }; -static const struct fs_parameter_spec rdt_param_specs[] = { +static const struct fs_parameter_spec rdt_fs_parameters[] = { fsparam_flag("cdp", Opt_cdp), fsparam_flag("cdpl2", Opt_cdpl2), fsparam_flag("mba_MBps", Opt_mba_mbps), {} }; -static const struct fs_parameter_description rdt_fs_parameters = { - .specs = rdt_param_specs, -}; - static int rdt_parse_param(struct fs_context *fc, struct fs_parameter *param) { struct rdt_fs_context *ctx = rdt_fc2context(fc); struct fs_parse_result result; int opt; - opt = fs_parse(fc, &rdt_fs_parameters, param, &result); + opt = fs_parse(fc, rdt_fs_parameters, param, &result); if (opt < 0) return opt; @@ -2279,7 +2275,7 @@ static void rdt_kill_sb(struct super_block *sb) static struct file_system_type rdt_fs_type = { .name = "resctrl", .init_fs_context = rdt_init_fs_context, - .parameters = &rdt_fs_parameters, + .parameters = rdt_fs_parameters, .kill_sb = rdt_kill_sb, }; diff --git a/drivers/base/devtmpfs.c b/drivers/base/devtmpfs.c index 6cdbf1531238..3db9e4df1aff 100644 --- a/drivers/base/devtmpfs.c +++ b/drivers/base/devtmpfs.c @@ -71,10 +71,10 @@ static struct file_system_type internal_fs_type = { .name = "devtmpfs", #ifdef CONFIG_TMPFS .init_fs_context = shmem_init_fs_context, - .parameters = &shmem_fs_parameters, + .parameters = shmem_fs_parameters, #else .init_fs_context = ramfs_init_fs_context, - .parameters = &ramfs_fs_parameters, + .parameters = ramfs_fs_parameters, #endif .kill_sb = kill_litter_super, }; diff --git a/drivers/block/rbd.c b/drivers/block/rbd.c index e87486920382..d0437b5fc023 100644 --- a/drivers/block/rbd.c +++ b/drivers/block/rbd.c @@ -848,7 +848,7 @@ enum { Opt_notrim, }; -static const struct fs_parameter_spec rbd_param_specs[] = { +static const struct fs_parameter_spec rbd_parameters[] = { fsparam_u32 ("alloc_size", Opt_alloc_size), fsparam_flag ("exclusive", Opt_exclusive), fsparam_flag ("lock_on_read", Opt_lock_on_read), @@ -863,10 +863,6 @@ static const struct fs_parameter_spec rbd_param_specs[] = { {} }; -static const struct fs_parameter_description rbd_parameters = { - .specs = rbd_param_specs, -}; - struct rbd_options { int queue_depth; int alloc_size; @@ -6359,7 +6355,7 @@ static int rbd_parse_param(struct fs_parameter *param, if (ret != -ENOPARAM) return ret; - token = __fs_parse(&log, &rbd_parameters, param, &result); + token = __fs_parse(&log, rbd_parameters, param, &result); dout("%s fs_parse '%s' token %d\n", __func__, param->key, token); if (token < 0) { if (token == -ENOPARAM) diff --git a/drivers/usb/gadget/function/f_fs.c b/drivers/usb/gadget/function/f_fs.c index eda1972b70eb..997e2c914901 100644 --- a/drivers/usb/gadget/function/f_fs.c +++ b/drivers/usb/gadget/function/f_fs.c @@ -1486,7 +1486,7 @@ enum { Opt_gid, }; -static const struct fs_parameter_spec ffs_fs_param_specs[] = { +static const struct fs_parameter_spec ffs_fs_fs_parameters[] = { fsparam_bool ("no_disconnect", Opt_no_disconnect), fsparam_u32 ("rmode", Opt_rmode), fsparam_u32 ("fmode", Opt_fmode), @@ -1496,10 +1496,6 @@ static const struct fs_parameter_spec ffs_fs_param_specs[] = { {} }; -static const struct fs_parameter_description ffs_fs_fs_parameters = { - .specs = ffs_fs_param_specs, -}; - static int ffs_fs_parse_param(struct fs_context *fc, struct fs_parameter *param) { struct ffs_sb_fill_data *data = fc->fs_private; @@ -1508,7 +1504,7 @@ static int ffs_fs_parse_param(struct fs_context *fc, struct fs_parameter *param) ENTER(); - opt = fs_parse(fc, &ffs_fs_fs_parameters, param, &result); + opt = fs_parse(fc, ffs_fs_fs_parameters, param, &result); if (opt < 0) return opt; @@ -1640,7 +1636,7 @@ static struct file_system_type ffs_fs_type = { .owner = THIS_MODULE, .name = "functionfs", .init_fs_context = ffs_fs_init_fs_context, - .parameters = &ffs_fs_fs_parameters, + .parameters = ffs_fs_fs_parameters, .kill_sb = ffs_fs_kill_sb, }; MODULE_ALIAS_FS("functionfs"); diff --git a/fs/afs/super.c b/fs/afs/super.c index 862c806bc22f..dda7a9a66848 100644 --- a/fs/afs/super.c +++ b/fs/afs/super.c @@ -38,13 +38,13 @@ static int afs_statfs(struct dentry *dentry, struct kstatfs *buf); static int afs_show_devname(struct seq_file *m, struct dentry *root); static int afs_show_options(struct seq_file *m, struct dentry *root); static int afs_init_fs_context(struct fs_context *fc); -static const struct fs_parameter_description afs_fs_parameters; +static const struct fs_parameter_spec afs_fs_parameters[]; struct file_system_type afs_fs_type = { .owner = THIS_MODULE, .name = "afs", .init_fs_context = afs_init_fs_context, - .parameters = &afs_fs_parameters, + .parameters = afs_fs_parameters, .kill_sb = afs_kill_super, .fs_flags = FS_RENAME_DOES_D_MOVE, }; @@ -81,7 +81,7 @@ static const struct constant_table afs_param_flock[] = { {} }; -static const struct fs_parameter_spec afs_param_specs[] = { +static const struct fs_parameter_spec afs_fs_parameters[] = { fsparam_flag ("autocell", Opt_autocell), fsparam_flag ("dyn", Opt_dyn), fsparam_enum ("flock", Opt_flock, afs_param_flock), @@ -89,10 +89,6 @@ static const struct fs_parameter_spec afs_param_specs[] = { {} }; -static const struct fs_parameter_description afs_fs_parameters = { - .specs = afs_param_specs, -}; - /* * initialise the filesystem */ @@ -321,7 +317,7 @@ static int afs_parse_param(struct fs_context *fc, struct fs_parameter *param) struct afs_fs_context *ctx = fc->fs_private; int opt; - opt = fs_parse(fc, &afs_fs_parameters, param, &result); + opt = fs_parse(fc, afs_fs_parameters, param, &result); if (opt < 0) return opt; diff --git a/fs/ceph/super.c b/fs/ceph/super.c index 497469149e4b..d52eb3edb45d 100644 --- a/fs/ceph/super.c +++ b/fs/ceph/super.c @@ -169,7 +169,7 @@ static const struct constant_table ceph_param_recover[] = { {} }; -static const struct fs_parameter_spec ceph_mount_param_specs[] = { +static const struct fs_parameter_spec ceph_mount_parameters[] = { fsparam_flag_no ("acl", Opt_acl), fsparam_flag_no ("asyncreaddir", Opt_asyncreaddir), fsparam_s32 ("caps_max", Opt_caps_max), @@ -198,10 +198,6 @@ static const struct fs_parameter_spec ceph_mount_param_specs[] = { {} }; -static const struct fs_parameter_description ceph_mount_parameters = { - .specs = ceph_mount_param_specs, -}; - struct ceph_parse_opts_ctx { struct ceph_options *copts; struct ceph_mount_options *opts; @@ -271,7 +267,7 @@ static int ceph_parse_mount_param(struct fs_context *fc, if (ret != -ENOPARAM) return ret; - token = fs_parse(fc, &ceph_mount_parameters, param, &result); + token = fs_parse(fc, ceph_mount_parameters, param, &result); dout("%s fs_parse '%s' token %d\n", __func__, param->key, token); if (token < 0) return token; diff --git a/fs/fs_parser.c b/fs/fs_parser.c index 3ed1e49d8267..5f8c06a1fb93 100644 --- a/fs/fs_parser.c +++ b/fs/fs_parser.c @@ -47,15 +47,14 @@ int lookup_constant(const struct constant_table *tbl, const char *name, int not_ EXPORT_SYMBOL(lookup_constant); static const struct fs_parameter_spec *fs_lookup_key( - const struct fs_parameter_description *desc, + const struct fs_parameter_spec *desc, const char *name) { const struct fs_parameter_spec *p; - - if (!desc->specs) + if (!desc) return NULL; - for (p = desc->specs; p->name; p++) + for (p = desc; p->name; p++) if (strcmp(p->name, name) == 0) return p; @@ -81,7 +80,7 @@ static const struct fs_parameter_spec *fs_lookup_key( * the parameter wasn't recognised and unknowns aren't okay. */ int __fs_parse(struct p_log *log, - const struct fs_parameter_description *desc, + const struct fs_parameter_spec *desc, struct fs_parameter *param, struct fs_parse_result *result) { @@ -355,39 +354,37 @@ bool validate_constant_table(const struct constant_table *tbl, size_t tbl_size, * @desc: The parameter description to validate. */ bool fs_validate_description(const char *name, - const struct fs_parameter_description *desc) + const struct fs_parameter_spec *desc) { const struct fs_parameter_spec *param, *p2; bool good = true; pr_notice("*** VALIDATE %s ***\n", name); - if (desc->specs) { - for (param = desc->specs; param->name; param++) { - enum fs_parameter_type t = param->type; + 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); + /* 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; - } 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->specs; p2 < param; p2++) { - if (strcmp(param->name, p2->name) == 0) { - pr_err("VALIDATE %s: PARAM[%s]: Duplicate\n", - name, param->name); - good = false; - } + /* Check for duplicate parameter names */ + for (p2 = desc; p2 < param; p2++) { + if (strcmp(param->name, p2->name) == 0) { + pr_err("VALIDATE %s: PARAM[%s]: Duplicate\n", + name, param->name); + good = false; } } } diff --git a/fs/fuse/inode.c b/fs/fuse/inode.c index 5a01daadee7e..f22bc344d161 100644 --- a/fs/fuse/inode.c +++ b/fs/fuse/inode.c @@ -448,7 +448,7 @@ enum { OPT_ERR }; -static const struct fs_parameter_spec fuse_param_specs[] = { +static const struct fs_parameter_spec fuse_fs_parameters[] = { fsparam_string ("source", OPT_SOURCE), fsparam_u32 ("fd", OPT_FD), fsparam_u32oct ("rootmode", OPT_ROOTMODE), @@ -462,17 +462,13 @@ static const struct fs_parameter_spec fuse_param_specs[] = { {} }; -static const struct fs_parameter_description fuse_fs_parameters = { - .specs = fuse_param_specs, -}; - static int fuse_parse_param(struct fs_context *fc, struct fs_parameter *param) { struct fs_parse_result result; struct fuse_fs_context *ctx = fc->fs_private; int opt; - opt = fs_parse(fc, &fuse_fs_parameters, param, &result); + opt = fs_parse(fc, fuse_fs_parameters, param, &result); if (opt < 0) return opt; @@ -1346,7 +1342,7 @@ static struct file_system_type fuse_fs_type = { .name = "fuse", .fs_flags = FS_HAS_SUBTYPE | FS_USERNS_MOUNT, .init_fs_context = fuse_init_fs_context, - .parameters = &fuse_fs_parameters, + .parameters = fuse_fs_parameters, .kill_sb = fuse_kill_sb_anon, }; MODULE_ALIAS_FS("fuse"); @@ -1362,7 +1358,7 @@ static struct file_system_type fuseblk_fs_type = { .owner = THIS_MODULE, .name = "fuseblk", .init_fs_context = fuse_init_fs_context, - .parameters = &fuse_fs_parameters, + .parameters = fuse_fs_parameters, .kill_sb = fuse_kill_sb_blk, .fs_flags = FS_REQUIRES_DEV | FS_HAS_SUBTYPE, }; diff --git a/fs/gfs2/ops_fstype.c b/fs/gfs2/ops_fstype.c index 8bc20425a830..32623d28612b 100644 --- a/fs/gfs2/ops_fstype.c +++ b/fs/gfs2/ops_fstype.c @@ -1306,7 +1306,7 @@ static const struct constant_table gfs2_param_errors[] = { {} }; -static const struct fs_parameter_spec gfs2_param_specs[] = { +static const struct fs_parameter_spec gfs2_fs_parameters[] = { fsparam_string ("lockproto", Opt_lockproto), fsparam_string ("locktable", Opt_locktable), fsparam_string ("hostdata", Opt_hostdata), @@ -1336,10 +1336,6 @@ static const struct fs_parameter_spec gfs2_param_specs[] = { {} }; -static const struct fs_parameter_description gfs2_fs_parameters = { - .specs = gfs2_param_specs, -}; - /* Parse a single mount parameter */ static int gfs2_parse_param(struct fs_context *fc, struct fs_parameter *param) { @@ -1347,7 +1343,7 @@ static int gfs2_parse_param(struct fs_context *fc, struct fs_parameter *param) struct fs_parse_result result; int o; - o = fs_parse(fc, &gfs2_fs_parameters, param, &result); + o = fs_parse(fc, gfs2_fs_parameters, param, &result); if (o < 0) return o; @@ -1649,7 +1645,7 @@ struct file_system_type gfs2_fs_type = { .name = "gfs2", .fs_flags = FS_REQUIRES_DEV, .init_fs_context = gfs2_init_fs_context, - .parameters = &gfs2_fs_parameters, + .parameters = gfs2_fs_parameters, .kill_sb = gfs2_kill_sb, .owner = THIS_MODULE, }; diff --git a/fs/hugetlbfs/inode.c b/fs/hugetlbfs/inode.c index c073f76478af..84d445e8b5bc 100644 --- a/fs/hugetlbfs/inode.c +++ b/fs/hugetlbfs/inode.c @@ -73,7 +73,7 @@ enum hugetlb_param { Opt_uid, }; -static const struct fs_parameter_spec hugetlb_param_specs[] = { +static const struct fs_parameter_spec hugetlb_fs_parameters[] = { fsparam_u32 ("gid", Opt_gid), fsparam_string("min_size", Opt_min_size), fsparam_u32 ("mode", Opt_mode), @@ -84,10 +84,6 @@ static const struct fs_parameter_spec hugetlb_param_specs[] = { {} }; -static const struct fs_parameter_description hugetlb_fs_parameters = { - .specs = hugetlb_param_specs, -}; - #ifdef CONFIG_NUMA static inline void hugetlb_set_vma_policy(struct vm_area_struct *vma, struct inode *inode, pgoff_t index) @@ -1170,7 +1166,7 @@ static int hugetlbfs_parse_param(struct fs_context *fc, struct fs_parameter *par unsigned long ps; int opt; - opt = fs_parse(fc, &hugetlb_fs_parameters, param, &result); + opt = fs_parse(fc, hugetlb_fs_parameters, param, &result); if (opt < 0) return opt; @@ -1357,7 +1353,7 @@ static int hugetlbfs_init_fs_context(struct fs_context *fc) static struct file_system_type hugetlbfs_fs_type = { .name = "hugetlbfs", .init_fs_context = hugetlbfs_init_fs_context, - .parameters = &hugetlb_fs_parameters, + .parameters = hugetlb_fs_parameters, .kill_sb = kill_litter_super, }; diff --git a/fs/jffs2/super.c b/fs/jffs2/super.c index f6fda79e98cf..05d7878dfad1 100644 --- a/fs/jffs2/super.c +++ b/fs/jffs2/super.c @@ -178,23 +178,19 @@ static const struct constant_table jffs2_param_compr[] = { {} }; -static const struct fs_parameter_spec jffs2_param_specs[] = { +static const struct fs_parameter_spec jffs2_fs_parameters[] = { fsparam_enum ("compr", Opt_override_compr, jffs2_param_compr), fsparam_u32 ("rp_size", Opt_rp_size), {} }; -const struct fs_parameter_description jffs2_fs_parameters = { - .specs = jffs2_param_specs, -}; - static int jffs2_parse_param(struct fs_context *fc, struct fs_parameter *param) { struct fs_parse_result result; struct jffs2_sb_info *c = fc->s_fs_info; int opt; - opt = fs_parse(fc, &jffs2_fs_parameters, param, &result); + opt = fs_parse(fc, jffs2_fs_parameters, param, &result); if (opt < 0) return opt; @@ -337,7 +333,7 @@ static struct file_system_type jffs2_fs_type = { .owner = THIS_MODULE, .name = "jffs2", .init_fs_context = jffs2_init_fs_context, - .parameters = &jffs2_fs_parameters, + .parameters = jffs2_fs_parameters, .kill_sb = jffs2_kill_sb, }; MODULE_ALIAS_FS("jffs2"); diff --git a/fs/nfs/fs_context.c b/fs/nfs/fs_context.c index 5f45e637e62a..39f980a0ee48 100644 --- a/fs/nfs/fs_context.c +++ b/fs/nfs/fs_context.c @@ -111,7 +111,7 @@ static const struct constant_table nfs_param_enums_lookupcache[] = { {} }; -static const struct fs_parameter_spec nfs_param_specs[] = { +static const struct fs_parameter_spec nfs_fs_parameters[] = { fsparam_flag_no("ac", Opt_ac), fsparam_u32 ("acdirmax", Opt_acdirmax), fsparam_u32 ("acdirmin", Opt_acdirmin), @@ -173,10 +173,6 @@ static const struct fs_parameter_spec nfs_param_specs[] = { {} }; -static const struct fs_parameter_description nfs_fs_parameters = { - .specs = nfs_param_specs, -}; - enum { Opt_vers_2, Opt_vers_3, @@ -443,7 +439,7 @@ static int nfs_fs_context_parse_param(struct fs_context *fc, dfprintk(MOUNT, "NFS: parsing nfs mount option '%s'\n", param->key); - opt = fs_parse(fc, &nfs_fs_parameters, param, &result); + opt = fs_parse(fc, nfs_fs_parameters, param, &result); if (opt < 0) return ctx->sloppy ? 1 : opt; @@ -1416,7 +1412,7 @@ struct file_system_type nfs_fs_type = { .owner = THIS_MODULE, .name = "nfs", .init_fs_context = nfs_init_fs_context, - .parameters = &nfs_fs_parameters, + .parameters = nfs_fs_parameters, .kill_sb = nfs_kill_super, .fs_flags = FS_RENAME_DOES_D_MOVE|FS_BINARY_MOUNTDATA, }; @@ -1428,7 +1424,7 @@ struct file_system_type nfs4_fs_type = { .owner = THIS_MODULE, .name = "nfs4", .init_fs_context = nfs_init_fs_context, - .parameters = &nfs_fs_parameters, + .parameters = nfs_fs_parameters, .kill_sb = nfs_kill_super, .fs_flags = FS_RENAME_DOES_D_MOVE|FS_BINARY_MOUNTDATA, }; diff --git a/fs/proc/root.c b/fs/proc/root.c index c44765447d05..6a5825e12bc9 100644 --- a/fs/proc/root.c +++ b/fs/proc/root.c @@ -41,23 +41,19 @@ enum proc_param { Opt_hidepid, }; -static const struct fs_parameter_spec proc_param_specs[] = { +static const struct fs_parameter_spec proc_fs_parameters[] = { fsparam_u32("gid", Opt_gid), fsparam_u32("hidepid", Opt_hidepid), {} }; -static const struct fs_parameter_description proc_fs_parameters = { - .specs = proc_param_specs, -}; - static int proc_parse_param(struct fs_context *fc, struct fs_parameter *param) { struct proc_fs_context *ctx = fc->fs_private; struct fs_parse_result result; int opt; - opt = fs_parse(fc, &proc_fs_parameters, param, &result); + opt = fs_parse(fc, proc_fs_parameters, param, &result); if (opt < 0) return opt; @@ -206,7 +202,7 @@ static void proc_kill_sb(struct super_block *sb) static struct file_system_type proc_fs_type = { .name = "proc", .init_fs_context = proc_init_fs_context, - .parameters = &proc_fs_parameters, + .parameters = proc_fs_parameters, .kill_sb = proc_kill_sb, .fs_flags = FS_USERNS_MOUNT | FS_DISALLOW_NOTIFY_PERM, }; diff --git a/fs/ramfs/inode.c b/fs/ramfs/inode.c index bb7ab562ff4d..ee179a81b3da 100644 --- a/fs/ramfs/inode.c +++ b/fs/ramfs/inode.c @@ -181,22 +181,18 @@ enum ramfs_param { Opt_mode, }; -static const struct fs_parameter_spec ramfs_param_specs[] = { +const struct fs_parameter_spec ramfs_fs_parameters[] = { fsparam_u32oct("mode", Opt_mode), {} }; -const struct fs_parameter_description ramfs_fs_parameters = { - .specs = ramfs_param_specs, -}; - static int ramfs_parse_param(struct fs_context *fc, struct fs_parameter *param) { struct fs_parse_result result; struct ramfs_fs_info *fsi = fc->s_fs_info; int opt; - opt = fs_parse(fc, &ramfs_fs_parameters, param, &result); + opt = fs_parse(fc, ramfs_fs_parameters, param, &result); if (opt < 0) { /* * We might like to report bad mount options here; @@ -277,7 +273,7 @@ static void ramfs_kill_sb(struct super_block *sb) static struct file_system_type ramfs_fs_type = { .name = "ramfs", .init_fs_context = ramfs_init_fs_context, - .parameters = &ramfs_fs_parameters, + .parameters = ramfs_fs_parameters, .kill_sb = ramfs_kill_sb, .fs_flags = FS_USERNS_MOUNT, }; diff --git a/fs/xfs/xfs_super.c b/fs/xfs/xfs_super.c index ee23a2bf1a81..b03d82fcf011 100644 --- a/fs/xfs/xfs_super.c +++ b/fs/xfs/xfs_super.c @@ -62,7 +62,7 @@ enum { Opt_discard, Opt_nodiscard, Opt_dax, }; -static const struct fs_parameter_spec xfs_param_specs[] = { +static const struct fs_parameter_spec xfs_fs_parameters[] = { fsparam_u32("logbufs", Opt_logbufs), fsparam_string("logbsize", Opt_logbsize), fsparam_string("logdev", Opt_logdev), @@ -106,10 +106,6 @@ static const struct fs_parameter_spec xfs_param_specs[] = { {} }; -static const struct fs_parameter_description xfs_fs_parameters = { - .specs = xfs_param_specs, -}; - struct proc_xfs_info { uint64_t flag; char *str; @@ -1145,7 +1141,7 @@ xfs_fc_parse_param( int size = 0; int opt; - opt = fs_parse(fc, &xfs_fs_parameters, param, &result); + opt = fs_parse(fc, xfs_fs_parameters, param, &result); if (opt < 0) return opt; @@ -1787,7 +1783,7 @@ static struct file_system_type xfs_fs_type = { .owner = THIS_MODULE, .name = "xfs", .init_fs_context = xfs_init_fs_context, - .parameters = &xfs_fs_parameters, + .parameters = xfs_fs_parameters, .kill_sb = kill_block_super, .fs_flags = FS_REQUIRES_DEV, }; diff --git a/include/linux/fs.h b/include/linux/fs.h index 98e0349adb52..5ace552a2a23 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h @@ -67,7 +67,7 @@ struct fscrypt_operations; struct fsverity_info; struct fsverity_operations; struct fs_context; -struct fs_parameter_description; +struct fs_parameter_spec; extern void __init inode_init(void); extern void __init inode_init_early(void); @@ -2224,7 +2224,7 @@ struct file_system_type { #define FS_DISALLOW_NOTIFY_PERM 16 /* Disable fanotify permission events */ #define FS_RENAME_DOES_D_MOVE 32768 /* FS will handle d_move() during rename() internally. */ int (*init_fs_context)(struct fs_context *); - const struct fs_parameter_description *parameters; + const struct fs_parameter_spec *parameters; struct dentry *(*mount) (struct file_system_type *, int, const char *, void *); void (*kill_sb) (struct super_block *); diff --git a/include/linux/fs_parser.h b/include/linux/fs_parser.h index ac439ee50aab..dcbac245e7a3 100644 --- a/include/linux/fs_parser.h +++ b/include/linux/fs_parser.h @@ -56,10 +56,6 @@ struct fs_parameter_spec { const void *data; }; -struct fs_parameter_description { - const struct fs_parameter_spec *specs; /* List of param specifications */ -}; - /* * Result of parse. */ @@ -74,12 +70,12 @@ struct fs_parse_result { }; extern int __fs_parse(struct p_log *log, - const struct fs_parameter_description *desc, + const struct fs_parameter_spec *desc, struct fs_parameter *value, struct fs_parse_result *result); static inline int fs_parse(struct fs_context *fc, - const struct fs_parameter_description *desc, + const struct fs_parameter_spec *desc, struct fs_parameter *param, struct fs_parse_result *result) { @@ -97,13 +93,13 @@ extern int lookup_constant(const struct constant_table tbl[], const char *name, extern bool validate_constant_table(const struct constant_table *tbl, size_t tbl_size, int low, int high, int special); extern bool fs_validate_description(const char *name, - const struct fs_parameter_description *desc); + const struct fs_parameter_spec *desc); #else static inline bool validate_constant_table(const struct constant_table *tbl, size_t tbl_size, int low, int high, int special) { return true; } static inline bool fs_validate_description(const char *name, - const struct fs_parameter_description *desc) + const struct fs_parameter_spec *desc) { return true; } #endif diff --git a/include/linux/ramfs.h b/include/linux/ramfs.h index b806a0ff6554..917528d102c4 100644 --- a/include/linux/ramfs.h +++ b/include/linux/ramfs.h @@ -2,6 +2,8 @@ #ifndef _LINUX_RAMFS_H #define _LINUX_RAMFS_H +#include // bleh... + struct inode *ramfs_get_inode(struct super_block *sb, const struct inode *dir, umode_t mode, dev_t dev); extern int ramfs_init_fs_context(struct fs_context *fc); @@ -16,7 +18,7 @@ ramfs_nommu_expand_for_mapping(struct inode *inode, size_t newsize) extern int ramfs_nommu_expand_for_mapping(struct inode *inode, size_t newsize); #endif -extern const struct fs_parameter_description ramfs_fs_parameters; +extern const struct fs_parameter_spec ramfs_fs_parameters[]; extern const struct file_operations ramfs_file_operations; extern const struct vm_operations_struct generic_file_vm_ops; diff --git a/include/linux/shmem_fs.h b/include/linux/shmem_fs.h index de8e4b71e3ba..d56fefef8905 100644 --- a/include/linux/shmem_fs.h +++ b/include/linux/shmem_fs.h @@ -8,6 +8,7 @@ #include #include #include +#include /* inode in-kernel data */ @@ -49,7 +50,7 @@ static inline struct shmem_inode_info *SHMEM_I(struct inode *inode) /* * Functions in mm/shmem.c called directly from elsewhere: */ -extern const struct fs_parameter_description shmem_fs_parameters; +extern const struct fs_parameter_spec shmem_fs_parameters[]; extern int shmem_init(void); extern int shmem_init_fs_context(struct fs_context *fc); extern struct file *shmem_file_setup(const char *name, diff --git a/kernel/bpf/inode.c b/kernel/bpf/inode.c index 9608aa48128d..f4b2ef72e265 100644 --- a/kernel/bpf/inode.c +++ b/kernel/bpf/inode.c @@ -587,15 +587,11 @@ enum { OPT_MODE, }; -static const struct fs_parameter_spec bpf_param_specs[] = { +static const struct fs_parameter_spec bpf_fs_parameters[] = { fsparam_u32oct ("mode", OPT_MODE), {} }; -static const struct fs_parameter_description bpf_fs_parameters = { - .specs = bpf_param_specs, -}; - struct bpf_mount_opts { umode_t mode; }; @@ -606,7 +602,7 @@ static int bpf_parse_param(struct fs_context *fc, struct fs_parameter *param) struct fs_parse_result result; int opt; - opt = fs_parse(fc, &bpf_fs_parameters, param, &result); + opt = fs_parse(fc, bpf_fs_parameters, param, &result); if (opt < 0) /* We might like to report bad mount options here, but * traditionally we've ignored all mount options, so we'd @@ -682,7 +678,7 @@ static struct file_system_type bpf_fs_type = { .owner = THIS_MODULE, .name = "bpf", .init_fs_context = bpf_init_fs_context, - .parameters = &bpf_fs_parameters, + .parameters = bpf_fs_parameters, .kill_sb = kill_litter_super, }; diff --git a/kernel/cgroup/cgroup-internal.h b/kernel/cgroup/cgroup-internal.h index 90d1710fef6c..bfbeabc17a9d 100644 --- a/kernel/cgroup/cgroup-internal.h +++ b/kernel/cgroup/cgroup-internal.h @@ -7,7 +7,7 @@ #include #include #include -#include +#include #define TRACE_CGROUP_PATH_LEN 1024 extern spinlock_t trace_cgroup_path_lock; @@ -265,7 +265,7 @@ extern const struct proc_ns_operations cgroupns_operations; */ extern struct cftype cgroup1_base_files[]; extern struct kernfs_syscall_ops cgroup1_kf_syscall_ops; -extern const struct fs_parameter_description cgroup1_fs_parameters; +extern const struct fs_parameter_spec cgroup1_fs_parameters[]; int proc_cgroupstats_show(struct seq_file *m, void *v); bool cgroup1_ssid_disabled(int ssid); diff --git a/kernel/cgroup/cgroup-v1.c b/kernel/cgroup/cgroup-v1.c index c7b526f33621..408545620dad 100644 --- a/kernel/cgroup/cgroup-v1.c +++ b/kernel/cgroup/cgroup-v1.c @@ -885,7 +885,7 @@ enum cgroup1_param { Opt_xattr, }; -static const struct fs_parameter_spec cgroup1_param_specs[] = { +const struct fs_parameter_spec cgroup1_fs_parameters[] = { fsparam_flag ("all", Opt_all), fsparam_flag ("clone_children", Opt_clone_children), fsparam_flag ("cpuset_v2_mode", Opt_cpuset_v2_mode), @@ -897,10 +897,6 @@ static const struct fs_parameter_spec cgroup1_param_specs[] = { {} }; -const struct fs_parameter_description cgroup1_fs_parameters = { - .specs = cgroup1_param_specs, -}; - int cgroup1_parse_param(struct fs_context *fc, struct fs_parameter *param) { struct cgroup_fs_context *ctx = cgroup_fc2context(fc); @@ -908,7 +904,7 @@ int cgroup1_parse_param(struct fs_context *fc, struct fs_parameter *param) struct fs_parse_result result; int opt, i; - opt = fs_parse(fc, &cgroup1_fs_parameters, param, &result); + opt = fs_parse(fc, cgroup1_fs_parameters, param, &result); if (opt == -ENOPARAM) { if (strcmp(param->key, "source") == 0) { fc->source = param->string; diff --git a/kernel/cgroup/cgroup.c b/kernel/cgroup/cgroup.c index d86d441d93ca..a70a37e85d11 100644 --- a/kernel/cgroup/cgroup.c +++ b/kernel/cgroup/cgroup.c @@ -1816,23 +1816,19 @@ enum cgroup2_param { nr__cgroup2_params }; -static const struct fs_parameter_spec cgroup2_param_specs[] = { +static const struct fs_parameter_spec cgroup2_fs_parameters[] = { fsparam_flag("nsdelegate", Opt_nsdelegate), fsparam_flag("memory_localevents", Opt_memory_localevents), {} }; -static const struct fs_parameter_description cgroup2_fs_parameters = { - .specs = cgroup2_param_specs, -}; - static int cgroup2_parse_param(struct fs_context *fc, struct fs_parameter *param) { struct cgroup_fs_context *ctx = cgroup_fc2context(fc); struct fs_parse_result result; int opt; - opt = fs_parse(fc, &cgroup2_fs_parameters, param, &result); + opt = fs_parse(fc, cgroup2_fs_parameters, param, &result); if (opt < 0) return opt; @@ -2155,7 +2151,7 @@ static void cgroup_kill_sb(struct super_block *sb) struct file_system_type cgroup_fs_type = { .name = "cgroup", .init_fs_context = cgroup_init_fs_context, - .parameters = &cgroup1_fs_parameters, + .parameters = cgroup1_fs_parameters, .kill_sb = cgroup_kill_sb, .fs_flags = FS_USERNS_MOUNT, }; @@ -2163,7 +2159,7 @@ struct file_system_type cgroup_fs_type = { static struct file_system_type cgroup2_fs_type = { .name = "cgroup2", .init_fs_context = cgroup_init_fs_context, - .parameters = &cgroup2_fs_parameters, + .parameters = cgroup2_fs_parameters, .kill_sb = cgroup_kill_sb, .fs_flags = FS_USERNS_MOUNT, }; diff --git a/mm/shmem.c b/mm/shmem.c index 445d038a54b9..efbbf2bc68fb 100644 --- a/mm/shmem.c +++ b/mm/shmem.c @@ -3391,7 +3391,7 @@ static const struct constant_table shmem_param_enums_huge[] = { {} }; -static const struct fs_parameter_spec shmem_param_specs[] = { +const struct fs_parameter_spec shmem_fs_parameters[] = { fsparam_u32 ("gid", Opt_gid), fsparam_enum ("huge", Opt_huge, shmem_param_enums_huge), fsparam_u32oct("mode", Opt_mode), @@ -3403,10 +3403,6 @@ static const struct fs_parameter_spec shmem_param_specs[] = { {} }; -const struct fs_parameter_description shmem_fs_parameters = { - .specs = shmem_param_specs, -}; - static int shmem_parse_one(struct fs_context *fc, struct fs_parameter *param) { struct shmem_options *ctx = fc->fs_private; @@ -3415,7 +3411,7 @@ static int shmem_parse_one(struct fs_context *fc, struct fs_parameter *param) char *rest; int opt; - opt = fs_parse(fc, &shmem_fs_parameters, param, &result); + opt = fs_parse(fc, shmem_fs_parameters, param, &result); if (opt < 0) return opt; @@ -3889,7 +3885,7 @@ static struct file_system_type shmem_fs_type = { .name = "tmpfs", .init_fs_context = shmem_init_fs_context, #ifdef CONFIG_TMPFS - .parameters = &shmem_fs_parameters, + .parameters = shmem_fs_parameters, #endif .kill_sb = kill_litter_super, .fs_flags = FS_USERNS_MOUNT, @@ -4035,7 +4031,7 @@ bool shmem_huge_enabled(struct vm_area_struct *vma) static struct file_system_type shmem_fs_type = { .name = "tmpfs", .init_fs_context = ramfs_init_fs_context, - .parameters = &ramfs_fs_parameters, + .parameters = ramfs_fs_parameters, .kill_sb = kill_litter_super, .fs_flags = FS_USERNS_MOUNT, }; diff --git a/net/ceph/ceph_common.c b/net/ceph/ceph_common.c index f639e04d9c63..a0e97f6c1072 100644 --- a/net/ceph/ceph_common.c +++ b/net/ceph/ceph_common.c @@ -269,7 +269,7 @@ enum { Opt_abort_on_full, }; -static const struct fs_parameter_spec ceph_param_specs[] = { +static const struct fs_parameter_spec ceph_parameters[] = { fsparam_flag ("abort_on_full", Opt_abort_on_full), fsparam_flag_no ("cephx_require_signatures", Opt_cephx_require_signatures), fsparam_flag_no ("cephx_sign_messages", Opt_cephx_sign_messages), @@ -290,10 +290,6 @@ static const struct fs_parameter_spec ceph_param_specs[] = { {} }; -static const struct fs_parameter_description ceph_parameters = { - .specs = ceph_param_specs, -}; - struct ceph_options *ceph_alloc_options(void) { struct ceph_options *opt; @@ -406,7 +402,7 @@ int ceph_parse_param(struct fs_parameter *param, struct ceph_options *opt, int token, err; struct p_log log = {.prefix = "libceph", .log = l}; - token = __fs_parse(&log, &ceph_parameters, param, &result); + token = __fs_parse(&log, ceph_parameters, param, &result); dout("%s fs_parse '%s' token %d\n", __func__, param->key, token); if (token < 0) return token; diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c index 54f34631bc16..d085569fd426 100644 --- a/security/selinux/hooks.c +++ b/security/selinux/hooks.c @@ -2808,7 +2808,7 @@ static int selinux_fs_context_dup(struct fs_context *fc, return 0; } -static const struct fs_parameter_spec selinux_param_specs[] = { +static const struct fs_parameter_spec selinux_fs_parameters[] = { fsparam_string(CONTEXT_STR, Opt_context), fsparam_string(DEFCONTEXT_STR, Opt_defcontext), fsparam_string(FSCONTEXT_STR, Opt_fscontext), @@ -2817,17 +2817,13 @@ static const struct fs_parameter_spec selinux_param_specs[] = { {} }; -static const struct fs_parameter_description selinux_fs_parameters = { - .specs = selinux_param_specs, -}; - static int selinux_fs_context_parse_param(struct fs_context *fc, struct fs_parameter *param) { struct fs_parse_result result; int opt, rc; - opt = fs_parse(fc, &selinux_fs_parameters, param, &result); + opt = fs_parse(fc, selinux_fs_parameters, param, &result); if (opt < 0) return opt; @@ -7144,7 +7140,7 @@ static __init int selinux_init(void) else pr_debug("SELinux: Starting in permissive mode\n"); - fs_validate_description("selinux", &selinux_fs_parameters); + fs_validate_description("selinux", selinux_fs_parameters); return 0; } diff --git a/security/smack/smack_lsm.c b/security/smack/smack_lsm.c index 646c0b4aa8c4..ed17049d39d5 100644 --- a/security/smack/smack_lsm.c +++ b/security/smack/smack_lsm.c @@ -678,7 +678,7 @@ static int smack_fs_context_dup(struct fs_context *fc, return 0; } -static const struct fs_parameter_spec smack_param_specs[] = { +static const struct fs_parameter_spec smack_fs_parameters[] = { fsparam_string("smackfsdef", Opt_fsdefault), fsparam_string("smackfsdefault", Opt_fsdefault), fsparam_string("smackfsfloor", Opt_fsfloor), @@ -688,10 +688,6 @@ static const struct fs_parameter_spec smack_param_specs[] = { {} }; -static const struct fs_parameter_description smack_fs_parameters = { - .specs = smack_param_specs, -}; - /** * smack_fs_context_parse_param - Parse a single mount parameter * @fc: The new filesystem context being constructed. @@ -706,7 +702,7 @@ static int smack_fs_context_parse_param(struct fs_context *fc, struct fs_parse_result result; int opt, rc; - opt = fs_parse(fc, &smack_fs_parameters, param, &result); + opt = fs_parse(fc, smack_fs_parameters, param, &result); if (opt < 0) return opt; -- cgit v1.2.3 From 48ce73b1bef20331007b35de7ade8fe26cd55e84 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Tue, 17 Dec 2019 20:03:59 -0500 Subject: fs_parse: handle optional arguments sanely Don't bother with "mixed" options that would allow both the form with and without argument (i.e. both -o foo and -o foo=bar). Rather than trying to shove both into a single fs_parameter_spec, allow having with-argument and no-argument specs with the same name and teach fs_parse to handle that. There are very few options of that sort, and they are actually easier to handle that way - callers end up with less postprocessing. Signed-off-by: Al Viro --- fs/ceph/super.c | 4 +- fs/fs_parser.c | 142 +++++++++++++++++++--------------------------- fs/gfs2/ops_fstype.c | 38 ++++--------- fs/nfs/fs_context.c | 18 ++++-- include/linux/fs_parser.h | 1 - 5 files changed, 82 insertions(+), 121 deletions(-) diff --git a/fs/ceph/super.c b/fs/ceph/super.c index d52eb3edb45d..acdcf96b5bc7 100644 --- a/fs/ceph/super.c +++ b/fs/ceph/super.c @@ -179,8 +179,8 @@ static const struct fs_parameter_spec ceph_mount_parameters[] = { fsparam_flag_no ("copyfrom", Opt_copyfrom), fsparam_flag_no ("dcache", Opt_dcache), fsparam_flag_no ("dirstat", Opt_dirstat), - __fsparam (fs_param_is_string, "fsc", Opt_fscache, - fs_param_neg_with_no | fs_param_v_optional, NULL), + fsparam_flag_no ("fsc", Opt_fscache), // fsc|nofsc + fsparam_string ("fsc", Opt_fscache), // fsc=... fsparam_flag_no ("ino32", Opt_ino32), fsparam_string ("mds_namespace", Opt_mds_namespace), fsparam_flag_no ("poolperm", Opt_poolperm), diff --git a/fs/fs_parser.c b/fs/fs_parser.c index 5f8c06a1fb93..db940fac84c3 100644 --- a/fs/fs_parser.c +++ b/fs/fs_parser.c @@ -46,19 +46,40 @@ int lookup_constant(const struct constant_table *tbl, const char *name, int not_ } EXPORT_SYMBOL(lookup_constant); +static inline bool is_flag(const struct fs_parameter_spec *p) +{ + return p->type == fs_param_is_flag; +} + static const struct fs_parameter_spec *fs_lookup_key( const struct fs_parameter_spec *desc, - const char *name) + struct fs_parameter *param, bool *negated) { - const struct fs_parameter_spec *p; - if (!desc) - return NULL; - - for (p = desc; p->name; p++) - if (strcmp(p->name, name) == 0) + const struct fs_parameter_spec *p, *other = NULL; + const char *name = param->key; + bool want_flag = param->type == fs_value_is_flag; + + *negated = false; + for (p = desc; p->name; p++) { + if (strcmp(p->name, name) != 0) + continue; + if (likely(is_flag(p) == want_flag)) return p; - - return NULL; + other = p; + } + if (want_flag) { + if (name[0] == 'n' && name[1] == 'o' && name[2]) { + for (p = desc; p->name; p++) { + if (strcmp(p->name, name + 2) != 0) + continue; + if (!(p->flags & fs_param_neg_with_no)) + continue; + *negated = true; + return p; + } + } + } + return other; } /* @@ -88,123 +109,77 @@ int __fs_parse(struct p_log *log, const struct constant_table *e; int ret = -ENOPARAM, b; - result->negated = false; result->uint_64 = 0; - p = fs_lookup_key(desc, param->key); - if (!p) { - /* If we didn't find something that looks like "noxxx", see if - * "xxx" takes the "no"-form negative - but only if there - * wasn't an value. - */ - if (param->type != fs_value_is_flag) - goto unknown_parameter; - if (param->key[0] != 'n' || param->key[1] != 'o' || !param->key[2]) - goto unknown_parameter; - - p = fs_lookup_key(desc, param->key + 2); - if (!p) - goto unknown_parameter; - if (!(p->flags & fs_param_neg_with_no)) - goto unknown_parameter; - result->boolean = false; - result->negated = true; - } + p = fs_lookup_key(desc, param, &result->negated); + if (!p) + return -ENOPARAM; if (p->flags & fs_param_deprecated) warn_plog(log, "Deprecated parameter '%s'", param->key); - if (result->negated) - goto okay; - - /* Certain parameter types only take a string and convert it. */ - switch (p->type) { - case __fs_param_wasnt_defined: - return -EINVAL; - case fs_param_is_u32: - case fs_param_is_u32_octal: - case fs_param_is_u32_hex: - case fs_param_is_s32: - case fs_param_is_u64: - case fs_param_is_enum: - case fs_param_is_string: - if (param->type == fs_value_is_string) { - if (p->flags & fs_param_v_optional) - break; - if (!*param->string) - goto bad_value; - break; - } - if (param->type == fs_value_is_flag) { - if (p->flags & fs_param_v_optional) - goto okay; - } - goto bad_value; - default: - break; - } - /* 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 (param->type != fs_value_is_flag) return inval_plog(log, "Unexpected value for '%s'", param->key); - result->boolean = true; + result->boolean = !result->negated; goto okay; - case fs_param_is_bool: - switch (param->type) { - case fs_value_is_flag: - result->boolean = true; - goto okay; - case fs_value_is_string: - if (param->size == 0) { - result->boolean = true; - goto okay; - } - b = lookup_constant(bool_names, param->string, -1); - if (b == -1) - goto bad_value; - result->boolean = b; - goto okay; - default: + 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: @@ -221,7 +196,6 @@ int __fs_parse(struct p_log *log, goto bad_value; goto maybe_okay; } - case fs_param_is_blockdev: case fs_param_is_path: goto okay; @@ -237,8 +211,6 @@ okay: bad_value: return inval_plog(log, "Bad value for '%s'", param->key); -unknown_parameter: - return -ENOPARAM; } EXPORT_SYMBOL(__fs_parse); @@ -382,6 +354,8 @@ bool fs_validate_description(const char *name, /* Check for duplicate parameter names */ for (p2 = desc; p2 < param; p2++) { if (strcmp(param->name, p2->name) == 0) { + if (is_flag(param) != is_flag(p2)) + continue; pr_err("VALIDATE %s: PARAM[%s]: Duplicate\n", name, param->name); good = false; diff --git a/fs/gfs2/ops_fstype.c b/fs/gfs2/ops_fstype.c index 32623d28612b..6d5502fff15c 100644 --- a/fs/gfs2/ops_fstype.c +++ b/fs/gfs2/ops_fstype.c @@ -1250,6 +1250,7 @@ enum gfs2_param { Opt_upgrade, Opt_acl, Opt_quota, + Opt_quota_flag, Opt_suiddir, Opt_data, Opt_meta, @@ -1264,26 +1265,13 @@ enum gfs2_param { Opt_loccookie, }; -enum opt_quota { - Opt_quota_unset = 0, - Opt_quota_off, - Opt_quota_account, - Opt_quota_on, -}; - static const struct constant_table gfs2_param_quota[] = { - {"off", Opt_quota_off }, - {"account", Opt_quota_account }, - {"on", Opt_quota_on }, + {"off", GFS2_QUOTA_OFF}, + {"account", GFS2_QUOTA_ACCOUNT}, + {"on", GFS2_QUOTA_ON}, {} }; -static const unsigned int opt_quota_values[] = { - [Opt_quota_off] = GFS2_QUOTA_OFF, - [Opt_quota_account] = GFS2_QUOTA_ACCOUNT, - [Opt_quota_on] = GFS2_QUOTA_ON, -}; - enum opt_data { Opt_data_writeback = GFS2_DATA_WRITEBACK, Opt_data_ordered = GFS2_DATA_ORDERED, @@ -1331,8 +1319,8 @@ static const struct fs_parameter_spec gfs2_fs_parameters[] = { fsparam_flag_no("rgrplvb", Opt_rgrplvb), fsparam_flag_no("loccookie", Opt_loccookie), /* quota can be a flag or an enum so it gets special treatment */ - __fsparam(fs_param_is_enum, "quota", Opt_quota, - fs_param_neg_with_no|fs_param_v_optional, gfs2_param_quota), + fsparam_flag_no("quota", Opt_quota_flag), + fsparam_enum("quota", Opt_quota, gfs2_param_quota), {} }; @@ -1380,17 +1368,11 @@ static int gfs2_parse_param(struct fs_context *fc, struct fs_parameter *param) case Opt_acl: args->ar_posix_acl = result.boolean; break; + case Opt_quota_flag: + args->ar_quota = result.negated ? GFS2_QUOTA_OFF : GFS2_QUOTA_ON; + break; case Opt_quota: - /* The quota option can be a flag or an enum. A non-zero int_32 - result means that we have an enum index. Otherwise we have - to rely on the 'negated' flag to tell us whether 'quota' or - 'noquota' was specified. */ - if (result.negated) - args->ar_quota = GFS2_QUOTA_OFF; - else if (result.int_32 > 0) - args->ar_quota = opt_quota_values[result.int_32]; - else - args->ar_quota = GFS2_QUOTA_ON; + args->ar_quota = result.int_32; break; case Opt_suiddir: args->ar_suiddir = result.boolean; diff --git a/fs/nfs/fs_context.c b/fs/nfs/fs_context.c index 39f980a0ee48..c87cdedbdd0c 100644 --- a/fs/nfs/fs_context.c +++ b/fs/nfs/fs_context.c @@ -45,6 +45,7 @@ enum nfs_param { Opt_cto, Opt_fg, Opt_fscache, + Opt_fscache_flag, Opt_hard, Opt_intr, Opt_local_lock, @@ -125,8 +126,8 @@ static const struct fs_parameter_spec nfs_fs_parameters[] = { fsparam_string("clientaddr", Opt_clientaddr), fsparam_flag_no("cto", Opt_cto), fsparam_flag ("fg", Opt_fg), - __fsparam(fs_param_is_string, "fsc", Opt_fscache, - fs_param_neg_with_no|fs_param_v_optional, NULL), + 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, fs_param_neg_with_no|fs_param_deprecated, NULL), @@ -537,14 +538,19 @@ static int nfs_fs_context_parse_param(struct fs_context *fc, else ctx->flags &= ~NFS_MOUNT_NORESVPORT; break; - case Opt_fscache: - kfree(ctx->fscache_uniq); - ctx->fscache_uniq = param->string; - param->string = NULL; + case Opt_fscache_flag: if (result.negated) ctx->options &= ~NFS_OPTION_FSCACHE; else ctx->options |= NFS_OPTION_FSCACHE; + kfree(ctx->fscache_uniq); + ctx->fscache_uniq = NULL; + break; + case Opt_fscache: + ctx->options |= NFS_OPTION_FSCACHE; + kfree(ctx->fscache_uniq); + ctx->fscache_uniq = param->string; + param->string = NULL; break; case Opt_migration: if (result.negated) diff --git a/include/linux/fs_parser.h b/include/linux/fs_parser.h index dcbac245e7a3..2e1e15f0cf4a 100644 --- a/include/linux/fs_parser.h +++ b/include/linux/fs_parser.h @@ -49,7 +49,6 @@ struct fs_parameter_spec { u8 opt; /* Option number (returned by fs_parse()) */ enum fs_parameter_type type:8; /* The desired parameter type */ unsigned short flags; -#define fs_param_v_optional 0x0001 /* The value is optional */ #define fs_param_neg_with_no 0x0002 /* "noxxx" is negative param */ #define fs_param_neg_with_empty 0x0004 /* "xxx=" is negative param */ #define fs_param_deprecated 0x0008 /* The param is deprecated */ -- cgit v1.2.3 From 328de5287b10abc967c517461cf2948bd8a5b4e9 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Wed, 18 Dec 2019 00:02:31 -0500 Subject: turn fs_param_is_... into functions Signed-off-by: Al Viro --- fs/fs_parser.c | 228 +++++++++++++++++++++++++--------------------- fs/nfs/fs_context.c | 2 +- include/linux/fs_parser.h | 38 +++----- 3 files changed, 139 insertions(+), 129 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), diff --git a/include/linux/fs_parser.h b/include/linux/fs_parser.h index 2e1e15f0cf4a..2eab6d5f6736 100644 --- a/include/linux/fs_parser.h +++ b/include/linux/fs_parser.h @@ -17,26 +17,18 @@ struct constant_table { int value; }; +struct fs_parameter_spec; +struct fs_parse_result; +typedef int fs_param_type(struct p_log *, + const struct fs_parameter_spec *, + struct fs_parameter *, + struct fs_parse_result *); /* * The type of parameter expected. */ -enum fs_parameter_type { - __fs_param_wasnt_defined, - fs_param_is_flag, - fs_param_is_bool, - fs_param_is_u32, - fs_param_is_u32_octal, - fs_param_is_u32_hex, - fs_param_is_s32, - fs_param_is_u64, - fs_param_is_enum, - fs_param_is_string, - fs_param_is_blob, - fs_param_is_blockdev, - fs_param_is_path, - fs_param_is_fd, - nr__fs_parameter_type, -}; +fs_param_type fs_param_is_bool, fs_param_is_u32, fs_param_is_s32, fs_param_is_u64, + fs_param_is_enum, fs_param_is_string, fs_param_is_blob, fs_param_is_blockdev, + fs_param_is_path, fs_param_is_fd; /* * Specification of the type of value a parameter wants. @@ -46,8 +38,8 @@ enum fs_parameter_type { */ struct fs_parameter_spec { const char *name; + fs_param_type *type; /* The desired parameter type */ u8 opt; /* Option number (returned by fs_parse()) */ - enum fs_parameter_type type:8; /* The desired parameter type */ unsigned short flags; #define fs_param_neg_with_no 0x0002 /* "noxxx" is negative param */ #define fs_param_neg_with_empty 0x0004 /* "xxx=" is negative param */ @@ -120,16 +112,15 @@ static inline bool fs_validate_description(const char *name, .data = DATA \ } -#define fsparam_flag(NAME, OPT) __fsparam(fs_param_is_flag, NAME, OPT, 0, NULL) +#define fsparam_flag(NAME, OPT) __fsparam(NULL, NAME, OPT, 0, NULL) #define fsparam_flag_no(NAME, OPT) \ - __fsparam(fs_param_is_flag, NAME, OPT, \ - fs_param_neg_with_no, NULL) + __fsparam(NULL, NAME, OPT, fs_param_neg_with_no, NULL) #define fsparam_bool(NAME, OPT) __fsparam(fs_param_is_bool, NAME, OPT, 0, NULL) #define fsparam_u32(NAME, OPT) __fsparam(fs_param_is_u32, NAME, OPT, 0, NULL) #define fsparam_u32oct(NAME, OPT) \ - __fsparam(fs_param_is_u32_octal, NAME, OPT, 0, NULL) + __fsparam(fs_param_is_u32, NAME, OPT, 0, (void *)8) #define fsparam_u32hex(NAME, OPT) \ - __fsparam(fs_param_is_u32_hex, NAME, OPT, 0, NULL) + __fsparam(fs_param_is_u32_hex, NAME, OPT, 0, (void *16)) #define fsparam_s32(NAME, OPT) __fsparam(fs_param_is_s32, NAME, OPT, 0, NULL) #define fsparam_u64(NAME, OPT) __fsparam(fs_param_is_u64, NAME, OPT, 0, NULL) #define fsparam_enum(NAME, OPT, array) __fsparam(fs_param_is_enum, NAME, OPT, 0, array) @@ -140,5 +131,4 @@ static inline bool fs_validate_description(const char *name, #define fsparam_path(NAME, OPT) __fsparam(fs_param_is_path, NAME, OPT, 0, NULL) #define fsparam_fd(NAME, OPT) __fsparam(fs_param_is_fd, NAME, OPT, 0, NULL) - #endif /* _LINUX_FS_PARSER_H */ -- cgit v1.2.3 From a3ff937b33d9dfd0923ac5279d87723048599057 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Sat, 21 Dec 2019 21:30:50 -0500 Subject: prefix-handling analogues of errorf() and friends called errorfc/infofc/warnfc/invalfc Signed-off-by: Al Viro --- include/linux/fs_context.h | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/include/linux/fs_context.h b/include/linux/fs_context.h index b2ad9b0a7af4..e6c3e4c61dad 100644 --- a/include/linux/fs_context.h +++ b/include/linux/fs_context.h @@ -203,6 +203,7 @@ void logfc(struct fc_log *log, const char *prefix, char level, const char *fmt, */ #define infof(fc, fmt, ...) __logfc(fc, 'i', fmt, ## __VA_ARGS__) #define info_plog(p, fmt, ...) __plog(p, 'i', fmt, ## __VA_ARGS__) +#define infofc(p, fmt, ...) __plog((&(fc)->log), 'i', fmt, ## __VA_ARGS__) /** * warnf - Store supplementary warning message @@ -214,6 +215,7 @@ void logfc(struct fc_log *log, const char *prefix, char level, const char *fmt, */ #define warnf(fc, fmt, ...) __logfc(fc, 'w', fmt, ## __VA_ARGS__) #define warn_plog(p, fmt, ...) __plog(p, 'w', fmt, ## __VA_ARGS__) +#define warnfc(fc, fmt, ...) __plog((&(fc)->log), 'w', fmt, ## __VA_ARGS__) /** * errorf - Store supplementary error message @@ -225,6 +227,7 @@ void logfc(struct fc_log *log, const char *prefix, char level, const char *fmt, */ #define errorf(fc, fmt, ...) __logfc(fc, 'e', fmt, ## __VA_ARGS__) #define error_plog(p, fmt, ...) __plog(p, 'e', fmt, ## __VA_ARGS__) +#define errorfc(fc, fmt, ...) __plog((&(fc)->log), 'e', fmt, ## __VA_ARGS__) /** * invalf - Store supplementary invalid argument error message @@ -236,5 +239,6 @@ void logfc(struct fc_log *log, const char *prefix, char level, const char *fmt, */ #define invalf(fc, fmt, ...) (errorf(fc, fmt, ## __VA_ARGS__), -EINVAL) #define inval_plog(p, fmt, ...) (error_plog(p, fmt, ## __VA_ARGS__), -EINVAL) +#define invalfc(fc, fmt, ...) (errorfc(fc, fmt, ## __VA_ARGS__), -EINVAL) #endif /* _LINUX_FS_CONTEXT_H */ -- cgit v1.2.3 From d53d0f7461a52b08b0146156d79c64c0842fd38d Mon Sep 17 00:00:00 2001 From: Al Viro Date: Sat, 21 Dec 2019 21:31:52 -0500 Subject: ceph: use errorfc() and friends instead of spelling the prefix out Signed-off-by: Al Viro --- fs/ceph/cache.c | 4 ++-- fs/ceph/super.c | 14 +++++++------- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/fs/ceph/cache.c b/fs/ceph/cache.c index 73f24f307a4a..270b769607a2 100644 --- a/fs/ceph/cache.c +++ b/fs/ceph/cache.c @@ -67,7 +67,7 @@ int ceph_fscache_register_fs(struct ceph_fs_client* fsc, struct fs_context *fc) if (uniq_len && memcmp(ent->uniquifier, fscache_uniq, uniq_len)) continue; - errorf(fc, "ceph: fscache cookie already registered for fsid %pU, use fsc= option", + errorfc(fc, "fscache cookie already registered for fsid %pU, use fsc= option", fsid); err = -EBUSY; goto out_unlock; @@ -96,7 +96,7 @@ int ceph_fscache_register_fs(struct ceph_fs_client* fsc, struct fs_context *fc) list_add_tail(&ent->list, &ceph_fscache_list); } else { kfree(ent); - errorf(fc, "ceph: unable to register fscache cookie for fsid %pU", + errorfc(fc, "unable to register fscache cookie for fsid %pU", fsid); /* all other fs ignore this error */ } diff --git a/fs/ceph/super.c b/fs/ceph/super.c index acdcf96b5bc7..ae7a4b1aa50a 100644 --- a/fs/ceph/super.c +++ b/fs/ceph/super.c @@ -222,7 +222,7 @@ static int ceph_parse_source(struct fs_parameter *param, struct fs_context *fc) dout("%s '%s'\n", __func__, dev_name); if (!dev_name || !*dev_name) - return invalf(fc, "ceph: Empty source"); + return invalfc(fc, "Empty source"); dev_name_end = strchr(dev_name, '/'); if (dev_name_end) { @@ -238,7 +238,7 @@ static int ceph_parse_source(struct fs_parameter *param, struct fs_context *fc) dev_name_end--; /* back up to ':' separator */ if (dev_name_end < dev_name || *dev_name_end != ':') - return invalf(fc, "ceph: No path or : separator in source"); + return invalfc(fc, "No path or : separator in source"); dout("device name '%.*s'\n", (int)(dev_name_end - dev_name), dev_name); if (fsopt->server_path) @@ -294,7 +294,7 @@ static int ceph_parse_mount_param(struct fs_context *fc, break; case Opt_source: if (fc->source) - return invalf(fc, "ceph: Multiple sources specified"); + return invalfc(fc, "Multiple sources specified"); return ceph_parse_source(param, fc); case Opt_wsize: if (result.uint_32 < PAGE_SIZE || @@ -385,7 +385,7 @@ static int ceph_parse_mount_param(struct fs_context *fc, } break; #else - return invalf(fc, "ceph: fscache support is disabled"); + return invalfc(fc, "fscache support is disabled"); #endif case Opt_poolperm: if (!result.negated) @@ -416,7 +416,7 @@ static int ceph_parse_mount_param(struct fs_context *fc, #ifdef CONFIG_CEPH_FS_POSIX_ACL fc->sb_flags |= SB_POSIXACL; #else - return invalf(fc, "ceph: POSIX ACL support is disabled"); + return invalfc(fc, "POSIX ACL support is disabled"); #endif } else { fc->sb_flags &= ~SB_POSIXACL; @@ -428,7 +428,7 @@ static int ceph_parse_mount_param(struct fs_context *fc, return 0; out_of_range: - return invalf(fc, "ceph: %s out of range", param->key); + return invalfc(fc, "%s out of range", param->key); } static void destroy_mount_options(struct ceph_mount_options *args) @@ -1012,7 +1012,7 @@ static int ceph_get_tree(struct fs_context *fc) dout("ceph_get_tree\n"); if (!fc->source) - return invalf(fc, "ceph: No source"); + return invalfc(fc, "No source"); #ifdef CONFIG_CEPH_FS_POSIX_ACL fc->sb_flags |= SB_POSIXACL; -- cgit v1.2.3 From 2e28c49ea648d29c3d7b625ea6996addf28335ec Mon Sep 17 00:00:00 2001 From: Al Viro Date: Sat, 21 Dec 2019 21:32:51 -0500 Subject: fuse: switch to use errorfc() et.al. Signed-off-by: Al Viro --- fs/fuse/inode.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/fs/fuse/inode.c b/fs/fuse/inode.c index f22bc344d161..557611dc2d46 100644 --- a/fs/fuse/inode.c +++ b/fs/fuse/inode.c @@ -475,14 +475,14 @@ static int fuse_parse_param(struct fs_context *fc, struct fs_parameter *param) switch (opt) { case OPT_SOURCE: if (fc->source) - return invalf(fc, "fuse: Multiple sources specified"); + return invalfc(fc, "Multiple sources specified"); fc->source = param->string; param->string = NULL; break; case OPT_SUBTYPE: if (ctx->subtype) - return invalf(fc, "fuse: Multiple subtypes specified"); + return invalfc(fc, "Multiple subtypes specified"); ctx->subtype = param->string; param->string = NULL; return 0; @@ -494,7 +494,7 @@ static int fuse_parse_param(struct fs_context *fc, struct fs_parameter *param) case OPT_ROOTMODE: if (!fuse_valid_type(result.uint_32)) - return invalf(fc, "fuse: Invalid rootmode"); + return invalfc(fc, "Invalid rootmode"); ctx->rootmode = result.uint_32; ctx->rootmode_present = 1; break; @@ -502,14 +502,14 @@ static int fuse_parse_param(struct fs_context *fc, struct fs_parameter *param) case OPT_USER_ID: ctx->user_id = make_kuid(fc->user_ns, result.uint_32); if (!uid_valid(ctx->user_id)) - return invalf(fc, "fuse: Invalid user_id"); + return invalfc(fc, "Invalid user_id"); ctx->user_id_present = 1; break; case OPT_GROUP_ID: ctx->group_id = make_kgid(fc->user_ns, result.uint_32); if (!gid_valid(ctx->group_id)) - return invalf(fc, "fuse: Invalid group_id"); + return invalfc(fc, "Invalid group_id"); ctx->group_id_present = 1; break; @@ -527,7 +527,7 @@ static int fuse_parse_param(struct fs_context *fc, struct fs_parameter *param) case OPT_BLKSIZE: if (!ctx->is_bdev) - return invalf(fc, "fuse: blksize only supported for fuseblk"); + return invalfc(fc, "blksize only supported for fuseblk"); ctx->blksize = result.uint_32; break; -- cgit v1.2.3 From 77cb271e6a5189613f55834f4fa448c004963bb6 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Sat, 21 Dec 2019 21:33:17 -0500 Subject: gfs2: switch to use of errorfc() et.al. Signed-off-by: Al Viro --- fs/gfs2/ops_fstype.c | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/fs/gfs2/ops_fstype.c b/fs/gfs2/ops_fstype.c index 6d5502fff15c..a496f5bc2c4f 100644 --- a/fs/gfs2/ops_fstype.c +++ b/fs/gfs2/ops_fstype.c @@ -1359,7 +1359,7 @@ static int gfs2_parse_param(struct fs_context *fc, struct fs_parameter *param) break; case Opt_debug: if (result.boolean && args->ar_errors == GFS2_ERRORS_PANIC) - return invalf(fc, "gfs2: -o debug and -o errors=panic are mutually exclusive"); + return invalfc(fc, "-o debug and -o errors=panic are mutually exclusive"); args->ar_debug = result.boolean; break; case Opt_upgrade: @@ -1389,27 +1389,27 @@ static int gfs2_parse_param(struct fs_context *fc, struct fs_parameter *param) break; case Opt_commit: if (result.int_32 <= 0) - return invalf(fc, "gfs2: commit mount option requires a positive numeric argument"); + return invalfc(fc, "commit mount option requires a positive numeric argument"); args->ar_commit = result.int_32; break; case Opt_statfs_quantum: if (result.int_32 < 0) - return invalf(fc, "gfs2: statfs_quantum mount option requires a non-negative numeric argument"); + return invalfc(fc, "statfs_quantum mount option requires a non-negative numeric argument"); args->ar_statfs_quantum = result.int_32; break; case Opt_quota_quantum: if (result.int_32 <= 0) - return invalf(fc, "gfs2: quota_quantum mount option requires a positive numeric argument"); + return invalfc(fc, "quota_quantum mount option requires a positive numeric argument"); args->ar_quota_quantum = result.int_32; break; case Opt_statfs_percent: if (result.int_32 < 0 || result.int_32 > 100) - return invalf(fc, "gfs2: statfs_percent mount option requires a numeric argument between 0 and 100"); + return invalfc(fc, "statfs_percent mount option requires a numeric argument between 0 and 100"); args->ar_statfs_percent = result.int_32; break; case Opt_errors: if (args->ar_debug && result.uint_32 == GFS2_ERRORS_PANIC) - return invalf(fc, "gfs2: -o debug and -o errors=panic are mutually exclusive"); + return invalfc(fc, "-o debug and -o errors=panic are mutually exclusive"); args->ar_errors = result.uint_32; break; case Opt_barrier: @@ -1422,7 +1422,7 @@ static int gfs2_parse_param(struct fs_context *fc, struct fs_parameter *param) args->ar_loccookie = result.boolean; break; default: - return invalf(fc, "gfs2: invalid mount option: %s", param->key); + return invalfc(fc, "invalid mount option: %s", param->key); } return 0; } @@ -1448,27 +1448,27 @@ static int gfs2_reconfigure(struct fs_context *fc) spin_unlock(>->gt_spin); if (strcmp(newargs->ar_lockproto, oldargs->ar_lockproto)) { - errorf(fc, "gfs2: reconfiguration of locking protocol not allowed"); + errorfc(fc, "reconfiguration of locking protocol not allowed"); return -EINVAL; } if (strcmp(newargs->ar_locktable, oldargs->ar_locktable)) { - errorf(fc, "gfs2: reconfiguration of lock table not allowed"); + errorfc(fc, "reconfiguration of lock table not allowed"); return -EINVAL; } if (strcmp(newargs->ar_hostdata, oldargs->ar_hostdata)) { - errorf(fc, "gfs2: reconfiguration of host data not allowed"); + errorfc(fc, "reconfiguration of host data not allowed"); return -EINVAL; } if (newargs->ar_spectator != oldargs->ar_spectator) { - errorf(fc, "gfs2: reconfiguration of spectator mode not allowed"); + errorfc(fc, "reconfiguration of spectator mode not allowed"); return -EINVAL; } if (newargs->ar_localflocks != oldargs->ar_localflocks) { - errorf(fc, "gfs2: reconfiguration of localflocks not allowed"); + errorfc(fc, "reconfiguration of localflocks not allowed"); return -EINVAL; } if (newargs->ar_meta != oldargs->ar_meta) { - errorf(fc, "gfs2: switching between gfs2 and gfs2meta not allowed"); + errorfc(fc, "switching between gfs2 and gfs2meta not allowed"); return -EINVAL; } if (oldargs->ar_spectator) @@ -1478,11 +1478,11 @@ static int gfs2_reconfigure(struct fs_context *fc) if (fc->sb_flags & SB_RDONLY) { error = gfs2_make_fs_ro(sdp); if (error) - errorf(fc, "gfs2: unable to remount read-only"); + errorfc(fc, "unable to remount read-only"); } else { error = gfs2_make_fs_rw(sdp); if (error) - errorf(fc, "gfs2: unable to remount read-write"); + errorfc(fc, "unable to remount read-write"); } } sdp->sd_args = *newargs; -- cgit v1.2.3 From e1ee7d8511f1b9305545837aa31358de3389c72c Mon Sep 17 00:00:00 2001 From: Al Viro Date: Sat, 21 Dec 2019 21:33:45 -0500 Subject: cramfs: switch to use of errofc() et.al. Signed-off-by: Al Viro --- fs/cramfs/inode.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/fs/cramfs/inode.c b/fs/cramfs/inode.c index 2f04024c3588..912308600d39 100644 --- a/fs/cramfs/inode.c +++ b/fs/cramfs/inode.c @@ -534,7 +534,7 @@ static int cramfs_read_super(struct super_block *sb, struct fs_context *fc, /* check for wrong endianness */ if (super->magic == CRAMFS_MAGIC_WEND) { if (!silent) - errorf(fc, "cramfs: wrong endianness"); + errorfc(fc, "wrong endianness"); return -EINVAL; } @@ -546,22 +546,22 @@ static int cramfs_read_super(struct super_block *sb, struct fs_context *fc, mutex_unlock(&read_mutex); if (super->magic != CRAMFS_MAGIC) { if (super->magic == CRAMFS_MAGIC_WEND && !silent) - errorf(fc, "cramfs: wrong endianness"); + errorfc(fc, "wrong endianness"); else if (!silent) - errorf(fc, "cramfs: wrong magic"); + errorfc(fc, "wrong magic"); return -EINVAL; } } /* get feature flags first */ if (super->flags & ~CRAMFS_SUPPORTED_FLAGS) { - errorf(fc, "cramfs: unsupported filesystem features"); + errorfc(fc, "unsupported filesystem features"); return -EINVAL; } /* Check that the root inode is in a sane state */ if (!S_ISDIR(super->root.mode)) { - errorf(fc, "cramfs: root is not a directory"); + errorfc(fc, "root is not a directory"); return -EINVAL; } /* correct strange, hard-coded permissions of mkcramfs */ @@ -580,12 +580,12 @@ static int cramfs_read_super(struct super_block *sb, struct fs_context *fc, sbi->magic = super->magic; sbi->flags = super->flags; if (root_offset == 0) - infof(fc, "cramfs: empty filesystem"); + infofc(fc, "empty filesystem"); else if (!(super->flags & CRAMFS_FLAG_SHIFTED_ROOT_OFFSET) && ((root_offset != sizeof(struct cramfs_super)) && (root_offset != 512 + sizeof(struct cramfs_super)))) { - errorf(fc, "cramfs: bad root offset %lu", root_offset); + errorfc(fc, "bad root offset %lu", root_offset); return -EINVAL; } -- cgit v1.2.3 From b5db30cfb9793fca05f6448ad68430ac7374bbdd Mon Sep 17 00:00:00 2001 From: Al Viro Date: Sat, 21 Dec 2019 21:34:06 -0500 Subject: hugetlbfs: switch to use of invalfc() Signed-off-by: Al Viro --- fs/hugetlbfs/inode.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fs/hugetlbfs/inode.c b/fs/hugetlbfs/inode.c index 84d445e8b5bc..aff8642f0c2e 100644 --- a/fs/hugetlbfs/inode.c +++ b/fs/hugetlbfs/inode.c @@ -1228,7 +1228,7 @@ static int hugetlbfs_parse_param(struct fs_context *fc, struct fs_parameter *par } bad_val: - return invalf(fc, "hugetlbfs: Bad value '%s' for mount option '%s'\n", + return invalfc(fc, "Bad value '%s' for mount option '%s'\n", param->string, param->key); } -- cgit v1.2.3 From bf45f7fcc4003a8347a172354e2b8b59a259822c Mon Sep 17 00:00:00 2001 From: Al Viro Date: Sat, 21 Dec 2019 21:34:41 -0500 Subject: procfs: switch to use of invalfc() Signed-off-by: Al Viro --- fs/proc/root.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fs/proc/root.c b/fs/proc/root.c index 6a5825e12bc9..a24976579f59 100644 --- a/fs/proc/root.c +++ b/fs/proc/root.c @@ -66,7 +66,7 @@ static int proc_parse_param(struct fs_context *fc, struct fs_parameter *param) ctx->hidepid = result.uint_32; if (ctx->hidepid < HIDEPID_OFF || ctx->hidepid > HIDEPID_INVISIBLE) - return invalf(fc, "proc: hidepid value must be between 0 and 2.\n"); + return invalfc(fc, "hidepid value must be between 0 and 2.\n"); break; default: -- cgit v1.2.3 From 58c025f0e803a45453bb5ada957cbf98163d3048 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Sat, 21 Dec 2019 21:35:27 -0500 Subject: cgroup1: switch to use of errorfc() et.al. Signed-off-by: Al Viro --- kernel/cgroup/cgroup-v1.c | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/kernel/cgroup/cgroup-v1.c b/kernel/cgroup/cgroup-v1.c index 408545620dad..be1a1c83cdd1 100644 --- a/kernel/cgroup/cgroup-v1.c +++ b/kernel/cgroup/cgroup-v1.c @@ -917,7 +917,7 @@ int cgroup1_parse_param(struct fs_context *fc, struct fs_parameter *param) ctx->subsys_mask |= (1 << i); return 0; } - return invalf(fc, "cgroup1: Unknown subsys name '%s'", param->key); + return invalfc(fc, "Unknown subsys name '%s'", param->key); } if (opt < 0) return opt; @@ -945,7 +945,7 @@ int cgroup1_parse_param(struct fs_context *fc, struct fs_parameter *param) case Opt_release_agent: /* Specifying two release agents is forbidden */ if (ctx->release_agent) - return invalf(fc, "cgroup1: release_agent respecified"); + return invalfc(fc, "release_agent respecified"); ctx->release_agent = param->string; param->string = NULL; break; @@ -955,9 +955,9 @@ int cgroup1_parse_param(struct fs_context *fc, struct fs_parameter *param) return -ENOENT; /* Can't specify an empty name */ if (!param->size) - return invalf(fc, "cgroup1: Empty name"); + return invalfc(fc, "Empty name"); if (param->size > MAX_CGROUP_ROOT_NAMELEN - 1) - return invalf(fc, "cgroup1: Name too long"); + return invalfc(fc, "Name too long"); /* Must match [\w.-]+ */ for (i = 0; i < param->size; i++) { char c = param->string[i]; @@ -965,11 +965,11 @@ int cgroup1_parse_param(struct fs_context *fc, struct fs_parameter *param) continue; if ((c == '.') || (c == '-') || (c == '_')) continue; - return invalf(fc, "cgroup1: Invalid name"); + return invalfc(fc, "Invalid name"); } /* Specifying two names is forbidden */ if (ctx->name) - return invalf(fc, "cgroup1: name respecified"); + return invalfc(fc, "name respecified"); ctx->name = param->string; param->string = NULL; break; @@ -1004,7 +1004,7 @@ static int check_cgroupfs_options(struct fs_context *fc) if (ctx->all_ss) { /* Mutually exclusive option 'all' + subsystem name */ if (ctx->subsys_mask) - return invalf(fc, "cgroup1: subsys name conflicts with all"); + return invalfc(fc, "subsys name conflicts with all"); /* 'all' => select all the subsystems */ ctx->subsys_mask = enabled; } @@ -1014,7 +1014,7 @@ static int check_cgroupfs_options(struct fs_context *fc) * empty hierarchies must have a name). */ if (!ctx->subsys_mask && !ctx->name) - return invalf(fc, "cgroup1: Need name or subsystem set"); + return invalfc(fc, "Need name or subsystem set"); /* * Option noprefix was introduced just for backward compatibility @@ -1022,11 +1022,11 @@ static int check_cgroupfs_options(struct fs_context *fc) * the cpuset subsystem. */ if ((ctx->flags & CGRP_ROOT_NOPREFIX) && (ctx->subsys_mask & mask)) - return invalf(fc, "cgroup1: noprefix used incorrectly"); + return invalfc(fc, "noprefix used incorrectly"); /* Can't specify "none" and some subsystems */ if (ctx->subsys_mask && ctx->none) - return invalf(fc, "cgroup1: none used incorrectly"); + return invalfc(fc, "none used incorrectly"); return 0; } @@ -1056,7 +1056,7 @@ int cgroup1_reconfigure(struct fs_context *fc) /* Don't allow flags or name to change at remount */ if ((ctx->flags ^ root->flags) || (ctx->name && strcmp(ctx->name, root->name))) { - errorf(fc, "option or name mismatch, new: 0x%x \"%s\", old: 0x%x \"%s\"", + errorfc(fc, "option or name mismatch, new: 0x%x \"%s\", old: 0x%x \"%s\"", ctx->flags, ctx->name ?: "", root->flags, root->name); ret = -EINVAL; goto out_unlock; @@ -1173,7 +1173,7 @@ static int cgroup1_root_to_use(struct fs_context *fc) * can't create new one without subsys specification. */ if (!ctx->subsys_mask && !ctx->none) - return invalf(fc, "cgroup1: No subsys list or none specified"); + return invalfc(fc, "No subsys list or none specified"); /* Hierarchies may only be created in the initial cgroup namespace. */ if (ctx->ns != &init_cgroup_ns) -- cgit v1.2.3 From f35aa2bc809eacc44c3cee41b52cef1c451d4a89 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Sat, 21 Dec 2019 21:35:55 -0500 Subject: tmpfs: switch to use of invalfc() Signed-off-by: Al Viro --- mm/shmem.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/mm/shmem.c b/mm/shmem.c index efbbf2bc68fb..c8f7540ef048 100644 --- a/mm/shmem.c +++ b/mm/shmem.c @@ -3475,9 +3475,9 @@ static int shmem_parse_one(struct fs_context *fc, struct fs_parameter *param) return 0; unsupported_parameter: - return invalf(fc, "tmpfs: Unsupported parameter '%s'", param->key); + return invalfc(fc, "Unsupported parameter '%s'", param->key); bad_value: - return invalf(fc, "tmpfs: Bad value for '%s'", param->key); + return invalfc(fc, "Bad value for '%s'", param->key); } static int shmem_parse_options(struct fs_context *fc, void *data) @@ -3583,7 +3583,7 @@ static int shmem_reconfigure(struct fs_context *fc) return 0; out: spin_unlock(&sbinfo->stat_lock); - return invalf(fc, "tmpfs: %s", err); + return invalfc(fc, "%s", err); } static int shmem_show_options(struct seq_file *seq, struct dentry *root) -- cgit v1.2.3