OSDN Git Service

fs_parse: get rid of ->enums
authorAl Viro <viro@zeniv.linux.org.uk>
Sat, 7 Sep 2019 02:12:08 +0000 (22:12 -0400)
committerAl Viro <viro@zeniv.linux.org.uk>
Fri, 7 Feb 2020 05:12:50 +0000 (00:12 -0500)
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 <viro@zeniv.linux.org.uk>
fs/afs/super.c
fs/ceph/super.c
fs/fs_parser.c
fs/gfs2/ops_fstype.c
fs/jffs2/super.c
fs/nfs/fs_context.c
include/linux/fs_parser.h
mm/shmem.c
net/ceph/ceph_common.c

index 7f8a9b3..42bf63b 100644 (file)
@@ -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,
 };
 
 /*
index 29a795f..0f7c891 100644 (file)
@@ -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 {
index 07ae041..3427519 100644 (file)
@@ -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 */
index e8b7b0c..0df8f2d 100644 (file)
@@ -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 */
index 0e6406c..ecd1a13 100644 (file)
@@ -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)
index 2c6dc1b..01c7688 100644 (file)
@@ -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 {
index 4532320..498cba1 100644 (file)
@@ -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 */
index 8793e8c..1c02c6c 100644 (file)
@@ -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)
index a9d6c97..c2d0b5c 100644 (file)
@@ -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),