From: "J. R. Okajima" <hooanon...@gmail.com>

commit 4fdd4d3893306b2a70f38a83c9b2e4d5b55a0796 aufs5-standalone upstream.

Adds parsing mount options as fs_context operations, which was started
by the preceding commit.  This "fs_context" series essentially moves some
parts of opts.c to fsctx.c, and adjusts it to fit fs_context scheme.
No enhancements, no bugfixes.

Since some parts of opts.c are moved out, this commit makes aufs
unusable but compilable.

As a first step, we start it by "br" mount option.  The other options
will follow by the succeeding commits.

Signed-off-by: J. R. Okajima <hooanon...@gmail.com>
Signed-off-by: Paul Gortmaker <paul.gortma...@windriver.com>
---
 fs/aufs/fsctx.c | 223 +++++++++++++++++++++++++++++++++++++++++++++++-
 fs/aufs/opts.c  |  67 +++------------
 fs/aufs/opts.h  |  37 +++++++-
 3 files changed, 268 insertions(+), 59 deletions(-)

diff --git a/fs/aufs/fsctx.c b/fs/aufs/fsctx.c
index f02cc9005d95..92ead39cbbaa 100644
--- a/fs/aufs/fsctx.c
+++ b/fs/aufs/fsctx.c
@@ -11,12 +11,227 @@
 #include "aufs.h"
 
 struct au_fsctx_opts {
+       aufs_bindex_t bindex;
+       unsigned char skipped;
        struct au_opt *opt, *opt_tail;
        struct super_block *sb;
        struct au_sbinfo *sbinfo;
        struct au_opts opts;
 };
 
+static void au_fsctx_dump(struct au_opts *opts)
+{
+#ifdef CONFIG_AUFS_DEBUG
+       /* reduce stack space */
+       union {
+               struct au_opt_add *add;
+       } u;
+       struct au_opt *opt;
+
+       opt = opts->opt;
+       while (opt->type != Opt_tail) {
+               switch (opt->type) {
+               case Opt_add:
+                       u.add = &opt->add;
+                       AuDbg("add {b%d, %s, 0x%x, %p}\n",
+                                 u.add->bindex, u.add->pathname, u.add->perm,
+                                 u.add->path.dentry);
+                       break;
+               /* re-commit later */
+
+               default:
+                       BUG();
+               }
+               opt++;
+       }
+#endif
+}
+
+/* ---------------------------------------------------------------------- */
+
+const struct fs_parameter_spec aufs_fsctx_paramspec[] = {
+       fsparam_string("br", Opt_br),
+       /* re-commit later */
+
+       {}
+};
+
+static int au_fsctx_parse_do_add(struct fs_context *fc, struct au_opt *opt,
+                                char *brspec, size_t speclen,
+                                aufs_bindex_t bindex)
+{
+       int err;
+       char *p;
+
+       AuDbg("brspec %s\n", brspec);
+
+       err = -ENOMEM;
+       if (!speclen)
+               speclen = strlen(brspec);
+       /* will be freed by au_fsctx_free() */
+       p = kmemdup_nul(brspec, speclen, GFP_NOFS);
+       if (unlikely(!p)) {
+               errorfc(fc, "failed in %s", brspec);
+               goto out;
+       }
+       err = au_opt_add(opt, p, fc->sb_flags, bindex);
+
+out:
+       AuTraceErr(err);
+       return err;
+}
+
+static int au_fsctx_parse_br(struct fs_context *fc, char *brspec)
+{
+       int err;
+       char *p;
+       struct au_fsctx_opts *a = fc->fs_private;
+       struct au_opt *opt = a->opt;
+       aufs_bindex_t bindex = a->bindex;
+
+       AuDbg("brspec %s\n", brspec);
+
+       err = -EINVAL;
+       while ((p = strsep(&brspec, ":")) && *p) {
+               err = au_fsctx_parse_do_add(fc, opt, p, /*len*/0, bindex);
+               AuTraceErr(err);
+               if (unlikely(err))
+                       break;
+               bindex++;
+               opt++;
+               if (unlikely(opt > a->opt_tail)) {
+                       err = -E2BIG;
+                       bindex--;
+                       opt--;
+                       break;
+               }
+               opt->type = Opt_tail;
+               a->skipped = 1;
+       }
+       a->bindex = bindex;
+       a->opt = opt;
+
+       AuTraceErr(err);
+       return err;
+}
+
+static int au_fsctx_parse_param(struct fs_context *fc, struct fs_parameter 
*param)
+{
+       int err, token;
+       struct fs_parse_result result;
+       struct au_fsctx_opts *a = fc->fs_private;
+       struct au_opt *opt = a->opt;
+
+       AuDbg("fc %p, param {key %s, string %s}\n",
+             fc, param->key, param->string);
+       err = fs_parse(fc, aufs_fsctx_paramspec, param, &result);
+       if (unlikely(err < 0))
+               goto out;
+       token = err;
+       AuDbg("token %d, res{negated %d, uint64 %llu}\n",
+             token, result.negated, result.uint_64);
+
+       err = -EINVAL;
+       a->skipped = 0;
+       switch (token) {
+       case Opt_br:
+               err = au_fsctx_parse_br(fc, param->string);
+               break;
+       /* re-commit later */
+
+       default:
+               a->skipped = 1;
+               err = -ENOPARAM;
+               break;
+       }
+       if (unlikely(err))
+               goto out;
+       if (a->skipped)
+               goto out;
+
+       switch (token) {
+       case Opt_br:
+               break;
+       default:
+               opt->type = token;
+               break;
+       }
+       opt++;
+       if (unlikely(opt > a->opt_tail)) {
+               err = -E2BIG;
+               opt--;
+       }
+       opt->type = Opt_tail;
+       a->opt = opt;
+
+out:
+       return err;
+}
+
+/*
+ * these options accept both 'name=val' and 'name:val' form.
+ * some accept optional '=' in its value.
+ * eg. br:/br1=rw:/br2=ro and br=/br1=rw:/br2=ro
+ */
+static inline unsigned int is_colonopt(char *str)
+{
+#define do_test(name)                                  \
+       if (!strncmp(str, name ":", sizeof(name)))      \
+               return sizeof(name) - 1;
+       do_test("br");
+       /* re-commit later */
+#undef do_test
+
+       return 0;
+}
+
+static int au_fsctx_parse_monolithic(struct fs_context *fc, void *data)
+{
+       int err;
+       unsigned int u;
+       char *str;
+       struct au_fsctx_opts *a = fc->fs_private;
+
+       str = data;
+       AuDbg("str %s\n", str);
+       while (1) {
+               u = is_colonopt(str);
+               if (u)
+                       str[u] = '=';
+               str = strchr(str, ',');
+               if (!str)
+                       break;
+               str++;
+       }
+       str = data;
+       AuDbg("str %s\n", str);
+
+       err = generic_parse_monolithic(fc, str);
+       AuTraceErr(err);
+       au_fsctx_dump(&a->opts);
+
+       return err;
+}
+
+/* ---------------------------------------------------------------------- */
+
+static void au_fsctx_opts_free(struct au_opts *opts)
+{
+       struct au_opt *opt;
+
+       opt = opts->opt;
+       while (opt->type != Opt_tail) {
+               switch (opt->type) {
+               case Opt_add:
+                       kfree(opt->add.pathname);
+                       path_put(&opt->add.path);
+                       break;
+               /* re-commit later */
+               }
+               opt++;
+       }
+}
+
 static void au_fsctx_free(struct fs_context *fc)
 {
        struct au_fsctx_opts *a = fc->fs_private;
@@ -26,12 +241,15 @@ static void au_fsctx_free(struct fs_context *fc)
              fc, fc->sb_flags, fc->sb_flags_mask, fc->purpose);
 
        kobject_put(&a->sbinfo->si_kobj);
+       au_fsctx_opts_free(&a->opts);
        free_page((unsigned long)a->opts.opt);
        au_kfree_rcu(a);
 }
 
 static const struct fs_context_operations au_fsctx_ops = {
-       .free                   = au_fsctx_free
+       .free                   = au_fsctx_free,
+       .parse_param            = au_fsctx_parse_param,
+       .parse_monolithic       = au_fsctx_parse_monolithic
        /* re-commit later */
 };
 
@@ -49,11 +267,12 @@ int aufs_fsctx_init(struct fs_context *fc)
        a = kzalloc(sizeof(*a), GFP_NOFS);
        if (unlikely(!a))
                goto out;
+       a->bindex = 0;
        a->opts.opt = (void *)__get_free_page(GFP_NOFS);
        if (unlikely(!a->opts.opt))
                goto out_a;
        a->opt = a->opts.opt;
-       a->opt->type = 0; /* re-commit later */
+       a->opt->type = Opt_tail;
        a->opts.max_opt = PAGE_SIZE / sizeof(*a->opts.opt);
        a->opt_tail = a->opt + a->opts.max_opt - 1;
        a->opts.sb_flags = fc->sb_flags;
diff --git a/fs/aufs/opts.c b/fs/aufs/opts.c
index b5dde6856069..ab232e5b8c58 100644
--- a/fs/aufs/opts.c
+++ b/fs/aufs/opts.c
@@ -26,36 +26,7 @@
 
 /* ---------------------------------------------------------------------- */
 
-enum {
-       Opt_br,
-       Opt_add, Opt_del, Opt_mod, Opt_append, Opt_prepend,
-       Opt_idel, Opt_imod,
-       Opt_dirwh, Opt_rdcache, Opt_rdblk, Opt_rdhash,
-       Opt_rdblk_def, Opt_rdhash_def,
-       Opt_xino, Opt_noxino,
-       Opt_trunc_xino, Opt_trunc_xino_v, Opt_notrunc_xino,
-       Opt_trunc_xino_path, Opt_itrunc_xino,
-       Opt_trunc_xib, Opt_notrunc_xib,
-       Opt_shwh, Opt_noshwh,
-       Opt_plink, Opt_noplink, Opt_list_plink,
-       Opt_udba,
-       Opt_dio, Opt_nodio,
-       Opt_diropq_a, Opt_diropq_w,
-       Opt_warn_perm, Opt_nowarn_perm,
-       Opt_wbr_copyup, Opt_wbr_create,
-       Opt_fhsm_sec,
-       Opt_verbose, Opt_noverbose,
-       Opt_sum, Opt_nosum, Opt_wsum,
-       Opt_dirperm1, Opt_nodirperm1,
-       Opt_dirren, Opt_nodirren,
-       Opt_acl, Opt_noacl,
-       Opt_tail, Opt_ignore, Opt_ignore_silent, Opt_err
-};
-
 static match_table_t options = {
-       {Opt_br, "br=%s"},
-       {Opt_br, "br:%s"},
-
        {Opt_add, "add=%d:%s"},
        {Opt_add, "add:%d:%s"},
        {Opt_add, "ins=%d:%s"},
@@ -183,8 +154,6 @@ static match_table_t options = {
        {Opt_err, NULL}
 };
 
-/* ---------------------------------------------------------------------- */
-
 static const char *au_parser_pattern(int val, match_table_t tbl)
 {
        struct match_token *p;
@@ -316,7 +285,7 @@ static int au_do_optstr_br_attr(au_br_perm_str_t *str, int 
perm)
        return q - str->a;
 }
 
-static int noinline_for_stack br_perm_val(char *perm)
+int au_br_perm_val(char *perm)
 {
        int val, bad, sz;
        char *p;
@@ -776,8 +745,8 @@ void au_opts_free(struct au_opts *opts)
        }
 }
 
-static int opt_add(struct au_opt *opt, char *opt_str, unsigned long sb_flags,
-                  aufs_bindex_t bindex)
+int au_opt_add(struct au_opt *opt, char *opt_str, unsigned long sb_flags,
+              aufs_bindex_t bindex)
 {
        int err;
        struct au_opt_add *add = &opt->add;
@@ -790,7 +759,7 @@ static int opt_add(struct au_opt *opt, char *opt_str, 
unsigned long sb_flags,
        if (p) {
                *p++ = 0;
                if (*p)
-                       add->perm = br_perm_val(p);
+                       add->perm = au_br_perm_val(p);
        }
 
        err = vfsub_kern_path(add->pathname, AuOpt_LkupDirFlags, &add->path);
@@ -873,7 +842,7 @@ au_opts_parse_mod(struct au_opt_mod *mod, substring_t 
args[])
                goto out;
        }
 
-       mod->perm = br_perm_val(p);
+       mod->perm = au_br_perm_val(p);
        AuDbg("mod path %s, perm 0x%x, %s\n", mod->path, mod->perm, p);
        mod->h_root = dget(path.dentry);
        path_put(&path);
@@ -1007,40 +976,26 @@ int au_opts_parse(struct super_block *sb, char *str, 
struct au_opts *opts)
                skipped = 0;
                token = match_token(opt_str, options, a->args);
                switch (token) {
-               case Opt_br:
-                       err = 0;
-                       while (!err && (opt_str = strsep(&a->args[0].from, ":"))
-                              && *opt_str) {
-                               err = opt_add(opt, opt_str, opts->sb_flags,
-                                             bindex++);
-                               if (unlikely(!err && ++opt > opt_tail)) {
-                                       err = -E2BIG;
-                                       break;
-                               }
-                               opt->type = Opt_tail;
-                               skipped = 1;
-                       }
-                       break;
                case Opt_add:
                        if (unlikely(match_int(&a->args[0], &n))) {
                                pr_err("bad integer in %s\n", opt_str);
                                break;
                        }
                        bindex = n;
-                       err = opt_add(opt, a->args[1].from, opts->sb_flags,
-                                     bindex);
+                       err = au_opt_add(opt, a->args[1].from, opts->sb_flags,
+                                        bindex);
                        if (!err)
                                opt->type = token;
                        break;
                case Opt_append:
-                       err = opt_add(opt, a->args[0].from, opts->sb_flags,
-                                     /*dummy bindex*/1);
+                       err = au_opt_add(opt, a->args[0].from, opts->sb_flags,
+                                        /*dummy bindex*/1);
                        if (!err)
                                opt->type = token;
                        break;
                case Opt_prepend:
-                       err = opt_add(opt, a->args[0].from, opts->sb_flags,
-                                     /*bindex*/0);
+                       err = au_opt_add(opt, a->args[0].from, opts->sb_flags,
+                                        /*bindex*/0);
                        if (!err)
                                opt->type = token;
                        break;
diff --git a/fs/aufs/opts.h b/fs/aufs/opts.h
index 98486c6b6579..ba948bb05fad 100644
--- a/fs/aufs/opts.h
+++ b/fs/aufs/opts.h
@@ -25,10 +25,36 @@
 
 #ifdef __KERNEL__
 
+#include <linux/fs_parser.h>
 #include <linux/namei.h>
 #include <linux/path.h>
 
-struct file;
+enum {
+       Opt_br,
+       /* re-commit later */
+       Opt_add, Opt_del, Opt_mod, Opt_append, Opt_prepend,
+       Opt_idel, Opt_imod,
+       Opt_dirwh, Opt_rdcache, Opt_rdblk, Opt_rdhash,
+       Opt_rdblk_def, Opt_rdhash_def,
+       Opt_xino, Opt_noxino,
+       Opt_trunc_xino, Opt_trunc_xino_v, Opt_notrunc_xino,
+       Opt_trunc_xino_path, Opt_itrunc_xino,
+       Opt_trunc_xib, Opt_notrunc_xib,
+       Opt_shwh, Opt_noshwh,
+       Opt_plink, Opt_noplink, Opt_list_plink,
+       Opt_udba,
+       Opt_dio, Opt_nodio,
+       Opt_diropq_a, Opt_diropq_w,
+       Opt_warn_perm, Opt_nowarn_perm,
+       Opt_wbr_copyup, Opt_wbr_create,
+       Opt_fhsm_sec,
+       Opt_verbose, Opt_noverbose,
+       Opt_sum, Opt_nosum, Opt_wsum,
+       Opt_dirperm1, Opt_nodirperm1,
+       Opt_dirren, Opt_nodirren,
+       Opt_acl, Opt_noacl,
+       Opt_tail, Opt_ignore, Opt_ignore_silent, Opt_err
+};
 
 /* ---------------------------------------------------------------------- */
 
@@ -127,6 +153,8 @@ enum {
 
 /* ---------------------------------------------------------------------- */
 
+struct file;
+
 struct au_opt_add {
        aufs_bindex_t   bindex;
        char            *pathname;
@@ -209,12 +237,15 @@ struct au_opts {
 /* ---------------------------------------------------------------------- */
 
 /* opts.c */
+int au_br_perm_val(char *perm);
 void au_optstr_br_perm(au_br_perm_str_t *str, int perm);
 const char *au_optstr_udba(int udba);
 const char *au_optstr_wbr_copyup(int wbr_copyup);
 const char *au_optstr_wbr_create(int wbr_create);
 
 void au_opts_free(struct au_opts *opts);
+int au_opt_add(struct au_opt *opt, char *opt_str, unsigned long sb_flags,
+              aufs_bindex_t bindex);
 struct super_block;
 int au_opts_parse(struct super_block *sb, char *str, struct au_opts *opts);
 int au_opts_verify(struct super_block *sb, unsigned long sb_flags,
@@ -224,5 +255,9 @@ int au_opts_remount(struct super_block *sb, struct au_opts 
*opts);
 
 unsigned int au_opt_udba(struct super_block *sb);
 
+/* fsctx.c */
+int aufs_fsctx_init(struct fs_context *fc);
+extern const struct fs_parameter_spec aufs_fsctx_paramspec[];
+
 #endif /* __KERNEL__ */
 #endif /* __AUFS_OPTS_H__ */
-- 
2.17.1

-=-=-=-=-=-=-=-=-=-=-=-
Links: You receive all messages sent to this group.
View/Reply Online (#11069): 
https://lists.yoctoproject.org/g/linux-yocto/message/11069
Mute This Topic: https://lists.yoctoproject.org/mt/90000699/21656
Group Owner: linux-yocto+ow...@lists.yoctoproject.org
Unsubscribe: https://lists.yoctoproject.org/g/linux-yocto/unsub 
[arch...@mail-archive.com]
-=-=-=-=-=-=-=-=-=-=-=-

Reply via email to