From: Amir Goldstein <amir73il@gmail.com>
To: Miklos Szeredi <miklos@szeredi.hu>
Cc: Christian Brauner <brauner@kernel.org>, linux-unionfs@vger.kernel.org
Subject: [PATCH v2 5/5] ovl: factor out ovl_parse_options() helper
Date: Sat, 17 Jun 2023 11:47:02 +0300 [thread overview]
Message-ID: <20230617084702.2468470-6-amir73il@gmail.com> (raw)
In-Reply-To: <20230617084702.2468470-1-amir73il@gmail.com>
For parsing a single mount option.
Signed-off-by: Amir Goldstein <amir73il@gmail.com>
---
fs/overlayfs/overlayfs.h | 8 ++
fs/overlayfs/super.c | 243 ++++++++++++++++++++-------------------
2 files changed, 135 insertions(+), 116 deletions(-)
diff --git a/fs/overlayfs/overlayfs.h b/fs/overlayfs/overlayfs.h
index 80c10228bd64..30227ccc758d 100644
--- a/fs/overlayfs/overlayfs.h
+++ b/fs/overlayfs/overlayfs.h
@@ -70,6 +70,14 @@ enum {
OVL_XINO_ON,
};
+/* The set of options that user requested explicitly via mount options */
+struct ovl_opt_set {
+ bool metacopy;
+ bool redirect;
+ bool nfs_export;
+ bool index;
+};
+
/*
* The tuple (fh,uuid) is a universal unique identifier for a copy up origin,
* where:
diff --git a/fs/overlayfs/super.c b/fs/overlayfs/super.c
index 5a84af92c91e..dbd9151dc073 100644
--- a/fs/overlayfs/super.c
+++ b/fs/overlayfs/super.c
@@ -514,131 +514,142 @@ static char *ovl_next_opt(char **s)
return sbegin;
}
-static int ovl_parse_opt(char *opt, struct ovl_config *config)
+static int ovl_parse_opt(char *opt, struct ovl_config *config,
+ struct ovl_opt_set *set)
{
- char *p;
- bool metacopy_opt = false, redirect_opt = false;
- bool nfs_export_opt = false, index_opt = false;
-
- while ((p = ovl_next_opt(&opt)) != NULL) {
- int token;
- substring_t args[MAX_OPT_ARGS];
-
- if (!*p)
- continue;
+ int err = 0;
+ int token;
+ substring_t args[MAX_OPT_ARGS];
- token = match_token(p, ovl_tokens, args);
- switch (token) {
- case OPT_UPPERDIR:
- kfree(config->upperdir);
- config->upperdir = match_strdup(&args[0]);
- if (!config->upperdir)
- return -ENOMEM;
- break;
+ if (!*opt)
+ return 0;
- case OPT_LOWERDIR:
- kfree(config->lowerdir);
- config->lowerdir = match_strdup(&args[0]);
- if (!config->lowerdir)
- return -ENOMEM;
- break;
+ token = match_token(opt, ovl_tokens, args);
+ switch (token) {
+ case OPT_UPPERDIR:
+ kfree(config->upperdir);
+ config->upperdir = match_strdup(&args[0]);
+ if (!config->upperdir)
+ return -ENOMEM;
+ break;
+
+ case OPT_LOWERDIR:
+ kfree(config->lowerdir);
+ config->lowerdir = match_strdup(&args[0]);
+ if (!config->lowerdir)
+ return -ENOMEM;
+ break;
+
+ case OPT_WORKDIR:
+ kfree(config->workdir);
+ config->workdir = match_strdup(&args[0]);
+ if (!config->workdir)
+ return -ENOMEM;
+ break;
+
+ case OPT_DEFAULT_PERMISSIONS:
+ config->default_permissions = true;
+ break;
+
+ case OPT_REDIRECT_DIR_ON:
+ config->redirect_mode = OVL_REDIRECT_ON;
+ set->redirect = true;
+ break;
+
+ case OPT_REDIRECT_DIR_OFF:
+ config->redirect_mode = ovl_redirect_always_follow ?
+ OVL_REDIRECT_FOLLOW :
+ OVL_REDIRECT_NOFOLLOW;
+ set->redirect = true;
+ break;
+
+ case OPT_REDIRECT_DIR_FOLLOW:
+ config->redirect_mode = OVL_REDIRECT_FOLLOW;
+ set->redirect = true;
+ break;
+
+ case OPT_REDIRECT_DIR_NOFOLLOW:
+ config->redirect_mode = OVL_REDIRECT_NOFOLLOW;
+ set->redirect = true;
+ break;
- case OPT_WORKDIR:
- kfree(config->workdir);
- config->workdir = match_strdup(&args[0]);
- if (!config->workdir)
- return -ENOMEM;
- break;
+ case OPT_INDEX_ON:
+ config->index = true;
+ set->index = true;
+ break;
- case OPT_DEFAULT_PERMISSIONS:
- config->default_permissions = true;
- break;
+ case OPT_INDEX_OFF:
+ config->index = false;
+ set->index = true;
+ break;
- case OPT_REDIRECT_DIR_ON:
- config->redirect_mode = OVL_REDIRECT_ON;
- redirect_opt = true;
- break;
+ case OPT_UUID_ON:
+ config->uuid = true;
+ break;
- case OPT_REDIRECT_DIR_OFF:
- config->redirect_mode = ovl_redirect_always_follow ?
- OVL_REDIRECT_FOLLOW :
- OVL_REDIRECT_NOFOLLOW;
- redirect_opt = true;
- break;
+ case OPT_UUID_OFF:
+ config->uuid = false;
+ break;
- case OPT_REDIRECT_DIR_FOLLOW:
- config->redirect_mode = OVL_REDIRECT_FOLLOW;
- redirect_opt = true;
- break;
+ case OPT_NFS_EXPORT_ON:
+ config->nfs_export = true;
+ set->nfs_export = true;
+ break;
- case OPT_REDIRECT_DIR_NOFOLLOW:
- config->redirect_mode = OVL_REDIRECT_NOFOLLOW;
- redirect_opt = true;
- break;
+ case OPT_NFS_EXPORT_OFF:
+ config->nfs_export = false;
+ set->nfs_export = true;
+ break;
- case OPT_INDEX_ON:
- config->index = true;
- index_opt = true;
- break;
+ case OPT_XINO_ON:
+ config->xino = OVL_XINO_ON;
+ break;
- case OPT_INDEX_OFF:
- config->index = false;
- index_opt = true;
- break;
+ case OPT_XINO_OFF:
+ config->xino = OVL_XINO_OFF;
+ break;
- case OPT_UUID_ON:
- config->uuid = true;
- break;
+ case OPT_XINO_AUTO:
+ config->xino = OVL_XINO_AUTO;
+ break;
- case OPT_UUID_OFF:
- config->uuid = false;
- break;
+ case OPT_METACOPY_ON:
+ config->metacopy = true;
+ set->metacopy = true;
+ break;
- case OPT_NFS_EXPORT_ON:
- config->nfs_export = true;
- nfs_export_opt = true;
- break;
-
- case OPT_NFS_EXPORT_OFF:
- config->nfs_export = false;
- nfs_export_opt = true;
- break;
-
- case OPT_XINO_ON:
- config->xino = OVL_XINO_ON;
- break;
-
- case OPT_XINO_OFF:
- config->xino = OVL_XINO_OFF;
- break;
+ case OPT_METACOPY_OFF:
+ config->metacopy = false;
+ set->metacopy = true;
+ break;
- case OPT_XINO_AUTO:
- config->xino = OVL_XINO_AUTO;
- break;
+ case OPT_VOLATILE:
+ config->ovl_volatile = true;
+ break;
- case OPT_METACOPY_ON:
- config->metacopy = true;
- metacopy_opt = true;
- break;
+ case OPT_USERXATTR:
+ config->userxattr = true;
+ break;
- case OPT_METACOPY_OFF:
- config->metacopy = false;
- metacopy_opt = true;
- break;
+ default:
+ pr_err("unrecognized mount option \"%s\" or missing value\n",
+ opt);
+ return -EINVAL;
+ }
- case OPT_VOLATILE:
- config->ovl_volatile = true;
- break;
+ return err;
+}
- case OPT_USERXATTR:
- config->userxattr = true;
- break;
+static int ovl_parse_options(char *opt, struct ovl_config *config)
+{
+ char *p;
+ int err;
+ struct ovl_opt_set set = {};
- default:
- pr_err("unrecognized mount option \"%s\" or missing value\n",
- p);
- return -EINVAL;
- }
+ while ((p = ovl_next_opt(&opt)) != NULL) {
+ err = ovl_parse_opt(p, config, &set);
+ if (err)
+ return err;
}
/* Workdir/index are useless in non-upper mount */
@@ -649,9 +660,9 @@ static int ovl_parse_opt(char *opt, struct ovl_config *config)
kfree(config->workdir);
config->workdir = NULL;
}
- if (config->index && index_opt) {
+ if (config->index && set.index) {
pr_info("option \"index=on\" is useless in a non-upper mount, ignore\n");
- index_opt = false;
+ set.index = false;
}
config->index = false;
}
@@ -670,12 +681,12 @@ static int ovl_parse_opt(char *opt, struct ovl_config *config)
/* Resolve metacopy -> redirect_dir dependency */
if (config->metacopy && config->redirect_mode != OVL_REDIRECT_ON) {
- if (metacopy_opt && redirect_opt) {
+ if (set.metacopy && set.redirect) {
pr_err("conflicting options: metacopy=on,redirect_dir=%s\n",
ovl_redirect_mode(config));
return -EINVAL;
}
- if (redirect_opt) {
+ if (set.redirect) {
/*
* There was an explicit redirect_dir=... that resulted
* in this conflict.
@@ -695,10 +706,10 @@ static int ovl_parse_opt(char *opt, struct ovl_config *config)
config->redirect_mode != OVL_REDIRECT_NOFOLLOW) {
pr_info("NFS export requires \"redirect_dir=nofollow\" on non-upper mount, falling back to nfs_export=off.\n");
config->nfs_export = false;
- } else if (nfs_export_opt && index_opt) {
+ } else if (set.nfs_export && set.index) {
pr_err("conflicting options: nfs_export=on,index=off\n");
return -EINVAL;
- } else if (index_opt) {
+ } else if (set.index) {
/*
* There was an explicit index=off that resulted
* in this conflict.
@@ -713,11 +724,11 @@ static int ovl_parse_opt(char *opt, struct ovl_config *config)
/* Resolve nfs_export -> !metacopy dependency */
if (config->nfs_export && config->metacopy) {
- if (nfs_export_opt && metacopy_opt) {
+ if (set.nfs_export && set.metacopy) {
pr_err("conflicting options: nfs_export=on,metacopy=on\n");
return -EINVAL;
}
- if (metacopy_opt) {
+ if (set.metacopy) {
/*
* There was an explicit metacopy=on that resulted
* in this conflict.
@@ -737,13 +748,13 @@ static int ovl_parse_opt(char *opt, struct ovl_config *config)
/* Resolve userxattr -> !redirect && !metacopy dependency */
if (config->userxattr) {
- if (redirect_opt &&
+ if (set.redirect &&
config->redirect_mode != OVL_REDIRECT_NOFOLLOW) {
pr_err("conflicting options: userxattr,redirect_dir=%s\n",
ovl_redirect_mode(config));
return -EINVAL;
}
- if (config->metacopy && metacopy_opt) {
+ if (config->metacopy && set.metacopy) {
pr_err("conflicting options: userxattr,metacopy=on\n");
return -EINVAL;
}
@@ -1981,7 +1992,7 @@ static int ovl_fill_super(struct super_block *sb, void *data, int silent)
ofs->config.nfs_export = ovl_nfs_export_def;
ofs->config.xino = ovl_xino_def();
ofs->config.metacopy = ovl_metacopy_def;
- err = ovl_parse_opt((char *) data, &ofs->config);
+ err = ovl_parse_options((char *) data, &ofs->config);
if (err)
goto out_err;
--
2.34.1
next prev parent reply other threads:[~2023-06-17 8:47 UTC|newest]
Thread overview: 16+ messages / expand[flat|nested] mbox.gz Atom feed top
2023-06-17 8:46 [PATCH v2 0/5] Prep patches for porting overlayfs to new mount api Amir Goldstein
2023-06-17 8:46 ` [PATCH v2 1/5] ovl: negate the ofs->share_whiteout boolean Amir Goldstein
2023-06-20 9:20 ` Christian Brauner
2023-06-17 8:46 ` [PATCH v2 2/5] ovl: clarify ovl_get_root() semantics Amir Goldstein
2023-06-20 9:21 ` Christian Brauner
2023-06-17 8:47 ` [PATCH v2 3/5] ovl: pass ovl_fs to xino helpers Amir Goldstein
2023-06-20 9:21 ` Christian Brauner
2023-06-17 8:47 ` [PATCH v2 4/5] ovl: store enum redirect_mode in config instead of a string Amir Goldstein
2023-06-20 8:48 ` Miklos Szeredi
2023-06-20 8:50 ` Miklos Szeredi
2023-06-20 9:23 ` Christian Brauner
2023-06-17 8:47 ` Amir Goldstein [this message]
2023-06-20 9:19 ` [PATCH v2 5/5] ovl: factor out ovl_parse_options() helper Christian Brauner
2023-06-20 9:26 ` [PATCH v2 0/5] Prep patches for porting overlayfs to new mount api Christian Brauner
2023-06-20 9:46 ` Amir Goldstein
2023-06-20 10:12 ` Christian Brauner
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20230617084702.2468470-6-amir73il@gmail.com \
--to=amir73il@gmail.com \
--cc=brauner@kernel.org \
--cc=linux-unionfs@vger.kernel.org \
--cc=miklos@szeredi.hu \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox