From: Scott Mayhew <smayhew@redhat.com> To: anna.schumaker@netapp.com, trond.myklebust@hammerspace.com Cc: dhowells@redhat.com, viro@zeniv.linux.org.uk, linux-nfs@vger.kernel.org, linux-fsdevel@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH v3 19/26] NFS: Split nfs_parse_mount_options() Date: Wed, 11 Sep 2019 12:16:14 -0400 Message-ID: <20190911161621.19832-20-smayhew@redhat.com> (raw) In-Reply-To: <20190911161621.19832-1-smayhew@redhat.com> From: David Howells <dhowells@redhat.com> Split nfs_parse_mount_options() to move the prologue, list-splitting and epilogue into one function and the per-option processing into another. Signed-off-by: David Howells <dhowells@redhat.com> Signed-off-by: Al Viro <viro@zeniv.linux.org.uk> --- fs/nfs/fs_context.c | 126 ++++++++++++++++++++++++-------------------- fs/nfs/internal.h | 3 ++ 2 files changed, 73 insertions(+), 56 deletions(-) diff --git a/fs/nfs/fs_context.c b/fs/nfs/fs_context.c index 5357430416d7..227a85f652b5 100644 --- a/fs/nfs/fs_context.c +++ b/fs/nfs/fs_context.c @@ -500,36 +500,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_fs_context *ctx) +static int nfs_fs_context_parse_option(struct nfs_fs_context *ctx, char *p) { - char *p, *string; - 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); - - rc = security_sb_eat_lsm_opts(raw, &ctx->lsm_opts); - if (rc) - goto out_security_failure; + 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); @@ -738,7 +720,7 @@ int nfs_parse_mount_options(char *raw, struct nfs_fs_context *ctx) if (!rc) { dfprintk(MOUNT, "NFS: unrecognized " "security flavor\n"); - return 0; + return -EINVAL; } break; case Opt_proto: @@ -748,24 +730,24 @@ int nfs_parse_mount_options(char *raw, struct nfs_fs_context *ctx) token = match_token(string, nfs_xprt_protocol_tokens, args); - protofamily = AF_INET; + ctx->protofamily = AF_INET; switch (token) { case Opt_xprt_udp6: - protofamily = AF_INET6; + ctx->protofamily = AF_INET6; /* fall through */ case Opt_xprt_udp: ctx->flags &= ~NFS_MOUNT_TCP; ctx->nfs_server.protocol = XPRT_TRANSPORT_UDP; break; case Opt_xprt_tcp6: - protofamily = AF_INET6; + ctx->protofamily = AF_INET6; /* fall through */ case Opt_xprt_tcp: ctx->flags |= NFS_MOUNT_TCP; ctx->nfs_server.protocol = XPRT_TRANSPORT_TCP; break; case Opt_xprt_rdma6: - protofamily = AF_INET6; + ctx->protofamily = AF_INET6; /* fall through */ case Opt_xprt_rdma: /* vector side protocols to TCP */ @@ -777,7 +759,7 @@ int nfs_parse_mount_options(char *raw, struct nfs_fs_context *ctx) dfprintk(MOUNT, "NFS: unrecognized " "transport protocol\n"); kfree(string); - return 0; + return -EINVAL; } kfree(string); break; @@ -789,16 +771,16 @@ int nfs_parse_mount_options(char *raw, struct nfs_fs_context *ctx) nfs_xprt_protocol_tokens, args); kfree(string); - mountfamily = AF_INET; + ctx->mountfamily = AF_INET; switch (token) { case Opt_xprt_udp6: - mountfamily = AF_INET6; + ctx->mountfamily = AF_INET6; /* fall through */ case Opt_xprt_udp: ctx->mount_server.protocol = XPRT_TRANSPORT_UDP; break; case Opt_xprt_tcp6: - mountfamily = AF_INET6; + ctx->mountfamily = AF_INET6; /* fall through */ case Opt_xprt_tcp: ctx->mount_server.protocol = XPRT_TRANSPORT_TCP; @@ -807,7 +789,7 @@ int nfs_parse_mount_options(char *raw, struct nfs_fs_context *ctx) default: dfprintk(MOUNT, "NFS: unrecognized " "transport protocol\n"); - return 0; + return -EINVAL; } break; case Opt_addr: @@ -871,7 +853,7 @@ int nfs_parse_mount_options(char *raw, struct nfs_fs_context *ctx) default: dfprintk(MOUNT, "NFS: invalid " "lookupcache argument\n"); - return 0; + return -EINVAL; }; break; case Opt_fscache_uniq: @@ -904,7 +886,7 @@ int nfs_parse_mount_options(char *raw, struct nfs_fs_context *ctx) default: dfprintk(MOUNT, "NFS: invalid " "local_lock argument\n"); - return 0; + return -EINVAL; }; break; @@ -912,7 +894,7 @@ int nfs_parse_mount_options(char *raw, struct nfs_fs_context *ctx) * Special options */ case Opt_sloppy: - sloppy = 1; + ctx->sloppy = 1; dfprintk(MOUNT, "NFS: relaxing parsing rules\n"); break; case Opt_userspace: @@ -922,12 +904,53 @@ int nfs_parse_mount_options(char *raw, struct nfs_fs_context *ctx) 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_fs_context *ctx) +{ + char *p; + 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); + + rc = security_sb_eat_lsm_opts(raw, &ctx->lsm_opts); + if (rc) + goto out_security_failure; + + while ((p = strsep(&raw, ",")) != NULL) { + if (!*p) + continue; + if (nfs_fs_context_parse_option(ctx, p) < 0) + invalid_option = true; + } + if (!sloppy && invalid_option) return 0; @@ -942,22 +965,26 @@ int nfs_parse_mount_options(char *raw, struct nfs_fs_context *ctx) * verify that any proto=/mountproto= options match the address * families in the addr=/mountaddr= options. */ - if (protofamily != AF_UNSPEC && - protofamily != ctx->nfs_server.address.ss_family) + if (ctx->protofamily != AF_UNSPEC && + ctx->protofamily != ctx->nfs_server.address.ss_family) goto out_proto_mismatch; - if (mountfamily != AF_UNSPEC) { + if (ctx->mountfamily != AF_UNSPEC) { if (ctx->mount_server.addrlen) { - if (mountfamily != ctx->mount_server.address.ss_family) + if (ctx->mountfamily != ctx->mount_server.address.ss_family) goto out_mountproto_mismatch; } else { - if (mountfamily != ctx->nfs_server.address.ss_family) + if (ctx->mountfamily != ctx->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", ctx->version, ctx->minorversion); + return 0; out_mountproto_mismatch: printk(KERN_INFO "NFS: mount server address does not match mountproto= " "option\n"); @@ -965,23 +992,10 @@ int nfs_parse_mount_options(char *raw, struct nfs_fs_context *ctx) 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", ctx->version, ctx->minorversion); - return 0; out_migration_misuse: printk(KERN_INFO "NFS: 'migration' not supported for this NFS version\n"); - return 0; -out_nomem: - printk(KERN_INFO "NFS: not enough memory to parse option\n"); - return 0; + return -EINVAL; out_security_failure: printk(KERN_INFO "NFS: security options invalid: %d\n", rc); return 0; diff --git a/fs/nfs/internal.h b/fs/nfs/internal.h index 632174d666a8..d084182f8e43 100644 --- a/fs/nfs/internal.h +++ b/fs/nfs/internal.h @@ -104,7 +104,10 @@ struct nfs_fs_context { 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; -- 2.17.2
next prev parent reply index Thread overview: 30+ messages / expand[flat|nested] mbox.gz Atom feed top 2019-09-11 16:15 [PATCH v3 00/26] nfs: Mount API conversion Scott Mayhew 2019-09-11 16:15 ` [PATCH v3 01/26] saner calling conventions for nfs_fs_mount_common() Scott Mayhew 2019-09-11 16:15 ` [PATCH v3 02/26] nfs: stash server into struct nfs_mount_info Scott Mayhew 2019-09-11 16:15 ` [PATCH v3 03/26] nfs: lift setting mount_info from nfs4_remote{,_referral}_mount Scott Mayhew 2019-09-11 16:15 ` [PATCH v3 04/26] nfs: fold nfs4_remote_fs_type and nfs4_remote_referral_fs_type Scott Mayhew 2019-09-11 16:16 ` [PATCH v3 05/26] nfs: don't bother setting/restoring export_path around do_nfs_root_mount() Scott Mayhew 2019-09-11 16:16 ` [PATCH v3 06/26] nfs4: fold nfs_do_root_mount/nfs_follow_remote_path Scott Mayhew 2019-09-11 16:16 ` [PATCH v3 07/26] nfs: lift setting mount_info from nfs_xdev_mount() Scott Mayhew 2019-09-11 16:16 ` [PATCH v3 08/26] nfs: stash nfs_subversion reference into nfs_mount_info Scott Mayhew 2019-09-11 16:16 ` [PATCH v3 09/26] nfs: don't bother passing nfs_subversion to ->try_mount() and nfs_fs_mount_common() Scott Mayhew 2019-09-11 16:16 ` [PATCH v3 10/26] nfs: merge xdev and remote file_system_type Scott Mayhew 2019-09-11 16:16 ` [PATCH v3 11/26] nfs: unexport nfs_fs_mount_common() Scott Mayhew 2019-09-11 16:16 ` [PATCH v3 12/26] nfs: don't pass nfs_subversion to ->create_server() Scott Mayhew 2019-09-11 16:16 ` [PATCH v3 13/26] nfs: get rid of mount_info ->fill_super() Scott Mayhew 2019-09-11 16:16 ` [PATCH v3 14/26] nfs_clone_sb_security(): simplify the check for server bogosity Scott Mayhew 2019-09-11 16:16 ` [PATCH v3 15/26] nfs: get rid of ->set_security() Scott Mayhew 2019-09-11 16:16 ` [PATCH v3 16/26] NFS: Move mount parameterisation bits into their own file Scott Mayhew 2019-09-11 18:24 ` Chuck Lever 2019-09-12 17:35 ` Scott Mayhew [not found] ` <014d1a8425545b633b982f63d78665b73bcf0075.camel@hammerspace.com> 2019-09-12 17:36 ` Scott Mayhew 2019-09-11 16:16 ` [PATCH v3 17/26] NFS: Constify mount argument match tables Scott Mayhew 2019-09-11 16:16 ` [PATCH v3 18/26] NFS: Rename struct nfs_parsed_mount_data to struct nfs_fs_context Scott Mayhew 2019-09-11 16:16 ` Scott Mayhew [this message] 2019-09-11 16:16 ` [PATCH v3 20/26] NFS: Deindent nfs_fs_context_parse_option() Scott Mayhew 2019-09-11 16:16 ` [PATCH v3 21/26] NFS: Add a small buffer in nfs_fs_context to avoid string dup Scott Mayhew 2019-09-11 16:16 ` [PATCH v3 22/26] NFS: Do some tidying of the parsing code Scott Mayhew 2019-09-11 16:16 ` [PATCH v3 23/26] NFS: rename nfs_fs_context pointer arg in a few functions Scott Mayhew 2019-09-11 16:16 ` [PATCH v3 24/26] NFS: Convert mount option parsing to use functionality from fs_parser.h Scott Mayhew 2019-09-11 16:16 ` [PATCH v3 25/26] NFS: Add fs_context support Scott Mayhew 2019-09-11 16:16 ` [PATCH v3 26/26] NFS: Attach supplementary error information to fs_context Scott Mayhew
Reply instructions: You may reply publically 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=20190911161621.19832-20-smayhew@redhat.com \ --to=smayhew@redhat.com \ --cc=anna.schumaker@netapp.com \ --cc=dhowells@redhat.com \ --cc=linux-fsdevel@vger.kernel.org \ --cc=linux-kernel@vger.kernel.org \ --cc=linux-nfs@vger.kernel.org \ --cc=trond.myklebust@hammerspace.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
Linux-NFS Archive on lore.kernel.org Archives are clonable: git clone --mirror https://lore.kernel.org/linux-nfs/0 linux-nfs/git/0.git # If you have public-inbox 1.1+ installed, you may # initialize and index your mirror using the following commands: public-inbox-init -V2 linux-nfs linux-nfs/ https://lore.kernel.org/linux-nfs \ linux-nfs@vger.kernel.org public-inbox-index linux-nfs Example config snippet for mirrors Newsgroup available over NNTP: nntp://nntp.lore.kernel.org/org.kernel.vger.linux-nfs AGPL code for this site: git clone https://public-inbox.org/public-inbox.git