From: David Howells <dhowells@redhat.com>
To: mszeredi@redhat.com, viro@zeniv.linux.org.uk, jlayton@redhat.com
Cc: dhowells@redhat.com, linux-fsdevel@vger.kernel.org,
linux-nfs@vger.kernel.org, linux-kernel@vger.kernel.org
Subject: [PATCH 15/21] NFS: Split nfs_parse_mount_options() [ver #3]
Date: Mon, 15 May 2017 16:20:18 +0100 [thread overview]
Message-ID: <149486161870.23956.10962026940795644533.stgit@warthog.procyon.org.uk> (raw)
In-Reply-To: <149486147335.23956.2504187638938281431.stgit@warthog.procyon.org.uk>
Split nfs_parse_mount_options() to move the prologue, list-splitting and
epilogue into one function and the per-option processing into another.
---
fs/nfs/internal.h | 3 +
fs/nfs/mount.c | 143 ++++++++++++++++++++++++++++++-----------------------
2 files changed, 83 insertions(+), 63 deletions(-)
diff --git a/fs/nfs/internal.h b/fs/nfs/internal.h
index af6ca28da48d..ed255241baa7 100644
--- a/fs/nfs/internal.h
+++ b/fs/nfs/internal.h
@@ -100,7 +100,10 @@ struct nfs_sb_config {
unsigned int version;
unsigned int minorversion;
char *fscache_uniq;
+ unsigned short protofamily;
+ unsigned short mountfamily;
bool need_mount;
+ bool sloppy;
struct {
struct sockaddr_storage address;
diff --git a/fs/nfs/mount.c b/fs/nfs/mount.c
index ef9683deb2a8..26153b471e48 100644
--- a/fs/nfs/mount.c
+++ b/fs/nfs/mount.c
@@ -494,46 +494,18 @@ static int nfs_get_option_ul_bound(substring_t args[], unsigned long *option,
}
/*
- * Error-check and convert a string of mount options from user space into
- * a data structure. The whole mount string is processed; bad options are
- * skipped as they are encountered. If there were no errors, return 1;
- * otherwise return 0 (zero).
+ * Parse a single mount option in "key[=val]" form.
*/
-int nfs_parse_mount_options(char *raw, struct nfs_sb_config *cfg)
+static int nfs_sb_config_parse_option(struct nfs_sb_config *cfg, char *p)
{
- char *p, *string, *secdata;
- int rc, sloppy = 0, invalid_option = 0;
- unsigned short protofamily = AF_UNSPEC;
- unsigned short mountfamily = AF_UNSPEC;
-
- if (!raw) {
- dfprintk(MOUNT, "NFS: mount options string was NULL.\n");
- return 1;
- }
- dfprintk(MOUNT, "NFS: nfs mount opts='%s'\n", raw);
-
- secdata = alloc_secdata();
- if (!secdata)
- goto out_nomem;
-
- rc = security_sb_copy_data(raw, secdata);
- if (rc)
- goto out_security_failure;
-
- rc = security_sb_parse_opts_str(secdata, &cfg->lsm_opts);
- if (rc)
- goto out_security_failure;
-
- free_secdata(secdata);
+ char *string;
+ int rc;
- while ((p = strsep(&raw, ",")) != NULL) {
+ {
substring_t args[MAX_OPT_ARGS];
unsigned long option;
int token;
- if (!*p)
- continue;
-
dfprintk(MOUNT, "NFS: parsing nfs mount option '%s'\n", p);
token = match_token(p, nfs_mount_option_tokens, args);
@@ -737,7 +709,7 @@ int nfs_parse_mount_options(char *raw, struct nfs_sb_config *cfg)
if (!rc) {
dfprintk(MOUNT, "NFS: unrecognized "
"security flavor\n");
- return 0;
+ return -EINVAL;
}
break;
case Opt_proto:
@@ -747,22 +719,22 @@ int nfs_parse_mount_options(char *raw, struct nfs_sb_config *cfg)
token = match_token(string,
nfs_xprt_protocol_tokens, args);
- protofamily = AF_INET;
+ cfg->protofamily = AF_INET;
switch (token) {
case Opt_xprt_udp6:
- protofamily = AF_INET6;
+ cfg->protofamily = AF_INET6;
case Opt_xprt_udp:
cfg->flags &= ~NFS_MOUNT_TCP;
cfg->nfs_server.protocol = XPRT_TRANSPORT_UDP;
break;
case Opt_xprt_tcp6:
- protofamily = AF_INET6;
+ cfg->protofamily = AF_INET6;
case Opt_xprt_tcp:
cfg->flags |= NFS_MOUNT_TCP;
cfg->nfs_server.protocol = XPRT_TRANSPORT_TCP;
break;
case Opt_xprt_rdma6:
- protofamily = AF_INET6;
+ cfg->protofamily = AF_INET6;
case Opt_xprt_rdma:
/* vector side protocols to TCP */
cfg->flags |= NFS_MOUNT_TCP;
@@ -773,7 +745,7 @@ int nfs_parse_mount_options(char *raw, struct nfs_sb_config *cfg)
dfprintk(MOUNT, "NFS: unrecognized "
"transport protocol\n");
kfree(string);
- return 0;
+ return -EINVAL;
}
kfree(string);
break;
@@ -785,15 +757,15 @@ int nfs_parse_mount_options(char *raw, struct nfs_sb_config *cfg)
nfs_xprt_protocol_tokens, args);
kfree(string);
- mountfamily = AF_INET;
+ cfg->mountfamily = AF_INET;
switch (token) {
case Opt_xprt_udp6:
- mountfamily = AF_INET6;
+ cfg->mountfamily = AF_INET6;
case Opt_xprt_udp:
cfg->mount_server.protocol = XPRT_TRANSPORT_UDP;
break;
case Opt_xprt_tcp6:
- mountfamily = AF_INET6;
+ cfg->mountfamily = AF_INET6;
case Opt_xprt_tcp:
cfg->mount_server.protocol = XPRT_TRANSPORT_TCP;
break;
@@ -801,7 +773,7 @@ int nfs_parse_mount_options(char *raw, struct nfs_sb_config *cfg)
default:
dfprintk(MOUNT, "NFS: unrecognized "
"transport protocol\n");
- return 0;
+ return -EINVAL;
}
break;
case Opt_addr:
@@ -860,7 +832,7 @@ int nfs_parse_mount_options(char *raw, struct nfs_sb_config *cfg)
default:
dfprintk(MOUNT, "NFS: invalid "
"lookupcache argument\n");
- return 0;
+ return -EINVAL;
};
break;
case Opt_fscache_uniq:
@@ -893,7 +865,7 @@ int nfs_parse_mount_options(char *raw, struct nfs_sb_config *cfg)
default:
dfprintk(MOUNT, "NFS: invalid "
"local_lock argument\n");
- return 0;
+ return -EINVAL;
};
break;
@@ -901,7 +873,7 @@ int nfs_parse_mount_options(char *raw, struct nfs_sb_config *cfg)
* Special options
*/
case Opt_sloppy:
- sloppy = 1;
+ cfg->sloppy = 1;
dfprintk(MOUNT, "NFS: relaxing parsing rules\n");
break;
case Opt_userspace:
@@ -911,12 +883,63 @@ int nfs_parse_mount_options(char *raw, struct nfs_sb_config *cfg)
break;
default:
- invalid_option = 1;
dfprintk(MOUNT, "NFS: unrecognized mount option "
"'%s'\n", p);
+ return -EINVAL;
}
}
+ return 0;
+
+out_invalid_address:
+ printk(KERN_INFO "NFS: bad IP address specified: %s\n", p);
+ return -EINVAL;
+out_invalid_value:
+ printk(KERN_INFO "NFS: bad mount option value specified: %s\n", p);
+ return -EINVAL;
+out_nomem:
+ printk(KERN_INFO "NFS: not enough memory to parse option\n");
+ return -ENOMEM;
+}
+
+/*
+ * Error-check and convert a string of mount options from user space into
+ * a data structure. The whole mount string is processed; bad options are
+ * skipped as they are encountered. If there were no errors, return 1;
+ * otherwise return 0 (zero).
+ */
+int nfs_parse_mount_options(char *raw, struct nfs_sb_config *cfg)
+{
+ char *p, *secdata;
+ int rc, sloppy = 0, invalid_option = 0;
+
+ if (!raw) {
+ dfprintk(MOUNT, "NFS: mount options string was NULL.\n");
+ return 1;
+ }
+ dfprintk(MOUNT, "NFS: nfs mount opts='%s'\n", raw);
+
+ secdata = alloc_secdata();
+ if (!secdata)
+ goto out_nomem;
+
+ rc = security_sb_copy_data(raw, secdata);
+ if (rc)
+ goto out_security_failure;
+
+ rc = security_sb_parse_opts_str(secdata, &cfg->lsm_opts);
+ if (rc)
+ goto out_security_failure;
+
+ free_secdata(secdata);
+
+ while ((p = strsep(&raw, ",")) != NULL) {
+ if (!*p)
+ continue;
+ if (nfs_sb_config_parse_option(cfg, p) < 0)
+ invalid_option = true;
+ }
+
if (!sloppy && invalid_option)
return 0;
@@ -931,22 +954,26 @@ int nfs_parse_mount_options(char *raw, struct nfs_sb_config *cfg)
* verify that any proto=/mountproto= options match the address
* families in the addr=/mountaddr= options.
*/
- if (protofamily != AF_UNSPEC &&
- protofamily != cfg->nfs_server.address.ss_family)
+ if (cfg->protofamily != AF_UNSPEC &&
+ cfg->protofamily != cfg->nfs_server.address.ss_family)
goto out_proto_mismatch;
- if (mountfamily != AF_UNSPEC) {
+ if (cfg->mountfamily != AF_UNSPEC) {
if (cfg->mount_server.addrlen) {
- if (mountfamily != cfg->mount_server.address.ss_family)
+ if (cfg->mountfamily != cfg->mount_server.address.ss_family)
goto out_mountproto_mismatch;
} else {
- if (mountfamily != cfg->nfs_server.address.ss_family)
+ if (cfg->mountfamily != cfg->nfs_server.address.ss_family)
goto out_mountproto_mismatch;
}
}
return 1;
+out_minorversion_mismatch:
+ printk(KERN_INFO "NFS: mount option vers=%u does not support "
+ "minorversion=%u\n", cfg->version, cfg->minorversion);
+ return 0;
out_mountproto_mismatch:
printk(KERN_INFO "NFS: mount server address does not match mountproto= "
"option\n");
@@ -954,20 +981,10 @@ int nfs_parse_mount_options(char *raw, struct nfs_sb_config *cfg)
out_proto_mismatch:
printk(KERN_INFO "NFS: server address does not match proto= option\n");
return 0;
-out_invalid_address:
- printk(KERN_INFO "NFS: bad IP address specified: %s\n", p);
- return 0;
-out_invalid_value:
- printk(KERN_INFO "NFS: bad mount option value specified: %s\n", p);
- return 0;
-out_minorversion_mismatch:
- printk(KERN_INFO "NFS: mount option vers=%u does not support "
- "minorversion=%u\n", cfg->version, cfg->minorversion);
- return 0;
out_migration_misuse:
printk(KERN_INFO
"NFS: 'migration' not supported for this NFS version\n");
- return 0;
+ return -EINVAL;
out_nomem:
printk(KERN_INFO "NFS: not enough memory to parse option\n");
return 0;
next prev parent reply other threads:[~2017-05-15 15:22 UTC|newest]
Thread overview: 28+ messages / expand[flat|nested] mbox.gz Atom feed top
2017-05-15 15:17 [RFC][PATCH 00/21] VFS: Introduce superblock configuration context [ver #3] David Howells
2017-05-15 15:18 ` [PATCH 01/21] Provide a function to create a NUL-terminated string from unterminated data " David Howells
2017-05-15 15:18 ` [PATCH 02/21] Clean up whitespace in fs/namespace.c " David Howells
2017-05-15 15:18 ` [PATCH 03/21] VFS: Make get_mnt_ns() return the namespace " David Howells
2017-05-15 15:18 ` [PATCH 04/21] VFS: Make get_filesystem() return the affected filesystem " David Howells
2017-05-15 15:19 ` [PATCH 05/21] VFS: Provide empty name qstr " David Howells
2017-05-15 15:19 ` [PATCH 06/21] VFS: Introduce a superblock configuration context " David Howells
2017-05-16 15:10 ` Miklos Szeredi
2017-05-16 16:33 ` David Howells
2017-05-17 7:54 ` Miklos Szeredi
2017-05-17 11:31 ` David Howells
2017-05-18 8:09 ` Miklos Szeredi
2017-05-19 14:05 ` David Howells
2017-05-15 15:19 ` [PATCH 07/21] Implement fsopen() to prepare for a mount " David Howells
2017-05-15 15:19 ` [PATCH 08/21] Implement fsmount() to effect a pre-configured " David Howells
2017-05-15 15:19 ` [PATCH 09/21] Sample program for driving fsopen/fsmount " David Howells
2017-05-15 15:19 ` [PATCH 10/21] procfs: Move proc_fill_super() to fs/proc/root.c " David Howells
2017-05-15 15:19 ` [PATCH 11/21] proc: Add superblock config support to procfs " David Howells
2017-05-15 15:19 ` [PATCH 12/21] NFS: Move mount bits into their own file " David Howells
2017-05-15 15:20 ` [PATCH 13/21] NFS: Constify mount argument match tables " David Howells
2017-05-15 15:20 ` [PATCH 14/21] NFS: Rename struct nfs_parsed_mount_data to struct nfs_sb_config " David Howells
2017-05-15 15:20 ` David Howells [this message]
2017-05-15 15:20 ` [PATCH 16/21] NFS: Deindent nfs_sb_config_parse_option() " David Howells
2017-05-15 15:20 ` [PATCH 17/21] NFS: Add a small buffer in nfs_sb_config to avoid string dup " David Howells
2017-05-15 15:20 ` [PATCH 18/21] NFS: Do some tidying of the parsing code " David Howells
2017-05-15 15:20 ` [PATCH 19/21] NFS: Add mount context support. " David Howells
2017-05-15 15:20 ` [PATCH 20/21] Support legacy filesystems " David Howells
2017-05-15 15:21 ` [PATCH 21/21] Add commands to create or update a superblock " David Howells
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=149486161870.23956.10962026940795644533.stgit@warthog.procyon.org.uk \
--to=dhowells@redhat.com \
--cc=jlayton@redhat.com \
--cc=linux-fsdevel@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-nfs@vger.kernel.org \
--cc=mszeredi@redhat.com \
--cc=viro@zeniv.linux.org.uk \
/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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.