From patchwork Thu May 23 16:15:50 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Howells X-Patchwork-Id: 10958253 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 393F413AD for ; Thu, 23 May 2019 16:16:08 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 267B927E01 for ; Thu, 23 May 2019 16:16:08 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 1AE6628384; Thu, 23 May 2019 16:16:08 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-7.9 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI, RCVD_IN_DNSWL_HI autolearn=unavailable version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id BCB3827E01 for ; Thu, 23 May 2019 16:16:07 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1731168AbfEWQP7 (ORCPT ); Thu, 23 May 2019 12:15:59 -0400 Received: from mx1.redhat.com ([209.132.183.28]:38908 "EHLO mx1.redhat.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1731073AbfEWQP6 (ORCPT ); Thu, 23 May 2019 12:15:58 -0400 Received: from smtp.corp.redhat.com (int-mx04.intmail.prod.int.phx2.redhat.com [10.5.11.14]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id BEAC73001749; Thu, 23 May 2019 16:15:55 +0000 (UTC) Received: from warthog.procyon.org.uk (ovpn-121-142.rdu2.redhat.com [10.10.121.142]) by smtp.corp.redhat.com (Postfix) with ESMTP id 6F31668365; Thu, 23 May 2019 16:15:51 +0000 (UTC) Organization: Red Hat UK Ltd. Registered Address: Red Hat UK Ltd, Amberley Place, 107-111 Peascod Street, Windsor, Berkshire, SI4 1TE, United Kingdom. Registered in England and Wales under Company Registration No. 3798903 Subject: [PATCH 01/23] saner calling conventions for nfs_fs_mount_common() From: David Howells To: trond.myklebust@hammerspace.com, anna.schumaker@netapp.com Cc: Al Viro , dhowells@redhat.com, viro@zeniv.linux.org.uk, linux-nfs@vger.kernel.org, linux-fsdevel@vger.kernel.org, linux-kernel@vger.kernel.org Date: Thu, 23 May 2019 17:15:50 +0100 Message-ID: <155862815043.26654.10359128329402412912.stgit@warthog.procyon.org.uk> In-Reply-To: <155862813755.26654.563679411147031501.stgit@warthog.procyon.org.uk> References: <155862813755.26654.563679411147031501.stgit@warthog.procyon.org.uk> User-Agent: StGit/unknown-version MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.14 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.46]); Thu, 23 May 2019 16:15:58 +0000 (UTC) Sender: linux-fsdevel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-fsdevel@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP From: Al Viro Allow it to take ERR_PTR() for server and return ERR_CAST() of it in such case. All callers used to open-code that... Reviewed-by: David Howells Signed-off-by: Al Viro --- fs/nfs/nfs4super.c | 16 +--------------- fs/nfs/super.c | 11 ++++------- 2 files changed, 5 insertions(+), 22 deletions(-) diff --git a/fs/nfs/nfs4super.c b/fs/nfs/nfs4super.c index 689977e148cb..a392e9454287 100644 --- a/fs/nfs/nfs4super.c +++ b/fs/nfs/nfs4super.c @@ -109,21 +109,12 @@ nfs4_remote_mount(struct file_system_type *fs_type, int flags, { struct nfs_mount_info *mount_info = info; struct nfs_server *server; - struct dentry *mntroot = ERR_PTR(-ENOMEM); mount_info->set_security = nfs_set_sb_security; /* Get a volume representation */ server = nfs4_create_server(mount_info, &nfs_v4); - if (IS_ERR(server)) { - mntroot = ERR_CAST(server); - goto out; - } - - mntroot = nfs_fs_mount_common(server, flags, dev_name, mount_info, &nfs_v4); - -out: - return mntroot; + return nfs_fs_mount_common(server, flags, dev_name, mount_info, &nfs_v4); } static struct vfsmount *nfs_do_root_mount(struct file_system_type *fs_type, @@ -279,11 +270,6 @@ nfs4_remote_referral_mount(struct file_system_type *fs_type, int flags, /* create a new volume representation */ server = nfs4_create_referral_server(mount_info.cloned, mount_info.mntfh); - if (IS_ERR(server)) { - mntroot = ERR_CAST(server); - goto out; - } - mntroot = nfs_fs_mount_common(server, flags, dev_name, &mount_info, &nfs_v4); out: nfs_free_fhandle(mount_info.mntfh); diff --git a/fs/nfs/super.c b/fs/nfs/super.c index d6c687419a81..e4108e20af0f 100644 --- a/fs/nfs/super.c +++ b/fs/nfs/super.c @@ -1881,9 +1881,6 @@ struct dentry *nfs_try_mount(int flags, const char *dev_name, else server = nfs_mod->rpc_ops->create_server(mount_info, nfs_mod); - if (IS_ERR(server)) - return ERR_CAST(server); - return nfs_fs_mount_common(server, flags, dev_name, mount_info, nfs_mod); } EXPORT_SYMBOL_GPL(nfs_try_mount); @@ -2618,6 +2615,9 @@ struct dentry *nfs_fs_mount_common(struct nfs_server *server, }; int error; + if (IS_ERR(server)) + return ERR_CAST(server); + if (server->flags & NFS_MOUNT_UNSHARED) compare_super = NULL; @@ -2766,10 +2766,7 @@ nfs_xdev_mount(struct file_system_type *fs_type, int flags, /* create a new volume representation */ server = nfs_mod->rpc_ops->clone_server(NFS_SB(data->sb), data->fh, data->fattr, data->authflavor); - if (IS_ERR(server)) - mntroot = ERR_CAST(server); - else - mntroot = nfs_fs_mount_common(server, flags, + mntroot = nfs_fs_mount_common(server, flags, dev_name, &mount_info, nfs_mod); dprintk("<-- nfs_xdev_mount() = %ld\n", From patchwork Thu May 23 16:16:01 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Howells X-Patchwork-Id: 10958255 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 6D110933 for ; Thu, 23 May 2019 16:16:18 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 56BD1283E8 for ; Thu, 23 May 2019 16:16:18 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 49BAF28384; Thu, 23 May 2019 16:16:18 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-7.9 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI, RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id C51CF27E01 for ; Thu, 23 May 2019 16:16:17 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1731291AbfEWQQN (ORCPT ); Thu, 23 May 2019 12:16:13 -0400 Received: from mx1.redhat.com ([209.132.183.28]:34094 "EHLO mx1.redhat.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1730918AbfEWQQM (ORCPT ); Thu, 23 May 2019 12:16:12 -0400 Received: from smtp.corp.redhat.com (int-mx05.intmail.prod.int.phx2.redhat.com [10.5.11.15]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 2B38C30A6973; Thu, 23 May 2019 16:16:12 +0000 (UTC) Received: from warthog.procyon.org.uk (ovpn-121-142.rdu2.redhat.com [10.10.121.142]) by smtp.corp.redhat.com (Postfix) with ESMTP id D9FD95B683; Thu, 23 May 2019 16:16:08 +0000 (UTC) Organization: Red Hat UK Ltd. Registered Address: Red Hat UK Ltd, Amberley Place, 107-111 Peascod Street, Windsor, Berkshire, SI4 1TE, United Kingdom. Registered in England and Wales under Company Registration No. 3798903 Subject: [PATCH 02/23] nfs: stash server into struct nfs_mount_info From: David Howells To: trond.myklebust@hammerspace.com, anna.schumaker@netapp.com Cc: Al Viro , dhowells@redhat.com, viro@zeniv.linux.org.uk, linux-nfs@vger.kernel.org, linux-fsdevel@vger.kernel.org, linux-kernel@vger.kernel.org Date: Thu, 23 May 2019 17:16:01 +0100 Message-ID: <155862816099.26654.9619516592946983710.stgit@warthog.procyon.org.uk> In-Reply-To: <155862813755.26654.563679411147031501.stgit@warthog.procyon.org.uk> References: <155862813755.26654.563679411147031501.stgit@warthog.procyon.org.uk> User-Agent: StGit/unknown-version MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.15 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.47]); Thu, 23 May 2019 16:16:12 +0000 (UTC) Sender: linux-fsdevel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-fsdevel@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP From: Al Viro Reviewed-by: David Howells Signed-off-by: Al Viro --- fs/nfs/internal.h | 3 ++- fs/nfs/nfs4super.c | 10 ++++------ fs/nfs/super.c | 19 ++++++++----------- 3 files changed, 14 insertions(+), 18 deletions(-) diff --git a/fs/nfs/internal.h b/fs/nfs/internal.h index 498fab72f70b..ce00e61b9b2a 100644 --- a/fs/nfs/internal.h +++ b/fs/nfs/internal.h @@ -149,6 +149,7 @@ struct nfs_mount_info { int (*set_security)(struct super_block *, struct dentry *, struct nfs_mount_info *); struct nfs_parsed_mount_data *parsed; struct nfs_clone_mount *cloned; + struct nfs_server *server; struct nfs_fh *mntfh; }; @@ -404,7 +405,7 @@ struct dentry *nfs_try_mount(int, const char *, struct nfs_mount_info *, struct nfs_subversion *); int nfs_set_sb_security(struct super_block *, struct dentry *, struct nfs_mount_info *); int nfs_clone_sb_security(struct super_block *, struct dentry *, struct nfs_mount_info *); -struct dentry *nfs_fs_mount_common(struct nfs_server *, int, const char *, +struct dentry *nfs_fs_mount_common(int, const char *, struct nfs_mount_info *, struct nfs_subversion *); struct dentry *nfs_fs_mount(struct file_system_type *, int, const char *, void *); struct dentry * nfs_xdev_mount_common(struct file_system_type *, int, diff --git a/fs/nfs/nfs4super.c b/fs/nfs/nfs4super.c index a392e9454287..a962042972fa 100644 --- a/fs/nfs/nfs4super.c +++ b/fs/nfs/nfs4super.c @@ -108,13 +108,12 @@ nfs4_remote_mount(struct file_system_type *fs_type, int flags, const char *dev_name, void *info) { struct nfs_mount_info *mount_info = info; - struct nfs_server *server; mount_info->set_security = nfs_set_sb_security; /* Get a volume representation */ - server = nfs4_create_server(mount_info, &nfs_v4); - return nfs_fs_mount_common(server, flags, dev_name, mount_info, &nfs_v4); + mount_info->server = nfs4_create_server(mount_info, &nfs_v4); + return nfs_fs_mount_common(flags, dev_name, mount_info, &nfs_v4); } static struct vfsmount *nfs_do_root_mount(struct file_system_type *fs_type, @@ -259,7 +258,6 @@ nfs4_remote_referral_mount(struct file_system_type *fs_type, int flags, .set_security = nfs_clone_sb_security, .cloned = raw_data, }; - struct nfs_server *server; struct dentry *mntroot = ERR_PTR(-ENOMEM); dprintk("--> nfs4_referral_get_sb()\n"); @@ -269,8 +267,8 @@ nfs4_remote_referral_mount(struct file_system_type *fs_type, int flags, goto out; /* create a new volume representation */ - server = nfs4_create_referral_server(mount_info.cloned, mount_info.mntfh); - mntroot = nfs_fs_mount_common(server, flags, dev_name, &mount_info, &nfs_v4); + mount_info.server = nfs4_create_referral_server(mount_info.cloned, mount_info.mntfh); + mntroot = nfs_fs_mount_common(flags, dev_name, &mount_info, &nfs_v4); out: nfs_free_fhandle(mount_info.mntfh); return mntroot; diff --git a/fs/nfs/super.c b/fs/nfs/super.c index e4108e20af0f..485604fa2ae3 100644 --- a/fs/nfs/super.c +++ b/fs/nfs/super.c @@ -1874,14 +1874,12 @@ struct dentry *nfs_try_mount(int flags, const char *dev_name, struct nfs_mount_info *mount_info, struct nfs_subversion *nfs_mod) { - struct nfs_server *server; - if (mount_info->parsed->need_mount) - server = nfs_try_mount_request(mount_info, nfs_mod); + mount_info->server = nfs_try_mount_request(mount_info, nfs_mod); else - server = nfs_mod->rpc_ops->create_server(mount_info, nfs_mod); + mount_info->server = nfs_mod->rpc_ops->create_server(mount_info, nfs_mod); - return nfs_fs_mount_common(server, flags, dev_name, mount_info, nfs_mod); + return nfs_fs_mount_common(flags, dev_name, mount_info, nfs_mod); } EXPORT_SYMBOL_GPL(nfs_try_mount); @@ -2601,20 +2599,21 @@ int nfs_clone_sb_security(struct super_block *s, struct dentry *mntroot, } EXPORT_SYMBOL_GPL(nfs_clone_sb_security); -struct dentry *nfs_fs_mount_common(struct nfs_server *server, - int flags, const char *dev_name, +struct dentry *nfs_fs_mount_common(int flags, const char *dev_name, struct nfs_mount_info *mount_info, struct nfs_subversion *nfs_mod) { struct super_block *s; struct dentry *mntroot = ERR_PTR(-ENOMEM); int (*compare_super)(struct super_block *, void *) = nfs_compare_super; + struct nfs_server *server = mount_info->server; struct nfs_sb_mountdata sb_mntdata = { .mntflags = flags, .server = server, }; int error; + mount_info->server = NULL; if (IS_ERR(server)) return ERR_CAST(server); @@ -2755,7 +2754,6 @@ nfs_xdev_mount(struct file_system_type *fs_type, int flags, .set_security = nfs_clone_sb_security, .cloned = data, }; - struct nfs_server *server; struct dentry *mntroot = ERR_PTR(-ENOMEM); struct nfs_subversion *nfs_mod = NFS_SB(data->sb)->nfs_client->cl_nfs_mod; @@ -2764,10 +2762,9 @@ nfs_xdev_mount(struct file_system_type *fs_type, int flags, mount_info.mntfh = mount_info.cloned->fh; /* create a new volume representation */ - server = nfs_mod->rpc_ops->clone_server(NFS_SB(data->sb), data->fh, data->fattr, data->authflavor); + mount_info.server = nfs_mod->rpc_ops->clone_server(NFS_SB(data->sb), data->fh, data->fattr, data->authflavor); - mntroot = nfs_fs_mount_common(server, flags, - dev_name, &mount_info, nfs_mod); + mntroot = nfs_fs_mount_common(flags, dev_name, &mount_info, nfs_mod); dprintk("<-- nfs_xdev_mount() = %ld\n", IS_ERR(mntroot) ? PTR_ERR(mntroot) : 0L); From patchwork Thu May 23 16:16:17 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Howells X-Patchwork-Id: 10958261 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 386571708 for ; Thu, 23 May 2019 16:16:28 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 252A126E82 for ; Thu, 23 May 2019 16:16:28 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 1918B28668; Thu, 23 May 2019 16:16:28 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-7.9 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI, RCVD_IN_DNSWL_HI autolearn=unavailable version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id A14C028671 for ; Thu, 23 May 2019 16:16:27 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1731212AbfEWQQW (ORCPT ); Thu, 23 May 2019 12:16:22 -0400 Received: from mx1.redhat.com ([209.132.183.28]:49274 "EHLO mx1.redhat.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1730918AbfEWQQW (ORCPT ); Thu, 23 May 2019 12:16:22 -0400 Received: from smtp.corp.redhat.com (int-mx01.intmail.prod.int.phx2.redhat.com [10.5.11.11]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 1A390821F3; Thu, 23 May 2019 16:16:22 +0000 (UTC) Received: from warthog.procyon.org.uk (ovpn-121-142.rdu2.redhat.com [10.10.121.142]) by smtp.corp.redhat.com (Postfix) with ESMTP id 37648600C1; Thu, 23 May 2019 16:16:19 +0000 (UTC) Organization: Red Hat UK Ltd. Registered Address: Red Hat UK Ltd, Amberley Place, 107-111 Peascod Street, Windsor, Berkshire, SI4 1TE, United Kingdom. Registered in England and Wales under Company Registration No. 3798903 Subject: [PATCH 03/23] nfs: lift setting mount_info from nfs4_remote{, _referral}_mount From: David Howells To: trond.myklebust@hammerspace.com, anna.schumaker@netapp.com Cc: Al Viro , dhowells@redhat.com, viro@zeniv.linux.org.uk, linux-nfs@vger.kernel.org, linux-fsdevel@vger.kernel.org, linux-kernel@vger.kernel.org Date: Thu, 23 May 2019 17:16:17 +0100 Message-ID: <155862817738.26654.16583027208956953428.stgit@warthog.procyon.org.uk> In-Reply-To: <155862813755.26654.563679411147031501.stgit@warthog.procyon.org.uk> References: <155862813755.26654.563679411147031501.stgit@warthog.procyon.org.uk> User-Agent: StGit/unknown-version MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.11 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.28]); Thu, 23 May 2019 16:16:22 +0000 (UTC) Sender: linux-fsdevel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-fsdevel@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP From: Al Viro Do that (fhandle allocation, setting struct server up) in nfs4_referral_mount() and nfs4_try_mount() resp. and pass the server and pointer to mount_info into nfs_do_root_mount() so that nfs4_remote_referral_mount()/nfs_remote_mount() could be merged. Since we are moving stuff from ->mount() instances to the points prior to vfs_kern_mount() that would trigger those, we need to make sure that do_nfs_root_mount() will do the corresponding cleanup itself if it doesn't trigger those ->mount() instances. Reviewed-by: David Howells Signed-off-by: Al Viro --- fs/nfs/nfs4super.c | 67 +++++++++++++++++++++++++++------------------------- 1 file changed, 35 insertions(+), 32 deletions(-) diff --git a/fs/nfs/nfs4super.c b/fs/nfs/nfs4super.c index a962042972fa..71a970ca3fb7 100644 --- a/fs/nfs/nfs4super.c +++ b/fs/nfs/nfs4super.c @@ -107,32 +107,37 @@ static struct dentry * nfs4_remote_mount(struct file_system_type *fs_type, int flags, const char *dev_name, void *info) { - struct nfs_mount_info *mount_info = info; - - mount_info->set_security = nfs_set_sb_security; - - /* Get a volume representation */ - mount_info->server = nfs4_create_server(mount_info, &nfs_v4); - return nfs_fs_mount_common(flags, dev_name, mount_info, &nfs_v4); + return nfs_fs_mount_common(flags, dev_name, info, &nfs_v4); } static struct vfsmount *nfs_do_root_mount(struct file_system_type *fs_type, - int flags, void *data, const char *hostname) + struct nfs_server *server, int flags, + struct nfs_mount_info *info, + const char *hostname) { struct vfsmount *root_mnt; char *root_devname; size_t len; + if (IS_ERR(server)) + return ERR_CAST(server); + len = strlen(hostname) + 5; root_devname = kmalloc(len, GFP_KERNEL); - if (root_devname == NULL) + if (root_devname == NULL) { + nfs_free_server(server); return ERR_PTR(-ENOMEM); + } /* Does hostname needs to be enclosed in brackets? */ if (strchr(hostname, ':')) snprintf(root_devname, len, "[%s]:/", hostname); else snprintf(root_devname, len, "%s:/", hostname); - root_mnt = vfs_kern_mount(fs_type, flags, root_devname, data); + info->server = server; + root_mnt = vfs_kern_mount(fs_type, flags, root_devname, info); + if (info->server) + nfs_free_server(info->server); + info->server = NULL; kfree(root_devname); return root_mnt; } @@ -233,11 +238,15 @@ struct dentry *nfs4_try_mount(int flags, const char *dev_name, struct dentry *res; struct nfs_parsed_mount_data *data = mount_info->parsed; + mount_info->set_security = nfs_set_sb_security; + dfprintk(MOUNT, "--> nfs4_try_mount()\n"); export_path = data->nfs_server.export_path; data->nfs_server.export_path = "/"; - root_mnt = nfs_do_root_mount(&nfs4_remote_fs_type, flags, mount_info, + root_mnt = nfs_do_root_mount(&nfs4_remote_fs_type, + nfs4_create_server(mount_info, &nfs_v4), + flags, mount_info, data->nfs_server.hostname); data->nfs_server.export_path = export_path; @@ -253,25 +262,7 @@ static struct dentry * nfs4_remote_referral_mount(struct file_system_type *fs_type, int flags, const char *dev_name, void *raw_data) { - struct nfs_mount_info mount_info = { - .fill_super = nfs_fill_super, - .set_security = nfs_clone_sb_security, - .cloned = raw_data, - }; - struct dentry *mntroot = ERR_PTR(-ENOMEM); - - dprintk("--> nfs4_referral_get_sb()\n"); - - mount_info.mntfh = nfs_alloc_fhandle(); - if (mount_info.cloned == NULL || mount_info.mntfh == NULL) - goto out; - - /* create a new volume representation */ - mount_info.server = nfs4_create_referral_server(mount_info.cloned, mount_info.mntfh); - mntroot = nfs_fs_mount_common(flags, dev_name, &mount_info, &nfs_v4); -out: - nfs_free_fhandle(mount_info.mntfh); - return mntroot; + return nfs_fs_mount_common(flags, dev_name, raw_data, &nfs_v4); } /* @@ -281,23 +272,35 @@ static struct dentry *nfs4_referral_mount(struct file_system_type *fs_type, int flags, const char *dev_name, void *raw_data) { struct nfs_clone_mount *data = raw_data; + struct nfs_mount_info mount_info = { + .fill_super = nfs_fill_super, + .set_security = nfs_clone_sb_security, + .cloned = data, + }; char *export_path; struct vfsmount *root_mnt; struct dentry *res; dprintk("--> nfs4_referral_mount()\n"); + mount_info.mntfh = nfs_alloc_fhandle(); + if (!mount_info.mntfh) + return ERR_PTR(-ENOMEM); + export_path = data->mnt_path; data->mnt_path = "/"; - root_mnt = nfs_do_root_mount(&nfs4_remote_referral_fs_type, - flags, data, data->hostname); + nfs4_create_referral_server(mount_info.cloned, + mount_info.mntfh), + flags, &mount_info, data->hostname); data->mnt_path = export_path; res = nfs_follow_remote_path(root_mnt, export_path); dprintk("<-- nfs4_referral_mount() = %d%s\n", PTR_ERR_OR_ZERO(res), IS_ERR(res) ? " [error]" : ""); + + nfs_free_fhandle(mount_info.mntfh); return res; } From patchwork Thu May 23 16:16:27 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Howells X-Patchwork-Id: 10958265 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 3811A933 for ; Thu, 23 May 2019 16:16:35 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 2536B27F86 for ; Thu, 23 May 2019 16:16:35 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 19F881FFD9; Thu, 23 May 2019 16:16:35 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-7.9 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI, RCVD_IN_DNSWL_HI autolearn=unavailable version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id B729F27F86 for ; Thu, 23 May 2019 16:16:34 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1731326AbfEWQQa (ORCPT ); Thu, 23 May 2019 12:16:30 -0400 Received: from mx1.redhat.com ([209.132.183.28]:49320 "EHLO mx1.redhat.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1730918AbfEWQQ3 (ORCPT ); Thu, 23 May 2019 12:16:29 -0400 Received: from smtp.corp.redhat.com (int-mx07.intmail.prod.int.phx2.redhat.com [10.5.11.22]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 97526821D1; Thu, 23 May 2019 16:16:29 +0000 (UTC) Received: from warthog.procyon.org.uk (ovpn-121-142.rdu2.redhat.com [10.10.121.142]) by smtp.corp.redhat.com (Postfix) with ESMTP id 1ECD81001F5B; Thu, 23 May 2019 16:16:27 +0000 (UTC) Organization: Red Hat UK Ltd. Registered Address: Red Hat UK Ltd, Amberley Place, 107-111 Peascod Street, Windsor, Berkshire, SI4 1TE, United Kingdom. Registered in England and Wales under Company Registration No. 3798903 Subject: [PATCH 04/23] nfs: fold nfs4_remote_fs_type and nfs4_remote_referral_fs_type From: David Howells To: trond.myklebust@hammerspace.com, anna.schumaker@netapp.com Cc: Al Viro , dhowells@redhat.com, viro@zeniv.linux.org.uk, linux-nfs@vger.kernel.org, linux-fsdevel@vger.kernel.org, linux-kernel@vger.kernel.org Date: Thu, 23 May 2019 17:16:27 +0100 Message-ID: <155862818734.26654.3150141109818847701.stgit@warthog.procyon.org.uk> In-Reply-To: <155862813755.26654.563679411147031501.stgit@warthog.procyon.org.uk> References: <155862813755.26654.563679411147031501.stgit@warthog.procyon.org.uk> User-Agent: StGit/unknown-version MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.84 on 10.5.11.22 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.28]); Thu, 23 May 2019 16:16:29 +0000 (UTC) Sender: linux-fsdevel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-fsdevel@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP From: Al Viro They are identical now. Reviewed-by: David Howells Signed-off-by: Al Viro --- fs/nfs/nfs4super.c | 26 ++++---------------------- 1 file changed, 4 insertions(+), 22 deletions(-) diff --git a/fs/nfs/nfs4super.c b/fs/nfs/nfs4super.c index 71a970ca3fb7..5d02925e3567 100644 --- a/fs/nfs/nfs4super.c +++ b/fs/nfs/nfs4super.c @@ -21,8 +21,6 @@ static struct dentry *nfs4_remote_mount(struct file_system_type *fs_type, int flags, const char *dev_name, void *raw_data); static struct dentry *nfs4_referral_mount(struct file_system_type *fs_type, int flags, const char *dev_name, void *raw_data); -static struct dentry *nfs4_remote_referral_mount(struct file_system_type *fs_type, - int flags, const char *dev_name, void *raw_data); static struct file_system_type nfs4_remote_fs_type = { .owner = THIS_MODULE, @@ -32,14 +30,6 @@ static struct file_system_type nfs4_remote_fs_type = { .fs_flags = FS_RENAME_DOES_D_MOVE|FS_BINARY_MOUNTDATA, }; -static struct file_system_type nfs4_remote_referral_fs_type = { - .owner = THIS_MODULE, - .name = "nfs4", - .mount = nfs4_remote_referral_mount, - .kill_sb = nfs_kill_super, - .fs_flags = FS_RENAME_DOES_D_MOVE|FS_BINARY_MOUNTDATA, -}; - struct file_system_type nfs4_referral_fs_type = { .owner = THIS_MODULE, .name = "nfs4", @@ -110,8 +100,7 @@ nfs4_remote_mount(struct file_system_type *fs_type, int flags, return nfs_fs_mount_common(flags, dev_name, info, &nfs_v4); } -static struct vfsmount *nfs_do_root_mount(struct file_system_type *fs_type, - struct nfs_server *server, int flags, +static struct vfsmount *nfs_do_root_mount(struct nfs_server *server, int flags, struct nfs_mount_info *info, const char *hostname) { @@ -134,7 +123,7 @@ static struct vfsmount *nfs_do_root_mount(struct file_system_type *fs_type, else snprintf(root_devname, len, "%s:/", hostname); info->server = server; - root_mnt = vfs_kern_mount(fs_type, flags, root_devname, info); + root_mnt = vfs_kern_mount(&nfs4_remote_fs_type, flags, root_devname, info); if (info->server) nfs_free_server(info->server); info->server = NULL; @@ -244,7 +233,7 @@ struct dentry *nfs4_try_mount(int flags, const char *dev_name, export_path = data->nfs_server.export_path; data->nfs_server.export_path = "/"; - root_mnt = nfs_do_root_mount(&nfs4_remote_fs_type, + root_mnt = nfs_do_root_mount( nfs4_create_server(mount_info, &nfs_v4), flags, mount_info, data->nfs_server.hostname); @@ -258,13 +247,6 @@ struct dentry *nfs4_try_mount(int flags, const char *dev_name, return res; } -static struct dentry * -nfs4_remote_referral_mount(struct file_system_type *fs_type, int flags, - const char *dev_name, void *raw_data) -{ - return nfs_fs_mount_common(flags, dev_name, raw_data, &nfs_v4); -} - /* * Create an NFS4 server record on referral traversal */ @@ -289,7 +271,7 @@ static struct dentry *nfs4_referral_mount(struct file_system_type *fs_type, export_path = data->mnt_path; data->mnt_path = "/"; - root_mnt = nfs_do_root_mount(&nfs4_remote_referral_fs_type, + root_mnt = nfs_do_root_mount( nfs4_create_referral_server(mount_info.cloned, mount_info.mntfh), flags, &mount_info, data->hostname); From patchwork Thu May 23 16:16:34 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Howells X-Patchwork-Id: 10958271 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id C3D111708 for ; Thu, 23 May 2019 16:16:42 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id B0D5E28161 for ; Thu, 23 May 2019 16:16:42 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id A4B9D283E8; Thu, 23 May 2019 16:16:42 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-7.9 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI, RCVD_IN_DNSWL_HI autolearn=unavailable version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 5700528451 for ; Thu, 23 May 2019 16:16:42 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1731200AbfEWQQh (ORCPT ); Thu, 23 May 2019 12:16:37 -0400 Received: from mx1.redhat.com ([209.132.183.28]:44304 "EHLO mx1.redhat.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1730899AbfEWQQh (ORCPT ); Thu, 23 May 2019 12:16:37 -0400 Received: from smtp.corp.redhat.com (int-mx05.intmail.prod.int.phx2.redhat.com [10.5.11.15]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 05CFB21BA4; Thu, 23 May 2019 16:16:37 +0000 (UTC) Received: from warthog.procyon.org.uk (ovpn-121-142.rdu2.redhat.com [10.10.121.142]) by smtp.corp.redhat.com (Postfix) with ESMTP id 950865B687; Thu, 23 May 2019 16:16:35 +0000 (UTC) Organization: Red Hat UK Ltd. Registered Address: Red Hat UK Ltd, Amberley Place, 107-111 Peascod Street, Windsor, Berkshire, SI4 1TE, United Kingdom. Registered in England and Wales under Company Registration No. 3798903 Subject: [PATCH 05/23] nfs: don't bother setting/restoring export_path around do_nfs_root_mount() From: David Howells To: trond.myklebust@hammerspace.com, anna.schumaker@netapp.com Cc: Al Viro , dhowells@redhat.com, viro@zeniv.linux.org.uk, linux-nfs@vger.kernel.org, linux-fsdevel@vger.kernel.org, linux-kernel@vger.kernel.org Date: Thu, 23 May 2019 17:16:34 +0100 Message-ID: <155862819482.26654.4715821294011084919.stgit@warthog.procyon.org.uk> In-Reply-To: <155862813755.26654.563679411147031501.stgit@warthog.procyon.org.uk> References: <155862813755.26654.563679411147031501.stgit@warthog.procyon.org.uk> User-Agent: StGit/unknown-version MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.15 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.30]); Thu, 23 May 2019 16:16:37 +0000 (UTC) Sender: linux-fsdevel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-fsdevel@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP From: Al Viro nothing in it will be looking at that thing anyway Reviewed-by: David Howells Signed-off-by: Al Viro --- fs/nfs/nfs4super.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/fs/nfs/nfs4super.c b/fs/nfs/nfs4super.c index 5d02925e3567..d498aa5acab0 100644 --- a/fs/nfs/nfs4super.c +++ b/fs/nfs/nfs4super.c @@ -232,12 +232,10 @@ struct dentry *nfs4_try_mount(int flags, const char *dev_name, dfprintk(MOUNT, "--> nfs4_try_mount()\n"); export_path = data->nfs_server.export_path; - data->nfs_server.export_path = "/"; root_mnt = nfs_do_root_mount( nfs4_create_server(mount_info, &nfs_v4), flags, mount_info, data->nfs_server.hostname); - data->nfs_server.export_path = export_path; res = nfs_follow_remote_path(root_mnt, export_path); @@ -270,12 +268,10 @@ static struct dentry *nfs4_referral_mount(struct file_system_type *fs_type, return ERR_PTR(-ENOMEM); export_path = data->mnt_path; - data->mnt_path = "/"; root_mnt = nfs_do_root_mount( nfs4_create_referral_server(mount_info.cloned, mount_info.mntfh), flags, &mount_info, data->hostname); - data->mnt_path = export_path; res = nfs_follow_remote_path(root_mnt, export_path); dprintk("<-- nfs4_referral_mount() = %d%s\n", From patchwork Thu May 23 16:16:42 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Howells X-Patchwork-Id: 10958273 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id BAFBB13AD for ; Thu, 23 May 2019 16:16:54 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id A3A1927F86 for ; Thu, 23 May 2019 16:16:54 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 97F1528451; Thu, 23 May 2019 16:16:54 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-7.9 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI, RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 74DCA27F86 for ; Thu, 23 May 2019 16:16:53 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1731353AbfEWQQs (ORCPT ); Thu, 23 May 2019 12:16:48 -0400 Received: from mx1.redhat.com ([209.132.183.28]:50525 "EHLO mx1.redhat.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1730899AbfEWQQs (ORCPT ); Thu, 23 May 2019 12:16:48 -0400 Received: from smtp.corp.redhat.com (int-mx07.intmail.prod.int.phx2.redhat.com [10.5.11.22]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 92152821F3; Thu, 23 May 2019 16:16:47 +0000 (UTC) Received: from warthog.procyon.org.uk (ovpn-121-142.rdu2.redhat.com [10.10.121.142]) by smtp.corp.redhat.com (Postfix) with ESMTP id 0338410027C7; Thu, 23 May 2019 16:16:45 +0000 (UTC) Organization: Red Hat UK Ltd. Registered Address: Red Hat UK Ltd, Amberley Place, 107-111 Peascod Street, Windsor, Berkshire, SI4 1TE, United Kingdom. Registered in England and Wales under Company Registration No. 3798903 Subject: [PATCH 06/23] nfs4: fold nfs_do_root_mount/nfs_follow_remote_path From: David Howells To: trond.myklebust@hammerspace.com, anna.schumaker@netapp.com Cc: Al Viro , dhowells@redhat.com, viro@zeniv.linux.org.uk, linux-nfs@vger.kernel.org, linux-fsdevel@vger.kernel.org, linux-kernel@vger.kernel.org Date: Thu, 23 May 2019 17:16:42 +0100 Message-ID: <155862820218.26654.5552330864350722718.stgit@warthog.procyon.org.uk> In-Reply-To: <155862813755.26654.563679411147031501.stgit@warthog.procyon.org.uk> References: <155862813755.26654.563679411147031501.stgit@warthog.procyon.org.uk> User-Agent: StGit/unknown-version MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.84 on 10.5.11.22 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.28]); Thu, 23 May 2019 16:16:47 +0000 (UTC) Sender: linux-fsdevel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-fsdevel@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP From: Al Viro Reviewed-by: David Howells Signed-off-by: Al Viro --- fs/nfs/nfs4super.c | 88 ++++++++++++++++++++++------------------------------ 1 file changed, 37 insertions(+), 51 deletions(-) diff --git a/fs/nfs/nfs4super.c b/fs/nfs/nfs4super.c index d498aa5acab0..1710df8240fb 100644 --- a/fs/nfs/nfs4super.c +++ b/fs/nfs/nfs4super.c @@ -100,37 +100,6 @@ nfs4_remote_mount(struct file_system_type *fs_type, int flags, return nfs_fs_mount_common(flags, dev_name, info, &nfs_v4); } -static struct vfsmount *nfs_do_root_mount(struct nfs_server *server, int flags, - struct nfs_mount_info *info, - const char *hostname) -{ - struct vfsmount *root_mnt; - char *root_devname; - size_t len; - - if (IS_ERR(server)) - return ERR_CAST(server); - - len = strlen(hostname) + 5; - root_devname = kmalloc(len, GFP_KERNEL); - if (root_devname == NULL) { - nfs_free_server(server); - return ERR_PTR(-ENOMEM); - } - /* Does hostname needs to be enclosed in brackets? */ - if (strchr(hostname, ':')) - snprintf(root_devname, len, "[%s]:/", hostname); - else - snprintf(root_devname, len, "%s:/", hostname); - info->server = server; - root_mnt = vfs_kern_mount(&nfs4_remote_fs_type, flags, root_devname, info); - if (info->server) - nfs_free_server(info->server); - info->server = NULL; - kfree(root_devname); - return root_mnt; -} - struct nfs_referral_count { struct list_head list; const struct task_struct *task; @@ -197,11 +166,38 @@ static void nfs_referral_loop_unprotect(void) kfree(p); } -static struct dentry *nfs_follow_remote_path(struct vfsmount *root_mnt, - const char *export_path) +static struct dentry *do_nfs4_mount(struct nfs_server *server, int flags, + struct nfs_mount_info *info, + const char *hostname, + const char *export_path) { + struct vfsmount *root_mnt; struct dentry *dentry; + char *root_devname; int err; + size_t len; + + if (IS_ERR(server)) + return ERR_CAST(server); + + len = strlen(hostname) + 5; + root_devname = kmalloc(len, GFP_KERNEL); + if (root_devname == NULL) { + nfs_free_server(server); + return ERR_PTR(-ENOMEM); + } + + /* Does hostname needs to be enclosed in brackets? */ + if (strchr(hostname, ':')) + snprintf(root_devname, len, "[%s]:/", hostname); + else + snprintf(root_devname, len, "%s:/", hostname); + info->server = server; + root_mnt = vfs_kern_mount(&nfs4_remote_fs_type, flags, root_devname, info); + if (info->server) + nfs_free_server(info->server); + info->server = NULL; + kfree(root_devname); if (IS_ERR(root_mnt)) return ERR_CAST(root_mnt); @@ -222,22 +218,17 @@ struct dentry *nfs4_try_mount(int flags, const char *dev_name, struct nfs_mount_info *mount_info, struct nfs_subversion *nfs_mod) { - char *export_path; - struct vfsmount *root_mnt; - struct dentry *res; struct nfs_parsed_mount_data *data = mount_info->parsed; + struct dentry *res; mount_info->set_security = nfs_set_sb_security; dfprintk(MOUNT, "--> nfs4_try_mount()\n"); - export_path = data->nfs_server.export_path; - root_mnt = nfs_do_root_mount( - nfs4_create_server(mount_info, &nfs_v4), - flags, mount_info, - data->nfs_server.hostname); - - res = nfs_follow_remote_path(root_mnt, export_path); + res = do_nfs4_mount(nfs4_create_server(mount_info, &nfs_v4), + flags, mount_info, + data->nfs_server.hostname, + data->nfs_server.export_path); dfprintk(MOUNT, "<-- nfs4_try_mount() = %d%s\n", PTR_ERR_OR_ZERO(res), @@ -257,8 +248,6 @@ static struct dentry *nfs4_referral_mount(struct file_system_type *fs_type, .set_security = nfs_clone_sb_security, .cloned = data, }; - char *export_path; - struct vfsmount *root_mnt; struct dentry *res; dprintk("--> nfs4_referral_mount()\n"); @@ -267,13 +256,10 @@ static struct dentry *nfs4_referral_mount(struct file_system_type *fs_type, if (!mount_info.mntfh) return ERR_PTR(-ENOMEM); - export_path = data->mnt_path; - root_mnt = nfs_do_root_mount( - nfs4_create_referral_server(mount_info.cloned, - mount_info.mntfh), - flags, &mount_info, data->hostname); + res = do_nfs4_mount(nfs4_create_referral_server(mount_info.cloned, + mount_info.mntfh), + flags, &mount_info, data->hostname, data->mnt_path); - res = nfs_follow_remote_path(root_mnt, export_path); dprintk("<-- nfs4_referral_mount() = %d%s\n", PTR_ERR_OR_ZERO(res), IS_ERR(res) ? " [error]" : ""); From patchwork Thu May 23 16:16:52 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Howells X-Patchwork-Id: 10958279 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 3ADEC13AD for ; Thu, 23 May 2019 16:17:04 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 27FD528161 for ; Thu, 23 May 2019 16:17:04 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 1B72628653; Thu, 23 May 2019 16:17:04 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-7.9 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI, RCVD_IN_DNSWL_HI autolearn=unavailable version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 99C5A28671 for ; Thu, 23 May 2019 16:17:03 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1731369AbfEWQQ6 (ORCPT ); Thu, 23 May 2019 12:16:58 -0400 Received: from mx1.redhat.com ([209.132.183.28]:44456 "EHLO mx1.redhat.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1730899AbfEWQQ6 (ORCPT ); Thu, 23 May 2019 12:16:58 -0400 Received: from smtp.corp.redhat.com (int-mx04.intmail.prod.int.phx2.redhat.com [10.5.11.14]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 6E588128B5; Thu, 23 May 2019 16:16:57 +0000 (UTC) Received: from warthog.procyon.org.uk (ovpn-121-142.rdu2.redhat.com [10.10.121.142]) by smtp.corp.redhat.com (Postfix) with ESMTP id 9164668369; Thu, 23 May 2019 16:16:53 +0000 (UTC) Organization: Red Hat UK Ltd. Registered Address: Red Hat UK Ltd, Amberley Place, 107-111 Peascod Street, Windsor, Berkshire, SI4 1TE, United Kingdom. Registered in England and Wales under Company Registration No. 3798903 Subject: [PATCH 07/23] nfs: lift setting mount_info from nfs_xdev_mount() From: David Howells To: trond.myklebust@hammerspace.com, anna.schumaker@netapp.com Cc: Al Viro , dhowells@redhat.com, viro@zeniv.linux.org.uk, linux-nfs@vger.kernel.org, linux-fsdevel@vger.kernel.org, linux-kernel@vger.kernel.org Date: Thu, 23 May 2019 17:16:52 +0100 Message-ID: <155862821282.26654.17943634417357032949.stgit@warthog.procyon.org.uk> In-Reply-To: <155862813755.26654.563679411147031501.stgit@warthog.procyon.org.uk> References: <155862813755.26654.563679411147031501.stgit@warthog.procyon.org.uk> User-Agent: StGit/unknown-version MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.14 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.30]); Thu, 23 May 2019 16:16:57 +0000 (UTC) Sender: linux-fsdevel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-fsdevel@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP From: Al Viro Do it in nfs_do_submount() instead. As a side benefit, nfs_clone_data doesn't need ->fh and ->fattr anymore. Reviewed-by: David Howells Signed-off-by: Al Viro --- fs/nfs/internal.h | 3 +-- fs/nfs/namespace.c | 35 +++++++++++++++++++++-------------- fs/nfs/super.c | 25 ++++--------------------- 3 files changed, 26 insertions(+), 37 deletions(-) diff --git a/fs/nfs/internal.h b/fs/nfs/internal.h index ce00e61b9b2a..496a0e03f2b2 100644 --- a/fs/nfs/internal.h +++ b/fs/nfs/internal.h @@ -42,8 +42,6 @@ static inline int nfs_attr_use_mounted_on_fileid(struct nfs_fattr *fattr) struct nfs_clone_mount { const struct super_block *sb; const struct dentry *dentry; - struct nfs_fh *fh; - struct nfs_fattr *fattr; char *hostname; char *mnt_path; struct sockaddr *addr; @@ -412,6 +410,7 @@ struct dentry * nfs_xdev_mount_common(struct file_system_type *, int, const char *, struct nfs_mount_info *); void nfs_kill_super(struct super_block *); void nfs_fill_super(struct super_block *, struct nfs_mount_info *); +void nfs_clone_super(struct super_block *, struct nfs_mount_info *); extern struct rpc_stat nfs_rpcstat; diff --git a/fs/nfs/namespace.c b/fs/nfs/namespace.c index 15f099a24c29..9622575682da 100644 --- a/fs/nfs/namespace.c +++ b/fs/nfs/namespace.c @@ -18,6 +18,7 @@ #include #include #include "internal.h" +#include "nfs.h" #define NFSDBG_FACILITY NFSDBG_VFS @@ -209,16 +210,6 @@ void nfs_release_automount_timer(void) cancel_delayed_work(&nfs_automount_task); } -/* - * Clone a mountpoint of the appropriate type - */ -static struct vfsmount *nfs_do_clone_mount(struct nfs_server *server, - const char *devname, - struct nfs_clone_mount *mountdata) -{ - return vfs_submount(mountdata->dentry, &nfs_xdev_fs_type, devname, mountdata); -} - /** * nfs_do_submount - set up mountpoint when crossing a filesystem boundary * @dentry: parent directory @@ -230,13 +221,20 @@ static struct vfsmount *nfs_do_clone_mount(struct nfs_server *server, struct vfsmount *nfs_do_submount(struct dentry *dentry, struct nfs_fh *fh, struct nfs_fattr *fattr, rpc_authflavor_t authflavor) { + struct super_block *sb = dentry->d_sb; struct nfs_clone_mount mountdata = { - .sb = dentry->d_sb, + .sb = sb, .dentry = dentry, - .fh = fh, - .fattr = fattr, .authflavor = authflavor, }; + struct nfs_mount_info mount_info = { + .fill_super = nfs_clone_super, + .set_security = nfs_clone_sb_security, + .cloned = &mountdata, + .mntfh = fh, + }; + struct nfs_subversion *nfs_mod = NFS_SB(sb)->nfs_client->cl_nfs_mod; + struct nfs_server *server; struct vfsmount *mnt; char *page = (char *) __get_free_page(GFP_USER); char *devname; @@ -244,12 +242,21 @@ struct vfsmount *nfs_do_submount(struct dentry *dentry, struct nfs_fh *fh, if (page == NULL) return ERR_PTR(-ENOMEM); + server = nfs_mod->rpc_ops->clone_server(NFS_SB(sb), fh, + fattr, authflavor); + if (IS_ERR(server)) + return ERR_CAST(server); + + mount_info.server = server; + devname = nfs_devname(dentry, page, PAGE_SIZE); if (IS_ERR(devname)) mnt = ERR_CAST(devname); else - mnt = nfs_do_clone_mount(NFS_SB(dentry->d_sb), devname, &mountdata); + mnt = vfs_submount(dentry, &nfs_xdev_fs_type, devname, &mount_info); + if (mount_info.server) + nfs_free_server(mount_info.server); free_page((unsigned long)page); return mnt; } diff --git a/fs/nfs/super.c b/fs/nfs/super.c index 485604fa2ae3..f0a8f1da394b 100644 --- a/fs/nfs/super.c +++ b/fs/nfs/super.c @@ -2363,7 +2363,7 @@ EXPORT_SYMBOL_GPL(nfs_fill_super); /* * Finish setting up a cloned NFS2/3/4 superblock */ -static void nfs_clone_super(struct super_block *sb, +void nfs_clone_super(struct super_block *sb, struct nfs_mount_info *mount_info) { const struct super_block *old_sb = mount_info->cloned->sb; @@ -2748,27 +2748,10 @@ static struct dentry * nfs_xdev_mount(struct file_system_type *fs_type, int flags, const char *dev_name, void *raw_data) { - struct nfs_clone_mount *data = raw_data; - struct nfs_mount_info mount_info = { - .fill_super = nfs_clone_super, - .set_security = nfs_clone_sb_security, - .cloned = data, - }; - struct dentry *mntroot = ERR_PTR(-ENOMEM); - struct nfs_subversion *nfs_mod = NFS_SB(data->sb)->nfs_client->cl_nfs_mod; - - dprintk("--> nfs_xdev_mount()\n"); + struct nfs_mount_info *info = raw_data; + struct nfs_subversion *nfs_mod = NFS_SB(info->cloned->sb)->nfs_client->cl_nfs_mod; - mount_info.mntfh = mount_info.cloned->fh; - - /* create a new volume representation */ - mount_info.server = nfs_mod->rpc_ops->clone_server(NFS_SB(data->sb), data->fh, data->fattr, data->authflavor); - - mntroot = nfs_fs_mount_common(flags, dev_name, &mount_info, nfs_mod); - - dprintk("<-- nfs_xdev_mount() = %ld\n", - IS_ERR(mntroot) ? PTR_ERR(mntroot) : 0L); - return mntroot; + return nfs_fs_mount_common(flags, dev_name, info, nfs_mod); } #if IS_ENABLED(CONFIG_NFS_V4) From patchwork Thu May 23 16:17:02 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Howells X-Patchwork-Id: 10958283 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id B74951708 for ; Thu, 23 May 2019 16:17:11 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 1A09027F86 for ; Thu, 23 May 2019 16:17:11 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 0B57B28658; Thu, 23 May 2019 16:17:11 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-7.9 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI, RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 9FAD127F86 for ; Thu, 23 May 2019 16:17:10 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1731386AbfEWQRF (ORCPT ); Thu, 23 May 2019 12:17:05 -0400 Received: from mx1.redhat.com ([209.132.183.28]:24858 "EHLO mx1.redhat.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1730899AbfEWQRF (ORCPT ); Thu, 23 May 2019 12:17:05 -0400 Received: from smtp.corp.redhat.com (int-mx03.intmail.prod.int.phx2.redhat.com [10.5.11.13]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id DCCA181111; Thu, 23 May 2019 16:17:04 +0000 (UTC) Received: from warthog.procyon.org.uk (ovpn-121-142.rdu2.redhat.com [10.10.121.142]) by smtp.corp.redhat.com (Postfix) with ESMTP id 7415F17CFB; Thu, 23 May 2019 16:17:03 +0000 (UTC) Organization: Red Hat UK Ltd. Registered Address: Red Hat UK Ltd, Amberley Place, 107-111 Peascod Street, Windsor, Berkshire, SI4 1TE, United Kingdom. Registered in England and Wales under Company Registration No. 3798903 Subject: [PATCH 08/23] nfs: stash nfs_subversion reference into nfs_mount_info From: David Howells To: trond.myklebust@hammerspace.com, anna.schumaker@netapp.com Cc: Al Viro , dhowells@redhat.com, viro@zeniv.linux.org.uk, linux-nfs@vger.kernel.org, linux-fsdevel@vger.kernel.org, linux-kernel@vger.kernel.org Date: Thu, 23 May 2019 17:17:02 +0100 Message-ID: <155862822265.26654.2410384551874971260.stgit@warthog.procyon.org.uk> In-Reply-To: <155862813755.26654.563679411147031501.stgit@warthog.procyon.org.uk> References: <155862813755.26654.563679411147031501.stgit@warthog.procyon.org.uk> User-Agent: StGit/unknown-version MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.13 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.28]); Thu, 23 May 2019 16:17:04 +0000 (UTC) Sender: linux-fsdevel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-fsdevel@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP From: Al Viro That will allow to get rid of passing those references around in quite a few places. Moreover, that will allow to merge xdev and remote file_system_type. Reviewed-by: David Howells Signed-off-by: Al Viro --- fs/nfs/internal.h | 1 + fs/nfs/namespace.c | 6 +++--- fs/nfs/nfs4super.c | 1 + fs/nfs/super.c | 1 + 4 files changed, 6 insertions(+), 3 deletions(-) diff --git a/fs/nfs/internal.h b/fs/nfs/internal.h index 496a0e03f2b2..62af450bb91a 100644 --- a/fs/nfs/internal.h +++ b/fs/nfs/internal.h @@ -149,6 +149,7 @@ struct nfs_mount_info { struct nfs_clone_mount *cloned; struct nfs_server *server; struct nfs_fh *mntfh; + struct nfs_subversion *nfs_mod; }; extern int nfs_mount(struct nfs_mount_request *info); diff --git a/fs/nfs/namespace.c b/fs/nfs/namespace.c index 9622575682da..476f4c0d5542 100644 --- a/fs/nfs/namespace.c +++ b/fs/nfs/namespace.c @@ -232,8 +232,8 @@ struct vfsmount *nfs_do_submount(struct dentry *dentry, struct nfs_fh *fh, .set_security = nfs_clone_sb_security, .cloned = &mountdata, .mntfh = fh, + .nfs_mod = NFS_SB(sb)->nfs_client->cl_nfs_mod, }; - struct nfs_subversion *nfs_mod = NFS_SB(sb)->nfs_client->cl_nfs_mod; struct nfs_server *server; struct vfsmount *mnt; char *page = (char *) __get_free_page(GFP_USER); @@ -242,8 +242,8 @@ struct vfsmount *nfs_do_submount(struct dentry *dentry, struct nfs_fh *fh, if (page == NULL) return ERR_PTR(-ENOMEM); - server = nfs_mod->rpc_ops->clone_server(NFS_SB(sb), fh, - fattr, authflavor); + server = mount_info.nfs_mod->rpc_ops->clone_server(NFS_SB(sb), fh, + fattr, authflavor); if (IS_ERR(server)) return ERR_CAST(server); diff --git a/fs/nfs/nfs4super.c b/fs/nfs/nfs4super.c index 1710df8240fb..25253c235fba 100644 --- a/fs/nfs/nfs4super.c +++ b/fs/nfs/nfs4super.c @@ -247,6 +247,7 @@ static struct dentry *nfs4_referral_mount(struct file_system_type *fs_type, .fill_super = nfs_fill_super, .set_security = nfs_clone_sb_security, .cloned = data, + .nfs_mod = &nfs_v4, }; struct dentry *res; diff --git a/fs/nfs/super.c b/fs/nfs/super.c index f0a8f1da394b..c76b4fe73fab 100644 --- a/fs/nfs/super.c +++ b/fs/nfs/super.c @@ -2713,6 +2713,7 @@ struct dentry *nfs_fs_mount(struct file_system_type *fs_type, mntroot = ERR_CAST(nfs_mod); goto out; } + mount_info.nfs_mod = nfs_mod; mntroot = nfs_mod->rpc_ops->try_mount(flags, dev_name, &mount_info, nfs_mod); From patchwork Thu May 23 16:17:10 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Howells X-Patchwork-Id: 10958285 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id AA37113AD for ; Thu, 23 May 2019 16:17:15 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 954E328161 for ; Thu, 23 May 2019 16:17:15 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 8988F2865F; Thu, 23 May 2019 16:17:15 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-7.9 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI, RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 0113928161 for ; Thu, 23 May 2019 16:17:15 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1731414AbfEWQRO (ORCPT ); Thu, 23 May 2019 12:17:14 -0400 Received: from mx1.redhat.com ([209.132.183.28]:57662 "EHLO mx1.redhat.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1730899AbfEWQRN (ORCPT ); Thu, 23 May 2019 12:17:13 -0400 Received: from smtp.corp.redhat.com (int-mx08.intmail.prod.int.phx2.redhat.com [10.5.11.23]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 65A4CAC2E5; Thu, 23 May 2019 16:17:13 +0000 (UTC) Received: from warthog.procyon.org.uk (ovpn-121-142.rdu2.redhat.com [10.10.121.142]) by smtp.corp.redhat.com (Postfix) with ESMTP id DC72359474; Thu, 23 May 2019 16:17:10 +0000 (UTC) Organization: Red Hat UK Ltd. Registered Address: Red Hat UK Ltd, Amberley Place, 107-111 Peascod Street, Windsor, Berkshire, SI4 1TE, United Kingdom. Registered in England and Wales under Company Registration No. 3798903 Subject: [PATCH 09/23] nfs: don't bother passing nfs_subversion to ->try_mount() and nfs_fs_mount_common() From: David Howells To: trond.myklebust@hammerspace.com, anna.schumaker@netapp.com Cc: Al Viro , dhowells@redhat.com, viro@zeniv.linux.org.uk, linux-nfs@vger.kernel.org, linux-fsdevel@vger.kernel.org, linux-kernel@vger.kernel.org Date: Thu, 23 May 2019 17:17:10 +0100 Message-ID: <155862823013.26654.3191093337797115762.stgit@warthog.procyon.org.uk> In-Reply-To: <155862813755.26654.563679411147031501.stgit@warthog.procyon.org.uk> References: <155862813755.26654.563679411147031501.stgit@warthog.procyon.org.uk> User-Agent: StGit/unknown-version MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.84 on 10.5.11.23 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.38]); Thu, 23 May 2019 16:17:13 +0000 (UTC) Sender: linux-fsdevel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-fsdevel@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP From: Al Viro Reviewed-by: David Howells Signed-off-by: Al Viro --- fs/nfs/internal.h | 6 ++---- fs/nfs/nfs4_fs.h | 2 +- fs/nfs/nfs4super.c | 5 ++--- fs/nfs/super.c | 19 ++++++++----------- include/linux/nfs_xdr.h | 3 +-- 5 files changed, 14 insertions(+), 21 deletions(-) diff --git a/fs/nfs/internal.h b/fs/nfs/internal.h index 62af450bb91a..47ed7e4b4171 100644 --- a/fs/nfs/internal.h +++ b/fs/nfs/internal.h @@ -400,12 +400,10 @@ extern struct file_system_type nfs_xdev_fs_type; extern struct file_system_type nfs4_referral_fs_type; #endif bool nfs_auth_info_match(const struct nfs_auth_info *, rpc_authflavor_t); -struct dentry *nfs_try_mount(int, const char *, struct nfs_mount_info *, - struct nfs_subversion *); +struct dentry *nfs_try_mount(int, const char *, struct nfs_mount_info *); int nfs_set_sb_security(struct super_block *, struct dentry *, struct nfs_mount_info *); int nfs_clone_sb_security(struct super_block *, struct dentry *, struct nfs_mount_info *); -struct dentry *nfs_fs_mount_common(int, const char *, - struct nfs_mount_info *, struct nfs_subversion *); +struct dentry *nfs_fs_mount_common(int, const char *, struct nfs_mount_info *); struct dentry *nfs_fs_mount(struct file_system_type *, int, const char *, void *); struct dentry * nfs_xdev_mount_common(struct file_system_type *, int, const char *, struct nfs_mount_info *); diff --git a/fs/nfs/nfs4_fs.h b/fs/nfs/nfs4_fs.h index 8a38a254f516..0bd8a5fc140b 100644 --- a/fs/nfs/nfs4_fs.h +++ b/fs/nfs/nfs4_fs.h @@ -516,7 +516,7 @@ extern const nfs4_stateid invalid_stateid; /* nfs4super.c */ struct nfs_mount_info; extern struct nfs_subversion nfs_v4; -struct dentry *nfs4_try_mount(int, const char *, struct nfs_mount_info *, struct nfs_subversion *); +struct dentry *nfs4_try_mount(int, const char *, struct nfs_mount_info *); extern bool nfs4_disable_idmapping; extern unsigned short max_session_slots; extern unsigned short max_session_cb_slots; diff --git a/fs/nfs/nfs4super.c b/fs/nfs/nfs4super.c index 25253c235fba..4a57fe53cf32 100644 --- a/fs/nfs/nfs4super.c +++ b/fs/nfs/nfs4super.c @@ -97,7 +97,7 @@ static struct dentry * nfs4_remote_mount(struct file_system_type *fs_type, int flags, const char *dev_name, void *info) { - return nfs_fs_mount_common(flags, dev_name, info, &nfs_v4); + return nfs_fs_mount_common(flags, dev_name, info); } struct nfs_referral_count { @@ -215,8 +215,7 @@ static struct dentry *do_nfs4_mount(struct nfs_server *server, int flags, } struct dentry *nfs4_try_mount(int flags, const char *dev_name, - struct nfs_mount_info *mount_info, - struct nfs_subversion *nfs_mod) + struct nfs_mount_info *mount_info) { struct nfs_parsed_mount_data *data = mount_info->parsed; struct dentry *res; diff --git a/fs/nfs/super.c b/fs/nfs/super.c index c76b4fe73fab..a713b70bfec4 100644 --- a/fs/nfs/super.c +++ b/fs/nfs/super.c @@ -1871,15 +1871,15 @@ static struct nfs_server *nfs_try_mount_request(struct nfs_mount_info *mount_inf } struct dentry *nfs_try_mount(int flags, const char *dev_name, - struct nfs_mount_info *mount_info, - struct nfs_subversion *nfs_mod) + struct nfs_mount_info *mount_info) { + struct nfs_subversion *nfs_mod = mount_info->nfs_mod; if (mount_info->parsed->need_mount) mount_info->server = nfs_try_mount_request(mount_info, nfs_mod); else mount_info->server = nfs_mod->rpc_ops->create_server(mount_info, nfs_mod); - return nfs_fs_mount_common(flags, dev_name, mount_info, nfs_mod); + return nfs_fs_mount_common(flags, dev_name, mount_info); } EXPORT_SYMBOL_GPL(nfs_try_mount); @@ -2600,8 +2600,7 @@ int nfs_clone_sb_security(struct super_block *s, struct dentry *mntroot, EXPORT_SYMBOL_GPL(nfs_clone_sb_security); struct dentry *nfs_fs_mount_common(int flags, const char *dev_name, - struct nfs_mount_info *mount_info, - struct nfs_subversion *nfs_mod) + struct nfs_mount_info *mount_info) { struct super_block *s; struct dentry *mntroot = ERR_PTR(-ENOMEM); @@ -2629,7 +2628,8 @@ struct dentry *nfs_fs_mount_common(int flags, const char *dev_name, sb_mntdata.mntflags |= SB_SYNCHRONOUS; /* Get a superblock - note that we may end up sharing one that already exists */ - s = sget(nfs_mod->nfs_fs, compare_super, nfs_set_super, flags, &sb_mntdata); + s = sget(mount_info->nfs_mod->nfs_fs, compare_super, nfs_set_super, + flags, &sb_mntdata); if (IS_ERR(s)) { mntroot = ERR_CAST(s); goto out_err_nosb; @@ -2715,7 +2715,7 @@ struct dentry *nfs_fs_mount(struct file_system_type *fs_type, } mount_info.nfs_mod = nfs_mod; - mntroot = nfs_mod->rpc_ops->try_mount(flags, dev_name, &mount_info, nfs_mod); + mntroot = nfs_mod->rpc_ops->try_mount(flags, dev_name, &mount_info); put_nfs_version(nfs_mod); out: @@ -2749,10 +2749,7 @@ static struct dentry * nfs_xdev_mount(struct file_system_type *fs_type, int flags, const char *dev_name, void *raw_data) { - struct nfs_mount_info *info = raw_data; - struct nfs_subversion *nfs_mod = NFS_SB(info->cloned->sb)->nfs_client->cl_nfs_mod; - - return nfs_fs_mount_common(flags, dev_name, info, nfs_mod); + return nfs_fs_mount_common(flags, dev_name, raw_data); } #if IS_ENABLED(CONFIG_NFS_V4) diff --git a/include/linux/nfs_xdr.h b/include/linux/nfs_xdr.h index 9b8324ec08f3..4fdf4a523185 100644 --- a/include/linux/nfs_xdr.h +++ b/include/linux/nfs_xdr.h @@ -1638,8 +1638,7 @@ struct nfs_rpc_ops { struct nfs_fsinfo *); struct vfsmount *(*submount) (struct nfs_server *, struct dentry *, struct nfs_fh *, struct nfs_fattr *); - struct dentry *(*try_mount) (int, const char *, struct nfs_mount_info *, - struct nfs_subversion *); + struct dentry *(*try_mount) (int, const char *, struct nfs_mount_info *); int (*getattr) (struct nfs_server *, struct nfs_fh *, struct nfs_fattr *, struct nfs4_label *, struct inode *); From patchwork Thu May 23 16:17:18 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Howells X-Patchwork-Id: 10958291 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id D114C13AD for ; Thu, 23 May 2019 16:17:27 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id BCF7627F86 for ; Thu, 23 May 2019 16:17:27 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id B154328451; Thu, 23 May 2019 16:17:27 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-7.9 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI, RCVD_IN_DNSWL_HI autolearn=unavailable version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 3C1A127F86 for ; Thu, 23 May 2019 16:17:27 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1731240AbfEWQRW (ORCPT ); Thu, 23 May 2019 12:17:22 -0400 Received: from mx1.redhat.com ([209.132.183.28]:56582 "EHLO mx1.redhat.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1730899AbfEWQRV (ORCPT ); Thu, 23 May 2019 12:17:21 -0400 Received: from smtp.corp.redhat.com (int-mx02.intmail.prod.int.phx2.redhat.com [10.5.11.12]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 30448916C0; Thu, 23 May 2019 16:17:21 +0000 (UTC) Received: from warthog.procyon.org.uk (ovpn-121-142.rdu2.redhat.com [10.10.121.142]) by smtp.corp.redhat.com (Postfix) with ESMTP id 6EFAA62516; Thu, 23 May 2019 16:17:19 +0000 (UTC) Organization: Red Hat UK Ltd. Registered Address: Red Hat UK Ltd, Amberley Place, 107-111 Peascod Street, Windsor, Berkshire, SI4 1TE, United Kingdom. Registered in England and Wales under Company Registration No. 3798903 Subject: [PATCH 10/23] nfs: merge xdev and remote file_system_type From: David Howells To: trond.myklebust@hammerspace.com, anna.schumaker@netapp.com Cc: Al Viro , dhowells@redhat.com, viro@zeniv.linux.org.uk, linux-nfs@vger.kernel.org, linux-fsdevel@vger.kernel.org, linux-kernel@vger.kernel.org Date: Thu, 23 May 2019 17:17:18 +0100 Message-ID: <155862823863.26654.16960229891755463792.stgit@warthog.procyon.org.uk> In-Reply-To: <155862813755.26654.563679411147031501.stgit@warthog.procyon.org.uk> References: <155862813755.26654.563679411147031501.stgit@warthog.procyon.org.uk> User-Agent: StGit/unknown-version MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.12 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.29]); Thu, 23 May 2019 16:17:21 +0000 (UTC) Sender: linux-fsdevel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-fsdevel@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP From: Al Viro they are identical now... Reviewed-by: David Howells Signed-off-by: Al Viro --- fs/nfs/internal.h | 2 +- fs/nfs/namespace.c | 2 +- fs/nfs/nfs4super.c | 22 +--------------------- fs/nfs/super.c | 14 ++++++++------ 4 files changed, 11 insertions(+), 29 deletions(-) diff --git a/fs/nfs/internal.h b/fs/nfs/internal.h index 47ed7e4b4171..3acf786fce57 100644 --- a/fs/nfs/internal.h +++ b/fs/nfs/internal.h @@ -395,7 +395,7 @@ extern int nfs_wait_atomic_killable(atomic_t *p, unsigned int mode); /* super.c */ extern const struct super_operations nfs_sops; extern struct file_system_type nfs_fs_type; -extern struct file_system_type nfs_xdev_fs_type; +extern struct file_system_type nfs_prepared_fs_type; #if IS_ENABLED(CONFIG_NFS_V4) extern struct file_system_type nfs4_referral_fs_type; #endif diff --git a/fs/nfs/namespace.c b/fs/nfs/namespace.c index 476f4c0d5542..7cda42ae000a 100644 --- a/fs/nfs/namespace.c +++ b/fs/nfs/namespace.c @@ -253,7 +253,7 @@ struct vfsmount *nfs_do_submount(struct dentry *dentry, struct nfs_fh *fh, if (IS_ERR(devname)) mnt = ERR_CAST(devname); else - mnt = vfs_submount(dentry, &nfs_xdev_fs_type, devname, &mount_info); + mnt = vfs_submount(dentry, &nfs_prepared_fs_type, devname, &mount_info); if (mount_info.server) nfs_free_server(mount_info.server); diff --git a/fs/nfs/nfs4super.c b/fs/nfs/nfs4super.c index 4a57fe53cf32..32b602e87bb5 100644 --- a/fs/nfs/nfs4super.c +++ b/fs/nfs/nfs4super.c @@ -17,19 +17,9 @@ static int nfs4_write_inode(struct inode *inode, struct writeback_control *wbc); static void nfs4_evict_inode(struct inode *inode); -static struct dentry *nfs4_remote_mount(struct file_system_type *fs_type, - int flags, const char *dev_name, void *raw_data); static struct dentry *nfs4_referral_mount(struct file_system_type *fs_type, int flags, const char *dev_name, void *raw_data); -static struct file_system_type nfs4_remote_fs_type = { - .owner = THIS_MODULE, - .name = "nfs4", - .mount = nfs4_remote_mount, - .kill_sb = nfs_kill_super, - .fs_flags = FS_RENAME_DOES_D_MOVE|FS_BINARY_MOUNTDATA, -}; - struct file_system_type nfs4_referral_fs_type = { .owner = THIS_MODULE, .name = "nfs4", @@ -90,16 +80,6 @@ static void nfs4_evict_inode(struct inode *inode) nfs_clear_inode(inode); } -/* - * Get the superblock for the NFS4 root partition - */ -static struct dentry * -nfs4_remote_mount(struct file_system_type *fs_type, int flags, - const char *dev_name, void *info) -{ - return nfs_fs_mount_common(flags, dev_name, info); -} - struct nfs_referral_count { struct list_head list; const struct task_struct *task; @@ -193,7 +173,7 @@ static struct dentry *do_nfs4_mount(struct nfs_server *server, int flags, else snprintf(root_devname, len, "%s:/", hostname); info->server = server; - root_mnt = vfs_kern_mount(&nfs4_remote_fs_type, flags, root_devname, info); + root_mnt = vfs_kern_mount(&nfs_prepared_fs_type, flags, root_devname, info); if (info->server) nfs_free_server(info->server); info->server = NULL; diff --git a/fs/nfs/super.c b/fs/nfs/super.c index a713b70bfec4..e189d640fb4f 100644 --- a/fs/nfs/super.c +++ b/fs/nfs/super.c @@ -287,7 +287,7 @@ static match_table_t nfs_vers_tokens = { { Opt_vers_err, NULL } }; -static struct dentry *nfs_xdev_mount(struct file_system_type *fs_type, +static struct dentry *nfs_prepared_mount(struct file_system_type *fs_type, int flags, const char *dev_name, void *raw_data); struct file_system_type nfs_fs_type = { @@ -300,13 +300,14 @@ struct file_system_type nfs_fs_type = { MODULE_ALIAS_FS("nfs"); EXPORT_SYMBOL_GPL(nfs_fs_type); -struct file_system_type nfs_xdev_fs_type = { +struct file_system_type nfs_prepared_fs_type = { .owner = THIS_MODULE, .name = "nfs", - .mount = nfs_xdev_mount, + .mount = nfs_prepared_mount, .kill_sb = nfs_kill_super, .fs_flags = FS_RENAME_DOES_D_MOVE|FS_BINARY_MOUNTDATA, }; +EXPORT_SYMBOL_GPL(nfs_prepared_fs_type); const struct super_operations nfs_sops = { .alloc_inode = nfs_alloc_inode, @@ -2743,11 +2744,12 @@ void nfs_kill_super(struct super_block *s) EXPORT_SYMBOL_GPL(nfs_kill_super); /* - * Clone an NFS2/3/4 server record on xdev traversal (FSID-change) + * Internal use only: mount_info is already set up by caller. + * Used for mountpoint crossings and for nfs4 root. */ static struct dentry * -nfs_xdev_mount(struct file_system_type *fs_type, int flags, - const char *dev_name, void *raw_data) +nfs_prepared_mount(struct file_system_type *fs_type, int flags, + const char *dev_name, void *raw_data) { return nfs_fs_mount_common(flags, dev_name, raw_data); } From patchwork Thu May 23 16:17:26 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Howells X-Patchwork-Id: 10958293 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 780E113AD for ; Thu, 23 May 2019 16:17:34 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 621011FFD9 for ; Thu, 23 May 2019 16:17:34 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 56C1828161; Thu, 23 May 2019 16:17:34 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-7.9 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI, RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id F17411FFD9 for ; Thu, 23 May 2019 16:17:33 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1731276AbfEWQRd (ORCPT ); Thu, 23 May 2019 12:17:33 -0400 Received: from mx1.redhat.com ([209.132.183.28]:37898 "EHLO mx1.redhat.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1730899AbfEWQRd (ORCPT ); Thu, 23 May 2019 12:17:33 -0400 Received: from smtp.corp.redhat.com (int-mx04.intmail.prod.int.phx2.redhat.com [10.5.11.14]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 890DD301E12F; Thu, 23 May 2019 16:17:32 +0000 (UTC) Received: from warthog.procyon.org.uk (ovpn-121-142.rdu2.redhat.com [10.10.121.142]) by smtp.corp.redhat.com (Postfix) with ESMTP id 470CF6836B; Thu, 23 May 2019 16:17:30 +0000 (UTC) Organization: Red Hat UK Ltd. Registered Address: Red Hat UK Ltd, Amberley Place, 107-111 Peascod Street, Windsor, Berkshire, SI4 1TE, United Kingdom. Registered in England and Wales under Company Registration No. 3798903 Subject: [PATCH 11/23] nfs: unexport nfs_fs_mount_common() From: David Howells To: trond.myklebust@hammerspace.com, anna.schumaker@netapp.com Cc: Al Viro , dhowells@redhat.com, viro@zeniv.linux.org.uk, linux-nfs@vger.kernel.org, linux-fsdevel@vger.kernel.org, linux-kernel@vger.kernel.org Date: Thu, 23 May 2019 17:17:26 +0100 Message-ID: <155862824640.26654.1917259249271782777.stgit@warthog.procyon.org.uk> In-Reply-To: <155862813755.26654.563679411147031501.stgit@warthog.procyon.org.uk> References: <155862813755.26654.563679411147031501.stgit@warthog.procyon.org.uk> User-Agent: StGit/unknown-version MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.14 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.41]); Thu, 23 May 2019 16:17:32 +0000 (UTC) Sender: linux-fsdevel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-fsdevel@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP From: Al Viro Make it static, even. And remove a stale extern of (long-gone) nfs_xdev_mount_common() from internal.h, while we are at it. Reviewed-by: David Howells Signed-off-by: Al Viro --- fs/nfs/internal.h | 3 --- fs/nfs/super.c | 5 +++-- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/fs/nfs/internal.h b/fs/nfs/internal.h index 3acf786fce57..88f4af7c6924 100644 --- a/fs/nfs/internal.h +++ b/fs/nfs/internal.h @@ -403,10 +403,7 @@ bool nfs_auth_info_match(const struct nfs_auth_info *, rpc_authflavor_t); struct dentry *nfs_try_mount(int, const char *, struct nfs_mount_info *); int nfs_set_sb_security(struct super_block *, struct dentry *, struct nfs_mount_info *); int nfs_clone_sb_security(struct super_block *, struct dentry *, struct nfs_mount_info *); -struct dentry *nfs_fs_mount_common(int, const char *, struct nfs_mount_info *); struct dentry *nfs_fs_mount(struct file_system_type *, int, const char *, void *); -struct dentry * nfs_xdev_mount_common(struct file_system_type *, int, - const char *, struct nfs_mount_info *); void nfs_kill_super(struct super_block *); void nfs_fill_super(struct super_block *, struct nfs_mount_info *); void nfs_clone_super(struct super_block *, struct nfs_mount_info *); diff --git a/fs/nfs/super.c b/fs/nfs/super.c index e189d640fb4f..6da484eb7b6a 100644 --- a/fs/nfs/super.c +++ b/fs/nfs/super.c @@ -1871,6 +1871,8 @@ static struct nfs_server *nfs_try_mount_request(struct nfs_mount_info *mount_inf return nfs_mod->rpc_ops->create_server(mount_info, nfs_mod); } +static struct dentry *nfs_fs_mount_common(int, const char *, struct nfs_mount_info *); + struct dentry *nfs_try_mount(int flags, const char *dev_name, struct nfs_mount_info *mount_info) { @@ -2600,7 +2602,7 @@ int nfs_clone_sb_security(struct super_block *s, struct dentry *mntroot, } EXPORT_SYMBOL_GPL(nfs_clone_sb_security); -struct dentry *nfs_fs_mount_common(int flags, const char *dev_name, +static struct dentry *nfs_fs_mount_common(int flags, const char *dev_name, struct nfs_mount_info *mount_info) { struct super_block *s; @@ -2682,7 +2684,6 @@ struct dentry *nfs_fs_mount_common(int flags, const char *dev_name, deactivate_locked_super(s); goto out; } -EXPORT_SYMBOL_GPL(nfs_fs_mount_common); struct dentry *nfs_fs_mount(struct file_system_type *fs_type, int flags, const char *dev_name, void *raw_data) From patchwork Thu May 23 16:17:37 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Howells X-Patchwork-Id: 10958299 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id C214213AD for ; Thu, 23 May 2019 16:17:46 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id ADCDE28671 for ; Thu, 23 May 2019 16:17:46 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id A21A028161; Thu, 23 May 2019 16:17:46 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-7.9 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI, RCVD_IN_DNSWL_HI autolearn=unavailable version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 125AA27D4A for ; Thu, 23 May 2019 16:17:46 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1731141AbfEWQRk (ORCPT ); Thu, 23 May 2019 12:17:40 -0400 Received: from mx1.redhat.com ([209.132.183.28]:34220 "EHLO mx1.redhat.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1730899AbfEWQRk (ORCPT ); Thu, 23 May 2019 12:17:40 -0400 Received: from smtp.corp.redhat.com (int-mx07.intmail.prod.int.phx2.redhat.com [10.5.11.22]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id D5F405946F; Thu, 23 May 2019 16:17:39 +0000 (UTC) Received: from warthog.procyon.org.uk (ovpn-121-142.rdu2.redhat.com [10.10.121.142]) by smtp.corp.redhat.com (Postfix) with ESMTP id 75160101E664; Thu, 23 May 2019 16:17:38 +0000 (UTC) Organization: Red Hat UK Ltd. Registered Address: Red Hat UK Ltd, Amberley Place, 107-111 Peascod Street, Windsor, Berkshire, SI4 1TE, United Kingdom. Registered in England and Wales under Company Registration No. 3798903 Subject: [PATCH 12/23] nfs: don't pass nfs_subversion to ->create_server() From: David Howells To: trond.myklebust@hammerspace.com, anna.schumaker@netapp.com Cc: Al Viro , dhowells@redhat.com, viro@zeniv.linux.org.uk, linux-nfs@vger.kernel.org, linux-fsdevel@vger.kernel.org, linux-kernel@vger.kernel.org Date: Thu, 23 May 2019 17:17:37 +0100 Message-ID: <155862825776.26654.10102968133151054180.stgit@warthog.procyon.org.uk> In-Reply-To: <155862813755.26654.563679411147031501.stgit@warthog.procyon.org.uk> References: <155862813755.26654.563679411147031501.stgit@warthog.procyon.org.uk> User-Agent: StGit/unknown-version MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.84 on 10.5.11.22 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.39]); Thu, 23 May 2019 16:17:39 +0000 (UTC) Sender: linux-fsdevel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-fsdevel@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP From: Al Viro pick it from mount_info Reviewed-by: David Howells Signed-off-by: Al Viro --- fs/nfs/client.c | 4 ++-- fs/nfs/internal.h | 7 ++----- fs/nfs/nfs3_fs.h | 2 +- fs/nfs/nfs3client.c | 5 ++--- fs/nfs/nfs4client.c | 3 +-- fs/nfs/nfs4super.c | 2 +- fs/nfs/super.c | 14 +++++++------- include/linux/nfs_xdr.h | 2 +- 8 files changed, 17 insertions(+), 22 deletions(-) diff --git a/fs/nfs/client.c b/fs/nfs/client.c index 3d04cb0b839e..d30e38e3802f 100644 --- a/fs/nfs/client.c +++ b/fs/nfs/client.c @@ -940,10 +940,10 @@ EXPORT_SYMBOL_GPL(nfs_free_server); * Create a version 2 or 3 volume record * - keyed on server and FSID */ -struct nfs_server *nfs_create_server(struct nfs_mount_info *mount_info, - struct nfs_subversion *nfs_mod) +struct nfs_server *nfs_create_server(struct nfs_mount_info *mount_info) { struct nfs_server *server; + struct nfs_subversion *nfs_mod = mount_info->nfs_mod; struct nfs_fattr *fattr; int error; diff --git a/fs/nfs/internal.h b/fs/nfs/internal.h index 88f4af7c6924..56aaec30947f 100644 --- a/fs/nfs/internal.h +++ b/fs/nfs/internal.h @@ -177,11 +177,8 @@ extern struct nfs_client *nfs4_find_client_ident(struct net *, int); extern struct nfs_client * nfs4_find_client_sessionid(struct net *, const struct sockaddr *, struct nfs4_sessionid *, u32); -extern struct nfs_server *nfs_create_server(struct nfs_mount_info *, - struct nfs_subversion *); -extern struct nfs_server *nfs4_create_server( - struct nfs_mount_info *, - struct nfs_subversion *); +extern struct nfs_server *nfs_create_server(struct nfs_mount_info *); +extern struct nfs_server *nfs4_create_server(struct nfs_mount_info *); extern struct nfs_server *nfs4_create_referral_server(struct nfs_clone_mount *, struct nfs_fh *); extern int nfs4_update_server(struct nfs_server *server, const char *hostname, diff --git a/fs/nfs/nfs3_fs.h b/fs/nfs/nfs3_fs.h index f82e11c4cb56..09602dc1889f 100644 --- a/fs/nfs/nfs3_fs.h +++ b/fs/nfs/nfs3_fs.h @@ -27,7 +27,7 @@ static inline int nfs3_proc_setacls(struct inode *inode, struct posix_acl *acl, #endif /* CONFIG_NFS_V3_ACL */ /* nfs3client.c */ -struct nfs_server *nfs3_create_server(struct nfs_mount_info *, struct nfs_subversion *); +struct nfs_server *nfs3_create_server(struct nfs_mount_info *); struct nfs_server *nfs3_clone_server(struct nfs_server *, struct nfs_fh *, struct nfs_fattr *, rpc_authflavor_t); diff --git a/fs/nfs/nfs3client.c b/fs/nfs/nfs3client.c index 1afdb0f7473f..362c3549a217 100644 --- a/fs/nfs/nfs3client.c +++ b/fs/nfs/nfs3client.c @@ -45,10 +45,9 @@ static inline void nfs_init_server_aclclient(struct nfs_server *server) } #endif -struct nfs_server *nfs3_create_server(struct nfs_mount_info *mount_info, - struct nfs_subversion *nfs_mod) +struct nfs_server *nfs3_create_server(struct nfs_mount_info *mount_info) { - struct nfs_server *server = nfs_create_server(mount_info, nfs_mod); + struct nfs_server *server = nfs_create_server(mount_info); /* Create a client RPC handle for the NFS v3 ACL management interface */ if (!IS_ERR(server)) nfs_init_server_aclclient(server); diff --git a/fs/nfs/nfs4client.c b/fs/nfs/nfs4client.c index 3ce246346f02..d8151d2da0ef 100644 --- a/fs/nfs/nfs4client.c +++ b/fs/nfs/nfs4client.c @@ -1098,8 +1098,7 @@ static int nfs4_init_server(struct nfs_server *server, */ /*struct nfs_server *nfs4_create_server(const struct nfs_parsed_mount_data *data, struct nfs_fh *mntfh)*/ -struct nfs_server *nfs4_create_server(struct nfs_mount_info *mount_info, - struct nfs_subversion *nfs_mod) +struct nfs_server *nfs4_create_server(struct nfs_mount_info *mount_info) { struct nfs_server *server; bool auth_probe; diff --git a/fs/nfs/nfs4super.c b/fs/nfs/nfs4super.c index 32b602e87bb5..0ec7675bb285 100644 --- a/fs/nfs/nfs4super.c +++ b/fs/nfs/nfs4super.c @@ -204,7 +204,7 @@ struct dentry *nfs4_try_mount(int flags, const char *dev_name, dfprintk(MOUNT, "--> nfs4_try_mount()\n"); - res = do_nfs4_mount(nfs4_create_server(mount_info, &nfs_v4), + res = do_nfs4_mount(nfs4_create_server(mount_info), flags, mount_info, data->nfs_server.hostname, data->nfs_server.export_path); diff --git a/fs/nfs/super.c b/fs/nfs/super.c index 6da484eb7b6a..ba9f2f860b76 100644 --- a/fs/nfs/super.c +++ b/fs/nfs/super.c @@ -1798,8 +1798,7 @@ static int nfs_request_mount(struct nfs_parsed_mount_data *args, return 0; } -static struct nfs_server *nfs_try_mount_request(struct nfs_mount_info *mount_info, - struct nfs_subversion *nfs_mod) +static struct nfs_server *nfs_try_mount_request(struct nfs_mount_info *mount_info) { int status; unsigned int i; @@ -1809,6 +1808,7 @@ static struct nfs_server *nfs_try_mount_request(struct nfs_mount_info *mount_inf struct nfs_parsed_mount_data *args = mount_info->parsed; rpc_authflavor_t authlist[NFS_MAX_SECFLAVORS]; unsigned int authlist_len = ARRAY_SIZE(authlist); + struct nfs_subversion *nfs_mod = mount_info->nfs_mod; status = nfs_request_mount(args, mount_info->mntfh, authlist, &authlist_len); @@ -1825,7 +1825,7 @@ static struct nfs_server *nfs_try_mount_request(struct nfs_mount_info *mount_inf args->selected_flavor); if (status) return ERR_PTR(status); - return nfs_mod->rpc_ops->create_server(mount_info, nfs_mod); + return nfs_mod->rpc_ops->create_server(mount_info); } /* @@ -1852,7 +1852,7 @@ static struct nfs_server *nfs_try_mount_request(struct nfs_mount_info *mount_inf } dfprintk(MOUNT, "NFS: attempting to use auth flavor %u\n", flavor); args->selected_flavor = flavor; - server = nfs_mod->rpc_ops->create_server(mount_info, nfs_mod); + server = nfs_mod->rpc_ops->create_server(mount_info); if (!IS_ERR(server)) return server; } @@ -1868,7 +1868,7 @@ static struct nfs_server *nfs_try_mount_request(struct nfs_mount_info *mount_inf /* Last chance! Try AUTH_UNIX */ dfprintk(MOUNT, "NFS: attempting to use auth flavor %u\n", RPC_AUTH_UNIX); args->selected_flavor = RPC_AUTH_UNIX; - return nfs_mod->rpc_ops->create_server(mount_info, nfs_mod); + return nfs_mod->rpc_ops->create_server(mount_info); } static struct dentry *nfs_fs_mount_common(int, const char *, struct nfs_mount_info *); @@ -1878,9 +1878,9 @@ struct dentry *nfs_try_mount(int flags, const char *dev_name, { struct nfs_subversion *nfs_mod = mount_info->nfs_mod; if (mount_info->parsed->need_mount) - mount_info->server = nfs_try_mount_request(mount_info, nfs_mod); + mount_info->server = nfs_try_mount_request(mount_info); else - mount_info->server = nfs_mod->rpc_ops->create_server(mount_info, nfs_mod); + mount_info->server = nfs_mod->rpc_ops->create_server(mount_info); return nfs_fs_mount_common(flags, dev_name, mount_info); } diff --git a/include/linux/nfs_xdr.h b/include/linux/nfs_xdr.h index 4fdf4a523185..82bdb91da2ae 100644 --- a/include/linux/nfs_xdr.h +++ b/include/linux/nfs_xdr.h @@ -1705,7 +1705,7 @@ struct nfs_rpc_ops { struct nfs_client *(*init_client) (struct nfs_client *, const struct nfs_client_initdata *); void (*free_client) (struct nfs_client *); - struct nfs_server *(*create_server)(struct nfs_mount_info *, struct nfs_subversion *); + struct nfs_server *(*create_server)(struct nfs_mount_info *); struct nfs_server *(*clone_server)(struct nfs_server *, struct nfs_fh *, struct nfs_fattr *, rpc_authflavor_t); }; From patchwork Thu May 23 16:17:45 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Howells X-Patchwork-Id: 10958301 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 3570813AD for ; Thu, 23 May 2019 16:17:53 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 2124B26E82 for ; Thu, 23 May 2019 16:17:53 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 15A99284CE; Thu, 23 May 2019 16:17:53 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-7.9 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI, RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 7382426E82 for ; Thu, 23 May 2019 16:17:52 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1731271AbfEWQRs (ORCPT ); Thu, 23 May 2019 12:17:48 -0400 Received: from mx1.redhat.com ([209.132.183.28]:60964 "EHLO mx1.redhat.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1730899AbfEWQRr (ORCPT ); Thu, 23 May 2019 12:17:47 -0400 Received: from smtp.corp.redhat.com (int-mx03.intmail.prod.int.phx2.redhat.com [10.5.11.13]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 58C1E772DD; Thu, 23 May 2019 16:17:47 +0000 (UTC) Received: from warthog.procyon.org.uk (ovpn-121-142.rdu2.redhat.com [10.10.121.142]) by smtp.corp.redhat.com (Postfix) with ESMTP id D301C17AC7; Thu, 23 May 2019 16:17:45 +0000 (UTC) Organization: Red Hat UK Ltd. Registered Address: Red Hat UK Ltd, Amberley Place, 107-111 Peascod Street, Windsor, Berkshire, SI4 1TE, United Kingdom. Registered in England and Wales under Company Registration No. 3798903 Subject: [PATCH 13/23] nfs: get rid of mount_info ->fill_super() From: David Howells To: trond.myklebust@hammerspace.com, anna.schumaker@netapp.com Cc: Al Viro , dhowells@redhat.com, viro@zeniv.linux.org.uk, linux-nfs@vger.kernel.org, linux-fsdevel@vger.kernel.org, linux-kernel@vger.kernel.org Date: Thu, 23 May 2019 17:17:45 +0100 Message-ID: <155862826508.26654.12495949988044019774.stgit@warthog.procyon.org.uk> In-Reply-To: <155862813755.26654.563679411147031501.stgit@warthog.procyon.org.uk> References: <155862813755.26654.563679411147031501.stgit@warthog.procyon.org.uk> User-Agent: StGit/unknown-version MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.13 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.26]); Thu, 23 May 2019 16:17:47 +0000 (UTC) Sender: linux-fsdevel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-fsdevel@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP From: Al Viro The only possible values are nfs_fill_super and nfs_clone_super. The latter is used only when crossing into a submount and it is almost identical to the former; the only differences are * ->s_time_gran unconditionally set to 1 (even for v2 mounts). Regression dating back to 2012, actually. * ->s_blocksize/->s_blocksize_bits set to that of parent. Rather than messing with the method, stash ->s_blocksize_bits in mount_info in submount case and after the (now unconditional) call of nfs_fill_super() override ->s_blocksize/->s_blocksize_bits if that has been set. Reviewed-by: David Howells Signed-off-by: Al Viro --- fs/nfs/internal.h | 4 +-- fs/nfs/namespace.c | 2 +- fs/nfs/nfs4super.c | 1 - fs/nfs/super.c | 66 +++++++++++++--------------------------------------- 4 files changed, 18 insertions(+), 55 deletions(-) diff --git a/fs/nfs/internal.h b/fs/nfs/internal.h index 56aaec30947f..61a480c06a76 100644 --- a/fs/nfs/internal.h +++ b/fs/nfs/internal.h @@ -143,7 +143,7 @@ struct nfs_mount_request { }; struct nfs_mount_info { - void (*fill_super)(struct super_block *, struct nfs_mount_info *); + unsigned int inherited_bsize; int (*set_security)(struct super_block *, struct dentry *, struct nfs_mount_info *); struct nfs_parsed_mount_data *parsed; struct nfs_clone_mount *cloned; @@ -402,8 +402,6 @@ int nfs_set_sb_security(struct super_block *, struct dentry *, struct nfs_mount_ int nfs_clone_sb_security(struct super_block *, struct dentry *, struct nfs_mount_info *); struct dentry *nfs_fs_mount(struct file_system_type *, int, const char *, void *); void nfs_kill_super(struct super_block *); -void nfs_fill_super(struct super_block *, struct nfs_mount_info *); -void nfs_clone_super(struct super_block *, struct nfs_mount_info *); extern struct rpc_stat nfs_rpcstat; diff --git a/fs/nfs/namespace.c b/fs/nfs/namespace.c index 7cda42ae000a..26f99ac5f5be 100644 --- a/fs/nfs/namespace.c +++ b/fs/nfs/namespace.c @@ -228,7 +228,7 @@ struct vfsmount *nfs_do_submount(struct dentry *dentry, struct nfs_fh *fh, .authflavor = authflavor, }; struct nfs_mount_info mount_info = { - .fill_super = nfs_clone_super, + .inherited_bsize = sb->s_blocksize_bits, .set_security = nfs_clone_sb_security, .cloned = &mountdata, .mntfh = fh, diff --git a/fs/nfs/nfs4super.c b/fs/nfs/nfs4super.c index 0ec7675bb285..aaae3b6f93b6 100644 --- a/fs/nfs/nfs4super.c +++ b/fs/nfs/nfs4super.c @@ -223,7 +223,6 @@ static struct dentry *nfs4_referral_mount(struct file_system_type *fs_type, { struct nfs_clone_mount *data = raw_data; struct nfs_mount_info mount_info = { - .fill_super = nfs_fill_super, .set_security = nfs_clone_sb_security, .cloned = data, .nfs_mod = &nfs_v4, diff --git a/fs/nfs/super.c b/fs/nfs/super.c index ba9f2f860b76..dd379898ab23 100644 --- a/fs/nfs/super.c +++ b/fs/nfs/super.c @@ -2316,29 +2316,9 @@ nfs_remount(struct super_block *sb, int *flags, char *raw_data) EXPORT_SYMBOL_GPL(nfs_remount); /* - * Initialise the common bits of the superblock + * Finish setting up an NFS superblock */ -static void nfs_initialise_sb(struct super_block *sb) -{ - struct nfs_server *server = NFS_SB(sb); - - sb->s_magic = NFS_SUPER_MAGIC; - - /* We probably want something more informative here */ - snprintf(sb->s_id, sizeof(sb->s_id), - "%u:%u", MAJOR(sb->s_dev), MINOR(sb->s_dev)); - - if (sb->s_blocksize == 0) - sb->s_blocksize = nfs_block_bits(server->wsize, - &sb->s_blocksize_bits); - - nfs_super_set_maxbytes(sb, server->maxfilesize); -} - -/* - * Finish setting up an NFS2/3 superblock - */ -void nfs_fill_super(struct super_block *sb, struct nfs_mount_info *mount_info) +static void nfs_fill_super(struct super_block *sb, struct nfs_mount_info *mount_info) { struct nfs_parsed_mount_data *data = mount_info->parsed; struct nfs_server *server = NFS_SB(sb); @@ -2359,35 +2339,17 @@ void nfs_fill_super(struct super_block *sb, struct nfs_mount_info *mount_info) sb->s_export_op = &nfs_export_ops; } - nfs_initialise_sb(sb); -} -EXPORT_SYMBOL_GPL(nfs_fill_super); - -/* - * Finish setting up a cloned NFS2/3/4 superblock - */ -void nfs_clone_super(struct super_block *sb, - struct nfs_mount_info *mount_info) -{ - const struct super_block *old_sb = mount_info->cloned->sb; - struct nfs_server *server = NFS_SB(sb); + sb->s_magic = NFS_SUPER_MAGIC; - sb->s_blocksize_bits = old_sb->s_blocksize_bits; - sb->s_blocksize = old_sb->s_blocksize; - sb->s_maxbytes = old_sb->s_maxbytes; - sb->s_xattr = old_sb->s_xattr; - sb->s_op = old_sb->s_op; - sb->s_time_gran = 1; - sb->s_export_op = old_sb->s_export_op; + /* We probably want something more informative here */ + snprintf(sb->s_id, sizeof(sb->s_id), + "%u:%u", MAJOR(sb->s_dev), MINOR(sb->s_dev)); - if (server->nfs_client->rpc_ops->version != 2) { - /* The VFS shouldn't apply the umask to mode bits. We will do - * so ourselves when necessary. - */ - sb->s_flags |= SB_POSIXACL; - } + if (sb->s_blocksize == 0) + sb->s_blocksize = nfs_block_bits(server->wsize, + &sb->s_blocksize_bits); - nfs_initialise_sb(sb); + nfs_super_set_maxbytes(sb, server->maxfilesize); } static int nfs_compare_mount_options(const struct super_block *s, const struct nfs_server *b, int flags) @@ -2653,8 +2615,13 @@ static struct dentry *nfs_fs_mount_common(int flags, const char *dev_name, } if (!s->s_root) { + unsigned bsize = mount_info->inherited_bsize; /* initial superblock/root creation */ - mount_info->fill_super(s, mount_info); + nfs_fill_super(s, mount_info); + if (bsize) { + s->s_blocksize_bits = bsize; + s->s_blocksize = 1U << bsize; + } nfs_get_cache_cookie(s, mount_info->parsed, mount_info->cloned); if (!(server->flags & NFS_MOUNT_UNSHARED)) s->s_iflags |= SB_I_MULTIROOT; @@ -2689,7 +2656,6 @@ struct dentry *nfs_fs_mount(struct file_system_type *fs_type, int flags, const char *dev_name, void *raw_data) { struct nfs_mount_info mount_info = { - .fill_super = nfs_fill_super, .set_security = nfs_set_sb_security, }; struct dentry *mntroot = ERR_PTR(-ENOMEM); From patchwork Thu May 23 16:17:52 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Howells X-Patchwork-Id: 10958305 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 7F6E013AD for ; Thu, 23 May 2019 16:18:01 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 69F4227D4A for ; Thu, 23 May 2019 16:18:01 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 5D8D02865F; Thu, 23 May 2019 16:18:01 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-7.9 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI, RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id F0AE327D4A for ; Thu, 23 May 2019 16:18:00 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1731264AbfEWQR4 (ORCPT ); Thu, 23 May 2019 12:17:56 -0400 Received: from mx1.redhat.com ([209.132.183.28]:34382 "EHLO mx1.redhat.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1730899AbfEWQR4 (ORCPT ); Thu, 23 May 2019 12:17:56 -0400 Received: from smtp.corp.redhat.com (int-mx04.intmail.prod.int.phx2.redhat.com [10.5.11.14]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 96F04792AE; Thu, 23 May 2019 16:17:56 +0000 (UTC) Received: from warthog.procyon.org.uk (ovpn-121-142.rdu2.redhat.com [10.10.121.142]) by smtp.corp.redhat.com (Postfix) with ESMTP id 4FF025D9C6; Thu, 23 May 2019 16:17:53 +0000 (UTC) Organization: Red Hat UK Ltd. Registered Address: Red Hat UK Ltd, Amberley Place, 107-111 Peascod Street, Windsor, Berkshire, SI4 1TE, United Kingdom. Registered in England and Wales under Company Registration No. 3798903 Subject: [PATCH 14/23] nfs_clone_sb_security(): simplify the check for server bogosity From: David Howells To: trond.myklebust@hammerspace.com, anna.schumaker@netapp.com Cc: Al Viro , dhowells@redhat.com, viro@zeniv.linux.org.uk, linux-nfs@vger.kernel.org, linux-fsdevel@vger.kernel.org, linux-kernel@vger.kernel.org Date: Thu, 23 May 2019 17:17:52 +0100 Message-ID: <155862827257.26654.7677886763177785697.stgit@warthog.procyon.org.uk> In-Reply-To: <155862813755.26654.563679411147031501.stgit@warthog.procyon.org.uk> References: <155862813755.26654.563679411147031501.stgit@warthog.procyon.org.uk> User-Agent: StGit/unknown-version MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.14 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.39]); Thu, 23 May 2019 16:17:56 +0000 (UTC) Sender: linux-fsdevel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-fsdevel@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP From: Al Viro We used to check ->i_op for being nfs_dir_inode_operations. With separate inode_operations for v3 and v4 that became bogus, but rather than going for protocol-dependent comparison we could've just checked ->i_fop instead; _that_ is the same for all protocol versions. Reviewed-by: David Howells Signed-off-by: Al Viro --- fs/nfs/super.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fs/nfs/super.c b/fs/nfs/super.c index dd379898ab23..a78f409e7634 100644 --- a/fs/nfs/super.c +++ b/fs/nfs/super.c @@ -2546,7 +2546,7 @@ int nfs_clone_sb_security(struct super_block *s, struct dentry *mntroot, unsigned long kflags = 0, kflags_out = 0; /* clone any lsm security options from the parent to the new sb */ - if (d_inode(mntroot)->i_op != NFS_SB(s)->nfs_client->rpc_ops->dir_inode_ops) + if (d_inode(mntroot)->i_fop != &nfs_dir_operations) return -ESTALE; if (NFS_SB(s)->caps & NFS_CAP_SECURITY_LABEL) From patchwork Thu May 23 16:18:01 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Howells X-Patchwork-Id: 10958311 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 5964713AD for ; Thu, 23 May 2019 16:18:10 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 464B226E82 for ; Thu, 23 May 2019 16:18:10 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 3912428448; Thu, 23 May 2019 16:18:10 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-7.9 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI, RCVD_IN_DNSWL_HI autolearn=unavailable version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id ADC3D27E01 for ; Thu, 23 May 2019 16:18:09 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1731293AbfEWQSF (ORCPT ); Thu, 23 May 2019 12:18:05 -0400 Received: from mx1.redhat.com ([209.132.183.28]:37042 "EHLO mx1.redhat.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1730860AbfEWQSE (ORCPT ); Thu, 23 May 2019 12:18:04 -0400 Received: from smtp.corp.redhat.com (int-mx06.intmail.prod.int.phx2.redhat.com [10.5.11.16]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 1AC6F308A104; Thu, 23 May 2019 16:18:04 +0000 (UTC) Received: from warthog.procyon.org.uk (ovpn-121-142.rdu2.redhat.com [10.10.121.142]) by smtp.corp.redhat.com (Postfix) with ESMTP id 96C5317162; Thu, 23 May 2019 16:18:02 +0000 (UTC) Organization: Red Hat UK Ltd. Registered Address: Red Hat UK Ltd, Amberley Place, 107-111 Peascod Street, Windsor, Berkshire, SI4 1TE, United Kingdom. Registered in England and Wales under Company Registration No. 3798903 Subject: [PATCH 15/23] nfs: get rid of ->set_security() From: David Howells To: trond.myklebust@hammerspace.com, anna.schumaker@netapp.com Cc: Al Viro , dhowells@redhat.com, viro@zeniv.linux.org.uk, linux-nfs@vger.kernel.org, linux-fsdevel@vger.kernel.org, linux-kernel@vger.kernel.org Date: Thu, 23 May 2019 17:18:01 +0100 Message-ID: <155862828182.26654.5120276809942525177.stgit@warthog.procyon.org.uk> In-Reply-To: <155862813755.26654.563679411147031501.stgit@warthog.procyon.org.uk> References: <155862813755.26654.563679411147031501.stgit@warthog.procyon.org.uk> User-Agent: StGit/unknown-version MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.16 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.44]); Thu, 23 May 2019 16:18:04 +0000 (UTC) Sender: linux-fsdevel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-fsdevel@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP From: Al Viro it's always either nfs_set_sb_security() or nfs_clone_sb_security(), the choice being controlled by mount_info->cloned != NULL. No need to add methods, especially when both instances live right next to the caller and are never accessed anywhere else. Reviewed-by: David Howells Signed-off-by: Al Viro --- fs/nfs/internal.h | 3 -- fs/nfs/namespace.c | 1 - fs/nfs/nfs4super.c | 3 -- fs/nfs/super.c | 69 ++++++++++++++++------------------------------------ 4 files changed, 21 insertions(+), 55 deletions(-) diff --git a/fs/nfs/internal.h b/fs/nfs/internal.h index 61a480c06a76..1665e0935241 100644 --- a/fs/nfs/internal.h +++ b/fs/nfs/internal.h @@ -144,7 +144,6 @@ struct nfs_mount_request { struct nfs_mount_info { unsigned int inherited_bsize; - int (*set_security)(struct super_block *, struct dentry *, struct nfs_mount_info *); struct nfs_parsed_mount_data *parsed; struct nfs_clone_mount *cloned; struct nfs_server *server; @@ -398,8 +397,6 @@ extern struct file_system_type nfs4_referral_fs_type; #endif bool nfs_auth_info_match(const struct nfs_auth_info *, rpc_authflavor_t); struct dentry *nfs_try_mount(int, const char *, struct nfs_mount_info *); -int nfs_set_sb_security(struct super_block *, struct dentry *, struct nfs_mount_info *); -int nfs_clone_sb_security(struct super_block *, struct dentry *, struct nfs_mount_info *); struct dentry *nfs_fs_mount(struct file_system_type *, int, const char *, void *); void nfs_kill_super(struct super_block *); diff --git a/fs/nfs/namespace.c b/fs/nfs/namespace.c index 26f99ac5f5be..1c4cb8914b20 100644 --- a/fs/nfs/namespace.c +++ b/fs/nfs/namespace.c @@ -229,7 +229,6 @@ struct vfsmount *nfs_do_submount(struct dentry *dentry, struct nfs_fh *fh, }; struct nfs_mount_info mount_info = { .inherited_bsize = sb->s_blocksize_bits, - .set_security = nfs_clone_sb_security, .cloned = &mountdata, .mntfh = fh, .nfs_mod = NFS_SB(sb)->nfs_client->cl_nfs_mod, diff --git a/fs/nfs/nfs4super.c b/fs/nfs/nfs4super.c index aaae3b6f93b6..513861b38b72 100644 --- a/fs/nfs/nfs4super.c +++ b/fs/nfs/nfs4super.c @@ -200,8 +200,6 @@ struct dentry *nfs4_try_mount(int flags, const char *dev_name, struct nfs_parsed_mount_data *data = mount_info->parsed; struct dentry *res; - mount_info->set_security = nfs_set_sb_security; - dfprintk(MOUNT, "--> nfs4_try_mount()\n"); res = do_nfs4_mount(nfs4_create_server(mount_info), @@ -223,7 +221,6 @@ static struct dentry *nfs4_referral_mount(struct file_system_type *fs_type, { struct nfs_clone_mount *data = raw_data; struct nfs_mount_info mount_info = { - .set_security = nfs_clone_sb_security, .cloned = data, .nfs_mod = &nfs_v4, }; diff --git a/fs/nfs/super.c b/fs/nfs/super.c index a78f409e7634..37e922324e99 100644 --- a/fs/nfs/super.c +++ b/fs/nfs/super.c @@ -2518,52 +2518,6 @@ static void nfs_get_cache_cookie(struct super_block *sb, } #endif -int nfs_set_sb_security(struct super_block *s, struct dentry *mntroot, - struct nfs_mount_info *mount_info) -{ - int error; - unsigned long kflags = 0, kflags_out = 0; - if (NFS_SB(s)->caps & NFS_CAP_SECURITY_LABEL) - kflags |= SECURITY_LSM_NATIVE_LABELS; - - error = security_sb_set_mnt_opts(s, mount_info->parsed->lsm_opts, - kflags, &kflags_out); - if (error) - goto err; - - if (NFS_SB(s)->caps & NFS_CAP_SECURITY_LABEL && - !(kflags_out & SECURITY_LSM_NATIVE_LABELS)) - NFS_SB(s)->caps &= ~NFS_CAP_SECURITY_LABEL; -err: - return error; -} -EXPORT_SYMBOL_GPL(nfs_set_sb_security); - -int nfs_clone_sb_security(struct super_block *s, struct dentry *mntroot, - struct nfs_mount_info *mount_info) -{ - int error; - unsigned long kflags = 0, kflags_out = 0; - - /* clone any lsm security options from the parent to the new sb */ - if (d_inode(mntroot)->i_fop != &nfs_dir_operations) - return -ESTALE; - - if (NFS_SB(s)->caps & NFS_CAP_SECURITY_LABEL) - kflags |= SECURITY_LSM_NATIVE_LABELS; - - error = security_sb_clone_mnt_opts(mount_info->cloned->sb, s, kflags, - &kflags_out); - if (error) - return error; - - if (NFS_SB(s)->caps & NFS_CAP_SECURITY_LABEL && - !(kflags_out & SECURITY_LSM_NATIVE_LABELS)) - NFS_SB(s)->caps &= ~NFS_CAP_SECURITY_LABEL; - return 0; -} -EXPORT_SYMBOL_GPL(nfs_clone_sb_security); - static struct dentry *nfs_fs_mount_common(int flags, const char *dev_name, struct nfs_mount_info *mount_info) { @@ -2571,6 +2525,7 @@ static struct dentry *nfs_fs_mount_common(int flags, const char *dev_name, struct dentry *mntroot = ERR_PTR(-ENOMEM); int (*compare_super)(struct super_block *, void *) = nfs_compare_super; struct nfs_server *server = mount_info->server; + unsigned long kflags = 0, kflags_out = 0; struct nfs_sb_mountdata sb_mntdata = { .mntflags = flags, .server = server, @@ -2631,7 +2586,26 @@ static struct dentry *nfs_fs_mount_common(int flags, const char *dev_name, if (IS_ERR(mntroot)) goto error_splat_super; - error = mount_info->set_security(s, mntroot, mount_info); + + if (NFS_SB(s)->caps & NFS_CAP_SECURITY_LABEL) + kflags |= SECURITY_LSM_NATIVE_LABELS; + if (mount_info->cloned) { + if (d_inode(mntroot)->i_fop != &nfs_dir_operations) { + error = -ESTALE; + goto error_splat_root; + } + /* clone any lsm security options from the parent to the new sb */ + error = security_sb_clone_mnt_opts(mount_info->cloned->sb, s, kflags, + &kflags_out); + } else { + error = security_sb_set_mnt_opts(s, mount_info->parsed->lsm_opts, + kflags, &kflags_out); + } + if (error) + goto error_splat_root; + if (NFS_SB(s)->caps & NFS_CAP_SECURITY_LABEL && + !(kflags_out & SECURITY_LSM_NATIVE_LABELS)) + NFS_SB(s)->caps &= ~NFS_CAP_SECURITY_LABEL; if (error) goto error_splat_root; @@ -2656,7 +2630,6 @@ struct dentry *nfs_fs_mount(struct file_system_type *fs_type, int flags, const char *dev_name, void *raw_data) { struct nfs_mount_info mount_info = { - .set_security = nfs_set_sb_security, }; struct dentry *mntroot = ERR_PTR(-ENOMEM); struct nfs_subversion *nfs_mod; From patchwork Thu May 23 16:18:09 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Howells X-Patchwork-Id: 10958319 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 041CE13AD for ; Thu, 23 May 2019 16:18:34 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id DA77527D4A for ; Thu, 23 May 2019 16:18:33 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id CEA8F27FA9; Thu, 23 May 2019 16:18:33 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-7.9 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI, RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id D1A84283E8 for ; Thu, 23 May 2019 16:18:29 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1731315AbfEWQSO (ORCPT ); Thu, 23 May 2019 12:18:14 -0400 Received: from mx1.redhat.com ([209.132.183.28]:33314 "EHLO mx1.redhat.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1730860AbfEWQSO (ORCPT ); Thu, 23 May 2019 12:18:14 -0400 Received: from smtp.corp.redhat.com (int-mx08.intmail.prod.int.phx2.redhat.com [10.5.11.23]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 86D91307D867; Thu, 23 May 2019 16:18:13 +0000 (UTC) Received: from warthog.procyon.org.uk (ovpn-121-142.rdu2.redhat.com [10.10.121.142]) by smtp.corp.redhat.com (Postfix) with ESMTP id 1FBB85B2C7; Thu, 23 May 2019 16:18:09 +0000 (UTC) Organization: Red Hat UK Ltd. Registered Address: Red Hat UK Ltd, Amberley Place, 107-111 Peascod Street, Windsor, Berkshire, SI4 1TE, United Kingdom. Registered in England and Wales under Company Registration No. 3798903 Subject: [PATCH 16/23] NFS: Move mount parameterisation bits into their own file From: David Howells To: trond.myklebust@hammerspace.com, anna.schumaker@netapp.com Cc: Al Viro , dhowells@redhat.com, viro@zeniv.linux.org.uk, linux-nfs@vger.kernel.org, linux-fsdevel@vger.kernel.org, linux-kernel@vger.kernel.org Date: Thu, 23 May 2019 17:18:09 +0100 Message-ID: <155862828932.26654.6328799130606456680.stgit@warthog.procyon.org.uk> In-Reply-To: <155862813755.26654.563679411147031501.stgit@warthog.procyon.org.uk> References: <155862813755.26654.563679411147031501.stgit@warthog.procyon.org.uk> User-Agent: StGit/unknown-version MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.84 on 10.5.11.23 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.48]); Thu, 23 May 2019 16:18:13 +0000 (UTC) Sender: linux-fsdevel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-fsdevel@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP Split various bits relating to mount parameterisation out from fs/nfs/super.c into their own file to form the basis of filesystem context handling for NFS. No other changes are made to the code beyond removing 'static' qualifiers. Signed-off-by: David Howells Signed-off-by: Al Viro --- fs/nfs/Makefile | 3 fs/nfs/fs_context.c | 1408 +++++++++++++++++++++++++++++++++++++++++++++++++++ fs/nfs/internal.h | 29 + fs/nfs/super.c | 1401 --------------------------------------------------- 4 files changed, 1439 insertions(+), 1402 deletions(-) create mode 100644 fs/nfs/fs_context.c diff --git a/fs/nfs/Makefile b/fs/nfs/Makefile index c587e3c4c6a6..0ba240405e3d 100644 --- a/fs/nfs/Makefile +++ b/fs/nfs/Makefile @@ -8,7 +8,8 @@ obj-$(CONFIG_NFS_FS) += nfs.o CFLAGS_nfstrace.o += -I$(src) nfs-y := client.o dir.o file.o getroot.o inode.o super.o \ io.o direct.o pagelist.o read.o symlink.o unlink.o \ - write.o namespace.o mount_clnt.o nfstrace.o export.o + write.o namespace.o mount_clnt.o nfstrace.o export.o \ + fs_context.o nfs-$(CONFIG_ROOT_NFS) += nfsroot.o nfs-$(CONFIG_SYSCTL) += sysctl.o nfs-$(CONFIG_NFS_FSCACHE) += fscache.o fscache-index.o diff --git a/fs/nfs/fs_context.c b/fs/nfs/fs_context.c new file mode 100644 index 000000000000..9711a2c7b479 --- /dev/null +++ b/fs/nfs/fs_context.c @@ -0,0 +1,1408 @@ +/* NFS mount handling. + * + * Copyright (C) 2018 Red Hat, Inc. All Rights Reserved. + * Written by David Howells (dhowells@redhat.com) + * + * Split from fs/nfs/super.c: + * + * Copyright (C) 1992 Rick Sladkey + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public Licence + * as published by the Free Software Foundation; either version + * 2 of the Licence, or (at your option) any later version. + */ + +#include +#include +#include +#include +#include +#include +#include "nfs.h" +#include "internal.h" + +#define NFSDBG_FACILITY NFSDBG_MOUNT + +#if IS_ENABLED(CONFIG_NFS_V3) +#define NFS_DEFAULT_VERSION 3 +#else +#define NFS_DEFAULT_VERSION 2 +#endif + +enum { + /* Mount options that take no arguments */ + Opt_soft, Opt_softerr, Opt_hard, + Opt_posix, Opt_noposix, + Opt_cto, Opt_nocto, + Opt_ac, Opt_noac, + Opt_lock, Opt_nolock, + Opt_udp, Opt_tcp, Opt_rdma, + Opt_acl, Opt_noacl, + Opt_rdirplus, Opt_nordirplus, + Opt_sharecache, Opt_nosharecache, + Opt_resvport, Opt_noresvport, + Opt_fscache, Opt_nofscache, + Opt_migration, Opt_nomigration, + + /* Mount options that take integer arguments */ + Opt_port, + Opt_rsize, Opt_wsize, Opt_bsize, + Opt_timeo, Opt_retrans, + Opt_acregmin, Opt_acregmax, + Opt_acdirmin, Opt_acdirmax, + Opt_actimeo, + Opt_namelen, + Opt_mountport, + Opt_mountvers, + Opt_minorversion, + + /* Mount options that take string arguments */ + Opt_nfsvers, + Opt_sec, Opt_proto, Opt_mountproto, Opt_mounthost, + Opt_addr, Opt_mountaddr, Opt_clientaddr, + Opt_lookupcache, + Opt_fscache_uniq, + Opt_local_lock, + + /* Special mount options */ + Opt_userspace, Opt_deprecated, Opt_sloppy, + + Opt_err +}; + +static const match_table_t nfs_mount_option_tokens = { + { Opt_userspace, "bg" }, + { Opt_userspace, "fg" }, + { Opt_userspace, "retry=%s" }, + + { Opt_sloppy, "sloppy" }, + + { Opt_soft, "soft" }, + { Opt_softerr, "softerr" }, + { Opt_hard, "hard" }, + { Opt_deprecated, "intr" }, + { Opt_deprecated, "nointr" }, + { Opt_posix, "posix" }, + { Opt_noposix, "noposix" }, + { Opt_cto, "cto" }, + { Opt_nocto, "nocto" }, + { Opt_ac, "ac" }, + { Opt_noac, "noac" }, + { Opt_lock, "lock" }, + { Opt_nolock, "nolock" }, + { Opt_udp, "udp" }, + { Opt_tcp, "tcp" }, + { Opt_rdma, "rdma" }, + { Opt_acl, "acl" }, + { Opt_noacl, "noacl" }, + { Opt_rdirplus, "rdirplus" }, + { Opt_nordirplus, "nordirplus" }, + { Opt_sharecache, "sharecache" }, + { Opt_nosharecache, "nosharecache" }, + { Opt_resvport, "resvport" }, + { Opt_noresvport, "noresvport" }, + { Opt_fscache, "fsc" }, + { Opt_nofscache, "nofsc" }, + { Opt_migration, "migration" }, + { Opt_nomigration, "nomigration" }, + + { Opt_port, "port=%s" }, + { Opt_rsize, "rsize=%s" }, + { Opt_wsize, "wsize=%s" }, + { Opt_bsize, "bsize=%s" }, + { Opt_timeo, "timeo=%s" }, + { Opt_retrans, "retrans=%s" }, + { Opt_acregmin, "acregmin=%s" }, + { Opt_acregmax, "acregmax=%s" }, + { Opt_acdirmin, "acdirmin=%s" }, + { Opt_acdirmax, "acdirmax=%s" }, + { Opt_actimeo, "actimeo=%s" }, + { Opt_namelen, "namlen=%s" }, + { Opt_mountport, "mountport=%s" }, + { Opt_mountvers, "mountvers=%s" }, + { Opt_minorversion, "minorversion=%s" }, + + { Opt_nfsvers, "nfsvers=%s" }, + { Opt_nfsvers, "vers=%s" }, + + { Opt_sec, "sec=%s" }, + { Opt_proto, "proto=%s" }, + { Opt_mountproto, "mountproto=%s" }, + { Opt_addr, "addr=%s" }, + { Opt_clientaddr, "clientaddr=%s" }, + { Opt_mounthost, "mounthost=%s" }, + { Opt_mountaddr, "mountaddr=%s" }, + + { Opt_lookupcache, "lookupcache=%s" }, + { Opt_fscache_uniq, "fsc=%s" }, + { Opt_local_lock, "local_lock=%s" }, + + /* The following needs to be listed after all other options */ + { Opt_nfsvers, "v%s" }, + + { Opt_err, NULL } +}; + +enum { + Opt_xprt_udp, Opt_xprt_udp6, Opt_xprt_tcp, Opt_xprt_tcp6, Opt_xprt_rdma, + Opt_xprt_rdma6, + + Opt_xprt_err +}; + +static const match_table_t nfs_xprt_protocol_tokens = { + { Opt_xprt_udp, "udp" }, + { Opt_xprt_udp6, "udp6" }, + { Opt_xprt_tcp, "tcp" }, + { Opt_xprt_tcp6, "tcp6" }, + { Opt_xprt_rdma, "rdma" }, + { Opt_xprt_rdma6, "rdma6" }, + + { Opt_xprt_err, NULL } +}; + +enum { + Opt_sec_none, Opt_sec_sys, + Opt_sec_krb5, Opt_sec_krb5i, Opt_sec_krb5p, + Opt_sec_lkey, Opt_sec_lkeyi, Opt_sec_lkeyp, + Opt_sec_spkm, Opt_sec_spkmi, Opt_sec_spkmp, + + Opt_sec_err +}; + +static const match_table_t nfs_secflavor_tokens = { + { Opt_sec_none, "none" }, + { Opt_sec_none, "null" }, + { Opt_sec_sys, "sys" }, + + { Opt_sec_krb5, "krb5" }, + { Opt_sec_krb5i, "krb5i" }, + { Opt_sec_krb5p, "krb5p" }, + + { Opt_sec_lkey, "lkey" }, + { Opt_sec_lkeyi, "lkeyi" }, + { Opt_sec_lkeyp, "lkeyp" }, + + { Opt_sec_spkm, "spkm3" }, + { Opt_sec_spkmi, "spkm3i" }, + { Opt_sec_spkmp, "spkm3p" }, + + { Opt_sec_err, NULL } +}; + +enum { + Opt_lookupcache_all, Opt_lookupcache_positive, + Opt_lookupcache_none, + + Opt_lookupcache_err +}; + +static match_table_t nfs_lookupcache_tokens = { + { Opt_lookupcache_all, "all" }, + { Opt_lookupcache_positive, "pos" }, + { Opt_lookupcache_positive, "positive" }, + { Opt_lookupcache_none, "none" }, + + { Opt_lookupcache_err, NULL } +}; + +enum { + Opt_local_lock_all, Opt_local_lock_flock, Opt_local_lock_posix, + Opt_local_lock_none, + + Opt_local_lock_err +}; + +static match_table_t nfs_local_lock_tokens = { + { Opt_local_lock_all, "all" }, + { Opt_local_lock_flock, "flock" }, + { Opt_local_lock_posix, "posix" }, + { Opt_local_lock_none, "none" }, + + { Opt_local_lock_err, NULL } +}; + +enum { + Opt_vers_2, Opt_vers_3, Opt_vers_4, Opt_vers_4_0, + Opt_vers_4_1, Opt_vers_4_2, + + Opt_vers_err +}; + +static match_table_t nfs_vers_tokens = { + { Opt_vers_2, "2" }, + { Opt_vers_3, "3" }, + { Opt_vers_4, "4" }, + { Opt_vers_4_0, "4.0" }, + { Opt_vers_4_1, "4.1" }, + { Opt_vers_4_2, "4.2" }, + + { Opt_vers_err, NULL } +}; + +struct nfs_parsed_mount_data *nfs_alloc_parsed_mount_data(void) +{ + struct nfs_parsed_mount_data *data; + + data = kzalloc(sizeof(*data), GFP_KERNEL); + if (data) { + data->timeo = NFS_UNSPEC_TIMEO; + data->retrans = NFS_UNSPEC_RETRANS; + data->acregmin = NFS_DEF_ACREGMIN; + data->acregmax = NFS_DEF_ACREGMAX; + data->acdirmin = NFS_DEF_ACDIRMIN; + data->acdirmax = NFS_DEF_ACDIRMAX; + data->mount_server.port = NFS_UNSPEC_PORT; + data->nfs_server.port = NFS_UNSPEC_PORT; + data->nfs_server.protocol = XPRT_TRANSPORT_TCP; + data->selected_flavor = RPC_AUTH_MAXFLAVOR; + data->minorversion = 0; + data->need_mount = true; + data->net = current->nsproxy->net_ns; + data->lsm_opts = NULL; + } + return data; +} + +void nfs_free_parsed_mount_data(struct nfs_parsed_mount_data *data) +{ + if (data) { + kfree(data->client_address); + kfree(data->mount_server.hostname); + kfree(data->nfs_server.export_path); + kfree(data->nfs_server.hostname); + kfree(data->fscache_uniq); + security_free_mnt_opts(&data->lsm_opts); + kfree(data); + } +} + +/* + * Sanity-check a server address provided by the mount command. + * + * Address family must be initialized, and address must not be + * the ANY address for that family. + */ +static int nfs_verify_server_address(struct sockaddr *addr) +{ + switch (addr->sa_family) { + case AF_INET: { + struct sockaddr_in *sa = (struct sockaddr_in *)addr; + return sa->sin_addr.s_addr != htonl(INADDR_ANY); + } + case AF_INET6: { + struct in6_addr *sa = &((struct sockaddr_in6 *)addr)->sin6_addr; + return !ipv6_addr_any(sa); + } + } + + dfprintk(MOUNT, "NFS: Invalid IP address specified\n"); + return 0; +} + +/* + * Sanity check the NFS transport protocol. + * + */ +static void nfs_validate_transport_protocol(struct nfs_parsed_mount_data *mnt) +{ + switch (mnt->nfs_server.protocol) { + case XPRT_TRANSPORT_UDP: + case XPRT_TRANSPORT_TCP: + case XPRT_TRANSPORT_RDMA: + break; + default: + mnt->nfs_server.protocol = XPRT_TRANSPORT_TCP; + } +} + +/* + * For text based NFSv2/v3 mounts, the mount protocol transport default + * settings should depend upon the specified NFS transport. + */ +static void nfs_set_mount_transport_protocol(struct nfs_parsed_mount_data *mnt) +{ + nfs_validate_transport_protocol(mnt); + + if (mnt->mount_server.protocol == XPRT_TRANSPORT_UDP || + mnt->mount_server.protocol == XPRT_TRANSPORT_TCP) + return; + switch (mnt->nfs_server.protocol) { + case XPRT_TRANSPORT_UDP: + mnt->mount_server.protocol = XPRT_TRANSPORT_UDP; + break; + case XPRT_TRANSPORT_TCP: + case XPRT_TRANSPORT_RDMA: + mnt->mount_server.protocol = XPRT_TRANSPORT_TCP; + } +} + +/* + * Add 'flavor' to 'auth_info' if not already present. + * Returns true if 'flavor' ends up in the list, false otherwise + */ +static bool nfs_auth_info_add(struct nfs_auth_info *auth_info, + rpc_authflavor_t flavor) +{ + unsigned int i; + unsigned int max_flavor_len = ARRAY_SIZE(auth_info->flavors); + + /* make sure this flavor isn't already in the list */ + for (i = 0; i < auth_info->flavor_len; i++) { + if (flavor == auth_info->flavors[i]) + return true; + } + + if (auth_info->flavor_len + 1 >= max_flavor_len) { + dfprintk(MOUNT, "NFS: too many sec= flavors\n"); + return false; + } + + auth_info->flavors[auth_info->flavor_len++] = flavor; + return true; +} + +/* + * Parse the value of the 'sec=' option. + */ +static int nfs_parse_security_flavors(char *value, + struct nfs_parsed_mount_data *mnt) +{ + substring_t args[MAX_OPT_ARGS]; + rpc_authflavor_t pseudoflavor; + char *p; + + dfprintk(MOUNT, "NFS: parsing sec=%s option\n", value); + + while ((p = strsep(&value, ":")) != NULL) { + switch (match_token(p, nfs_secflavor_tokens, args)) { + case Opt_sec_none: + pseudoflavor = RPC_AUTH_NULL; + break; + case Opt_sec_sys: + pseudoflavor = RPC_AUTH_UNIX; + break; + case Opt_sec_krb5: + pseudoflavor = RPC_AUTH_GSS_KRB5; + break; + case Opt_sec_krb5i: + pseudoflavor = RPC_AUTH_GSS_KRB5I; + break; + case Opt_sec_krb5p: + pseudoflavor = RPC_AUTH_GSS_KRB5P; + break; + case Opt_sec_lkey: + pseudoflavor = RPC_AUTH_GSS_LKEY; + break; + case Opt_sec_lkeyi: + pseudoflavor = RPC_AUTH_GSS_LKEYI; + break; + case Opt_sec_lkeyp: + pseudoflavor = RPC_AUTH_GSS_LKEYP; + break; + case Opt_sec_spkm: + pseudoflavor = RPC_AUTH_GSS_SPKM; + break; + case Opt_sec_spkmi: + pseudoflavor = RPC_AUTH_GSS_SPKMI; + break; + case Opt_sec_spkmp: + pseudoflavor = RPC_AUTH_GSS_SPKMP; + break; + default: + dfprintk(MOUNT, + "NFS: sec= option '%s' not recognized\n", p); + return 0; + } + + if (!nfs_auth_info_add(&mnt->auth_info, pseudoflavor)) + return 0; + } + + return 1; +} + +static int nfs_parse_version_string(char *string, + struct nfs_parsed_mount_data *mnt, + substring_t *args) +{ + mnt->flags &= ~NFS_MOUNT_VER3; + switch (match_token(string, nfs_vers_tokens, args)) { + case Opt_vers_2: + mnt->version = 2; + break; + case Opt_vers_3: + mnt->flags |= NFS_MOUNT_VER3; + mnt->version = 3; + break; + case Opt_vers_4: + /* Backward compatibility option. In future, + * the mount program should always supply + * a NFSv4 minor version number. + */ + mnt->version = 4; + break; + case Opt_vers_4_0: + mnt->version = 4; + mnt->minorversion = 0; + break; + case Opt_vers_4_1: + mnt->version = 4; + mnt->minorversion = 1; + break; + case Opt_vers_4_2: + mnt->version = 4; + mnt->minorversion = 2; + break; + default: + return 0; + } + return 1; +} + +static int nfs_get_option_str(substring_t args[], char **option) +{ + kfree(*option); + *option = match_strdup(args); + return !*option; +} + +static int nfs_get_option_ul(substring_t args[], unsigned long *option) +{ + int rc; + char *string; + + string = match_strdup(args); + if (string == NULL) + return -ENOMEM; + rc = kstrtoul(string, 10, option); + kfree(string); + + return rc; +} + +static int nfs_get_option_ul_bound(substring_t args[], unsigned long *option, + unsigned long l_bound, unsigned long u_bound) +{ + int ret; + + ret = nfs_get_option_ul(args, option); + if (ret != 0) + return ret; + if (*option < l_bound || *option > u_bound) + return -ERANGE; + return 0; +} + +/* + * 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_parsed_mount_data *mnt) +{ + 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, &mnt->lsm_opts); + if (rc) + goto out_security_failure; + + 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); + switch (token) { + + /* + * boolean options: foo/nofoo + */ + case Opt_soft: + mnt->flags |= NFS_MOUNT_SOFT; + mnt->flags &= ~NFS_MOUNT_SOFTERR; + break; + case Opt_softerr: + mnt->flags |= NFS_MOUNT_SOFTERR; + mnt->flags &= ~NFS_MOUNT_SOFT; + break; + case Opt_hard: + mnt->flags &= ~(NFS_MOUNT_SOFT|NFS_MOUNT_SOFTERR); + break; + case Opt_posix: + mnt->flags |= NFS_MOUNT_POSIX; + break; + case Opt_noposix: + mnt->flags &= ~NFS_MOUNT_POSIX; + break; + case Opt_cto: + mnt->flags &= ~NFS_MOUNT_NOCTO; + break; + case Opt_nocto: + mnt->flags |= NFS_MOUNT_NOCTO; + break; + case Opt_ac: + mnt->flags &= ~NFS_MOUNT_NOAC; + break; + case Opt_noac: + mnt->flags |= NFS_MOUNT_NOAC; + break; + case Opt_lock: + mnt->flags &= ~NFS_MOUNT_NONLM; + mnt->flags &= ~(NFS_MOUNT_LOCAL_FLOCK | + NFS_MOUNT_LOCAL_FCNTL); + break; + case Opt_nolock: + mnt->flags |= NFS_MOUNT_NONLM; + mnt->flags |= (NFS_MOUNT_LOCAL_FLOCK | + NFS_MOUNT_LOCAL_FCNTL); + break; + case Opt_udp: + mnt->flags &= ~NFS_MOUNT_TCP; + mnt->nfs_server.protocol = XPRT_TRANSPORT_UDP; + break; + case Opt_tcp: + mnt->flags |= NFS_MOUNT_TCP; + mnt->nfs_server.protocol = XPRT_TRANSPORT_TCP; + break; + case Opt_rdma: + mnt->flags |= NFS_MOUNT_TCP; /* for side protocols */ + mnt->nfs_server.protocol = XPRT_TRANSPORT_RDMA; + xprt_load_transport(p); + break; + case Opt_acl: + mnt->flags &= ~NFS_MOUNT_NOACL; + break; + case Opt_noacl: + mnt->flags |= NFS_MOUNT_NOACL; + break; + case Opt_rdirplus: + mnt->flags &= ~NFS_MOUNT_NORDIRPLUS; + break; + case Opt_nordirplus: + mnt->flags |= NFS_MOUNT_NORDIRPLUS; + break; + case Opt_sharecache: + mnt->flags &= ~NFS_MOUNT_UNSHARED; + break; + case Opt_nosharecache: + mnt->flags |= NFS_MOUNT_UNSHARED; + break; + case Opt_resvport: + mnt->flags &= ~NFS_MOUNT_NORESVPORT; + break; + case Opt_noresvport: + mnt->flags |= NFS_MOUNT_NORESVPORT; + break; + case Opt_fscache: + mnt->options |= NFS_OPTION_FSCACHE; + kfree(mnt->fscache_uniq); + mnt->fscache_uniq = NULL; + break; + case Opt_nofscache: + mnt->options &= ~NFS_OPTION_FSCACHE; + kfree(mnt->fscache_uniq); + mnt->fscache_uniq = NULL; + break; + case Opt_migration: + mnt->options |= NFS_OPTION_MIGRATION; + break; + case Opt_nomigration: + mnt->options &= ~NFS_OPTION_MIGRATION; + break; + + /* + * options that take numeric values + */ + case Opt_port: + if (nfs_get_option_ul(args, &option) || + option > USHRT_MAX) + goto out_invalid_value; + mnt->nfs_server.port = option; + break; + case Opt_rsize: + if (nfs_get_option_ul(args, &option)) + goto out_invalid_value; + mnt->rsize = option; + break; + case Opt_wsize: + if (nfs_get_option_ul(args, &option)) + goto out_invalid_value; + mnt->wsize = option; + break; + case Opt_bsize: + if (nfs_get_option_ul(args, &option)) + goto out_invalid_value; + mnt->bsize = option; + break; + case Opt_timeo: + if (nfs_get_option_ul_bound(args, &option, 1, INT_MAX)) + goto out_invalid_value; + mnt->timeo = option; + break; + case Opt_retrans: + if (nfs_get_option_ul_bound(args, &option, 0, INT_MAX)) + goto out_invalid_value; + mnt->retrans = option; + break; + case Opt_acregmin: + if (nfs_get_option_ul(args, &option)) + goto out_invalid_value; + mnt->acregmin = option; + break; + case Opt_acregmax: + if (nfs_get_option_ul(args, &option)) + goto out_invalid_value; + mnt->acregmax = option; + break; + case Opt_acdirmin: + if (nfs_get_option_ul(args, &option)) + goto out_invalid_value; + mnt->acdirmin = option; + break; + case Opt_acdirmax: + if (nfs_get_option_ul(args, &option)) + goto out_invalid_value; + mnt->acdirmax = option; + break; + case Opt_actimeo: + if (nfs_get_option_ul(args, &option)) + goto out_invalid_value; + mnt->acregmin = mnt->acregmax = + mnt->acdirmin = mnt->acdirmax = option; + break; + case Opt_namelen: + if (nfs_get_option_ul(args, &option)) + goto out_invalid_value; + mnt->namlen = option; + break; + case Opt_mountport: + if (nfs_get_option_ul(args, &option) || + option > USHRT_MAX) + goto out_invalid_value; + mnt->mount_server.port = option; + break; + case Opt_mountvers: + if (nfs_get_option_ul(args, &option) || + option < NFS_MNT_VERSION || + option > NFS_MNT3_VERSION) + goto out_invalid_value; + mnt->mount_server.version = option; + break; + case Opt_minorversion: + if (nfs_get_option_ul(args, &option)) + goto out_invalid_value; + if (option > NFS4_MAX_MINOR_VERSION) + goto out_invalid_value; + mnt->minorversion = option; + break; + + /* + * options that take text values + */ + case Opt_nfsvers: + string = match_strdup(args); + if (string == NULL) + goto out_nomem; + rc = nfs_parse_version_string(string, mnt, args); + kfree(string); + if (!rc) + goto out_invalid_value; + break; + case Opt_sec: + string = match_strdup(args); + if (string == NULL) + goto out_nomem; + rc = nfs_parse_security_flavors(string, mnt); + kfree(string); + if (!rc) { + dfprintk(MOUNT, "NFS: unrecognized " + "security flavor\n"); + return 0; + } + break; + case Opt_proto: + string = match_strdup(args); + if (string == NULL) + goto out_nomem; + token = match_token(string, + nfs_xprt_protocol_tokens, args); + + protofamily = AF_INET; + switch (token) { + case Opt_xprt_udp6: + protofamily = AF_INET6; + /* fall through */ + case Opt_xprt_udp: + mnt->flags &= ~NFS_MOUNT_TCP; + mnt->nfs_server.protocol = XPRT_TRANSPORT_UDP; + break; + case Opt_xprt_tcp6: + protofamily = AF_INET6; + /* fall through */ + case Opt_xprt_tcp: + mnt->flags |= NFS_MOUNT_TCP; + mnt->nfs_server.protocol = XPRT_TRANSPORT_TCP; + break; + case Opt_xprt_rdma6: + protofamily = AF_INET6; + /* fall through */ + case Opt_xprt_rdma: + /* vector side protocols to TCP */ + mnt->flags |= NFS_MOUNT_TCP; + mnt->nfs_server.protocol = XPRT_TRANSPORT_RDMA; + xprt_load_transport(string); + break; + default: + dfprintk(MOUNT, "NFS: unrecognized " + "transport protocol\n"); + kfree(string); + return 0; + } + kfree(string); + break; + case Opt_mountproto: + string = match_strdup(args); + if (string == NULL) + goto out_nomem; + token = match_token(string, + nfs_xprt_protocol_tokens, args); + kfree(string); + + mountfamily = AF_INET; + switch (token) { + case Opt_xprt_udp6: + mountfamily = AF_INET6; + /* fall through */ + case Opt_xprt_udp: + mnt->mount_server.protocol = XPRT_TRANSPORT_UDP; + break; + case Opt_xprt_tcp6: + mountfamily = AF_INET6; + /* fall through */ + case Opt_xprt_tcp: + mnt->mount_server.protocol = XPRT_TRANSPORT_TCP; + break; + case Opt_xprt_rdma: /* not used for side protocols */ + default: + dfprintk(MOUNT, "NFS: unrecognized " + "transport protocol\n"); + return 0; + } + break; + case Opt_addr: + string = match_strdup(args); + if (string == NULL) + goto out_nomem; + mnt->nfs_server.addrlen = + rpc_pton(mnt->net, string, strlen(string), + (struct sockaddr *) + &mnt->nfs_server.address, + sizeof(mnt->nfs_server.address)); + kfree(string); + if (mnt->nfs_server.addrlen == 0) + goto out_invalid_address; + break; + case Opt_clientaddr: + if (nfs_get_option_str(args, &mnt->client_address)) + goto out_nomem; + break; + case Opt_mounthost: + if (nfs_get_option_str(args, + &mnt->mount_server.hostname)) + goto out_nomem; + break; + case Opt_mountaddr: + string = match_strdup(args); + if (string == NULL) + goto out_nomem; + mnt->mount_server.addrlen = + rpc_pton(mnt->net, string, strlen(string), + (struct sockaddr *) + &mnt->mount_server.address, + sizeof(mnt->mount_server.address)); + kfree(string); + if (mnt->mount_server.addrlen == 0) + goto out_invalid_address; + break; + case Opt_lookupcache: + string = match_strdup(args); + if (string == NULL) + goto out_nomem; + token = match_token(string, + nfs_lookupcache_tokens, args); + kfree(string); + switch (token) { + case Opt_lookupcache_all: + mnt->flags &= ~(NFS_MOUNT_LOOKUP_CACHE_NONEG|NFS_MOUNT_LOOKUP_CACHE_NONE); + break; + case Opt_lookupcache_positive: + mnt->flags &= ~NFS_MOUNT_LOOKUP_CACHE_NONE; + mnt->flags |= NFS_MOUNT_LOOKUP_CACHE_NONEG; + break; + case Opt_lookupcache_none: + mnt->flags |= NFS_MOUNT_LOOKUP_CACHE_NONEG|NFS_MOUNT_LOOKUP_CACHE_NONE; + break; + default: + dfprintk(MOUNT, "NFS: invalid " + "lookupcache argument\n"); + return 0; + }; + break; + case Opt_fscache_uniq: + if (nfs_get_option_str(args, &mnt->fscache_uniq)) + goto out_nomem; + mnt->options |= NFS_OPTION_FSCACHE; + break; + case Opt_local_lock: + string = match_strdup(args); + if (string == NULL) + goto out_nomem; + token = match_token(string, nfs_local_lock_tokens, + args); + kfree(string); + switch (token) { + case Opt_local_lock_all: + mnt->flags |= (NFS_MOUNT_LOCAL_FLOCK | + NFS_MOUNT_LOCAL_FCNTL); + break; + case Opt_local_lock_flock: + mnt->flags |= NFS_MOUNT_LOCAL_FLOCK; + break; + case Opt_local_lock_posix: + mnt->flags |= NFS_MOUNT_LOCAL_FCNTL; + break; + case Opt_local_lock_none: + mnt->flags &= ~(NFS_MOUNT_LOCAL_FLOCK | + NFS_MOUNT_LOCAL_FCNTL); + break; + default: + dfprintk(MOUNT, "NFS: invalid " + "local_lock argument\n"); + return 0; + }; + break; + + /* + * Special options + */ + case Opt_sloppy: + sloppy = 1; + dfprintk(MOUNT, "NFS: relaxing parsing rules\n"); + break; + case Opt_userspace: + case Opt_deprecated: + dfprintk(MOUNT, "NFS: ignoring mount option " + "'%s'\n", p); + break; + + default: + invalid_option = 1; + dfprintk(MOUNT, "NFS: unrecognized mount option " + "'%s'\n", p); + } + } + + if (!sloppy && invalid_option) + return 0; + + if (mnt->minorversion && mnt->version != 4) + goto out_minorversion_mismatch; + + if (mnt->options & NFS_OPTION_MIGRATION && + (mnt->version != 4 || mnt->minorversion != 0)) + goto out_migration_misuse; + + /* + * verify that any proto=/mountproto= options match the address + * families in the addr=/mountaddr= options. + */ + if (protofamily != AF_UNSPEC && + protofamily != mnt->nfs_server.address.ss_family) + goto out_proto_mismatch; + + if (mountfamily != AF_UNSPEC) { + if (mnt->mount_server.addrlen) { + if (mountfamily != mnt->mount_server.address.ss_family) + goto out_mountproto_mismatch; + } else { + if (mountfamily != mnt->nfs_server.address.ss_family) + goto out_mountproto_mismatch; + } + } + + return 1; + +out_mountproto_mismatch: + printk(KERN_INFO "NFS: mount server address does not match mountproto= " + "option\n"); + return 0; +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", mnt->version, mnt->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; +out_security_failure: + printk(KERN_INFO "NFS: security options invalid: %d\n", rc); + return 0; +} + +/* + * Split "dev_name" into "hostname:export_path". + * + * The leftmost colon demarks the split between the server's hostname + * and the export path. If the hostname starts with a left square + * bracket, then it may contain colons. + * + * Note: caller frees hostname and export path, even on error. + */ +static int nfs_parse_devname(const char *dev_name, + char **hostname, size_t maxnamlen, + char **export_path, size_t maxpathlen) +{ + size_t len; + char *end; + + if (unlikely(!dev_name || !*dev_name)) { + dfprintk(MOUNT, "NFS: device name not specified\n"); + return -EINVAL; + } + + /* Is the host name protected with square brakcets? */ + if (*dev_name == '[') { + end = strchr(++dev_name, ']'); + if (end == NULL || end[1] != ':') + goto out_bad_devname; + + len = end - dev_name; + end++; + } else { + char *comma; + + end = strchr(dev_name, ':'); + if (end == NULL) + goto out_bad_devname; + len = end - dev_name; + + /* kill possible hostname list: not supported */ + comma = strchr(dev_name, ','); + if (comma != NULL && comma < end) + len = comma - dev_name; + } + + if (len > maxnamlen) + goto out_hostname; + + /* N.B. caller will free nfs_server.hostname in all cases */ + *hostname = kstrndup(dev_name, len, GFP_KERNEL); + if (*hostname == NULL) + goto out_nomem; + len = strlen(++end); + if (len > maxpathlen) + goto out_path; + *export_path = kstrndup(end, len, GFP_KERNEL); + if (!*export_path) + goto out_nomem; + + dfprintk(MOUNT, "NFS: MNTPATH: '%s'\n", *export_path); + return 0; + +out_bad_devname: + dfprintk(MOUNT, "NFS: device name not in host:path format\n"); + return -EINVAL; + +out_nomem: + dfprintk(MOUNT, "NFS: not enough memory to parse device name\n"); + return -ENOMEM; + +out_hostname: + dfprintk(MOUNT, "NFS: server hostname too long\n"); + return -ENAMETOOLONG; + +out_path: + dfprintk(MOUNT, "NFS: export pathname too long\n"); + return -ENAMETOOLONG; +} + +/* + * Validate the NFS2/NFS3 mount data + * - fills in the mount root filehandle + * + * For option strings, user space handles the following behaviors: + * + * + DNS: mapping server host name to IP address ("addr=" option) + * + * + failure mode: how to behave if a mount request can't be handled + * immediately ("fg/bg" option) + * + * + retry: how often to retry a mount request ("retry=" option) + * + * + breaking back: trying proto=udp after proto=tcp, v2 after v3, + * mountproto=tcp after mountproto=udp, and so on + */ +static int nfs23_validate_mount_data(void *options, + struct nfs_parsed_mount_data *args, + struct nfs_fh *mntfh, + const char *dev_name) +{ + struct nfs_mount_data *data = (struct nfs_mount_data *)options; + struct sockaddr *sap = (struct sockaddr *)&args->nfs_server.address; + int extra_flags = NFS_MOUNT_LEGACY_INTERFACE; + + if (data == NULL) + goto out_no_data; + + args->version = NFS_DEFAULT_VERSION; + switch (data->version) { + case 1: + data->namlen = 0; /* fall through */ + case 2: + data->bsize = 0; /* fall through */ + case 3: + if (data->flags & NFS_MOUNT_VER3) + goto out_no_v3; + data->root.size = NFS2_FHSIZE; + memcpy(data->root.data, data->old_root.data, NFS2_FHSIZE); + /* Turn off security negotiation */ + extra_flags |= NFS_MOUNT_SECFLAVOUR; + /* fall through */ + case 4: + if (data->flags & NFS_MOUNT_SECFLAVOUR) + goto out_no_sec; + /* fall through */ + case 5: + memset(data->context, 0, sizeof(data->context)); + /* fall through */ + case 6: + if (data->flags & NFS_MOUNT_VER3) { + if (data->root.size > NFS3_FHSIZE || data->root.size == 0) + goto out_invalid_fh; + mntfh->size = data->root.size; + args->version = 3; + } else { + mntfh->size = NFS2_FHSIZE; + args->version = 2; + } + + + memcpy(mntfh->data, data->root.data, mntfh->size); + if (mntfh->size < sizeof(mntfh->data)) + memset(mntfh->data + mntfh->size, 0, + sizeof(mntfh->data) - mntfh->size); + + /* + * Translate to nfs_parsed_mount_data, which nfs_fill_super + * can deal with. + */ + args->flags = data->flags & NFS_MOUNT_FLAGMASK; + args->flags |= extra_flags; + args->rsize = data->rsize; + args->wsize = data->wsize; + args->timeo = data->timeo; + args->retrans = data->retrans; + args->acregmin = data->acregmin; + args->acregmax = data->acregmax; + args->acdirmin = data->acdirmin; + args->acdirmax = data->acdirmax; + args->need_mount = false; + + memcpy(sap, &data->addr, sizeof(data->addr)); + args->nfs_server.addrlen = sizeof(data->addr); + args->nfs_server.port = ntohs(data->addr.sin_port); + if (sap->sa_family != AF_INET || + !nfs_verify_server_address(sap)) + goto out_no_address; + + if (!(data->flags & NFS_MOUNT_TCP)) + args->nfs_server.protocol = XPRT_TRANSPORT_UDP; + /* N.B. caller will free nfs_server.hostname in all cases */ + args->nfs_server.hostname = kstrdup(data->hostname, GFP_KERNEL); + args->namlen = data->namlen; + args->bsize = data->bsize; + + if (data->flags & NFS_MOUNT_SECFLAVOUR) + args->selected_flavor = data->pseudoflavor; + else + args->selected_flavor = RPC_AUTH_UNIX; + if (!args->nfs_server.hostname) + goto out_nomem; + + if (!(data->flags & NFS_MOUNT_NONLM)) + args->flags &= ~(NFS_MOUNT_LOCAL_FLOCK| + NFS_MOUNT_LOCAL_FCNTL); + else + args->flags |= (NFS_MOUNT_LOCAL_FLOCK| + NFS_MOUNT_LOCAL_FCNTL); + /* + * The legacy version 6 binary mount data from userspace has a + * field used only to transport selinux information into the + * the kernel. To continue to support that functionality we + * have a touch of selinux knowledge here in the NFS code. The + * userspace code converted context=blah to just blah so we are + * converting back to the full string selinux understands. + */ + if (data->context[0]){ +#ifdef CONFIG_SECURITY_SELINUX + int rc; + data->context[NFS_MAX_CONTEXT_LEN] = '\0'; + rc = security_add_mnt_opt("context", data->context, + strlen(data->context), &args->lsm_opts); + if (rc) + return rc; +#else + return -EINVAL; +#endif + } + + break; + default: + return NFS_TEXT_DATA; + } + + return 0; + +out_no_data: + dfprintk(MOUNT, "NFS: mount program didn't pass any mount data\n"); + return -EINVAL; + +out_no_v3: + dfprintk(MOUNT, "NFS: nfs_mount_data version %d does not support v3\n", + data->version); + return -EINVAL; + +out_no_sec: + dfprintk(MOUNT, "NFS: nfs_mount_data version supports only AUTH_SYS\n"); + return -EINVAL; + +out_nomem: + dfprintk(MOUNT, "NFS: not enough memory to handle mount options\n"); + return -ENOMEM; + +out_no_address: + dfprintk(MOUNT, "NFS: mount program didn't pass remote address\n"); + return -EINVAL; + +out_invalid_fh: + dfprintk(MOUNT, "NFS: invalid root filehandle\n"); + return -EINVAL; +} + +#if IS_ENABLED(CONFIG_NFS_V4) + +static void nfs4_validate_mount_flags(struct nfs_parsed_mount_data *args) +{ + args->flags &= ~(NFS_MOUNT_NONLM|NFS_MOUNT_NOACL|NFS_MOUNT_VER3| + NFS_MOUNT_LOCAL_FLOCK|NFS_MOUNT_LOCAL_FCNTL); +} + +/* + * Validate NFSv4 mount options + */ +static int nfs4_validate_mount_data(void *options, + struct nfs_parsed_mount_data *args, + const char *dev_name) +{ + struct sockaddr *sap = (struct sockaddr *)&args->nfs_server.address; + struct nfs4_mount_data *data = (struct nfs4_mount_data *)options; + char *c; + + if (data == NULL) + goto out_no_data; + + args->version = 4; + + switch (data->version) { + case 1: + if (data->host_addrlen > sizeof(args->nfs_server.address)) + goto out_no_address; + if (data->host_addrlen == 0) + goto out_no_address; + args->nfs_server.addrlen = data->host_addrlen; + if (copy_from_user(sap, data->host_addr, data->host_addrlen)) + return -EFAULT; + if (!nfs_verify_server_address(sap)) + goto out_no_address; + args->nfs_server.port = ntohs(((struct sockaddr_in *)sap)->sin_port); + + if (data->auth_flavourlen) { + rpc_authflavor_t pseudoflavor; + if (data->auth_flavourlen > 1) + goto out_inval_auth; + if (copy_from_user(&pseudoflavor, + data->auth_flavours, + sizeof(pseudoflavor))) + return -EFAULT; + args->selected_flavor = pseudoflavor; + } else + args->selected_flavor = RPC_AUTH_UNIX; + + c = strndup_user(data->hostname.data, NFS4_MAXNAMLEN); + if (IS_ERR(c)) + return PTR_ERR(c); + args->nfs_server.hostname = c; + + c = strndup_user(data->mnt_path.data, NFS4_MAXPATHLEN); + if (IS_ERR(c)) + return PTR_ERR(c); + args->nfs_server.export_path = c; + dfprintk(MOUNT, "NFS: MNTPATH: '%s'\n", c); + + c = strndup_user(data->client_addr.data, 16); + if (IS_ERR(c)) + return PTR_ERR(c); + args->client_address = c; + + /* + * Translate to nfs_parsed_mount_data, which nfs4_fill_super + * can deal with. + */ + + args->flags = data->flags & NFS4_MOUNT_FLAGMASK; + args->rsize = data->rsize; + args->wsize = data->wsize; + args->timeo = data->timeo; + args->retrans = data->retrans; + args->acregmin = data->acregmin; + args->acregmax = data->acregmax; + args->acdirmin = data->acdirmin; + args->acdirmax = data->acdirmax; + args->nfs_server.protocol = data->proto; + nfs_validate_transport_protocol(args); + if (args->nfs_server.protocol == XPRT_TRANSPORT_UDP) + goto out_invalid_transport_udp; + + break; + default: + return NFS_TEXT_DATA; + } + + return 0; + +out_no_data: + dfprintk(MOUNT, "NFS4: mount program didn't pass any mount data\n"); + return -EINVAL; + +out_inval_auth: + dfprintk(MOUNT, "NFS4: Invalid number of RPC auth flavours %d\n", + data->auth_flavourlen); + return -EINVAL; + +out_no_address: + dfprintk(MOUNT, "NFS4: mount program didn't pass remote address\n"); + return -EINVAL; + +out_invalid_transport_udp: + dfprintk(MOUNT, "NFSv4: Unsupported transport protocol udp\n"); + return -EINVAL; +} + +int nfs_validate_mount_data(struct file_system_type *fs_type, + void *options, + struct nfs_parsed_mount_data *args, + struct nfs_fh *mntfh, + const char *dev_name) +{ + if (fs_type == &nfs_fs_type) + return nfs23_validate_mount_data(options, args, mntfh, dev_name); + return nfs4_validate_mount_data(options, args, dev_name); +} +#else +int nfs_validate_mount_data(struct file_system_type *fs_type, + void *options, + struct nfs_parsed_mount_data *args, + struct nfs_fh *mntfh, + const char *dev_name) +{ + return nfs23_validate_mount_data(options, args, mntfh, dev_name); +} +#endif + +int nfs_validate_text_mount_data(void *options, + struct nfs_parsed_mount_data *args, + const char *dev_name) +{ + int port = 0; + int max_namelen = PAGE_SIZE; + int max_pathlen = NFS_MAXPATHLEN; + struct sockaddr *sap = (struct sockaddr *)&args->nfs_server.address; + + if (nfs_parse_mount_options((char *)options, args) == 0) + return -EINVAL; + + if (!nfs_verify_server_address(sap)) + goto out_no_address; + + if (args->version == 4) { +#if IS_ENABLED(CONFIG_NFS_V4) + if (args->nfs_server.protocol == XPRT_TRANSPORT_RDMA) + port = NFS_RDMA_PORT; + else + port = NFS_PORT; + max_namelen = NFS4_MAXNAMLEN; + max_pathlen = NFS4_MAXPATHLEN; + nfs_validate_transport_protocol(args); + if (args->nfs_server.protocol == XPRT_TRANSPORT_UDP) + goto out_invalid_transport_udp; + nfs4_validate_mount_flags(args); +#else + goto out_v4_not_compiled; +#endif /* CONFIG_NFS_V4 */ + } else { + nfs_set_mount_transport_protocol(args); + if (args->nfs_server.protocol == XPRT_TRANSPORT_RDMA) + port = NFS_RDMA_PORT; + } + + nfs_set_port(sap, &args->nfs_server.port, port); + + return nfs_parse_devname(dev_name, + &args->nfs_server.hostname, + max_namelen, + &args->nfs_server.export_path, + max_pathlen); + +#if !IS_ENABLED(CONFIG_NFS_V4) +out_v4_not_compiled: + dfprintk(MOUNT, "NFS: NFSv4 is not compiled into kernel\n"); + return -EPROTONOSUPPORT; +#else +out_invalid_transport_udp: + dfprintk(MOUNT, "NFSv4: Unsupported transport protocol udp\n"); + return -EINVAL; +#endif /* !CONFIG_NFS_V4 */ + +out_no_address: + dfprintk(MOUNT, "NFS: mount program didn't pass remote address\n"); + return -EINVAL; +} diff --git a/fs/nfs/internal.h b/fs/nfs/internal.h index 1665e0935241..edc83c901a19 100644 --- a/fs/nfs/internal.h +++ b/fs/nfs/internal.h @@ -7,6 +7,7 @@ #include #include #include +#include #include #include @@ -231,6 +232,22 @@ extern const struct svc_version nfs4_callback_version1; extern const struct svc_version nfs4_callback_version4; struct nfs_pageio_descriptor; + +/* mount.c */ +#define NFS_TEXT_DATA 1 + +extern struct nfs_parsed_mount_data *nfs_alloc_parsed_mount_data(void); +extern void nfs_free_parsed_mount_data(struct nfs_parsed_mount_data *data); +extern int nfs_parse_mount_options(char *raw, struct nfs_parsed_mount_data *mnt); +extern int nfs_validate_mount_data(struct file_system_type *fs_type, + void *options, + struct nfs_parsed_mount_data *args, + struct nfs_fh *mntfh, + const char *dev_name); +extern int nfs_validate_text_mount_data(void *options, + struct nfs_parsed_mount_data *args, + const char *dev_name); + /* pagelist.c */ extern int __init nfs_init_nfspagecache(void); extern void nfs_destroy_nfspagecache(void); @@ -762,3 +779,15 @@ static inline bool nfs_error_is_fatal(int err) } } +/* + * Select between a default port value and a user-specified port value. + * If a zero value is set, then autobind will be used. + */ +static inline void nfs_set_port(struct sockaddr *sap, int *port, + const unsigned short default_port) +{ + if (*port == NFS_UNSPEC_PORT) + *port = default_port; + + rpc_set_port(sap, *port); +} diff --git a/fs/nfs/super.c b/fs/nfs/super.c index 37e922324e99..00368e212a85 100644 --- a/fs/nfs/super.c +++ b/fs/nfs/super.c @@ -68,224 +68,6 @@ #include "nfs.h" #define NFSDBG_FACILITY NFSDBG_VFS -#define NFS_TEXT_DATA 1 - -#if IS_ENABLED(CONFIG_NFS_V3) -#define NFS_DEFAULT_VERSION 3 -#else -#define NFS_DEFAULT_VERSION 2 -#endif - -enum { - /* Mount options that take no arguments */ - Opt_soft, Opt_softerr, Opt_hard, - Opt_posix, Opt_noposix, - Opt_cto, Opt_nocto, - Opt_ac, Opt_noac, - Opt_lock, Opt_nolock, - Opt_udp, Opt_tcp, Opt_rdma, - Opt_acl, Opt_noacl, - Opt_rdirplus, Opt_nordirplus, - Opt_sharecache, Opt_nosharecache, - Opt_resvport, Opt_noresvport, - Opt_fscache, Opt_nofscache, - Opt_migration, Opt_nomigration, - - /* Mount options that take integer arguments */ - Opt_port, - Opt_rsize, Opt_wsize, Opt_bsize, - Opt_timeo, Opt_retrans, - Opt_acregmin, Opt_acregmax, - Opt_acdirmin, Opt_acdirmax, - Opt_actimeo, - Opt_namelen, - Opt_mountport, - Opt_mountvers, - Opt_minorversion, - - /* Mount options that take string arguments */ - Opt_nfsvers, - Opt_sec, Opt_proto, Opt_mountproto, Opt_mounthost, - Opt_addr, Opt_mountaddr, Opt_clientaddr, - Opt_lookupcache, - Opt_fscache_uniq, - Opt_local_lock, - - /* Special mount options */ - Opt_userspace, Opt_deprecated, Opt_sloppy, - - Opt_err -}; - -static const match_table_t nfs_mount_option_tokens = { - { Opt_userspace, "bg" }, - { Opt_userspace, "fg" }, - { Opt_userspace, "retry=%s" }, - - { Opt_sloppy, "sloppy" }, - - { Opt_soft, "soft" }, - { Opt_softerr, "softerr" }, - { Opt_hard, "hard" }, - { Opt_deprecated, "intr" }, - { Opt_deprecated, "nointr" }, - { Opt_posix, "posix" }, - { Opt_noposix, "noposix" }, - { Opt_cto, "cto" }, - { Opt_nocto, "nocto" }, - { Opt_ac, "ac" }, - { Opt_noac, "noac" }, - { Opt_lock, "lock" }, - { Opt_nolock, "nolock" }, - { Opt_udp, "udp" }, - { Opt_tcp, "tcp" }, - { Opt_rdma, "rdma" }, - { Opt_acl, "acl" }, - { Opt_noacl, "noacl" }, - { Opt_rdirplus, "rdirplus" }, - { Opt_nordirplus, "nordirplus" }, - { Opt_sharecache, "sharecache" }, - { Opt_nosharecache, "nosharecache" }, - { Opt_resvport, "resvport" }, - { Opt_noresvport, "noresvport" }, - { Opt_fscache, "fsc" }, - { Opt_nofscache, "nofsc" }, - { Opt_migration, "migration" }, - { Opt_nomigration, "nomigration" }, - - { Opt_port, "port=%s" }, - { Opt_rsize, "rsize=%s" }, - { Opt_wsize, "wsize=%s" }, - { Opt_bsize, "bsize=%s" }, - { Opt_timeo, "timeo=%s" }, - { Opt_retrans, "retrans=%s" }, - { Opt_acregmin, "acregmin=%s" }, - { Opt_acregmax, "acregmax=%s" }, - { Opt_acdirmin, "acdirmin=%s" }, - { Opt_acdirmax, "acdirmax=%s" }, - { Opt_actimeo, "actimeo=%s" }, - { Opt_namelen, "namlen=%s" }, - { Opt_mountport, "mountport=%s" }, - { Opt_mountvers, "mountvers=%s" }, - { Opt_minorversion, "minorversion=%s" }, - - { Opt_nfsvers, "nfsvers=%s" }, - { Opt_nfsvers, "vers=%s" }, - - { Opt_sec, "sec=%s" }, - { Opt_proto, "proto=%s" }, - { Opt_mountproto, "mountproto=%s" }, - { Opt_addr, "addr=%s" }, - { Opt_clientaddr, "clientaddr=%s" }, - { Opt_mounthost, "mounthost=%s" }, - { Opt_mountaddr, "mountaddr=%s" }, - - { Opt_lookupcache, "lookupcache=%s" }, - { Opt_fscache_uniq, "fsc=%s" }, - { Opt_local_lock, "local_lock=%s" }, - - /* The following needs to be listed after all other options */ - { Opt_nfsvers, "v%s" }, - - { Opt_err, NULL } -}; - -enum { - Opt_xprt_udp, Opt_xprt_udp6, Opt_xprt_tcp, Opt_xprt_tcp6, Opt_xprt_rdma, - Opt_xprt_rdma6, - - Opt_xprt_err -}; - -static const match_table_t nfs_xprt_protocol_tokens = { - { Opt_xprt_udp, "udp" }, - { Opt_xprt_udp6, "udp6" }, - { Opt_xprt_tcp, "tcp" }, - { Opt_xprt_tcp6, "tcp6" }, - { Opt_xprt_rdma, "rdma" }, - { Opt_xprt_rdma6, "rdma6" }, - - { Opt_xprt_err, NULL } -}; - -enum { - Opt_sec_none, Opt_sec_sys, - Opt_sec_krb5, Opt_sec_krb5i, Opt_sec_krb5p, - Opt_sec_lkey, Opt_sec_lkeyi, Opt_sec_lkeyp, - Opt_sec_spkm, Opt_sec_spkmi, Opt_sec_spkmp, - - Opt_sec_err -}; - -static const match_table_t nfs_secflavor_tokens = { - { Opt_sec_none, "none" }, - { Opt_sec_none, "null" }, - { Opt_sec_sys, "sys" }, - - { Opt_sec_krb5, "krb5" }, - { Opt_sec_krb5i, "krb5i" }, - { Opt_sec_krb5p, "krb5p" }, - - { Opt_sec_lkey, "lkey" }, - { Opt_sec_lkeyi, "lkeyi" }, - { Opt_sec_lkeyp, "lkeyp" }, - - { Opt_sec_spkm, "spkm3" }, - { Opt_sec_spkmi, "spkm3i" }, - { Opt_sec_spkmp, "spkm3p" }, - - { Opt_sec_err, NULL } -}; - -enum { - Opt_lookupcache_all, Opt_lookupcache_positive, - Opt_lookupcache_none, - - Opt_lookupcache_err -}; - -static match_table_t nfs_lookupcache_tokens = { - { Opt_lookupcache_all, "all" }, - { Opt_lookupcache_positive, "pos" }, - { Opt_lookupcache_positive, "positive" }, - { Opt_lookupcache_none, "none" }, - - { Opt_lookupcache_err, NULL } -}; - -enum { - Opt_local_lock_all, Opt_local_lock_flock, Opt_local_lock_posix, - Opt_local_lock_none, - - Opt_local_lock_err -}; - -static match_table_t nfs_local_lock_tokens = { - { Opt_local_lock_all, "all" }, - { Opt_local_lock_flock, "flock" }, - { Opt_local_lock_posix, "posix" }, - { Opt_local_lock_none, "none" }, - - { Opt_local_lock_err, NULL } -}; - -enum { - Opt_vers_2, Opt_vers_3, Opt_vers_4, Opt_vers_4_0, - Opt_vers_4_1, Opt_vers_4_2, - - Opt_vers_err -}; - -static match_table_t nfs_vers_tokens = { - { Opt_vers_2, "2" }, - { Opt_vers_3, "3" }, - { Opt_vers_4, "4" }, - { Opt_vers_4_0, "4.0" }, - { Opt_vers_4_1, "4.1" }, - { Opt_vers_4_2, "4.2" }, - - { Opt_vers_err, NULL } -}; static struct dentry *nfs_prepared_mount(struct file_system_type *fs_type, int flags, const char *dev_name, void *raw_data); @@ -326,10 +108,6 @@ const struct super_operations nfs_sops = { EXPORT_SYMBOL_GPL(nfs_sops); #if IS_ENABLED(CONFIG_NFS_V4) -static void nfs4_validate_mount_flags(struct nfs_parsed_mount_data *); -static int nfs4_validate_mount_data(void *options, - struct nfs_parsed_mount_data *args, const char *dev_name); - struct file_system_type nfs4_fs_type = { .owner = THIS_MODULE, .name = "nfs4", @@ -915,141 +693,6 @@ void nfs_umount_begin(struct super_block *sb) } EXPORT_SYMBOL_GPL(nfs_umount_begin); -static struct nfs_parsed_mount_data *nfs_alloc_parsed_mount_data(void) -{ - struct nfs_parsed_mount_data *data; - - data = kzalloc(sizeof(*data), GFP_KERNEL); - if (data) { - data->timeo = NFS_UNSPEC_TIMEO; - data->retrans = NFS_UNSPEC_RETRANS; - data->acregmin = NFS_DEF_ACREGMIN; - data->acregmax = NFS_DEF_ACREGMAX; - data->acdirmin = NFS_DEF_ACDIRMIN; - data->acdirmax = NFS_DEF_ACDIRMAX; - data->mount_server.port = NFS_UNSPEC_PORT; - data->nfs_server.port = NFS_UNSPEC_PORT; - data->nfs_server.protocol = XPRT_TRANSPORT_TCP; - data->selected_flavor = RPC_AUTH_MAXFLAVOR; - data->minorversion = 0; - data->need_mount = true; - data->net = current->nsproxy->net_ns; - data->lsm_opts = NULL; - } - return data; -} - -static void nfs_free_parsed_mount_data(struct nfs_parsed_mount_data *data) -{ - if (data) { - kfree(data->client_address); - kfree(data->mount_server.hostname); - kfree(data->nfs_server.export_path); - kfree(data->nfs_server.hostname); - kfree(data->fscache_uniq); - security_free_mnt_opts(&data->lsm_opts); - kfree(data); - } -} - -/* - * Sanity-check a server address provided by the mount command. - * - * Address family must be initialized, and address must not be - * the ANY address for that family. - */ -static int nfs_verify_server_address(struct sockaddr *addr) -{ - switch (addr->sa_family) { - case AF_INET: { - struct sockaddr_in *sa = (struct sockaddr_in *)addr; - return sa->sin_addr.s_addr != htonl(INADDR_ANY); - } - case AF_INET6: { - struct in6_addr *sa = &((struct sockaddr_in6 *)addr)->sin6_addr; - return !ipv6_addr_any(sa); - } - } - - dfprintk(MOUNT, "NFS: Invalid IP address specified\n"); - return 0; -} - -/* - * Select between a default port value and a user-specified port value. - * If a zero value is set, then autobind will be used. - */ -static void nfs_set_port(struct sockaddr *sap, int *port, - const unsigned short default_port) -{ - if (*port == NFS_UNSPEC_PORT) - *port = default_port; - - rpc_set_port(sap, *port); -} - -/* - * Sanity check the NFS transport protocol. - * - */ -static void nfs_validate_transport_protocol(struct nfs_parsed_mount_data *mnt) -{ - switch (mnt->nfs_server.protocol) { - case XPRT_TRANSPORT_UDP: - case XPRT_TRANSPORT_TCP: - case XPRT_TRANSPORT_RDMA: - break; - default: - mnt->nfs_server.protocol = XPRT_TRANSPORT_TCP; - } -} - -/* - * For text based NFSv2/v3 mounts, the mount protocol transport default - * settings should depend upon the specified NFS transport. - */ -static void nfs_set_mount_transport_protocol(struct nfs_parsed_mount_data *mnt) -{ - nfs_validate_transport_protocol(mnt); - - if (mnt->mount_server.protocol == XPRT_TRANSPORT_UDP || - mnt->mount_server.protocol == XPRT_TRANSPORT_TCP) - return; - switch (mnt->nfs_server.protocol) { - case XPRT_TRANSPORT_UDP: - mnt->mount_server.protocol = XPRT_TRANSPORT_UDP; - break; - case XPRT_TRANSPORT_TCP: - case XPRT_TRANSPORT_RDMA: - mnt->mount_server.protocol = XPRT_TRANSPORT_TCP; - } -} - -/* - * Add 'flavor' to 'auth_info' if not already present. - * Returns true if 'flavor' ends up in the list, false otherwise - */ -static bool nfs_auth_info_add(struct nfs_auth_info *auth_info, - rpc_authflavor_t flavor) -{ - unsigned int i; - unsigned int max_flavor_len = ARRAY_SIZE(auth_info->flavors); - - /* make sure this flavor isn't already in the list */ - for (i = 0; i < auth_info->flavor_len; i++) { - if (flavor == auth_info->flavors[i]) - return true; - } - - if (auth_info->flavor_len + 1 >= max_flavor_len) { - dfprintk(MOUNT, "NFS: too many sec= flavors\n"); - return false; - } - - auth_info->flavors[auth_info->flavor_len++] = flavor; - return true; -} - /* * Return true if 'match' is in auth_info or auth_info is empty. * Return false otherwise. @@ -1070,622 +713,6 @@ bool nfs_auth_info_match(const struct nfs_auth_info *auth_info, } EXPORT_SYMBOL_GPL(nfs_auth_info_match); -/* - * Parse the value of the 'sec=' option. - */ -static int nfs_parse_security_flavors(char *value, - struct nfs_parsed_mount_data *mnt) -{ - substring_t args[MAX_OPT_ARGS]; - rpc_authflavor_t pseudoflavor; - char *p; - - dfprintk(MOUNT, "NFS: parsing sec=%s option\n", value); - - while ((p = strsep(&value, ":")) != NULL) { - switch (match_token(p, nfs_secflavor_tokens, args)) { - case Opt_sec_none: - pseudoflavor = RPC_AUTH_NULL; - break; - case Opt_sec_sys: - pseudoflavor = RPC_AUTH_UNIX; - break; - case Opt_sec_krb5: - pseudoflavor = RPC_AUTH_GSS_KRB5; - break; - case Opt_sec_krb5i: - pseudoflavor = RPC_AUTH_GSS_KRB5I; - break; - case Opt_sec_krb5p: - pseudoflavor = RPC_AUTH_GSS_KRB5P; - break; - case Opt_sec_lkey: - pseudoflavor = RPC_AUTH_GSS_LKEY; - break; - case Opt_sec_lkeyi: - pseudoflavor = RPC_AUTH_GSS_LKEYI; - break; - case Opt_sec_lkeyp: - pseudoflavor = RPC_AUTH_GSS_LKEYP; - break; - case Opt_sec_spkm: - pseudoflavor = RPC_AUTH_GSS_SPKM; - break; - case Opt_sec_spkmi: - pseudoflavor = RPC_AUTH_GSS_SPKMI; - break; - case Opt_sec_spkmp: - pseudoflavor = RPC_AUTH_GSS_SPKMP; - break; - default: - dfprintk(MOUNT, - "NFS: sec= option '%s' not recognized\n", p); - return 0; - } - - if (!nfs_auth_info_add(&mnt->auth_info, pseudoflavor)) - return 0; - } - - return 1; -} - -static int nfs_parse_version_string(char *string, - struct nfs_parsed_mount_data *mnt, - substring_t *args) -{ - mnt->flags &= ~NFS_MOUNT_VER3; - switch (match_token(string, nfs_vers_tokens, args)) { - case Opt_vers_2: - mnt->version = 2; - break; - case Opt_vers_3: - mnt->flags |= NFS_MOUNT_VER3; - mnt->version = 3; - break; - case Opt_vers_4: - /* Backward compatibility option. In future, - * the mount program should always supply - * a NFSv4 minor version number. - */ - mnt->version = 4; - break; - case Opt_vers_4_0: - mnt->version = 4; - mnt->minorversion = 0; - break; - case Opt_vers_4_1: - mnt->version = 4; - mnt->minorversion = 1; - break; - case Opt_vers_4_2: - mnt->version = 4; - mnt->minorversion = 2; - break; - default: - return 0; - } - return 1; -} - -static int nfs_get_option_str(substring_t args[], char **option) -{ - kfree(*option); - *option = match_strdup(args); - return !*option; -} - -static int nfs_get_option_ul(substring_t args[], unsigned long *option) -{ - int rc; - char *string; - - string = match_strdup(args); - if (string == NULL) - return -ENOMEM; - rc = kstrtoul(string, 10, option); - kfree(string); - - return rc; -} - -static int nfs_get_option_ul_bound(substring_t args[], unsigned long *option, - unsigned long l_bound, unsigned long u_bound) -{ - int ret; - - ret = nfs_get_option_ul(args, option); - if (ret != 0) - return ret; - if (*option < l_bound || *option > u_bound) - return -ERANGE; - return 0; -} - -/* - * 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). - */ -static int nfs_parse_mount_options(char *raw, - struct nfs_parsed_mount_data *mnt) -{ - 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, &mnt->lsm_opts); - if (rc) - goto out_security_failure; - - 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); - switch (token) { - - /* - * boolean options: foo/nofoo - */ - case Opt_soft: - mnt->flags |= NFS_MOUNT_SOFT; - mnt->flags &= ~NFS_MOUNT_SOFTERR; - break; - case Opt_softerr: - mnt->flags |= NFS_MOUNT_SOFTERR; - mnt->flags &= ~NFS_MOUNT_SOFT; - break; - case Opt_hard: - mnt->flags &= ~(NFS_MOUNT_SOFT|NFS_MOUNT_SOFTERR); - break; - case Opt_posix: - mnt->flags |= NFS_MOUNT_POSIX; - break; - case Opt_noposix: - mnt->flags &= ~NFS_MOUNT_POSIX; - break; - case Opt_cto: - mnt->flags &= ~NFS_MOUNT_NOCTO; - break; - case Opt_nocto: - mnt->flags |= NFS_MOUNT_NOCTO; - break; - case Opt_ac: - mnt->flags &= ~NFS_MOUNT_NOAC; - break; - case Opt_noac: - mnt->flags |= NFS_MOUNT_NOAC; - break; - case Opt_lock: - mnt->flags &= ~NFS_MOUNT_NONLM; - mnt->flags &= ~(NFS_MOUNT_LOCAL_FLOCK | - NFS_MOUNT_LOCAL_FCNTL); - break; - case Opt_nolock: - mnt->flags |= NFS_MOUNT_NONLM; - mnt->flags |= (NFS_MOUNT_LOCAL_FLOCK | - NFS_MOUNT_LOCAL_FCNTL); - break; - case Opt_udp: - mnt->flags &= ~NFS_MOUNT_TCP; - mnt->nfs_server.protocol = XPRT_TRANSPORT_UDP; - break; - case Opt_tcp: - mnt->flags |= NFS_MOUNT_TCP; - mnt->nfs_server.protocol = XPRT_TRANSPORT_TCP; - break; - case Opt_rdma: - mnt->flags |= NFS_MOUNT_TCP; /* for side protocols */ - mnt->nfs_server.protocol = XPRT_TRANSPORT_RDMA; - xprt_load_transport(p); - break; - case Opt_acl: - mnt->flags &= ~NFS_MOUNT_NOACL; - break; - case Opt_noacl: - mnt->flags |= NFS_MOUNT_NOACL; - break; - case Opt_rdirplus: - mnt->flags &= ~NFS_MOUNT_NORDIRPLUS; - break; - case Opt_nordirplus: - mnt->flags |= NFS_MOUNT_NORDIRPLUS; - break; - case Opt_sharecache: - mnt->flags &= ~NFS_MOUNT_UNSHARED; - break; - case Opt_nosharecache: - mnt->flags |= NFS_MOUNT_UNSHARED; - break; - case Opt_resvport: - mnt->flags &= ~NFS_MOUNT_NORESVPORT; - break; - case Opt_noresvport: - mnt->flags |= NFS_MOUNT_NORESVPORT; - break; - case Opt_fscache: - mnt->options |= NFS_OPTION_FSCACHE; - kfree(mnt->fscache_uniq); - mnt->fscache_uniq = NULL; - break; - case Opt_nofscache: - mnt->options &= ~NFS_OPTION_FSCACHE; - kfree(mnt->fscache_uniq); - mnt->fscache_uniq = NULL; - break; - case Opt_migration: - mnt->options |= NFS_OPTION_MIGRATION; - break; - case Opt_nomigration: - mnt->options &= ~NFS_OPTION_MIGRATION; - break; - - /* - * options that take numeric values - */ - case Opt_port: - if (nfs_get_option_ul(args, &option) || - option > USHRT_MAX) - goto out_invalid_value; - mnt->nfs_server.port = option; - break; - case Opt_rsize: - if (nfs_get_option_ul(args, &option)) - goto out_invalid_value; - mnt->rsize = option; - break; - case Opt_wsize: - if (nfs_get_option_ul(args, &option)) - goto out_invalid_value; - mnt->wsize = option; - break; - case Opt_bsize: - if (nfs_get_option_ul(args, &option)) - goto out_invalid_value; - mnt->bsize = option; - break; - case Opt_timeo: - if (nfs_get_option_ul_bound(args, &option, 1, INT_MAX)) - goto out_invalid_value; - mnt->timeo = option; - break; - case Opt_retrans: - if (nfs_get_option_ul_bound(args, &option, 0, INT_MAX)) - goto out_invalid_value; - mnt->retrans = option; - break; - case Opt_acregmin: - if (nfs_get_option_ul(args, &option)) - goto out_invalid_value; - mnt->acregmin = option; - break; - case Opt_acregmax: - if (nfs_get_option_ul(args, &option)) - goto out_invalid_value; - mnt->acregmax = option; - break; - case Opt_acdirmin: - if (nfs_get_option_ul(args, &option)) - goto out_invalid_value; - mnt->acdirmin = option; - break; - case Opt_acdirmax: - if (nfs_get_option_ul(args, &option)) - goto out_invalid_value; - mnt->acdirmax = option; - break; - case Opt_actimeo: - if (nfs_get_option_ul(args, &option)) - goto out_invalid_value; - mnt->acregmin = mnt->acregmax = - mnt->acdirmin = mnt->acdirmax = option; - break; - case Opt_namelen: - if (nfs_get_option_ul(args, &option)) - goto out_invalid_value; - mnt->namlen = option; - break; - case Opt_mountport: - if (nfs_get_option_ul(args, &option) || - option > USHRT_MAX) - goto out_invalid_value; - mnt->mount_server.port = option; - break; - case Opt_mountvers: - if (nfs_get_option_ul(args, &option) || - option < NFS_MNT_VERSION || - option > NFS_MNT3_VERSION) - goto out_invalid_value; - mnt->mount_server.version = option; - break; - case Opt_minorversion: - if (nfs_get_option_ul(args, &option)) - goto out_invalid_value; - if (option > NFS4_MAX_MINOR_VERSION) - goto out_invalid_value; - mnt->minorversion = option; - break; - - /* - * options that take text values - */ - case Opt_nfsvers: - string = match_strdup(args); - if (string == NULL) - goto out_nomem; - rc = nfs_parse_version_string(string, mnt, args); - kfree(string); - if (!rc) - goto out_invalid_value; - break; - case Opt_sec: - string = match_strdup(args); - if (string == NULL) - goto out_nomem; - rc = nfs_parse_security_flavors(string, mnt); - kfree(string); - if (!rc) { - dfprintk(MOUNT, "NFS: unrecognized " - "security flavor\n"); - return 0; - } - break; - case Opt_proto: - string = match_strdup(args); - if (string == NULL) - goto out_nomem; - token = match_token(string, - nfs_xprt_protocol_tokens, args); - - protofamily = AF_INET; - switch (token) { - case Opt_xprt_udp6: - protofamily = AF_INET6; - /* fall through */ - case Opt_xprt_udp: - mnt->flags &= ~NFS_MOUNT_TCP; - mnt->nfs_server.protocol = XPRT_TRANSPORT_UDP; - break; - case Opt_xprt_tcp6: - protofamily = AF_INET6; - /* fall through */ - case Opt_xprt_tcp: - mnt->flags |= NFS_MOUNT_TCP; - mnt->nfs_server.protocol = XPRT_TRANSPORT_TCP; - break; - case Opt_xprt_rdma6: - protofamily = AF_INET6; - /* fall through */ - case Opt_xprt_rdma: - /* vector side protocols to TCP */ - mnt->flags |= NFS_MOUNT_TCP; - mnt->nfs_server.protocol = XPRT_TRANSPORT_RDMA; - xprt_load_transport(string); - break; - default: - dfprintk(MOUNT, "NFS: unrecognized " - "transport protocol\n"); - kfree(string); - return 0; - } - kfree(string); - break; - case Opt_mountproto: - string = match_strdup(args); - if (string == NULL) - goto out_nomem; - token = match_token(string, - nfs_xprt_protocol_tokens, args); - kfree(string); - - mountfamily = AF_INET; - switch (token) { - case Opt_xprt_udp6: - mountfamily = AF_INET6; - /* fall through */ - case Opt_xprt_udp: - mnt->mount_server.protocol = XPRT_TRANSPORT_UDP; - break; - case Opt_xprt_tcp6: - mountfamily = AF_INET6; - /* fall through */ - case Opt_xprt_tcp: - mnt->mount_server.protocol = XPRT_TRANSPORT_TCP; - break; - case Opt_xprt_rdma: /* not used for side protocols */ - default: - dfprintk(MOUNT, "NFS: unrecognized " - "transport protocol\n"); - return 0; - } - break; - case Opt_addr: - string = match_strdup(args); - if (string == NULL) - goto out_nomem; - mnt->nfs_server.addrlen = - rpc_pton(mnt->net, string, strlen(string), - (struct sockaddr *) - &mnt->nfs_server.address, - sizeof(mnt->nfs_server.address)); - kfree(string); - if (mnt->nfs_server.addrlen == 0) - goto out_invalid_address; - break; - case Opt_clientaddr: - if (nfs_get_option_str(args, &mnt->client_address)) - goto out_nomem; - break; - case Opt_mounthost: - if (nfs_get_option_str(args, - &mnt->mount_server.hostname)) - goto out_nomem; - break; - case Opt_mountaddr: - string = match_strdup(args); - if (string == NULL) - goto out_nomem; - mnt->mount_server.addrlen = - rpc_pton(mnt->net, string, strlen(string), - (struct sockaddr *) - &mnt->mount_server.address, - sizeof(mnt->mount_server.address)); - kfree(string); - if (mnt->mount_server.addrlen == 0) - goto out_invalid_address; - break; - case Opt_lookupcache: - string = match_strdup(args); - if (string == NULL) - goto out_nomem; - token = match_token(string, - nfs_lookupcache_tokens, args); - kfree(string); - switch (token) { - case Opt_lookupcache_all: - mnt->flags &= ~(NFS_MOUNT_LOOKUP_CACHE_NONEG|NFS_MOUNT_LOOKUP_CACHE_NONE); - break; - case Opt_lookupcache_positive: - mnt->flags &= ~NFS_MOUNT_LOOKUP_CACHE_NONE; - mnt->flags |= NFS_MOUNT_LOOKUP_CACHE_NONEG; - break; - case Opt_lookupcache_none: - mnt->flags |= NFS_MOUNT_LOOKUP_CACHE_NONEG|NFS_MOUNT_LOOKUP_CACHE_NONE; - break; - default: - dfprintk(MOUNT, "NFS: invalid " - "lookupcache argument\n"); - return 0; - }; - break; - case Opt_fscache_uniq: - if (nfs_get_option_str(args, &mnt->fscache_uniq)) - goto out_nomem; - mnt->options |= NFS_OPTION_FSCACHE; - break; - case Opt_local_lock: - string = match_strdup(args); - if (string == NULL) - goto out_nomem; - token = match_token(string, nfs_local_lock_tokens, - args); - kfree(string); - switch (token) { - case Opt_local_lock_all: - mnt->flags |= (NFS_MOUNT_LOCAL_FLOCK | - NFS_MOUNT_LOCAL_FCNTL); - break; - case Opt_local_lock_flock: - mnt->flags |= NFS_MOUNT_LOCAL_FLOCK; - break; - case Opt_local_lock_posix: - mnt->flags |= NFS_MOUNT_LOCAL_FCNTL; - break; - case Opt_local_lock_none: - mnt->flags &= ~(NFS_MOUNT_LOCAL_FLOCK | - NFS_MOUNT_LOCAL_FCNTL); - break; - default: - dfprintk(MOUNT, "NFS: invalid " - "local_lock argument\n"); - return 0; - }; - break; - - /* - * Special options - */ - case Opt_sloppy: - sloppy = 1; - dfprintk(MOUNT, "NFS: relaxing parsing rules\n"); - break; - case Opt_userspace: - case Opt_deprecated: - dfprintk(MOUNT, "NFS: ignoring mount option " - "'%s'\n", p); - break; - - default: - invalid_option = 1; - dfprintk(MOUNT, "NFS: unrecognized mount option " - "'%s'\n", p); - } - } - - if (!sloppy && invalid_option) - return 0; - - if (mnt->minorversion && mnt->version != 4) - goto out_minorversion_mismatch; - - if (mnt->options & NFS_OPTION_MIGRATION && - (mnt->version != 4 || mnt->minorversion != 0)) - goto out_migration_misuse; - - /* - * verify that any proto=/mountproto= options match the address - * families in the addr=/mountaddr= options. - */ - if (protofamily != AF_UNSPEC && - protofamily != mnt->nfs_server.address.ss_family) - goto out_proto_mismatch; - - if (mountfamily != AF_UNSPEC) { - if (mnt->mount_server.addrlen) { - if (mountfamily != mnt->mount_server.address.ss_family) - goto out_mountproto_mismatch; - } else { - if (mountfamily != mnt->nfs_server.address.ss_family) - goto out_mountproto_mismatch; - } - } - - return 1; - -out_mountproto_mismatch: - printk(KERN_INFO "NFS: mount server address does not match mountproto= " - "option\n"); - return 0; -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", mnt->version, mnt->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; -out_security_failure: - printk(KERN_INFO "NFS: security options invalid: %d\n", rc); - return 0; -} - /* * Ensure that a specified authtype in args->auth_info is supported by * the server. Returns 0 and sets args->selected_flavor if it's ok, and @@ -1886,327 +913,6 @@ struct dentry *nfs_try_mount(int flags, const char *dev_name, } EXPORT_SYMBOL_GPL(nfs_try_mount); -/* - * Split "dev_name" into "hostname:export_path". - * - * The leftmost colon demarks the split between the server's hostname - * and the export path. If the hostname starts with a left square - * bracket, then it may contain colons. - * - * Note: caller frees hostname and export path, even on error. - */ -static int nfs_parse_devname(const char *dev_name, - char **hostname, size_t maxnamlen, - char **export_path, size_t maxpathlen) -{ - size_t len; - char *end; - - if (unlikely(!dev_name || !*dev_name)) { - dfprintk(MOUNT, "NFS: device name not specified\n"); - return -EINVAL; - } - - /* Is the host name protected with square brakcets? */ - if (*dev_name == '[') { - end = strchr(++dev_name, ']'); - if (end == NULL || end[1] != ':') - goto out_bad_devname; - - len = end - dev_name; - end++; - } else { - char *comma; - - end = strchr(dev_name, ':'); - if (end == NULL) - goto out_bad_devname; - len = end - dev_name; - - /* kill possible hostname list: not supported */ - comma = strchr(dev_name, ','); - if (comma != NULL && comma < end) - len = comma - dev_name; - } - - if (len > maxnamlen) - goto out_hostname; - - /* N.B. caller will free nfs_server.hostname in all cases */ - *hostname = kstrndup(dev_name, len, GFP_KERNEL); - if (*hostname == NULL) - goto out_nomem; - len = strlen(++end); - if (len > maxpathlen) - goto out_path; - *export_path = kstrndup(end, len, GFP_KERNEL); - if (!*export_path) - goto out_nomem; - - dfprintk(MOUNT, "NFS: MNTPATH: '%s'\n", *export_path); - return 0; - -out_bad_devname: - dfprintk(MOUNT, "NFS: device name not in host:path format\n"); - return -EINVAL; - -out_nomem: - dfprintk(MOUNT, "NFS: not enough memory to parse device name\n"); - return -ENOMEM; - -out_hostname: - dfprintk(MOUNT, "NFS: server hostname too long\n"); - return -ENAMETOOLONG; - -out_path: - dfprintk(MOUNT, "NFS: export pathname too long\n"); - return -ENAMETOOLONG; -} - -/* - * Validate the NFS2/NFS3 mount data - * - fills in the mount root filehandle - * - * For option strings, user space handles the following behaviors: - * - * + DNS: mapping server host name to IP address ("addr=" option) - * - * + failure mode: how to behave if a mount request can't be handled - * immediately ("fg/bg" option) - * - * + retry: how often to retry a mount request ("retry=" option) - * - * + breaking back: trying proto=udp after proto=tcp, v2 after v3, - * mountproto=tcp after mountproto=udp, and so on - */ -static int nfs23_validate_mount_data(void *options, - struct nfs_parsed_mount_data *args, - struct nfs_fh *mntfh, - const char *dev_name) -{ - struct nfs_mount_data *data = (struct nfs_mount_data *)options; - struct sockaddr *sap = (struct sockaddr *)&args->nfs_server.address; - int extra_flags = NFS_MOUNT_LEGACY_INTERFACE; - - if (data == NULL) - goto out_no_data; - - args->version = NFS_DEFAULT_VERSION; - switch (data->version) { - case 1: - data->namlen = 0; /* fall through */ - case 2: - data->bsize = 0; /* fall through */ - case 3: - if (data->flags & NFS_MOUNT_VER3) - goto out_no_v3; - data->root.size = NFS2_FHSIZE; - memcpy(data->root.data, data->old_root.data, NFS2_FHSIZE); - /* Turn off security negotiation */ - extra_flags |= NFS_MOUNT_SECFLAVOUR; - /* fall through */ - case 4: - if (data->flags & NFS_MOUNT_SECFLAVOUR) - goto out_no_sec; - /* fall through */ - case 5: - memset(data->context, 0, sizeof(data->context)); - /* fall through */ - case 6: - if (data->flags & NFS_MOUNT_VER3) { - if (data->root.size > NFS3_FHSIZE || data->root.size == 0) - goto out_invalid_fh; - mntfh->size = data->root.size; - args->version = 3; - } else { - mntfh->size = NFS2_FHSIZE; - args->version = 2; - } - - - memcpy(mntfh->data, data->root.data, mntfh->size); - if (mntfh->size < sizeof(mntfh->data)) - memset(mntfh->data + mntfh->size, 0, - sizeof(mntfh->data) - mntfh->size); - - /* - * Translate to nfs_parsed_mount_data, which nfs_fill_super - * can deal with. - */ - args->flags = data->flags & NFS_MOUNT_FLAGMASK; - args->flags |= extra_flags; - args->rsize = data->rsize; - args->wsize = data->wsize; - args->timeo = data->timeo; - args->retrans = data->retrans; - args->acregmin = data->acregmin; - args->acregmax = data->acregmax; - args->acdirmin = data->acdirmin; - args->acdirmax = data->acdirmax; - args->need_mount = false; - - memcpy(sap, &data->addr, sizeof(data->addr)); - args->nfs_server.addrlen = sizeof(data->addr); - args->nfs_server.port = ntohs(data->addr.sin_port); - if (sap->sa_family != AF_INET || - !nfs_verify_server_address(sap)) - goto out_no_address; - - if (!(data->flags & NFS_MOUNT_TCP)) - args->nfs_server.protocol = XPRT_TRANSPORT_UDP; - /* N.B. caller will free nfs_server.hostname in all cases */ - args->nfs_server.hostname = kstrdup(data->hostname, GFP_KERNEL); - args->namlen = data->namlen; - args->bsize = data->bsize; - - if (data->flags & NFS_MOUNT_SECFLAVOUR) - args->selected_flavor = data->pseudoflavor; - else - args->selected_flavor = RPC_AUTH_UNIX; - if (!args->nfs_server.hostname) - goto out_nomem; - - if (!(data->flags & NFS_MOUNT_NONLM)) - args->flags &= ~(NFS_MOUNT_LOCAL_FLOCK| - NFS_MOUNT_LOCAL_FCNTL); - else - args->flags |= (NFS_MOUNT_LOCAL_FLOCK| - NFS_MOUNT_LOCAL_FCNTL); - /* - * The legacy version 6 binary mount data from userspace has a - * field used only to transport selinux information into the - * the kernel. To continue to support that functionality we - * have a touch of selinux knowledge here in the NFS code. The - * userspace code converted context=blah to just blah so we are - * converting back to the full string selinux understands. - */ - if (data->context[0]){ -#ifdef CONFIG_SECURITY_SELINUX - int rc; - data->context[NFS_MAX_CONTEXT_LEN] = '\0'; - rc = security_add_mnt_opt("context", data->context, - strlen(data->context), &args->lsm_opts); - if (rc) - return rc; -#else - return -EINVAL; -#endif - } - - break; - default: - return NFS_TEXT_DATA; - } - - return 0; - -out_no_data: - dfprintk(MOUNT, "NFS: mount program didn't pass any mount data\n"); - return -EINVAL; - -out_no_v3: - dfprintk(MOUNT, "NFS: nfs_mount_data version %d does not support v3\n", - data->version); - return -EINVAL; - -out_no_sec: - dfprintk(MOUNT, "NFS: nfs_mount_data version supports only AUTH_SYS\n"); - return -EINVAL; - -out_nomem: - dfprintk(MOUNT, "NFS: not enough memory to handle mount options\n"); - return -ENOMEM; - -out_no_address: - dfprintk(MOUNT, "NFS: mount program didn't pass remote address\n"); - return -EINVAL; - -out_invalid_fh: - dfprintk(MOUNT, "NFS: invalid root filehandle\n"); - return -EINVAL; -} - -#if IS_ENABLED(CONFIG_NFS_V4) -static int nfs_validate_mount_data(struct file_system_type *fs_type, - void *options, - struct nfs_parsed_mount_data *args, - struct nfs_fh *mntfh, - const char *dev_name) -{ - if (fs_type == &nfs_fs_type) - return nfs23_validate_mount_data(options, args, mntfh, dev_name); - return nfs4_validate_mount_data(options, args, dev_name); -} -#else -static int nfs_validate_mount_data(struct file_system_type *fs_type, - void *options, - struct nfs_parsed_mount_data *args, - struct nfs_fh *mntfh, - const char *dev_name) -{ - return nfs23_validate_mount_data(options, args, mntfh, dev_name); -} -#endif - -static int nfs_validate_text_mount_data(void *options, - struct nfs_parsed_mount_data *args, - const char *dev_name) -{ - int port = 0; - int max_namelen = PAGE_SIZE; - int max_pathlen = NFS_MAXPATHLEN; - struct sockaddr *sap = (struct sockaddr *)&args->nfs_server.address; - - if (nfs_parse_mount_options((char *)options, args) == 0) - return -EINVAL; - - if (!nfs_verify_server_address(sap)) - goto out_no_address; - - if (args->version == 4) { -#if IS_ENABLED(CONFIG_NFS_V4) - if (args->nfs_server.protocol == XPRT_TRANSPORT_RDMA) - port = NFS_RDMA_PORT; - else - port = NFS_PORT; - max_namelen = NFS4_MAXNAMLEN; - max_pathlen = NFS4_MAXPATHLEN; - nfs_validate_transport_protocol(args); - if (args->nfs_server.protocol == XPRT_TRANSPORT_UDP) - goto out_invalid_transport_udp; - nfs4_validate_mount_flags(args); -#else - goto out_v4_not_compiled; -#endif /* CONFIG_NFS_V4 */ - } else { - nfs_set_mount_transport_protocol(args); - if (args->nfs_server.protocol == XPRT_TRANSPORT_RDMA) - port = NFS_RDMA_PORT; - } - - nfs_set_port(sap, &args->nfs_server.port, port); - - return nfs_parse_devname(dev_name, - &args->nfs_server.hostname, - max_namelen, - &args->nfs_server.export_path, - max_pathlen); - -#if !IS_ENABLED(CONFIG_NFS_V4) -out_v4_not_compiled: - dfprintk(MOUNT, "NFS: NFSv4 is not compiled into kernel\n"); - return -EPROTONOSUPPORT; -#else -out_invalid_transport_udp: - dfprintk(MOUNT, "NFSv4: Unsupported transport protocol udp\n"); - return -EINVAL; -#endif /* !CONFIG_NFS_V4 */ - -out_no_address: - dfprintk(MOUNT, "NFS: mount program didn't pass remote address\n"); - return -EINVAL; -} - #define NFS_REMOUNT_CMP_FLAGMASK ~(NFS_MOUNT_INTR \ | NFS_MOUNT_SECURE \ | NFS_MOUNT_TCP \ @@ -2696,113 +1402,6 @@ nfs_prepared_mount(struct file_system_type *fs_type, int flags, #if IS_ENABLED(CONFIG_NFS_V4) -static void nfs4_validate_mount_flags(struct nfs_parsed_mount_data *args) -{ - args->flags &= ~(NFS_MOUNT_NONLM|NFS_MOUNT_NOACL|NFS_MOUNT_VER3| - NFS_MOUNT_LOCAL_FLOCK|NFS_MOUNT_LOCAL_FCNTL); -} - -/* - * Validate NFSv4 mount options - */ -static int nfs4_validate_mount_data(void *options, - struct nfs_parsed_mount_data *args, - const char *dev_name) -{ - struct sockaddr *sap = (struct sockaddr *)&args->nfs_server.address; - struct nfs4_mount_data *data = (struct nfs4_mount_data *)options; - char *c; - - if (data == NULL) - goto out_no_data; - - args->version = 4; - - switch (data->version) { - case 1: - if (data->host_addrlen > sizeof(args->nfs_server.address)) - goto out_no_address; - if (data->host_addrlen == 0) - goto out_no_address; - args->nfs_server.addrlen = data->host_addrlen; - if (copy_from_user(sap, data->host_addr, data->host_addrlen)) - return -EFAULT; - if (!nfs_verify_server_address(sap)) - goto out_no_address; - args->nfs_server.port = ntohs(((struct sockaddr_in *)sap)->sin_port); - - if (data->auth_flavourlen) { - rpc_authflavor_t pseudoflavor; - if (data->auth_flavourlen > 1) - goto out_inval_auth; - if (copy_from_user(&pseudoflavor, - data->auth_flavours, - sizeof(pseudoflavor))) - return -EFAULT; - args->selected_flavor = pseudoflavor; - } else - args->selected_flavor = RPC_AUTH_UNIX; - - c = strndup_user(data->hostname.data, NFS4_MAXNAMLEN); - if (IS_ERR(c)) - return PTR_ERR(c); - args->nfs_server.hostname = c; - - c = strndup_user(data->mnt_path.data, NFS4_MAXPATHLEN); - if (IS_ERR(c)) - return PTR_ERR(c); - args->nfs_server.export_path = c; - dfprintk(MOUNT, "NFS: MNTPATH: '%s'\n", c); - - c = strndup_user(data->client_addr.data, 16); - if (IS_ERR(c)) - return PTR_ERR(c); - args->client_address = c; - - /* - * Translate to nfs_parsed_mount_data, which nfs4_fill_super - * can deal with. - */ - - args->flags = data->flags & NFS4_MOUNT_FLAGMASK; - args->rsize = data->rsize; - args->wsize = data->wsize; - args->timeo = data->timeo; - args->retrans = data->retrans; - args->acregmin = data->acregmin; - args->acregmax = data->acregmax; - args->acdirmin = data->acdirmin; - args->acdirmax = data->acdirmax; - args->nfs_server.protocol = data->proto; - nfs_validate_transport_protocol(args); - if (args->nfs_server.protocol == XPRT_TRANSPORT_UDP) - goto out_invalid_transport_udp; - - break; - default: - return NFS_TEXT_DATA; - } - - return 0; - -out_no_data: - dfprintk(MOUNT, "NFS4: mount program didn't pass any mount data\n"); - return -EINVAL; - -out_inval_auth: - dfprintk(MOUNT, "NFS4: Invalid number of RPC auth flavours %d\n", - data->auth_flavourlen); - return -EINVAL; - -out_no_address: - dfprintk(MOUNT, "NFS4: mount program didn't pass remote address\n"); - return -EINVAL; - -out_invalid_transport_udp: - dfprintk(MOUNT, "NFSv4: Unsupported transport protocol udp\n"); - return -EINVAL; -} - /* * NFS v4 module parameters need to stay in the * NFS client for backwards compatibility From patchwork Thu May 23 16:18:18 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Howells X-Patchwork-Id: 10958315 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 84D56933 for ; Thu, 23 May 2019 16:18:26 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 712E2286B3 for ; Thu, 23 May 2019 16:18:26 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 65703286C4; Thu, 23 May 2019 16:18:26 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-7.9 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI, RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 1DA2F283E8 for ; Thu, 23 May 2019 16:18:26 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1731540AbfEWQSV (ORCPT ); Thu, 23 May 2019 12:18:21 -0400 Received: from mx1.redhat.com ([209.132.183.28]:57232 "EHLO mx1.redhat.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1730951AbfEWQSV (ORCPT ); Thu, 23 May 2019 12:18:21 -0400 Received: from smtp.corp.redhat.com (int-mx07.intmail.prod.int.phx2.redhat.com [10.5.11.22]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id D596220276; Thu, 23 May 2019 16:18:20 +0000 (UTC) Received: from warthog.procyon.org.uk (ovpn-121-142.rdu2.redhat.com [10.10.121.142]) by smtp.corp.redhat.com (Postfix) with ESMTP id 853FC10027C6; Thu, 23 May 2019 16:18:19 +0000 (UTC) Organization: Red Hat UK Ltd. Registered Address: Red Hat UK Ltd, Amberley Place, 107-111 Peascod Street, Windsor, Berkshire, SI4 1TE, United Kingdom. Registered in England and Wales under Company Registration No. 3798903 Subject: [PATCH 17/23] NFS: Constify mount argument match tables From: David Howells To: trond.myklebust@hammerspace.com, anna.schumaker@netapp.com Cc: Al Viro , dhowells@redhat.com, viro@zeniv.linux.org.uk, linux-nfs@vger.kernel.org, linux-fsdevel@vger.kernel.org, linux-kernel@vger.kernel.org Date: Thu, 23 May 2019 17:18:18 +0100 Message-ID: <155862829878.26654.11973311261680429646.stgit@warthog.procyon.org.uk> In-Reply-To: <155862813755.26654.563679411147031501.stgit@warthog.procyon.org.uk> References: <155862813755.26654.563679411147031501.stgit@warthog.procyon.org.uk> User-Agent: StGit/unknown-version MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.84 on 10.5.11.22 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.29]); Thu, 23 May 2019 16:18:20 +0000 (UTC) Sender: linux-fsdevel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-fsdevel@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP The mount argument match tables should never be altered so constify them. Signed-off-by: David Howells Signed-off-by: Al Viro --- fs/nfs/fs_context.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/fs/nfs/fs_context.c b/fs/nfs/fs_context.c index 9711a2c7b479..265c22b3367f 100644 --- a/fs/nfs/fs_context.c +++ b/fs/nfs/fs_context.c @@ -198,7 +198,7 @@ enum { Opt_lookupcache_err }; -static match_table_t nfs_lookupcache_tokens = { +static const match_table_t nfs_lookupcache_tokens = { { Opt_lookupcache_all, "all" }, { Opt_lookupcache_positive, "pos" }, { Opt_lookupcache_positive, "positive" }, @@ -214,7 +214,7 @@ enum { Opt_local_lock_err }; -static match_table_t nfs_local_lock_tokens = { +static const match_table_t nfs_local_lock_tokens = { { Opt_local_lock_all, "all" }, { Opt_local_lock_flock, "flock" }, { Opt_local_lock_posix, "posix" }, @@ -230,7 +230,7 @@ enum { Opt_vers_err }; -static match_table_t nfs_vers_tokens = { +static const match_table_t nfs_vers_tokens = { { Opt_vers_2, "2" }, { Opt_vers_3, "3" }, { Opt_vers_4, "4" }, From patchwork Thu May 23 16:18:26 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Howells X-Patchwork-Id: 10958323 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 7B240933 for ; Thu, 23 May 2019 16:18:38 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 6155527D4A for ; Thu, 23 May 2019 16:18:38 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 5589228451; Thu, 23 May 2019 16:18:38 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-7.9 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI, RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 53EC527D4A for ; Thu, 23 May 2019 16:18:35 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1731329AbfEWQSa (ORCPT ); Thu, 23 May 2019 12:18:30 -0400 Received: from mx1.redhat.com ([209.132.183.28]:38516 "EHLO mx1.redhat.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1730860AbfEWQS3 (ORCPT ); Thu, 23 May 2019 12:18:29 -0400 Received: from smtp.corp.redhat.com (int-mx06.intmail.prod.int.phx2.redhat.com [10.5.11.16]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 06AC8317917D; Thu, 23 May 2019 16:18:29 +0000 (UTC) Received: from warthog.procyon.org.uk (ovpn-121-142.rdu2.redhat.com [10.10.121.142]) by smtp.corp.redhat.com (Postfix) with ESMTP id D9F845C219; Thu, 23 May 2019 16:18:26 +0000 (UTC) Organization: Red Hat UK Ltd. Registered Address: Red Hat UK Ltd, Amberley Place, 107-111 Peascod Street, Windsor, Berkshire, SI4 1TE, United Kingdom. Registered in England and Wales under Company Registration No. 3798903 Subject: [PATCH 18/23] NFS: Rename struct nfs_parsed_mount_data to struct nfs_fs_context From: David Howells To: trond.myklebust@hammerspace.com, anna.schumaker@netapp.com Cc: Al Viro , dhowells@redhat.com, viro@zeniv.linux.org.uk, linux-nfs@vger.kernel.org, linux-fsdevel@vger.kernel.org, linux-kernel@vger.kernel.org Date: Thu, 23 May 2019 17:18:26 +0100 Message-ID: <155862830607.26654.17544079891001252500.stgit@warthog.procyon.org.uk> In-Reply-To: <155862813755.26654.563679411147031501.stgit@warthog.procyon.org.uk> References: <155862813755.26654.563679411147031501.stgit@warthog.procyon.org.uk> User-Agent: StGit/unknown-version MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.16 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.41]); Thu, 23 May 2019 16:18:29 +0000 (UTC) Sender: linux-fsdevel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-fsdevel@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP Rename struct nfs_parsed_mount_data to struct nfs_fs_context and rename pointers to it to "ctx". At some point this will be pointed to by an fs_context struct's fs_private pointer. Signed-off-by: David Howells Signed-off-by: Al Viro --- fs/nfs/client.c | 64 ++++--- fs/nfs/fs_context.c | 444 +++++++++++++++++++++++++-------------------------- fs/nfs/internal.h | 14 +- fs/nfs/nfs4client.c | 58 +++---- fs/nfs/nfs4super.c | 6 - fs/nfs/super.c | 192 +++++++++++----------- 6 files changed, 389 insertions(+), 389 deletions(-) diff --git a/fs/nfs/client.c b/fs/nfs/client.c index d30e38e3802f..4534ecebe380 100644 --- a/fs/nfs/client.c +++ b/fs/nfs/client.c @@ -649,26 +649,26 @@ EXPORT_SYMBOL_GPL(nfs_init_client); * Create a version 2 or 3 client */ static int nfs_init_server(struct nfs_server *server, - const struct nfs_parsed_mount_data *data, + const struct nfs_fs_context *cfg, struct nfs_subversion *nfs_mod) { struct rpc_timeout timeparms; struct nfs_client_initdata cl_init = { - .hostname = data->nfs_server.hostname, - .addr = (const struct sockaddr *)&data->nfs_server.address, - .addrlen = data->nfs_server.addrlen, + .hostname = cfg->nfs_server.hostname, + .addr = (const struct sockaddr *)&cfg->nfs_server.address, + .addrlen = cfg->nfs_server.addrlen, .nfs_mod = nfs_mod, - .proto = data->nfs_server.protocol, - .net = data->net, + .proto = cfg->nfs_server.protocol, + .net = cfg->net, .timeparms = &timeparms, .cred = server->cred, }; struct nfs_client *clp; int error; - nfs_init_timeout_values(&timeparms, data->nfs_server.protocol, - data->timeo, data->retrans); - if (data->flags & NFS_MOUNT_NORESVPORT) + nfs_init_timeout_values(&timeparms, cfg->nfs_server.protocol, + cfg->timeo, cfg->retrans); + if (cfg->flags & NFS_MOUNT_NORESVPORT) set_bit(NFS_CS_NORESVPORT, &cl_init.init_flags); /* Allocate or find a client reference we can use */ @@ -679,46 +679,46 @@ static int nfs_init_server(struct nfs_server *server, server->nfs_client = clp; /* Initialise the client representation from the mount data */ - server->flags = data->flags; - server->options = data->options; + server->flags = cfg->flags; + server->options = cfg->options; server->caps |= NFS_CAP_HARDLINKS|NFS_CAP_SYMLINKS|NFS_CAP_FILEID| NFS_CAP_MODE|NFS_CAP_NLINK|NFS_CAP_OWNER|NFS_CAP_OWNER_GROUP| NFS_CAP_ATIME|NFS_CAP_CTIME|NFS_CAP_MTIME; - if (data->rsize) - server->rsize = nfs_block_size(data->rsize, NULL); - if (data->wsize) - server->wsize = nfs_block_size(data->wsize, NULL); + if (cfg->rsize) + server->rsize = nfs_block_size(cfg->rsize, NULL); + if (cfg->wsize) + server->wsize = nfs_block_size(cfg->wsize, NULL); - server->acregmin = data->acregmin * HZ; - server->acregmax = data->acregmax * HZ; - server->acdirmin = data->acdirmin * HZ; - server->acdirmax = data->acdirmax * HZ; + server->acregmin = cfg->acregmin * HZ; + server->acregmax = cfg->acregmax * HZ; + server->acdirmin = cfg->acdirmin * HZ; + server->acdirmax = cfg->acdirmax * HZ; /* Start lockd here, before we might error out */ error = nfs_start_lockd(server); if (error < 0) goto error; - server->port = data->nfs_server.port; - server->auth_info = data->auth_info; + server->port = cfg->nfs_server.port; + server->auth_info = cfg->auth_info; error = nfs_init_server_rpcclient(server, &timeparms, - data->selected_flavor); + cfg->selected_flavor); if (error < 0) goto error; /* Preserve the values of mount_server-related mount options */ - if (data->mount_server.addrlen) { - memcpy(&server->mountd_address, &data->mount_server.address, - data->mount_server.addrlen); - server->mountd_addrlen = data->mount_server.addrlen; + if (cfg->mount_server.addrlen) { + memcpy(&server->mountd_address, &cfg->mount_server.address, + cfg->mount_server.addrlen); + server->mountd_addrlen = cfg->mount_server.addrlen; } - server->mountd_version = data->mount_server.version; - server->mountd_port = data->mount_server.port; - server->mountd_protocol = data->mount_server.protocol; + server->mountd_version = cfg->mount_server.version; + server->mountd_port = cfg->mount_server.port; + server->mountd_protocol = cfg->mount_server.protocol; - server->namelen = data->namlen; + server->namelen = cfg->namlen; return 0; error: @@ -959,7 +959,7 @@ struct nfs_server *nfs_create_server(struct nfs_mount_info *mount_info) goto error; /* Get a client representation */ - error = nfs_init_server(server, mount_info->parsed, nfs_mod); + error = nfs_init_server(server, mount_info->ctx, nfs_mod); if (error < 0) goto error; @@ -970,7 +970,7 @@ struct nfs_server *nfs_create_server(struct nfs_mount_info *mount_info) if (server->nfs_client->rpc_ops->version == 3) { if (server->namelen == 0 || server->namelen > NFS3_MAXNAMLEN) server->namelen = NFS3_MAXNAMLEN; - if (!(mount_info->parsed->flags & NFS_MOUNT_NORDIRPLUS)) + if (!(mount_info->ctx->flags & NFS_MOUNT_NORDIRPLUS)) server->caps |= NFS_CAP_READDIRPLUS; } else { if (server->namelen == 0 || server->namelen > NFS2_MAXNAMLEN) diff --git a/fs/nfs/fs_context.c b/fs/nfs/fs_context.c index 265c22b3367f..10fe721756eb 100644 --- a/fs/nfs/fs_context.c +++ b/fs/nfs/fs_context.c @@ -241,40 +241,40 @@ static const match_table_t nfs_vers_tokens = { { Opt_vers_err, NULL } }; -struct nfs_parsed_mount_data *nfs_alloc_parsed_mount_data(void) +struct nfs_fs_context *nfs_alloc_parsed_mount_data(void) { - struct nfs_parsed_mount_data *data; - - data = kzalloc(sizeof(*data), GFP_KERNEL); - if (data) { - data->timeo = NFS_UNSPEC_TIMEO; - data->retrans = NFS_UNSPEC_RETRANS; - data->acregmin = NFS_DEF_ACREGMIN; - data->acregmax = NFS_DEF_ACREGMAX; - data->acdirmin = NFS_DEF_ACDIRMIN; - data->acdirmax = NFS_DEF_ACDIRMAX; - data->mount_server.port = NFS_UNSPEC_PORT; - data->nfs_server.port = NFS_UNSPEC_PORT; - data->nfs_server.protocol = XPRT_TRANSPORT_TCP; - data->selected_flavor = RPC_AUTH_MAXFLAVOR; - data->minorversion = 0; - data->need_mount = true; - data->net = current->nsproxy->net_ns; - data->lsm_opts = NULL; + struct nfs_fs_context *ctx; + + ctx = kzalloc(sizeof(*ctx), GFP_KERNEL); + if (ctx) { + ctx->timeo = NFS_UNSPEC_TIMEO; + ctx->retrans = NFS_UNSPEC_RETRANS; + ctx->acregmin = NFS_DEF_ACREGMIN; + ctx->acregmax = NFS_DEF_ACREGMAX; + ctx->acdirmin = NFS_DEF_ACDIRMIN; + ctx->acdirmax = NFS_DEF_ACDIRMAX; + ctx->mount_server.port = NFS_UNSPEC_PORT; + ctx->nfs_server.port = NFS_UNSPEC_PORT; + ctx->nfs_server.protocol = XPRT_TRANSPORT_TCP; + ctx->selected_flavor = RPC_AUTH_MAXFLAVOR; + ctx->minorversion = 0; + ctx->need_mount = true; + ctx->net = current->nsproxy->net_ns; + ctx->lsm_opts = NULL; } - return data; + return ctx; } -void nfs_free_parsed_mount_data(struct nfs_parsed_mount_data *data) +void nfs_free_parsed_mount_data(struct nfs_fs_context *ctx) { - if (data) { - kfree(data->client_address); - kfree(data->mount_server.hostname); - kfree(data->nfs_server.export_path); - kfree(data->nfs_server.hostname); - kfree(data->fscache_uniq); - security_free_mnt_opts(&data->lsm_opts); - kfree(data); + if (ctx) { + kfree(ctx->client_address); + kfree(ctx->mount_server.hostname); + kfree(ctx->nfs_server.export_path); + kfree(ctx->nfs_server.hostname); + kfree(ctx->fscache_uniq); + security_free_mnt_opts(&ctx->lsm_opts); + kfree(ctx); } } @@ -305,15 +305,15 @@ static int nfs_verify_server_address(struct sockaddr *addr) * Sanity check the NFS transport protocol. * */ -static void nfs_validate_transport_protocol(struct nfs_parsed_mount_data *mnt) +static void nfs_validate_transport_protocol(struct nfs_fs_context *ctx) { - switch (mnt->nfs_server.protocol) { + switch (ctx->nfs_server.protocol) { case XPRT_TRANSPORT_UDP: case XPRT_TRANSPORT_TCP: case XPRT_TRANSPORT_RDMA: break; default: - mnt->nfs_server.protocol = XPRT_TRANSPORT_TCP; + ctx->nfs_server.protocol = XPRT_TRANSPORT_TCP; } } @@ -321,20 +321,20 @@ static void nfs_validate_transport_protocol(struct nfs_parsed_mount_data *mnt) * For text based NFSv2/v3 mounts, the mount protocol transport default * settings should depend upon the specified NFS transport. */ -static void nfs_set_mount_transport_protocol(struct nfs_parsed_mount_data *mnt) +static void nfs_set_mount_transport_protocol(struct nfs_fs_context *ctx) { - nfs_validate_transport_protocol(mnt); + nfs_validate_transport_protocol(ctx); - if (mnt->mount_server.protocol == XPRT_TRANSPORT_UDP || - mnt->mount_server.protocol == XPRT_TRANSPORT_TCP) + if (ctx->mount_server.protocol == XPRT_TRANSPORT_UDP || + ctx->mount_server.protocol == XPRT_TRANSPORT_TCP) return; - switch (mnt->nfs_server.protocol) { + switch (ctx->nfs_server.protocol) { case XPRT_TRANSPORT_UDP: - mnt->mount_server.protocol = XPRT_TRANSPORT_UDP; + ctx->mount_server.protocol = XPRT_TRANSPORT_UDP; break; case XPRT_TRANSPORT_TCP: case XPRT_TRANSPORT_RDMA: - mnt->mount_server.protocol = XPRT_TRANSPORT_TCP; + ctx->mount_server.protocol = XPRT_TRANSPORT_TCP; } } @@ -366,8 +366,7 @@ static bool nfs_auth_info_add(struct nfs_auth_info *auth_info, /* * Parse the value of the 'sec=' option. */ -static int nfs_parse_security_flavors(char *value, - struct nfs_parsed_mount_data *mnt) +static int nfs_parse_security_flavors(char *value, struct nfs_fs_context *ctx) { substring_t args[MAX_OPT_ARGS]; rpc_authflavor_t pseudoflavor; @@ -416,7 +415,7 @@ static int nfs_parse_security_flavors(char *value, return 0; } - if (!nfs_auth_info_add(&mnt->auth_info, pseudoflavor)) + if (!nfs_auth_info_add(&ctx->auth_info, pseudoflavor)) return 0; } @@ -424,36 +423,36 @@ static int nfs_parse_security_flavors(char *value, } static int nfs_parse_version_string(char *string, - struct nfs_parsed_mount_data *mnt, + struct nfs_fs_context *ctx, substring_t *args) { - mnt->flags &= ~NFS_MOUNT_VER3; + ctx->flags &= ~NFS_MOUNT_VER3; switch (match_token(string, nfs_vers_tokens, args)) { case Opt_vers_2: - mnt->version = 2; + ctx->version = 2; break; case Opt_vers_3: - mnt->flags |= NFS_MOUNT_VER3; - mnt->version = 3; + ctx->flags |= NFS_MOUNT_VER3; + ctx->version = 3; break; case Opt_vers_4: /* Backward compatibility option. In future, * the mount program should always supply * a NFSv4 minor version number. */ - mnt->version = 4; + ctx->version = 4; break; case Opt_vers_4_0: - mnt->version = 4; - mnt->minorversion = 0; + ctx->version = 4; + ctx->minorversion = 0; break; case Opt_vers_4_1: - mnt->version = 4; - mnt->minorversion = 1; + ctx->version = 4; + ctx->minorversion = 1; break; case Opt_vers_4_2: - mnt->version = 4; - mnt->minorversion = 2; + ctx->version = 4; + ctx->minorversion = 2; break; default: return 0; @@ -501,7 +500,7 @@ static int nfs_get_option_ul_bound(substring_t args[], unsigned long *option, * 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_parsed_mount_data *mnt) +int nfs_parse_mount_options(char *raw, struct nfs_fs_context *ctx) { char *p, *string; int rc, sloppy = 0, invalid_option = 0; @@ -514,7 +513,7 @@ int nfs_parse_mount_options(char *raw, struct nfs_parsed_mount_data *mnt) } dfprintk(MOUNT, "NFS: nfs mount opts='%s'\n", raw); - rc = security_sb_eat_lsm_opts(raw, &mnt->lsm_opts); + rc = security_sb_eat_lsm_opts(raw, &ctx->lsm_opts); if (rc) goto out_security_failure; @@ -535,96 +534,96 @@ int nfs_parse_mount_options(char *raw, struct nfs_parsed_mount_data *mnt) * boolean options: foo/nofoo */ case Opt_soft: - mnt->flags |= NFS_MOUNT_SOFT; - mnt->flags &= ~NFS_MOUNT_SOFTERR; + ctx->flags |= NFS_MOUNT_SOFT; + ctx->flags &= ~NFS_MOUNT_SOFTERR; break; case Opt_softerr: - mnt->flags |= NFS_MOUNT_SOFTERR; - mnt->flags &= ~NFS_MOUNT_SOFT; + ctx->flags |= NFS_MOUNT_SOFTERR; + ctx->flags &= ~NFS_MOUNT_SOFT; break; case Opt_hard: - mnt->flags &= ~(NFS_MOUNT_SOFT|NFS_MOUNT_SOFTERR); + ctx->flags &= ~(NFS_MOUNT_SOFT|NFS_MOUNT_SOFTERR); break; case Opt_posix: - mnt->flags |= NFS_MOUNT_POSIX; + ctx->flags |= NFS_MOUNT_POSIX; break; case Opt_noposix: - mnt->flags &= ~NFS_MOUNT_POSIX; + ctx->flags &= ~NFS_MOUNT_POSIX; break; case Opt_cto: - mnt->flags &= ~NFS_MOUNT_NOCTO; + ctx->flags &= ~NFS_MOUNT_NOCTO; break; case Opt_nocto: - mnt->flags |= NFS_MOUNT_NOCTO; + ctx->flags |= NFS_MOUNT_NOCTO; break; case Opt_ac: - mnt->flags &= ~NFS_MOUNT_NOAC; + ctx->flags &= ~NFS_MOUNT_NOAC; break; case Opt_noac: - mnt->flags |= NFS_MOUNT_NOAC; + ctx->flags |= NFS_MOUNT_NOAC; break; case Opt_lock: - mnt->flags &= ~NFS_MOUNT_NONLM; - mnt->flags &= ~(NFS_MOUNT_LOCAL_FLOCK | + ctx->flags &= ~NFS_MOUNT_NONLM; + ctx->flags &= ~(NFS_MOUNT_LOCAL_FLOCK | NFS_MOUNT_LOCAL_FCNTL); break; case Opt_nolock: - mnt->flags |= NFS_MOUNT_NONLM; - mnt->flags |= (NFS_MOUNT_LOCAL_FLOCK | + ctx->flags |= NFS_MOUNT_NONLM; + ctx->flags |= (NFS_MOUNT_LOCAL_FLOCK | NFS_MOUNT_LOCAL_FCNTL); break; case Opt_udp: - mnt->flags &= ~NFS_MOUNT_TCP; - mnt->nfs_server.protocol = XPRT_TRANSPORT_UDP; + ctx->flags &= ~NFS_MOUNT_TCP; + ctx->nfs_server.protocol = XPRT_TRANSPORT_UDP; break; case Opt_tcp: - mnt->flags |= NFS_MOUNT_TCP; - mnt->nfs_server.protocol = XPRT_TRANSPORT_TCP; + ctx->flags |= NFS_MOUNT_TCP; + ctx->nfs_server.protocol = XPRT_TRANSPORT_TCP; break; case Opt_rdma: - mnt->flags |= NFS_MOUNT_TCP; /* for side protocols */ - mnt->nfs_server.protocol = XPRT_TRANSPORT_RDMA; + ctx->flags |= NFS_MOUNT_TCP; /* for side protocols */ + ctx->nfs_server.protocol = XPRT_TRANSPORT_RDMA; xprt_load_transport(p); break; case Opt_acl: - mnt->flags &= ~NFS_MOUNT_NOACL; + ctx->flags &= ~NFS_MOUNT_NOACL; break; case Opt_noacl: - mnt->flags |= NFS_MOUNT_NOACL; + ctx->flags |= NFS_MOUNT_NOACL; break; case Opt_rdirplus: - mnt->flags &= ~NFS_MOUNT_NORDIRPLUS; + ctx->flags &= ~NFS_MOUNT_NORDIRPLUS; break; case Opt_nordirplus: - mnt->flags |= NFS_MOUNT_NORDIRPLUS; + ctx->flags |= NFS_MOUNT_NORDIRPLUS; break; case Opt_sharecache: - mnt->flags &= ~NFS_MOUNT_UNSHARED; + ctx->flags &= ~NFS_MOUNT_UNSHARED; break; case Opt_nosharecache: - mnt->flags |= NFS_MOUNT_UNSHARED; + ctx->flags |= NFS_MOUNT_UNSHARED; break; case Opt_resvport: - mnt->flags &= ~NFS_MOUNT_NORESVPORT; + ctx->flags &= ~NFS_MOUNT_NORESVPORT; break; case Opt_noresvport: - mnt->flags |= NFS_MOUNT_NORESVPORT; + ctx->flags |= NFS_MOUNT_NORESVPORT; break; case Opt_fscache: - mnt->options |= NFS_OPTION_FSCACHE; - kfree(mnt->fscache_uniq); - mnt->fscache_uniq = NULL; + ctx->options |= NFS_OPTION_FSCACHE; + kfree(ctx->fscache_uniq); + ctx->fscache_uniq = NULL; break; case Opt_nofscache: - mnt->options &= ~NFS_OPTION_FSCACHE; - kfree(mnt->fscache_uniq); - mnt->fscache_uniq = NULL; + ctx->options &= ~NFS_OPTION_FSCACHE; + kfree(ctx->fscache_uniq); + ctx->fscache_uniq = NULL; break; case Opt_migration: - mnt->options |= NFS_OPTION_MIGRATION; + ctx->options |= NFS_OPTION_MIGRATION; break; case Opt_nomigration: - mnt->options &= ~NFS_OPTION_MIGRATION; + ctx->options &= ~NFS_OPTION_MIGRATION; break; /* @@ -634,83 +633,83 @@ int nfs_parse_mount_options(char *raw, struct nfs_parsed_mount_data *mnt) if (nfs_get_option_ul(args, &option) || option > USHRT_MAX) goto out_invalid_value; - mnt->nfs_server.port = option; + ctx->nfs_server.port = option; break; case Opt_rsize: if (nfs_get_option_ul(args, &option)) goto out_invalid_value; - mnt->rsize = option; + ctx->rsize = option; break; case Opt_wsize: if (nfs_get_option_ul(args, &option)) goto out_invalid_value; - mnt->wsize = option; + ctx->wsize = option; break; case Opt_bsize: if (nfs_get_option_ul(args, &option)) goto out_invalid_value; - mnt->bsize = option; + ctx->bsize = option; break; case Opt_timeo: if (nfs_get_option_ul_bound(args, &option, 1, INT_MAX)) goto out_invalid_value; - mnt->timeo = option; + ctx->timeo = option; break; case Opt_retrans: if (nfs_get_option_ul_bound(args, &option, 0, INT_MAX)) goto out_invalid_value; - mnt->retrans = option; + ctx->retrans = option; break; case Opt_acregmin: if (nfs_get_option_ul(args, &option)) goto out_invalid_value; - mnt->acregmin = option; + ctx->acregmin = option; break; case Opt_acregmax: if (nfs_get_option_ul(args, &option)) goto out_invalid_value; - mnt->acregmax = option; + ctx->acregmax = option; break; case Opt_acdirmin: if (nfs_get_option_ul(args, &option)) goto out_invalid_value; - mnt->acdirmin = option; + ctx->acdirmin = option; break; case Opt_acdirmax: if (nfs_get_option_ul(args, &option)) goto out_invalid_value; - mnt->acdirmax = option; + ctx->acdirmax = option; break; case Opt_actimeo: if (nfs_get_option_ul(args, &option)) goto out_invalid_value; - mnt->acregmin = mnt->acregmax = - mnt->acdirmin = mnt->acdirmax = option; + ctx->acregmin = ctx->acregmax = + ctx->acdirmin = ctx->acdirmax = option; break; case Opt_namelen: if (nfs_get_option_ul(args, &option)) goto out_invalid_value; - mnt->namlen = option; + ctx->namlen = option; break; case Opt_mountport: if (nfs_get_option_ul(args, &option) || option > USHRT_MAX) goto out_invalid_value; - mnt->mount_server.port = option; + ctx->mount_server.port = option; break; case Opt_mountvers: if (nfs_get_option_ul(args, &option) || option < NFS_MNT_VERSION || option > NFS_MNT3_VERSION) goto out_invalid_value; - mnt->mount_server.version = option; + ctx->mount_server.version = option; break; case Opt_minorversion: if (nfs_get_option_ul(args, &option)) goto out_invalid_value; if (option > NFS4_MAX_MINOR_VERSION) goto out_invalid_value; - mnt->minorversion = option; + ctx->minorversion = option; break; /* @@ -720,7 +719,7 @@ int nfs_parse_mount_options(char *raw, struct nfs_parsed_mount_data *mnt) string = match_strdup(args); if (string == NULL) goto out_nomem; - rc = nfs_parse_version_string(string, mnt, args); + rc = nfs_parse_version_string(string, ctx, args); kfree(string); if (!rc) goto out_invalid_value; @@ -729,7 +728,7 @@ int nfs_parse_mount_options(char *raw, struct nfs_parsed_mount_data *mnt) string = match_strdup(args); if (string == NULL) goto out_nomem; - rc = nfs_parse_security_flavors(string, mnt); + rc = nfs_parse_security_flavors(string, ctx); kfree(string); if (!rc) { dfprintk(MOUNT, "NFS: unrecognized " @@ -750,23 +749,23 @@ int nfs_parse_mount_options(char *raw, struct nfs_parsed_mount_data *mnt) protofamily = AF_INET6; /* fall through */ case Opt_xprt_udp: - mnt->flags &= ~NFS_MOUNT_TCP; - mnt->nfs_server.protocol = XPRT_TRANSPORT_UDP; + ctx->flags &= ~NFS_MOUNT_TCP; + ctx->nfs_server.protocol = XPRT_TRANSPORT_UDP; break; case Opt_xprt_tcp6: protofamily = AF_INET6; /* fall through */ case Opt_xprt_tcp: - mnt->flags |= NFS_MOUNT_TCP; - mnt->nfs_server.protocol = XPRT_TRANSPORT_TCP; + ctx->flags |= NFS_MOUNT_TCP; + ctx->nfs_server.protocol = XPRT_TRANSPORT_TCP; break; case Opt_xprt_rdma6: protofamily = AF_INET6; /* fall through */ case Opt_xprt_rdma: /* vector side protocols to TCP */ - mnt->flags |= NFS_MOUNT_TCP; - mnt->nfs_server.protocol = XPRT_TRANSPORT_RDMA; + ctx->flags |= NFS_MOUNT_TCP; + ctx->nfs_server.protocol = XPRT_TRANSPORT_RDMA; xprt_load_transport(string); break; default: @@ -791,13 +790,13 @@ int nfs_parse_mount_options(char *raw, struct nfs_parsed_mount_data *mnt) mountfamily = AF_INET6; /* fall through */ case Opt_xprt_udp: - mnt->mount_server.protocol = XPRT_TRANSPORT_UDP; + ctx->mount_server.protocol = XPRT_TRANSPORT_UDP; break; case Opt_xprt_tcp6: mountfamily = AF_INET6; /* fall through */ case Opt_xprt_tcp: - mnt->mount_server.protocol = XPRT_TRANSPORT_TCP; + ctx->mount_server.protocol = XPRT_TRANSPORT_TCP; break; case Opt_xprt_rdma: /* not used for side protocols */ default: @@ -810,35 +809,35 @@ int nfs_parse_mount_options(char *raw, struct nfs_parsed_mount_data *mnt) string = match_strdup(args); if (string == NULL) goto out_nomem; - mnt->nfs_server.addrlen = - rpc_pton(mnt->net, string, strlen(string), + ctx->nfs_server.addrlen = + rpc_pton(ctx->net, string, strlen(string), (struct sockaddr *) - &mnt->nfs_server.address, - sizeof(mnt->nfs_server.address)); + &ctx->nfs_server.address, + sizeof(ctx->nfs_server.address)); kfree(string); - if (mnt->nfs_server.addrlen == 0) + if (ctx->nfs_server.addrlen == 0) goto out_invalid_address; break; case Opt_clientaddr: - if (nfs_get_option_str(args, &mnt->client_address)) + if (nfs_get_option_str(args, &ctx->client_address)) goto out_nomem; break; case Opt_mounthost: if (nfs_get_option_str(args, - &mnt->mount_server.hostname)) + &ctx->mount_server.hostname)) goto out_nomem; break; case Opt_mountaddr: string = match_strdup(args); if (string == NULL) goto out_nomem; - mnt->mount_server.addrlen = - rpc_pton(mnt->net, string, strlen(string), + ctx->mount_server.addrlen = + rpc_pton(ctx->net, string, strlen(string), (struct sockaddr *) - &mnt->mount_server.address, - sizeof(mnt->mount_server.address)); + &ctx->mount_server.address, + sizeof(ctx->mount_server.address)); kfree(string); - if (mnt->mount_server.addrlen == 0) + if (ctx->mount_server.addrlen == 0) goto out_invalid_address; break; case Opt_lookupcache: @@ -850,14 +849,14 @@ int nfs_parse_mount_options(char *raw, struct nfs_parsed_mount_data *mnt) kfree(string); switch (token) { case Opt_lookupcache_all: - mnt->flags &= ~(NFS_MOUNT_LOOKUP_CACHE_NONEG|NFS_MOUNT_LOOKUP_CACHE_NONE); + ctx->flags &= ~(NFS_MOUNT_LOOKUP_CACHE_NONEG|NFS_MOUNT_LOOKUP_CACHE_NONE); break; case Opt_lookupcache_positive: - mnt->flags &= ~NFS_MOUNT_LOOKUP_CACHE_NONE; - mnt->flags |= NFS_MOUNT_LOOKUP_CACHE_NONEG; + ctx->flags &= ~NFS_MOUNT_LOOKUP_CACHE_NONE; + ctx->flags |= NFS_MOUNT_LOOKUP_CACHE_NONEG; break; case Opt_lookupcache_none: - mnt->flags |= NFS_MOUNT_LOOKUP_CACHE_NONEG|NFS_MOUNT_LOOKUP_CACHE_NONE; + ctx->flags |= NFS_MOUNT_LOOKUP_CACHE_NONEG|NFS_MOUNT_LOOKUP_CACHE_NONE; break; default: dfprintk(MOUNT, "NFS: invalid " @@ -866,9 +865,9 @@ int nfs_parse_mount_options(char *raw, struct nfs_parsed_mount_data *mnt) }; break; case Opt_fscache_uniq: - if (nfs_get_option_str(args, &mnt->fscache_uniq)) + if (nfs_get_option_str(args, &ctx->fscache_uniq)) goto out_nomem; - mnt->options |= NFS_OPTION_FSCACHE; + ctx->options |= NFS_OPTION_FSCACHE; break; case Opt_local_lock: string = match_strdup(args); @@ -879,17 +878,17 @@ int nfs_parse_mount_options(char *raw, struct nfs_parsed_mount_data *mnt) kfree(string); switch (token) { case Opt_local_lock_all: - mnt->flags |= (NFS_MOUNT_LOCAL_FLOCK | + ctx->flags |= (NFS_MOUNT_LOCAL_FLOCK | NFS_MOUNT_LOCAL_FCNTL); break; case Opt_local_lock_flock: - mnt->flags |= NFS_MOUNT_LOCAL_FLOCK; + ctx->flags |= NFS_MOUNT_LOCAL_FLOCK; break; case Opt_local_lock_posix: - mnt->flags |= NFS_MOUNT_LOCAL_FCNTL; + ctx->flags |= NFS_MOUNT_LOCAL_FCNTL; break; case Opt_local_lock_none: - mnt->flags &= ~(NFS_MOUNT_LOCAL_FLOCK | + ctx->flags &= ~(NFS_MOUNT_LOCAL_FLOCK | NFS_MOUNT_LOCAL_FCNTL); break; default: @@ -922,11 +921,11 @@ int nfs_parse_mount_options(char *raw, struct nfs_parsed_mount_data *mnt) if (!sloppy && invalid_option) return 0; - if (mnt->minorversion && mnt->version != 4) + if (ctx->minorversion && ctx->version != 4) goto out_minorversion_mismatch; - if (mnt->options & NFS_OPTION_MIGRATION && - (mnt->version != 4 || mnt->minorversion != 0)) + if (ctx->options & NFS_OPTION_MIGRATION && + (ctx->version != 4 || ctx->minorversion != 0)) goto out_migration_misuse; /* @@ -934,15 +933,15 @@ int nfs_parse_mount_options(char *raw, struct nfs_parsed_mount_data *mnt) * families in the addr=/mountaddr= options. */ if (protofamily != AF_UNSPEC && - protofamily != mnt->nfs_server.address.ss_family) + protofamily != ctx->nfs_server.address.ss_family) goto out_proto_mismatch; if (mountfamily != AF_UNSPEC) { - if (mnt->mount_server.addrlen) { - if (mountfamily != mnt->mount_server.address.ss_family) + if (ctx->mount_server.addrlen) { + if (mountfamily != ctx->mount_server.address.ss_family) goto out_mountproto_mismatch; } else { - if (mountfamily != mnt->nfs_server.address.ss_family) + if (mountfamily != ctx->nfs_server.address.ss_family) goto out_mountproto_mismatch; } } @@ -964,7 +963,7 @@ int nfs_parse_mount_options(char *raw, struct nfs_parsed_mount_data *mnt) return 0; out_minorversion_mismatch: printk(KERN_INFO "NFS: mount option vers=%u does not support " - "minorversion=%u\n", mnt->version, mnt->minorversion); + "minorversion=%u\n", ctx->version, ctx->minorversion); return 0; out_migration_misuse: printk(KERN_INFO @@ -1072,18 +1071,18 @@ static int nfs_parse_devname(const char *dev_name, * mountproto=tcp after mountproto=udp, and so on */ static int nfs23_validate_mount_data(void *options, - struct nfs_parsed_mount_data *args, + struct nfs_fs_context *ctx, struct nfs_fh *mntfh, const char *dev_name) { struct nfs_mount_data *data = (struct nfs_mount_data *)options; - struct sockaddr *sap = (struct sockaddr *)&args->nfs_server.address; + struct sockaddr *sap = (struct sockaddr *)&ctx->nfs_server.address; int extra_flags = NFS_MOUNT_LEGACY_INTERFACE; if (data == NULL) goto out_no_data; - args->version = NFS_DEFAULT_VERSION; + ctx->version = NFS_DEFAULT_VERSION; switch (data->version) { case 1: data->namlen = 0; /* fall through */ @@ -1109,10 +1108,10 @@ static int nfs23_validate_mount_data(void *options, if (data->root.size > NFS3_FHSIZE || data->root.size == 0) goto out_invalid_fh; mntfh->size = data->root.size; - args->version = 3; + ctx->version = 3; } else { mntfh->size = NFS2_FHSIZE; - args->version = 2; + ctx->version = 2; } @@ -1122,47 +1121,47 @@ static int nfs23_validate_mount_data(void *options, sizeof(mntfh->data) - mntfh->size); /* - * Translate to nfs_parsed_mount_data, which nfs_fill_super + * Translate to nfs_fs_context, which nfs_fill_super * can deal with. */ - args->flags = data->flags & NFS_MOUNT_FLAGMASK; - args->flags |= extra_flags; - args->rsize = data->rsize; - args->wsize = data->wsize; - args->timeo = data->timeo; - args->retrans = data->retrans; - args->acregmin = data->acregmin; - args->acregmax = data->acregmax; - args->acdirmin = data->acdirmin; - args->acdirmax = data->acdirmax; - args->need_mount = false; + ctx->flags = data->flags & NFS_MOUNT_FLAGMASK; + ctx->flags |= extra_flags; + ctx->rsize = data->rsize; + ctx->wsize = data->wsize; + ctx->timeo = data->timeo; + ctx->retrans = data->retrans; + ctx->acregmin = data->acregmin; + ctx->acregmax = data->acregmax; + ctx->acdirmin = data->acdirmin; + ctx->acdirmax = data->acdirmax; + ctx->need_mount = false; memcpy(sap, &data->addr, sizeof(data->addr)); - args->nfs_server.addrlen = sizeof(data->addr); - args->nfs_server.port = ntohs(data->addr.sin_port); + ctx->nfs_server.addrlen = sizeof(data->addr); + ctx->nfs_server.port = ntohs(data->addr.sin_port); if (sap->sa_family != AF_INET || !nfs_verify_server_address(sap)) goto out_no_address; if (!(data->flags & NFS_MOUNT_TCP)) - args->nfs_server.protocol = XPRT_TRANSPORT_UDP; + ctx->nfs_server.protocol = XPRT_TRANSPORT_UDP; /* N.B. caller will free nfs_server.hostname in all cases */ - args->nfs_server.hostname = kstrdup(data->hostname, GFP_KERNEL); - args->namlen = data->namlen; - args->bsize = data->bsize; + ctx->nfs_server.hostname = kstrdup(data->hostname, GFP_KERNEL); + ctx->namlen = data->namlen; + ctx->bsize = data->bsize; if (data->flags & NFS_MOUNT_SECFLAVOUR) - args->selected_flavor = data->pseudoflavor; + ctx->selected_flavor = data->pseudoflavor; else - args->selected_flavor = RPC_AUTH_UNIX; - if (!args->nfs_server.hostname) + ctx->selected_flavor = RPC_AUTH_UNIX; + if (!ctx->nfs_server.hostname) goto out_nomem; if (!(data->flags & NFS_MOUNT_NONLM)) - args->flags &= ~(NFS_MOUNT_LOCAL_FLOCK| + ctx->flags &= ~(NFS_MOUNT_LOCAL_FLOCK| NFS_MOUNT_LOCAL_FCNTL); else - args->flags |= (NFS_MOUNT_LOCAL_FLOCK| + ctx->flags |= (NFS_MOUNT_LOCAL_FLOCK| NFS_MOUNT_LOCAL_FCNTL); /* * The legacy version 6 binary mount data from userspace has a @@ -1177,7 +1176,7 @@ static int nfs23_validate_mount_data(void *options, int rc; data->context[NFS_MAX_CONTEXT_LEN] = '\0'; rc = security_add_mnt_opt("context", data->context, - strlen(data->context), &args->lsm_opts); + strlen(data->context), ctx->lsm_opts); if (rc) return rc; #else @@ -1219,10 +1218,9 @@ static int nfs23_validate_mount_data(void *options, } #if IS_ENABLED(CONFIG_NFS_V4) - -static void nfs4_validate_mount_flags(struct nfs_parsed_mount_data *args) +static void nfs4_validate_mount_flags(struct nfs_fs_context *ctx) { - args->flags &= ~(NFS_MOUNT_NONLM|NFS_MOUNT_NOACL|NFS_MOUNT_VER3| + ctx->flags &= ~(NFS_MOUNT_NONLM|NFS_MOUNT_NOACL|NFS_MOUNT_VER3| NFS_MOUNT_LOCAL_FLOCK|NFS_MOUNT_LOCAL_FCNTL); } @@ -1230,30 +1228,30 @@ static void nfs4_validate_mount_flags(struct nfs_parsed_mount_data *args) * Validate NFSv4 mount options */ static int nfs4_validate_mount_data(void *options, - struct nfs_parsed_mount_data *args, + struct nfs_fs_context *ctx, const char *dev_name) { - struct sockaddr *sap = (struct sockaddr *)&args->nfs_server.address; + struct sockaddr *sap = (struct sockaddr *)&ctx->nfs_server.address; struct nfs4_mount_data *data = (struct nfs4_mount_data *)options; char *c; if (data == NULL) goto out_no_data; - args->version = 4; + ctx->version = 4; switch (data->version) { case 1: - if (data->host_addrlen > sizeof(args->nfs_server.address)) + if (data->host_addrlen > sizeof(ctx->nfs_server.address)) goto out_no_address; if (data->host_addrlen == 0) goto out_no_address; - args->nfs_server.addrlen = data->host_addrlen; + ctx->nfs_server.addrlen = data->host_addrlen; if (copy_from_user(sap, data->host_addr, data->host_addrlen)) return -EFAULT; if (!nfs_verify_server_address(sap)) goto out_no_address; - args->nfs_server.port = ntohs(((struct sockaddr_in *)sap)->sin_port); + ctx->nfs_server.port = ntohs(((struct sockaddr_in *)sap)->sin_port); if (data->auth_flavourlen) { rpc_authflavor_t pseudoflavor; @@ -1263,43 +1261,43 @@ static int nfs4_validate_mount_data(void *options, data->auth_flavours, sizeof(pseudoflavor))) return -EFAULT; - args->selected_flavor = pseudoflavor; + ctx->selected_flavor = pseudoflavor; } else - args->selected_flavor = RPC_AUTH_UNIX; + ctx->selected_flavor = RPC_AUTH_UNIX; c = strndup_user(data->hostname.data, NFS4_MAXNAMLEN); if (IS_ERR(c)) return PTR_ERR(c); - args->nfs_server.hostname = c; + ctx->nfs_server.hostname = c; c = strndup_user(data->mnt_path.data, NFS4_MAXPATHLEN); if (IS_ERR(c)) return PTR_ERR(c); - args->nfs_server.export_path = c; + ctx->nfs_server.export_path = c; dfprintk(MOUNT, "NFS: MNTPATH: '%s'\n", c); c = strndup_user(data->client_addr.data, 16); if (IS_ERR(c)) return PTR_ERR(c); - args->client_address = c; + ctx->client_address = c; /* - * Translate to nfs_parsed_mount_data, which nfs4_fill_super + * Translate to nfs_fs_context, which nfs4_fill_super * can deal with. */ - args->flags = data->flags & NFS4_MOUNT_FLAGMASK; - args->rsize = data->rsize; - args->wsize = data->wsize; - args->timeo = data->timeo; - args->retrans = data->retrans; - args->acregmin = data->acregmin; - args->acregmax = data->acregmax; - args->acdirmin = data->acdirmin; - args->acdirmax = data->acdirmax; - args->nfs_server.protocol = data->proto; - nfs_validate_transport_protocol(args); - if (args->nfs_server.protocol == XPRT_TRANSPORT_UDP) + ctx->flags = data->flags & NFS4_MOUNT_FLAGMASK; + ctx->rsize = data->rsize; + ctx->wsize = data->wsize; + ctx->timeo = data->timeo; + ctx->retrans = data->retrans; + ctx->acregmin = data->acregmin; + ctx->acregmax = data->acregmax; + ctx->acdirmin = data->acdirmin; + ctx->acdirmax = data->acdirmax; + ctx->nfs_server.protocol = data->proto; + nfs_validate_transport_protocol(ctx); + if (ctx->nfs_server.protocol == XPRT_TRANSPORT_UDP) goto out_invalid_transport_udp; break; @@ -1329,67 +1327,67 @@ static int nfs4_validate_mount_data(void *options, int nfs_validate_mount_data(struct file_system_type *fs_type, void *options, - struct nfs_parsed_mount_data *args, + struct nfs_fs_context *ctx, struct nfs_fh *mntfh, const char *dev_name) { if (fs_type == &nfs_fs_type) - return nfs23_validate_mount_data(options, args, mntfh, dev_name); - return nfs4_validate_mount_data(options, args, dev_name); + return nfs23_validate_mount_data(options, ctx, mntfh, dev_name); + return nfs4_validate_mount_data(options, ctx, dev_name); } #else int nfs_validate_mount_data(struct file_system_type *fs_type, void *options, - struct nfs_parsed_mount_data *args, + struct nfs_fs_context *ctx, struct nfs_fh *mntfh, const char *dev_name) { - return nfs23_validate_mount_data(options, args, mntfh, dev_name); + return nfs23_validate_mount_data(options, ctx, mntfh, dev_name); } #endif int nfs_validate_text_mount_data(void *options, - struct nfs_parsed_mount_data *args, + struct nfs_fs_context *ctx, const char *dev_name) { int port = 0; int max_namelen = PAGE_SIZE; int max_pathlen = NFS_MAXPATHLEN; - struct sockaddr *sap = (struct sockaddr *)&args->nfs_server.address; + struct sockaddr *sap = (struct sockaddr *)&ctx->nfs_server.address; - if (nfs_parse_mount_options((char *)options, args) == 0) + if (nfs_parse_mount_options((char *)options, ctx) == 0) return -EINVAL; if (!nfs_verify_server_address(sap)) goto out_no_address; - if (args->version == 4) { + if (ctx->version == 4) { #if IS_ENABLED(CONFIG_NFS_V4) - if (args->nfs_server.protocol == XPRT_TRANSPORT_RDMA) + if (ctx->nfs_server.protocol == XPRT_TRANSPORT_RDMA) port = NFS_RDMA_PORT; else port = NFS_PORT; max_namelen = NFS4_MAXNAMLEN; max_pathlen = NFS4_MAXPATHLEN; - nfs_validate_transport_protocol(args); - if (args->nfs_server.protocol == XPRT_TRANSPORT_UDP) + nfs_validate_transport_protocol(ctx); + if (ctx->nfs_server.protocol == XPRT_TRANSPORT_UDP) goto out_invalid_transport_udp; - nfs4_validate_mount_flags(args); + nfs4_validate_mount_flags(ctx); #else goto out_v4_not_compiled; #endif /* CONFIG_NFS_V4 */ } else { - nfs_set_mount_transport_protocol(args); - if (args->nfs_server.protocol == XPRT_TRANSPORT_RDMA) + nfs_set_mount_transport_protocol(ctx); + if (ctx->nfs_server.protocol == XPRT_TRANSPORT_RDMA) port = NFS_RDMA_PORT; } - nfs_set_port(sap, &args->nfs_server.port, port); + nfs_set_port(sap, &ctx->nfs_server.port, port); return nfs_parse_devname(dev_name, - &args->nfs_server.hostname, + &ctx->nfs_server.hostname, max_namelen, - &args->nfs_server.export_path, + &ctx->nfs_server.export_path, max_pathlen); #if !IS_ENABLED(CONFIG_NFS_V4) diff --git a/fs/nfs/internal.h b/fs/nfs/internal.h index edc83c901a19..8bb6ee61d99c 100644 --- a/fs/nfs/internal.h +++ b/fs/nfs/internal.h @@ -89,7 +89,7 @@ struct nfs_client_initdata { /* * In-kernel mount arguments */ -struct nfs_parsed_mount_data { +struct nfs_fs_context { int flags; unsigned int rsize, wsize; unsigned int timeo, retrans; @@ -145,7 +145,7 @@ struct nfs_mount_request { struct nfs_mount_info { unsigned int inherited_bsize; - struct nfs_parsed_mount_data *parsed; + struct nfs_fs_context *ctx; struct nfs_clone_mount *cloned; struct nfs_server *server; struct nfs_fh *mntfh; @@ -236,16 +236,16 @@ struct nfs_pageio_descriptor; /* mount.c */ #define NFS_TEXT_DATA 1 -extern struct nfs_parsed_mount_data *nfs_alloc_parsed_mount_data(void); -extern void nfs_free_parsed_mount_data(struct nfs_parsed_mount_data *data); -extern int nfs_parse_mount_options(char *raw, struct nfs_parsed_mount_data *mnt); +extern struct nfs_fs_context *nfs_alloc_parsed_mount_data(void); +extern void nfs_free_parsed_mount_data(struct nfs_fs_context *ctx); +extern int nfs_parse_mount_options(char *raw, struct nfs_fs_context *ctx); extern int nfs_validate_mount_data(struct file_system_type *fs_type, void *options, - struct nfs_parsed_mount_data *args, + struct nfs_fs_context *ctx, struct nfs_fh *mntfh, const char *dev_name); extern int nfs_validate_text_mount_data(void *options, - struct nfs_parsed_mount_data *args, + struct nfs_fs_context *ctx, const char *dev_name); /* pagelist.c */ diff --git a/fs/nfs/nfs4client.c b/fs/nfs/nfs4client.c index d8151d2da0ef..e05f754d1eb1 100644 --- a/fs/nfs/nfs4client.c +++ b/fs/nfs/nfs4client.c @@ -1043,60 +1043,60 @@ static int nfs4_server_common_setup(struct nfs_server *server, * Create a version 4 volume record */ static int nfs4_init_server(struct nfs_server *server, - struct nfs_parsed_mount_data *data) + struct nfs_fs_context *ctx) { struct rpc_timeout timeparms; int error; - nfs_init_timeout_values(&timeparms, data->nfs_server.protocol, - data->timeo, data->retrans); + nfs_init_timeout_values(&timeparms, ctx->nfs_server.protocol, + ctx->timeo, ctx->retrans); /* Initialise the client representation from the mount data */ - server->flags = data->flags; - server->options = data->options; - server->auth_info = data->auth_info; + server->flags = ctx->flags; + server->options = ctx->options; + server->auth_info = ctx->auth_info; /* Use the first specified auth flavor. If this flavor isn't * allowed by the server, use the SECINFO path to try the * other specified flavors */ - if (data->auth_info.flavor_len >= 1) - data->selected_flavor = data->auth_info.flavors[0]; + if (ctx->auth_info.flavor_len >= 1) + ctx->selected_flavor = ctx->auth_info.flavors[0]; else - data->selected_flavor = RPC_AUTH_UNIX; + ctx->selected_flavor = RPC_AUTH_UNIX; /* Get a client record */ error = nfs4_set_client(server, - data->nfs_server.hostname, - (const struct sockaddr *)&data->nfs_server.address, - data->nfs_server.addrlen, - data->client_address, - data->nfs_server.protocol, + ctx->nfs_server.hostname, + (const struct sockaddr *)&ctx->nfs_server.address, + ctx->nfs_server.addrlen, + ctx->client_address, + ctx->nfs_server.protocol, &timeparms, - data->minorversion, - data->net); + ctx->minorversion, + ctx->net); if (error < 0) return error; - if (data->rsize) - server->rsize = nfs_block_size(data->rsize, NULL); - if (data->wsize) - server->wsize = nfs_block_size(data->wsize, NULL); + if (ctx->rsize) + server->rsize = nfs_block_size(ctx->rsize, NULL); + if (ctx->wsize) + server->wsize = nfs_block_size(ctx->wsize, NULL); - server->acregmin = data->acregmin * HZ; - server->acregmax = data->acregmax * HZ; - server->acdirmin = data->acdirmin * HZ; - server->acdirmax = data->acdirmax * HZ; - server->port = data->nfs_server.port; + server->acregmin = ctx->acregmin * HZ; + server->acregmax = ctx->acregmax * HZ; + server->acdirmin = ctx->acdirmin * HZ; + server->acdirmax = ctx->acdirmax * HZ; + server->port = ctx->nfs_server.port; return nfs_init_server_rpcclient(server, &timeparms, - data->selected_flavor); + ctx->selected_flavor); } /* * Create a version 4 volume record * - keyed on server and FSID */ -/*struct nfs_server *nfs4_create_server(const struct nfs_parsed_mount_data *data, +/*struct nfs_server *nfs4_create_server(const struct nfs_fs_context *data, struct nfs_fh *mntfh)*/ struct nfs_server *nfs4_create_server(struct nfs_mount_info *mount_info) { @@ -1110,10 +1110,10 @@ struct nfs_server *nfs4_create_server(struct nfs_mount_info *mount_info) server->cred = get_cred(current_cred()); - auth_probe = mount_info->parsed->auth_info.flavor_len < 1; + auth_probe = mount_info->ctx->auth_info.flavor_len < 1; /* set up the general RPC client */ - error = nfs4_init_server(server, mount_info->parsed); + error = nfs4_init_server(server, mount_info->ctx); if (error < 0) goto error; diff --git a/fs/nfs/nfs4super.c b/fs/nfs/nfs4super.c index 513861b38b72..48a9f19904e0 100644 --- a/fs/nfs/nfs4super.c +++ b/fs/nfs/nfs4super.c @@ -197,15 +197,15 @@ static struct dentry *do_nfs4_mount(struct nfs_server *server, int flags, struct dentry *nfs4_try_mount(int flags, const char *dev_name, struct nfs_mount_info *mount_info) { - struct nfs_parsed_mount_data *data = mount_info->parsed; + struct nfs_fs_context *ctx = mount_info->ctx; struct dentry *res; dfprintk(MOUNT, "--> nfs4_try_mount()\n"); res = do_nfs4_mount(nfs4_create_server(mount_info), flags, mount_info, - data->nfs_server.hostname, - data->nfs_server.export_path); + ctx->nfs_server.hostname, + ctx->nfs_server.export_path); dfprintk(MOUNT, "<-- nfs4_try_mount() = %d%s\n", PTR_ERR_OR_ZERO(res), diff --git a/fs/nfs/super.c b/fs/nfs/super.c index 00368e212a85..d7f99526ee73 100644 --- a/fs/nfs/super.c +++ b/fs/nfs/super.c @@ -714,12 +714,13 @@ bool nfs_auth_info_match(const struct nfs_auth_info *auth_info, EXPORT_SYMBOL_GPL(nfs_auth_info_match); /* - * Ensure that a specified authtype in args->auth_info is supported by - * the server. Returns 0 and sets args->selected_flavor if it's ok, and + * Ensure that a specified authtype in cfg->auth_info is supported by + * the server. Returns 0 and sets cfg->selected_flavor if it's ok, and * -EACCES if not. */ -static int nfs_verify_authflavors(struct nfs_parsed_mount_data *args, - rpc_authflavor_t *server_authlist, unsigned int count) +static int nfs_verify_authflavors(struct nfs_fs_context *cfg, + rpc_authflavor_t *server_authlist, + unsigned int count) { rpc_authflavor_t flavor = RPC_AUTH_MAXFLAVOR; bool found_auth_null = false; @@ -740,7 +741,7 @@ static int nfs_verify_authflavors(struct nfs_parsed_mount_data *args, for (i = 0; i < count; i++) { flavor = server_authlist[i]; - if (nfs_auth_info_match(&args->auth_info, flavor)) + if (nfs_auth_info_match(&cfg->auth_info, flavor)) goto out; if (flavor == RPC_AUTH_NULL) @@ -748,7 +749,7 @@ static int nfs_verify_authflavors(struct nfs_parsed_mount_data *args, } if (found_auth_null) { - flavor = args->auth_info.flavors[0]; + flavor = cfg->auth_info.flavors[0]; goto out; } @@ -757,8 +758,8 @@ static int nfs_verify_authflavors(struct nfs_parsed_mount_data *args, return -EACCES; out: - args->selected_flavor = flavor; - dfprintk(MOUNT, "NFS: using auth flavor %u\n", args->selected_flavor); + cfg->selected_flavor = flavor; + dfprintk(MOUNT, "NFS: using auth flavor %u\n", cfg->selected_flavor); return 0; } @@ -766,50 +767,50 @@ static int nfs_verify_authflavors(struct nfs_parsed_mount_data *args, * Use the remote server's MOUNT service to request the NFS file handle * corresponding to the provided path. */ -static int nfs_request_mount(struct nfs_parsed_mount_data *args, +static int nfs_request_mount(struct nfs_fs_context *cfg, struct nfs_fh *root_fh, rpc_authflavor_t *server_authlist, unsigned int *server_authlist_len) { struct nfs_mount_request request = { .sap = (struct sockaddr *) - &args->mount_server.address, - .dirpath = args->nfs_server.export_path, - .protocol = args->mount_server.protocol, + &cfg->mount_server.address, + .dirpath = cfg->nfs_server.export_path, + .protocol = cfg->mount_server.protocol, .fh = root_fh, - .noresvport = args->flags & NFS_MOUNT_NORESVPORT, + .noresvport = cfg->flags & NFS_MOUNT_NORESVPORT, .auth_flav_len = server_authlist_len, .auth_flavs = server_authlist, - .net = args->net, + .net = cfg->net, }; int status; - if (args->mount_server.version == 0) { - switch (args->version) { + if (cfg->mount_server.version == 0) { + switch (cfg->version) { default: - args->mount_server.version = NFS_MNT3_VERSION; + cfg->mount_server.version = NFS_MNT3_VERSION; break; case 2: - args->mount_server.version = NFS_MNT_VERSION; + cfg->mount_server.version = NFS_MNT_VERSION; } } - request.version = args->mount_server.version; + request.version = cfg->mount_server.version; - if (args->mount_server.hostname) - request.hostname = args->mount_server.hostname; + if (cfg->mount_server.hostname) + request.hostname = cfg->mount_server.hostname; else - request.hostname = args->nfs_server.hostname; + request.hostname = cfg->nfs_server.hostname; /* * Construct the mount server's address. */ - if (args->mount_server.address.ss_family == AF_UNSPEC) { - memcpy(request.sap, &args->nfs_server.address, - args->nfs_server.addrlen); - args->mount_server.addrlen = args->nfs_server.addrlen; + if (cfg->mount_server.address.ss_family == AF_UNSPEC) { + memcpy(request.sap, &cfg->nfs_server.address, + cfg->nfs_server.addrlen); + cfg->mount_server.addrlen = cfg->nfs_server.addrlen; } - request.salen = args->mount_server.addrlen; - nfs_set_port(request.sap, &args->mount_server.port, 0); + request.salen = cfg->mount_server.addrlen; + nfs_set_port(request.sap, &cfg->mount_server.port, 0); /* * Now ask the mount server to map our export path @@ -832,12 +833,12 @@ static struct nfs_server *nfs_try_mount_request(struct nfs_mount_info *mount_inf bool tried_auth_unix = false; bool auth_null_in_list = false; struct nfs_server *server = ERR_PTR(-EACCES); - struct nfs_parsed_mount_data *args = mount_info->parsed; + struct nfs_fs_context *ctx = mount_info->ctx; rpc_authflavor_t authlist[NFS_MAX_SECFLAVORS]; unsigned int authlist_len = ARRAY_SIZE(authlist); struct nfs_subversion *nfs_mod = mount_info->nfs_mod; - status = nfs_request_mount(args, mount_info->mntfh, authlist, + status = nfs_request_mount(ctx, mount_info->mntfh, authlist, &authlist_len); if (status) return ERR_PTR(status); @@ -846,10 +847,10 @@ static struct nfs_server *nfs_try_mount_request(struct nfs_mount_info *mount_inf * Was a sec= authflavor specified in the options? First, verify * whether the server supports it, and then just try to use it if so. */ - if (args->auth_info.flavor_len > 0) { - status = nfs_verify_authflavors(args, authlist, authlist_len); + if (ctx->auth_info.flavor_len > 0) { + status = nfs_verify_authflavors(ctx, authlist, authlist_len); dfprintk(MOUNT, "NFS: using auth flavor %u\n", - args->selected_flavor); + ctx->selected_flavor); if (status) return ERR_PTR(status); return nfs_mod->rpc_ops->create_server(mount_info); @@ -878,7 +879,7 @@ static struct nfs_server *nfs_try_mount_request(struct nfs_mount_info *mount_inf /* Fallthrough */ } dfprintk(MOUNT, "NFS: attempting to use auth flavor %u\n", flavor); - args->selected_flavor = flavor; + ctx->selected_flavor = flavor; server = nfs_mod->rpc_ops->create_server(mount_info); if (!IS_ERR(server)) return server; @@ -894,7 +895,7 @@ static struct nfs_server *nfs_try_mount_request(struct nfs_mount_info *mount_inf /* Last chance! Try AUTH_UNIX */ dfprintk(MOUNT, "NFS: attempting to use auth flavor %u\n", RPC_AUTH_UNIX); - args->selected_flavor = RPC_AUTH_UNIX; + ctx->selected_flavor = RPC_AUTH_UNIX; return nfs_mod->rpc_ops->create_server(mount_info); } @@ -904,7 +905,7 @@ struct dentry *nfs_try_mount(int flags, const char *dev_name, struct nfs_mount_info *mount_info) { struct nfs_subversion *nfs_mod = mount_info->nfs_mod; - if (mount_info->parsed->need_mount) + if (mount_info->ctx->need_mount) mount_info->server = nfs_try_mount_request(mount_info); else mount_info->server = nfs_mod->rpc_ops->create_server(mount_info); @@ -928,23 +929,23 @@ EXPORT_SYMBOL_GPL(nfs_try_mount); static int nfs_compare_remount_data(struct nfs_server *nfss, - struct nfs_parsed_mount_data *data) + struct nfs_fs_context *ctx) { - if ((data->flags ^ nfss->flags) & NFS_REMOUNT_CMP_FLAGMASK || - data->rsize != nfss->rsize || - data->wsize != nfss->wsize || - data->version != nfss->nfs_client->rpc_ops->version || - data->minorversion != nfss->nfs_client->cl_minorversion || - data->retrans != nfss->client->cl_timeout->to_retries || - !nfs_auth_info_match(&data->auth_info, nfss->client->cl_auth->au_flavor) || - data->acregmin != nfss->acregmin / HZ || - data->acregmax != nfss->acregmax / HZ || - data->acdirmin != nfss->acdirmin / HZ || - data->acdirmax != nfss->acdirmax / HZ || - data->timeo != (10U * nfss->client->cl_timeout->to_initval / HZ) || - data->nfs_server.port != nfss->port || - data->nfs_server.addrlen != nfss->nfs_client->cl_addrlen || - !rpc_cmp_addr((struct sockaddr *)&data->nfs_server.address, + if ((ctx->flags ^ nfss->flags) & NFS_REMOUNT_CMP_FLAGMASK || + ctx->rsize != nfss->rsize || + ctx->wsize != nfss->wsize || + ctx->version != nfss->nfs_client->rpc_ops->version || + ctx->minorversion != nfss->nfs_client->cl_minorversion || + ctx->retrans != nfss->client->cl_timeout->to_retries || + !nfs_auth_info_match(&ctx->auth_info, nfss->client->cl_auth->au_flavor) || + ctx->acregmin != nfss->acregmin / HZ || + ctx->acregmax != nfss->acregmax / HZ || + ctx->acdirmin != nfss->acdirmin / HZ || + ctx->acdirmax != nfss->acdirmax / HZ || + ctx->timeo != (10U * nfss->client->cl_timeout->to_initval / HZ) || + ctx->nfs_server.port != nfss->port || + ctx->nfs_server.addrlen != nfss->nfs_client->cl_addrlen || + !rpc_cmp_addr((struct sockaddr *)&ctx->nfs_server.address, (struct sockaddr *)&nfss->nfs_client->cl_addr)) return -EINVAL; @@ -956,7 +957,7 @@ nfs_remount(struct super_block *sb, int *flags, char *raw_data) { int error; struct nfs_server *nfss = sb->s_fs_info; - struct nfs_parsed_mount_data *data; + struct nfs_fs_context *ctx; struct nfs_mount_data *options = (struct nfs_mount_data *)raw_data; struct nfs4_mount_data *options4 = (struct nfs4_mount_data *)raw_data; u32 nfsvers = nfss->nfs_client->rpc_ops->version; @@ -974,32 +975,32 @@ nfs_remount(struct super_block *sb, int *flags, char *raw_data) options->version <= 6)))) return 0; - data = nfs_alloc_parsed_mount_data(); - if (data == NULL) + ctx = nfs_alloc_parsed_mount_data(); + if (ctx == NULL) return -ENOMEM; /* fill out struct with values from existing mount */ - data->flags = nfss->flags; - data->rsize = nfss->rsize; - data->wsize = nfss->wsize; - data->retrans = nfss->client->cl_timeout->to_retries; - data->selected_flavor = nfss->client->cl_auth->au_flavor; - data->acregmin = nfss->acregmin / HZ; - data->acregmax = nfss->acregmax / HZ; - data->acdirmin = nfss->acdirmin / HZ; - data->acdirmax = nfss->acdirmax / HZ; - data->timeo = 10U * nfss->client->cl_timeout->to_initval / HZ; - data->nfs_server.port = nfss->port; - data->nfs_server.addrlen = nfss->nfs_client->cl_addrlen; - data->version = nfsvers; - data->minorversion = nfss->nfs_client->cl_minorversion; - data->net = current->nsproxy->net_ns; - memcpy(&data->nfs_server.address, &nfss->nfs_client->cl_addr, - data->nfs_server.addrlen); + ctx->flags = nfss->flags; + ctx->rsize = nfss->rsize; + ctx->wsize = nfss->wsize; + ctx->retrans = nfss->client->cl_timeout->to_retries; + ctx->selected_flavor = nfss->client->cl_auth->au_flavor; + ctx->acregmin = nfss->acregmin / HZ; + ctx->acregmax = nfss->acregmax / HZ; + ctx->acdirmin = nfss->acdirmin / HZ; + ctx->acdirmax = nfss->acdirmax / HZ; + ctx->timeo = 10U * nfss->client->cl_timeout->to_initval / HZ; + ctx->nfs_server.port = nfss->port; + ctx->nfs_server.addrlen = nfss->nfs_client->cl_addrlen; + ctx->version = nfsvers; + ctx->minorversion = nfss->nfs_client->cl_minorversion; + ctx->net = current->nsproxy->net_ns; + memcpy(&ctx->nfs_server.address, &nfss->nfs_client->cl_addr, + ctx->nfs_server.addrlen); /* overwrite those values with any that were specified */ error = -EINVAL; - if (!nfs_parse_mount_options((char *)options, data)) + if (!nfs_parse_mount_options((char *)options, ctx)) goto out; /* @@ -1008,15 +1009,15 @@ nfs_remount(struct super_block *sb, int *flags, char *raw_data) * will clear SB_SYNCHRONOUS if -o sync wasn't specified in the * remount options, so we have to explicitly reset it. */ - if (data->flags & NFS_MOUNT_NOAC) + if (ctx->flags & NFS_MOUNT_NOAC) *flags |= SB_SYNCHRONOUS; /* compare new mount options with old ones */ - error = nfs_compare_remount_data(nfss, data); + error = nfs_compare_remount_data(nfss, ctx); if (!error) - error = security_sb_remount(sb, data->lsm_opts); + error = security_sb_remount(sb, ctx->lsm_opts); out: - nfs_free_parsed_mount_data(data); + nfs_free_parsed_mount_data(ctx); return error; } EXPORT_SYMBOL_GPL(nfs_remount); @@ -1026,15 +1027,15 @@ EXPORT_SYMBOL_GPL(nfs_remount); */ static void nfs_fill_super(struct super_block *sb, struct nfs_mount_info *mount_info) { - struct nfs_parsed_mount_data *data = mount_info->parsed; + struct nfs_fs_context *ctx = mount_info->ctx; struct nfs_server *server = NFS_SB(sb); sb->s_blocksize_bits = 0; sb->s_blocksize = 0; sb->s_xattr = server->nfs_client->cl_nfs_mod->xattr; sb->s_op = server->nfs_client->cl_nfs_mod->sops; - if (data && data->bsize) - sb->s_blocksize = nfs_block_size(data->bsize, &sb->s_blocksize_bits); + if (ctx && ctx->bsize) + sb->s_blocksize = nfs_block_size(ctx->bsize, &sb->s_blocksize_bits); if (server->nfs_client->rpc_ops->version != 2) { /* The VFS shouldn't apply the umask to mode bits. We will do @@ -1186,7 +1187,7 @@ static int nfs_compare_super(struct super_block *sb, void *data) #ifdef CONFIG_NFS_FSCACHE static void nfs_get_cache_cookie(struct super_block *sb, - struct nfs_parsed_mount_data *parsed, + struct nfs_fs_context *ctx, struct nfs_clone_mount *cloned) { struct nfs_server *nfss = NFS_SB(sb); @@ -1196,12 +1197,12 @@ static void nfs_get_cache_cookie(struct super_block *sb, nfss->fscache_key = NULL; nfss->fscache = NULL; - if (parsed) { - if (!(parsed->options & NFS_OPTION_FSCACHE)) + if (ctx) { + if (!(ctx->options & NFS_OPTION_FSCACHE)) return; - if (parsed->fscache_uniq) { - uniq = parsed->fscache_uniq; - ulen = strlen(parsed->fscache_uniq); + if (ctx->fscache_uniq) { + uniq = ctx->fscache_uniq; + ulen = strlen(ctx->fscache_uniq); } } else if (cloned) { struct nfs_server *mnt_s = NFS_SB(cloned->sb); @@ -1218,7 +1219,7 @@ static void nfs_get_cache_cookie(struct super_block *sb, } #else static void nfs_get_cache_cookie(struct super_block *sb, - struct nfs_parsed_mount_data *parsed, + struct nfs_fs_context *parsed, struct nfs_clone_mount *cloned) { } @@ -1283,7 +1284,7 @@ static struct dentry *nfs_fs_mount_common(int flags, const char *dev_name, s->s_blocksize_bits = bsize; s->s_blocksize = 1U << bsize; } - nfs_get_cache_cookie(s, mount_info->parsed, mount_info->cloned); + nfs_get_cache_cookie(s, mount_info->ctx, mount_info->cloned); if (!(server->flags & NFS_MOUNT_UNSHARED)) s->s_iflags |= SB_I_MULTIROOT; } @@ -1304,7 +1305,7 @@ static struct dentry *nfs_fs_mount_common(int flags, const char *dev_name, error = security_sb_clone_mnt_opts(mount_info->cloned->sb, s, kflags, &kflags_out); } else { - error = security_sb_set_mnt_opts(s, mount_info->parsed->lsm_opts, + error = security_sb_set_mnt_opts(s, mount_info->ctx->lsm_opts, kflags, &kflags_out); } if (error) @@ -1341,21 +1342,22 @@ struct dentry *nfs_fs_mount(struct file_system_type *fs_type, struct nfs_subversion *nfs_mod; int error; - mount_info.parsed = nfs_alloc_parsed_mount_data(); + mount_info.ctx = nfs_alloc_parsed_mount_data(); mount_info.mntfh = nfs_alloc_fhandle(); - if (mount_info.parsed == NULL || mount_info.mntfh == NULL) + if (mount_info.ctx == NULL || mount_info.mntfh == NULL) goto out; /* Validate the mount data */ - error = nfs_validate_mount_data(fs_type, raw_data, mount_info.parsed, mount_info.mntfh, dev_name); + error = nfs_validate_mount_data(fs_type, raw_data, mount_info.ctx, mount_info.mntfh, dev_name); if (error == NFS_TEXT_DATA) - error = nfs_validate_text_mount_data(raw_data, mount_info.parsed, dev_name); + error = nfs_validate_text_mount_data(raw_data, + mount_info.ctx, dev_name); if (error < 0) { mntroot = ERR_PTR(error); goto out; } - nfs_mod = get_nfs_version(mount_info.parsed->version); + nfs_mod = get_nfs_version(mount_info.ctx->version); if (IS_ERR(nfs_mod)) { mntroot = ERR_CAST(nfs_mod); goto out; @@ -1366,7 +1368,7 @@ struct dentry *nfs_fs_mount(struct file_system_type *fs_type, put_nfs_version(nfs_mod); out: - nfs_free_parsed_mount_data(mount_info.parsed); + nfs_free_parsed_mount_data(mount_info.ctx); nfs_free_fhandle(mount_info.mntfh); return mntroot; } From patchwork Thu May 23 16:18:34 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Howells X-Patchwork-Id: 10958329 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 67C1D933 for ; Thu, 23 May 2019 16:18:43 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 53FEE27FA9 for ; Thu, 23 May 2019 16:18:43 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 482412847F; Thu, 23 May 2019 16:18:43 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-7.9 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI, RCVD_IN_DNSWL_HI autolearn=unavailable version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 9725927FA9 for ; Thu, 23 May 2019 16:18:42 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1731332AbfEWQSh (ORCPT ); Thu, 23 May 2019 12:18:37 -0400 Received: from mx1.redhat.com ([209.132.183.28]:45118 "EHLO mx1.redhat.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1731107AbfEWQSg (ORCPT ); Thu, 23 May 2019 12:18:36 -0400 Received: from smtp.corp.redhat.com (int-mx05.intmail.prod.int.phx2.redhat.com [10.5.11.15]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 9416AC0586C1; Thu, 23 May 2019 16:18:36 +0000 (UTC) Received: from warthog.procyon.org.uk (ovpn-121-142.rdu2.redhat.com [10.10.121.142]) by smtp.corp.redhat.com (Postfix) with ESMTP id 30B3B5B684; Thu, 23 May 2019 16:18:35 +0000 (UTC) Organization: Red Hat UK Ltd. Registered Address: Red Hat UK Ltd, Amberley Place, 107-111 Peascod Street, Windsor, Berkshire, SI4 1TE, United Kingdom. Registered in England and Wales under Company Registration No. 3798903 Subject: [PATCH 19/23] NFS: Split nfs_parse_mount_options() From: David Howells To: trond.myklebust@hammerspace.com, anna.schumaker@netapp.com Cc: Al Viro , dhowells@redhat.com, viro@zeniv.linux.org.uk, linux-nfs@vger.kernel.org, linux-fsdevel@vger.kernel.org, linux-kernel@vger.kernel.org Date: Thu, 23 May 2019 17:18:34 +0100 Message-ID: <155862831424.26654.5571901018563890124.stgit@warthog.procyon.org.uk> In-Reply-To: <155862813755.26654.563679411147031501.stgit@warthog.procyon.org.uk> References: <155862813755.26654.563679411147031501.stgit@warthog.procyon.org.uk> User-Agent: StGit/unknown-version MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.15 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.31]); Thu, 23 May 2019 16:18:36 +0000 (UTC) Sender: linux-fsdevel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-fsdevel@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP 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 Signed-off-by: Al Viro --- 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 10fe721756eb..f4e04721363f 100644 --- a/fs/nfs/fs_context.c +++ b/fs/nfs/fs_context.c @@ -495,36 +495,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); @@ -733,7 +715,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: @@ -743,24 +725,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 */ @@ -772,7 +754,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; @@ -784,16 +766,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; @@ -802,7 +784,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: @@ -861,7 +843,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: @@ -894,7 +876,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; @@ -902,7 +884,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: @@ -912,12 +894,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; @@ -932,22 +955,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"); @@ -955,23 +982,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 8bb6ee61d99c..c4a1203163ba 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; From patchwork Thu May 23 16:18:41 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Howells X-Patchwork-Id: 10958333 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 553FE13AD for ; Thu, 23 May 2019 16:18:51 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 411082808F for ; Thu, 23 May 2019 16:18:51 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 3584C28161; Thu, 23 May 2019 16:18:51 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-7.9 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI, RCVD_IN_DNSWL_HI autolearn=unavailable version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 0A67D28653 for ; Thu, 23 May 2019 16:18:50 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1731580AbfEWQSp (ORCPT ); Thu, 23 May 2019 12:18:45 -0400 Received: from mx1.redhat.com ([209.132.183.28]:33270 "EHLO mx1.redhat.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1731107AbfEWQSp (ORCPT ); Thu, 23 May 2019 12:18:45 -0400 Received: from smtp.corp.redhat.com (int-mx08.intmail.prod.int.phx2.redhat.com [10.5.11.23]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id B161487645; Thu, 23 May 2019 16:18:44 +0000 (UTC) Received: from warthog.procyon.org.uk (ovpn-121-142.rdu2.redhat.com [10.10.121.142]) by smtp.corp.redhat.com (Postfix) with ESMTP id 8BC402E043; Thu, 23 May 2019 16:18:42 +0000 (UTC) Organization: Red Hat UK Ltd. Registered Address: Red Hat UK Ltd, Amberley Place, 107-111 Peascod Street, Windsor, Berkshire, SI4 1TE, United Kingdom. Registered in England and Wales under Company Registration No. 3798903 Subject: [PATCH 20/23] NFS: Deindent nfs_fs_context_parse_option() From: David Howells To: trond.myklebust@hammerspace.com, anna.schumaker@netapp.com Cc: Al Viro , dhowells@redhat.com, viro@zeniv.linux.org.uk, linux-nfs@vger.kernel.org, linux-fsdevel@vger.kernel.org, linux-kernel@vger.kernel.org Date: Thu, 23 May 2019 17:18:41 +0100 Message-ID: <155862832180.26654.11735963506085471355.stgit@warthog.procyon.org.uk> In-Reply-To: <155862813755.26654.563679411147031501.stgit@warthog.procyon.org.uk> References: <155862813755.26654.563679411147031501.stgit@warthog.procyon.org.uk> User-Agent: StGit/unknown-version MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.84 on 10.5.11.23 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.26]); Thu, 23 May 2019 16:18:44 +0000 (UTC) Sender: linux-fsdevel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-fsdevel@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP Deindent nfs_fs_context_parse_option(). Signed-off-by: David Howells Signed-off-by: Al Viro --- fs/nfs/fs_context.c | 729 +++++++++++++++++++++++++-------------------------- 1 file changed, 362 insertions(+), 367 deletions(-) diff --git a/fs/nfs/fs_context.c b/fs/nfs/fs_context.c index f4e04721363f..c7796fb76732 100644 --- a/fs/nfs/fs_context.c +++ b/fs/nfs/fs_context.c @@ -499,405 +499,400 @@ static int nfs_get_option_ul_bound(substring_t args[], unsigned long *option, */ static int nfs_fs_context_parse_option(struct nfs_fs_context *ctx, char *p) { + substring_t args[MAX_OPT_ARGS]; + unsigned long option; char *string; - int rc; - - { - substring_t args[MAX_OPT_ARGS]; - unsigned long option; - int token; + int token, rc; - dfprintk(MOUNT, "NFS: parsing nfs mount option '%s'\n", p); - - token = match_token(p, nfs_mount_option_tokens, args); - switch (token) { + dfprintk(MOUNT, "NFS: parsing nfs mount option '%s'\n", p); + token = match_token(p, nfs_mount_option_tokens, args); + switch (token) { /* * boolean options: foo/nofoo */ - case Opt_soft: - ctx->flags |= NFS_MOUNT_SOFT; - ctx->flags &= ~NFS_MOUNT_SOFTERR; - break; - case Opt_softerr: - ctx->flags |= NFS_MOUNT_SOFTERR; - ctx->flags &= ~NFS_MOUNT_SOFT; - break; - case Opt_hard: - ctx->flags &= ~(NFS_MOUNT_SOFT|NFS_MOUNT_SOFTERR); - break; - case Opt_posix: - ctx->flags |= NFS_MOUNT_POSIX; - break; - case Opt_noposix: - ctx->flags &= ~NFS_MOUNT_POSIX; - break; - case Opt_cto: - ctx->flags &= ~NFS_MOUNT_NOCTO; - break; - case Opt_nocto: - ctx->flags |= NFS_MOUNT_NOCTO; - break; - case Opt_ac: - ctx->flags &= ~NFS_MOUNT_NOAC; - break; - case Opt_noac: - ctx->flags |= NFS_MOUNT_NOAC; - break; - case Opt_lock: - ctx->flags &= ~NFS_MOUNT_NONLM; - ctx->flags &= ~(NFS_MOUNT_LOCAL_FLOCK | - NFS_MOUNT_LOCAL_FCNTL); - break; - case Opt_nolock: - ctx->flags |= NFS_MOUNT_NONLM; - ctx->flags |= (NFS_MOUNT_LOCAL_FLOCK | - NFS_MOUNT_LOCAL_FCNTL); - break; - case Opt_udp: - ctx->flags &= ~NFS_MOUNT_TCP; - ctx->nfs_server.protocol = XPRT_TRANSPORT_UDP; - break; - case Opt_tcp: - ctx->flags |= NFS_MOUNT_TCP; - ctx->nfs_server.protocol = XPRT_TRANSPORT_TCP; - break; - case Opt_rdma: - ctx->flags |= NFS_MOUNT_TCP; /* for side protocols */ - ctx->nfs_server.protocol = XPRT_TRANSPORT_RDMA; - xprt_load_transport(p); - break; - case Opt_acl: - ctx->flags &= ~NFS_MOUNT_NOACL; - break; - case Opt_noacl: - ctx->flags |= NFS_MOUNT_NOACL; - break; - case Opt_rdirplus: - ctx->flags &= ~NFS_MOUNT_NORDIRPLUS; - break; - case Opt_nordirplus: - ctx->flags |= NFS_MOUNT_NORDIRPLUS; - break; - case Opt_sharecache: - ctx->flags &= ~NFS_MOUNT_UNSHARED; - break; - case Opt_nosharecache: - ctx->flags |= NFS_MOUNT_UNSHARED; - break; - case Opt_resvport: - ctx->flags &= ~NFS_MOUNT_NORESVPORT; - break; - case Opt_noresvport: - ctx->flags |= NFS_MOUNT_NORESVPORT; - break; - case Opt_fscache: - ctx->options |= NFS_OPTION_FSCACHE; - kfree(ctx->fscache_uniq); - ctx->fscache_uniq = NULL; - break; - case Opt_nofscache: - ctx->options &= ~NFS_OPTION_FSCACHE; - kfree(ctx->fscache_uniq); - ctx->fscache_uniq = NULL; - break; - case Opt_migration: - ctx->options |= NFS_OPTION_MIGRATION; - break; - case Opt_nomigration: - ctx->options &= ~NFS_OPTION_MIGRATION; - break; + case Opt_soft: + ctx->flags |= NFS_MOUNT_SOFT; + ctx->flags &= ~NFS_MOUNT_SOFTERR; + break; + case Opt_softerr: + ctx->flags |= NFS_MOUNT_SOFTERR; + ctx->flags &= ~NFS_MOUNT_SOFT; + break; + case Opt_hard: + ctx->flags &= ~(NFS_MOUNT_SOFT|NFS_MOUNT_SOFTERR); + break; + case Opt_posix: + ctx->flags |= NFS_MOUNT_POSIX; + break; + case Opt_noposix: + ctx->flags &= ~NFS_MOUNT_POSIX; + break; + case Opt_cto: + ctx->flags &= ~NFS_MOUNT_NOCTO; + break; + case Opt_nocto: + ctx->flags |= NFS_MOUNT_NOCTO; + break; + case Opt_ac: + ctx->flags &= ~NFS_MOUNT_NOAC; + break; + case Opt_noac: + ctx->flags |= NFS_MOUNT_NOAC; + break; + case Opt_lock: + ctx->flags &= ~NFS_MOUNT_NONLM; + ctx->flags &= ~(NFS_MOUNT_LOCAL_FLOCK | + NFS_MOUNT_LOCAL_FCNTL); + break; + case Opt_nolock: + ctx->flags |= NFS_MOUNT_NONLM; + ctx->flags |= (NFS_MOUNT_LOCAL_FLOCK | + NFS_MOUNT_LOCAL_FCNTL); + break; + case Opt_udp: + ctx->flags &= ~NFS_MOUNT_TCP; + ctx->nfs_server.protocol = XPRT_TRANSPORT_UDP; + break; + case Opt_tcp: + ctx->flags |= NFS_MOUNT_TCP; + ctx->nfs_server.protocol = XPRT_TRANSPORT_TCP; + break; + case Opt_rdma: + ctx->flags |= NFS_MOUNT_TCP; /* for side protocols */ + ctx->nfs_server.protocol = XPRT_TRANSPORT_RDMA; + xprt_load_transport(p); + break; + case Opt_acl: + ctx->flags &= ~NFS_MOUNT_NOACL; + break; + case Opt_noacl: + ctx->flags |= NFS_MOUNT_NOACL; + break; + case Opt_rdirplus: + ctx->flags &= ~NFS_MOUNT_NORDIRPLUS; + break; + case Opt_nordirplus: + ctx->flags |= NFS_MOUNT_NORDIRPLUS; + break; + case Opt_sharecache: + ctx->flags &= ~NFS_MOUNT_UNSHARED; + break; + case Opt_nosharecache: + ctx->flags |= NFS_MOUNT_UNSHARED; + break; + case Opt_resvport: + ctx->flags &= ~NFS_MOUNT_NORESVPORT; + break; + case Opt_noresvport: + ctx->flags |= NFS_MOUNT_NORESVPORT; + break; + case Opt_fscache: + ctx->options |= NFS_OPTION_FSCACHE; + kfree(ctx->fscache_uniq); + ctx->fscache_uniq = NULL; + break; + case Opt_nofscache: + ctx->options &= ~NFS_OPTION_FSCACHE; + kfree(ctx->fscache_uniq); + ctx->fscache_uniq = NULL; + break; + case Opt_migration: + ctx->options |= NFS_OPTION_MIGRATION; + break; + case Opt_nomigration: + ctx->options &= ~NFS_OPTION_MIGRATION; + break; /* * options that take numeric values */ - case Opt_port: - if (nfs_get_option_ul(args, &option) || - option > USHRT_MAX) - goto out_invalid_value; - ctx->nfs_server.port = option; - break; - case Opt_rsize: - if (nfs_get_option_ul(args, &option)) - goto out_invalid_value; - ctx->rsize = option; - break; - case Opt_wsize: - if (nfs_get_option_ul(args, &option)) - goto out_invalid_value; - ctx->wsize = option; - break; - case Opt_bsize: - if (nfs_get_option_ul(args, &option)) - goto out_invalid_value; - ctx->bsize = option; - break; - case Opt_timeo: - if (nfs_get_option_ul_bound(args, &option, 1, INT_MAX)) - goto out_invalid_value; - ctx->timeo = option; - break; - case Opt_retrans: - if (nfs_get_option_ul_bound(args, &option, 0, INT_MAX)) - goto out_invalid_value; - ctx->retrans = option; - break; - case Opt_acregmin: - if (nfs_get_option_ul(args, &option)) - goto out_invalid_value; - ctx->acregmin = option; - break; - case Opt_acregmax: - if (nfs_get_option_ul(args, &option)) - goto out_invalid_value; - ctx->acregmax = option; - break; - case Opt_acdirmin: - if (nfs_get_option_ul(args, &option)) - goto out_invalid_value; - ctx->acdirmin = option; - break; - case Opt_acdirmax: - if (nfs_get_option_ul(args, &option)) - goto out_invalid_value; - ctx->acdirmax = option; - break; - case Opt_actimeo: - if (nfs_get_option_ul(args, &option)) - goto out_invalid_value; - ctx->acregmin = ctx->acregmax = + case Opt_port: + if (nfs_get_option_ul(args, &option) || + option > USHRT_MAX) + goto out_invalid_value; + ctx->nfs_server.port = option; + break; + case Opt_rsize: + if (nfs_get_option_ul(args, &option)) + goto out_invalid_value; + ctx->rsize = option; + break; + case Opt_wsize: + if (nfs_get_option_ul(args, &option)) + goto out_invalid_value; + ctx->wsize = option; + break; + case Opt_bsize: + if (nfs_get_option_ul(args, &option)) + goto out_invalid_value; + ctx->bsize = option; + break; + case Opt_timeo: + if (nfs_get_option_ul_bound(args, &option, 1, INT_MAX)) + goto out_invalid_value; + ctx->timeo = option; + break; + case Opt_retrans: + if (nfs_get_option_ul_bound(args, &option, 0, INT_MAX)) + goto out_invalid_value; + ctx->retrans = option; + break; + case Opt_acregmin: + if (nfs_get_option_ul(args, &option)) + goto out_invalid_value; + ctx->acregmin = option; + break; + case Opt_acregmax: + if (nfs_get_option_ul(args, &option)) + goto out_invalid_value; + ctx->acregmax = option; + break; + case Opt_acdirmin: + if (nfs_get_option_ul(args, &option)) + goto out_invalid_value; + ctx->acdirmin = option; + break; + case Opt_acdirmax: + if (nfs_get_option_ul(args, &option)) + goto out_invalid_value; + ctx->acdirmax = option; + break; + case Opt_actimeo: + if (nfs_get_option_ul(args, &option)) + goto out_invalid_value; + ctx->acregmin = ctx->acregmax = ctx->acdirmin = ctx->acdirmax = option; - break; - case Opt_namelen: - if (nfs_get_option_ul(args, &option)) - goto out_invalid_value; - ctx->namlen = option; - break; - case Opt_mountport: - if (nfs_get_option_ul(args, &option) || - option > USHRT_MAX) - goto out_invalid_value; - ctx->mount_server.port = option; - break; - case Opt_mountvers: - if (nfs_get_option_ul(args, &option) || - option < NFS_MNT_VERSION || - option > NFS_MNT3_VERSION) - goto out_invalid_value; - ctx->mount_server.version = option; - break; - case Opt_minorversion: - if (nfs_get_option_ul(args, &option)) - goto out_invalid_value; - if (option > NFS4_MAX_MINOR_VERSION) - goto out_invalid_value; - ctx->minorversion = option; - break; + break; + case Opt_namelen: + if (nfs_get_option_ul(args, &option)) + goto out_invalid_value; + ctx->namlen = option; + break; + case Opt_mountport: + if (nfs_get_option_ul(args, &option) || + option > USHRT_MAX) + goto out_invalid_value; + ctx->mount_server.port = option; + break; + case Opt_mountvers: + if (nfs_get_option_ul(args, &option) || + option < NFS_MNT_VERSION || + option > NFS_MNT3_VERSION) + goto out_invalid_value; + ctx->mount_server.version = option; + break; + case Opt_minorversion: + if (nfs_get_option_ul(args, &option)) + goto out_invalid_value; + if (option > NFS4_MAX_MINOR_VERSION) + goto out_invalid_value; + ctx->minorversion = option; + break; /* * options that take text values */ - case Opt_nfsvers: - string = match_strdup(args); - if (string == NULL) - goto out_nomem; - rc = nfs_parse_version_string(string, ctx, args); - kfree(string); - if (!rc) - goto out_invalid_value; + case Opt_nfsvers: + string = match_strdup(args); + if (string == NULL) + goto out_nomem; + rc = nfs_parse_version_string(string, ctx, args); + kfree(string); + if (!rc) + goto out_invalid_value; + break; + case Opt_sec: + string = match_strdup(args); + if (string == NULL) + goto out_nomem; + rc = nfs_parse_security_flavors(string, ctx); + kfree(string); + if (!rc) { + dfprintk(MOUNT, "NFS: unrecognized " + "security flavor\n"); + return -EINVAL; + } + break; + case Opt_proto: + string = match_strdup(args); + if (string == NULL) + goto out_nomem; + token = match_token(string, + nfs_xprt_protocol_tokens, args); + + ctx->protofamily = AF_INET; + switch (token) { + case Opt_xprt_udp6: + 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_sec: - string = match_strdup(args); - if (string == NULL) - goto out_nomem; - rc = nfs_parse_security_flavors(string, ctx); - kfree(string); - if (!rc) { - dfprintk(MOUNT, "NFS: unrecognized " - "security flavor\n"); - return -EINVAL; - } + case Opt_xprt_tcp6: + 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_proto: - string = match_strdup(args); - if (string == NULL) - goto out_nomem; - token = match_token(string, - nfs_xprt_protocol_tokens, args); - - ctx->protofamily = AF_INET; - switch (token) { - case Opt_xprt_udp6: - 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: - 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: - ctx->protofamily = AF_INET6; - /* fall through */ - case Opt_xprt_rdma: - /* vector side protocols to TCP */ - ctx->flags |= NFS_MOUNT_TCP; - ctx->nfs_server.protocol = XPRT_TRANSPORT_RDMA; - xprt_load_transport(string); - break; - default: - dfprintk(MOUNT, "NFS: unrecognized " - "transport protocol\n"); - kfree(string); - return -EINVAL; - } - kfree(string); + case Opt_xprt_rdma6: + ctx->protofamily = AF_INET6; + /* fall through */ + case Opt_xprt_rdma: + /* vector side protocols to TCP */ + ctx->flags |= NFS_MOUNT_TCP; + ctx->nfs_server.protocol = XPRT_TRANSPORT_RDMA; + xprt_load_transport(string); break; - case Opt_mountproto: - string = match_strdup(args); - if (string == NULL) - goto out_nomem; - token = match_token(string, - nfs_xprt_protocol_tokens, args); + default: + dfprintk(MOUNT, "NFS: unrecognized " + "transport protocol\n"); kfree(string); + return -EINVAL; + } + kfree(string); + break; + case Opt_mountproto: + string = match_strdup(args); + if (string == NULL) + goto out_nomem; + token = match_token(string, + nfs_xprt_protocol_tokens, args); + kfree(string); - ctx->mountfamily = AF_INET; - switch (token) { - case Opt_xprt_udp6: - ctx->mountfamily = AF_INET6; - /* fall through */ - case Opt_xprt_udp: - ctx->mount_server.protocol = XPRT_TRANSPORT_UDP; - break; - case Opt_xprt_tcp6: - ctx->mountfamily = AF_INET6; - /* fall through */ - case Opt_xprt_tcp: - ctx->mount_server.protocol = XPRT_TRANSPORT_TCP; - break; - case Opt_xprt_rdma: /* not used for side protocols */ - default: - dfprintk(MOUNT, "NFS: unrecognized " - "transport protocol\n"); - return -EINVAL; - } - break; - case Opt_addr: - string = match_strdup(args); - if (string == NULL) - goto out_nomem; - ctx->nfs_server.addrlen = - rpc_pton(ctx->net, string, strlen(string), - (struct sockaddr *) - &ctx->nfs_server.address, - sizeof(ctx->nfs_server.address)); - kfree(string); - if (ctx->nfs_server.addrlen == 0) - goto out_invalid_address; + ctx->mountfamily = AF_INET; + switch (token) { + case Opt_xprt_udp6: + ctx->mountfamily = AF_INET6; + /* fall through */ + case Opt_xprt_udp: + ctx->mount_server.protocol = XPRT_TRANSPORT_UDP; + break; + case Opt_xprt_tcp6: + ctx->mountfamily = AF_INET6; + /* fall through */ + case Opt_xprt_tcp: + ctx->mount_server.protocol = XPRT_TRANSPORT_TCP; + break; + case Opt_xprt_rdma: /* not used for side protocols */ + default: + dfprintk(MOUNT, "NFS: unrecognized " + "transport protocol\n"); + return -EINVAL; + } + break; + case Opt_addr: + string = match_strdup(args); + if (string == NULL) + goto out_nomem; + ctx->nfs_server.addrlen = + rpc_pton(ctx->net, string, strlen(string), + (struct sockaddr *) + &ctx->nfs_server.address, + sizeof(ctx->nfs_server.address)); + kfree(string); + if (ctx->nfs_server.addrlen == 0) + goto out_invalid_address; + break; + case Opt_clientaddr: + if (nfs_get_option_str(args, &ctx->client_address)) + goto out_nomem; + break; + case Opt_mounthost: + if (nfs_get_option_str(args, + &ctx->mount_server.hostname)) + goto out_nomem; + break; + case Opt_mountaddr: + string = match_strdup(args); + if (string == NULL) + goto out_nomem; + ctx->mount_server.addrlen = + rpc_pton(ctx->net, string, strlen(string), + (struct sockaddr *) + &ctx->mount_server.address, + sizeof(ctx->mount_server.address)); + kfree(string); + if (ctx->mount_server.addrlen == 0) + goto out_invalid_address; + break; + case Opt_lookupcache: + string = match_strdup(args); + if (string == NULL) + goto out_nomem; + token = match_token(string, + nfs_lookupcache_tokens, args); + kfree(string); + switch (token) { + case Opt_lookupcache_all: + ctx->flags &= ~(NFS_MOUNT_LOOKUP_CACHE_NONEG|NFS_MOUNT_LOOKUP_CACHE_NONE); break; - case Opt_clientaddr: - if (nfs_get_option_str(args, &ctx->client_address)) - goto out_nomem; + case Opt_lookupcache_positive: + ctx->flags &= ~NFS_MOUNT_LOOKUP_CACHE_NONE; + ctx->flags |= NFS_MOUNT_LOOKUP_CACHE_NONEG; break; - case Opt_mounthost: - if (nfs_get_option_str(args, - &ctx->mount_server.hostname)) - goto out_nomem; + case Opt_lookupcache_none: + ctx->flags |= NFS_MOUNT_LOOKUP_CACHE_NONEG|NFS_MOUNT_LOOKUP_CACHE_NONE; break; - case Opt_mountaddr: - string = match_strdup(args); - if (string == NULL) - goto out_nomem; - ctx->mount_server.addrlen = - rpc_pton(ctx->net, string, strlen(string), - (struct sockaddr *) - &ctx->mount_server.address, - sizeof(ctx->mount_server.address)); - kfree(string); - if (ctx->mount_server.addrlen == 0) - goto out_invalid_address; + default: + dfprintk(MOUNT, "NFS: invalid " + "lookupcache argument\n"); + return -EINVAL; + }; + break; + case Opt_fscache_uniq: + if (nfs_get_option_str(args, &ctx->fscache_uniq)) + goto out_nomem; + ctx->options |= NFS_OPTION_FSCACHE; + break; + case Opt_local_lock: + string = match_strdup(args); + if (string == NULL) + goto out_nomem; + token = match_token(string, nfs_local_lock_tokens, + args); + kfree(string); + switch (token) { + case Opt_local_lock_all: + ctx->flags |= (NFS_MOUNT_LOCAL_FLOCK | + NFS_MOUNT_LOCAL_FCNTL); break; - case Opt_lookupcache: - string = match_strdup(args); - if (string == NULL) - goto out_nomem; - token = match_token(string, - nfs_lookupcache_tokens, args); - kfree(string); - switch (token) { - case Opt_lookupcache_all: - ctx->flags &= ~(NFS_MOUNT_LOOKUP_CACHE_NONEG|NFS_MOUNT_LOOKUP_CACHE_NONE); - break; - case Opt_lookupcache_positive: - ctx->flags &= ~NFS_MOUNT_LOOKUP_CACHE_NONE; - ctx->flags |= NFS_MOUNT_LOOKUP_CACHE_NONEG; - break; - case Opt_lookupcache_none: - ctx->flags |= NFS_MOUNT_LOOKUP_CACHE_NONEG|NFS_MOUNT_LOOKUP_CACHE_NONE; - break; - default: - dfprintk(MOUNT, "NFS: invalid " - "lookupcache argument\n"); - return -EINVAL; - }; + case Opt_local_lock_flock: + ctx->flags |= NFS_MOUNT_LOCAL_FLOCK; break; - case Opt_fscache_uniq: - if (nfs_get_option_str(args, &ctx->fscache_uniq)) - goto out_nomem; - ctx->options |= NFS_OPTION_FSCACHE; + case Opt_local_lock_posix: + ctx->flags |= NFS_MOUNT_LOCAL_FCNTL; break; - case Opt_local_lock: - string = match_strdup(args); - if (string == NULL) - goto out_nomem; - token = match_token(string, nfs_local_lock_tokens, - args); - kfree(string); - switch (token) { - case Opt_local_lock_all: - ctx->flags |= (NFS_MOUNT_LOCAL_FLOCK | - NFS_MOUNT_LOCAL_FCNTL); - break; - case Opt_local_lock_flock: - ctx->flags |= NFS_MOUNT_LOCAL_FLOCK; - break; - case Opt_local_lock_posix: - ctx->flags |= NFS_MOUNT_LOCAL_FCNTL; - break; - case Opt_local_lock_none: - ctx->flags &= ~(NFS_MOUNT_LOCAL_FLOCK | - NFS_MOUNT_LOCAL_FCNTL); - break; - default: - dfprintk(MOUNT, "NFS: invalid " - "local_lock argument\n"); - return -EINVAL; - }; + case Opt_local_lock_none: + ctx->flags &= ~(NFS_MOUNT_LOCAL_FLOCK | + NFS_MOUNT_LOCAL_FCNTL); break; + default: + dfprintk(MOUNT, "NFS: invalid " + "local_lock argument\n"); + return -EINVAL; + }; + break; /* * Special options */ - case Opt_sloppy: - ctx->sloppy = 1; - dfprintk(MOUNT, "NFS: relaxing parsing rules\n"); - break; - case Opt_userspace: - case Opt_deprecated: - dfprintk(MOUNT, "NFS: ignoring mount option " - "'%s'\n", p); - break; + case Opt_sloppy: + ctx->sloppy = 1; + dfprintk(MOUNT, "NFS: relaxing parsing rules\n"); + break; + case Opt_userspace: + case Opt_deprecated: + dfprintk(MOUNT, "NFS: ignoring mount option " + "'%s'\n", p); + break; - default: - dfprintk(MOUNT, "NFS: unrecognized mount option " - "'%s'\n", p); - return -EINVAL; - } + default: + dfprintk(MOUNT, "NFS: unrecognized mount option " + "'%s'\n", p); + return -EINVAL; } return 0; From patchwork Thu May 23 16:18:50 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Howells X-Patchwork-Id: 10958339 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 1DA50933 for ; Thu, 23 May 2019 16:19:08 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 0748628555 for ; Thu, 23 May 2019 16:19:08 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id F001428384; Thu, 23 May 2019 16:19:07 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-7.9 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI, RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 6E8902808F for ; Thu, 23 May 2019 16:19:07 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1731579AbfEWQSx (ORCPT ); Thu, 23 May 2019 12:18:53 -0400 Received: from mx1.redhat.com ([209.132.183.28]:52812 "EHLO mx1.redhat.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1731107AbfEWQSx (ORCPT ); Thu, 23 May 2019 12:18:53 -0400 Received: from smtp.corp.redhat.com (int-mx01.intmail.prod.int.phx2.redhat.com [10.5.11.11]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 71540308FBA9; Thu, 23 May 2019 16:18:52 +0000 (UTC) Received: from warthog.procyon.org.uk (ovpn-121-142.rdu2.redhat.com [10.10.121.142]) by smtp.corp.redhat.com (Postfix) with ESMTP id D6568604CC; Thu, 23 May 2019 16:18:50 +0000 (UTC) Organization: Red Hat UK Ltd. Registered Address: Red Hat UK Ltd, Amberley Place, 107-111 Peascod Street, Windsor, Berkshire, SI4 1TE, United Kingdom. Registered in England and Wales under Company Registration No. 3798903 Subject: [PATCH 21/23] NFS: Add a small buffer in nfs_fs_context to avoid string dup From: David Howells To: trond.myklebust@hammerspace.com, anna.schumaker@netapp.com Cc: Al Viro , dhowells@redhat.com, viro@zeniv.linux.org.uk, linux-nfs@vger.kernel.org, linux-fsdevel@vger.kernel.org, linux-kernel@vger.kernel.org Date: Thu, 23 May 2019 17:18:50 +0100 Message-ID: <155862832993.26654.13644247168126569903.stgit@warthog.procyon.org.uk> In-Reply-To: <155862813755.26654.563679411147031501.stgit@warthog.procyon.org.uk> References: <155862813755.26654.563679411147031501.stgit@warthog.procyon.org.uk> User-Agent: StGit/unknown-version MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.11 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.43]); Thu, 23 May 2019 16:18:52 +0000 (UTC) Sender: linux-fsdevel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-fsdevel@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP Add a small buffer in nfs_fs_context to avoid string duplication when parsing numbers. Also make the parsing function wrapper place the parsed integer directly in the appropriate nfs_fs_context struct member. Signed-off-by: David Howells Signed-off-by: Al Viro --- fs/nfs/fs_context.c | 82 +++++++++++++++++++-------------------------------- fs/nfs/internal.h | 2 + 2 files changed, 32 insertions(+), 52 deletions(-) diff --git a/fs/nfs/fs_context.c b/fs/nfs/fs_context.c index c7796fb76732..5ba534127c0b 100644 --- a/fs/nfs/fs_context.c +++ b/fs/nfs/fs_context.c @@ -467,27 +467,22 @@ static int nfs_get_option_str(substring_t args[], char **option) return !*option; } -static int nfs_get_option_ul(substring_t args[], unsigned long *option) +static int nfs_get_option_ui(struct nfs_fs_context *ctx, + substring_t args[], unsigned int *option) { - int rc; - char *string; - - string = match_strdup(args); - if (string == NULL) - return -ENOMEM; - rc = kstrtoul(string, 10, option); - kfree(string); - - return rc; + match_strlcpy(ctx->buf, args, sizeof(ctx->buf)); + return kstrtouint(ctx->buf, 10, option); } -static int nfs_get_option_ul_bound(substring_t args[], unsigned long *option, - unsigned long l_bound, unsigned long u_bound) +static int nfs_get_option_ui_bound(struct nfs_fs_context *ctx, + substring_t args[], unsigned int *option, + unsigned int l_bound, unsigned u_bound) { int ret; - ret = nfs_get_option_ul(args, option); - if (ret != 0) + match_strlcpy(ctx->buf, args, sizeof(ctx->buf)); + ret = kstrtouint(ctx->buf, 10, option); + if (ret < 0) return ret; if (*option < l_bound || *option > u_bound) return -ERANGE; @@ -500,7 +495,6 @@ static int nfs_get_option_ul_bound(substring_t args[], unsigned long *option, static int nfs_fs_context_parse_option(struct nfs_fs_context *ctx, char *p) { substring_t args[MAX_OPT_ARGS]; - unsigned long option; char *string; int token, rc; @@ -608,86 +602,70 @@ static int nfs_fs_context_parse_option(struct nfs_fs_context *ctx, char *p) * options that take numeric values */ case Opt_port: - if (nfs_get_option_ul(args, &option) || - option > USHRT_MAX) + if (nfs_get_option_ui_bound(ctx, args, &ctx->nfs_server.port, + 0, USHRT_MAX)) goto out_invalid_value; - ctx->nfs_server.port = option; break; case Opt_rsize: - if (nfs_get_option_ul(args, &option)) + if (nfs_get_option_ui(ctx, args, &ctx->rsize)) goto out_invalid_value; - ctx->rsize = option; break; case Opt_wsize: - if (nfs_get_option_ul(args, &option)) + if (nfs_get_option_ui(ctx, args, &ctx->wsize)) goto out_invalid_value; - ctx->wsize = option; break; case Opt_bsize: - if (nfs_get_option_ul(args, &option)) + if (nfs_get_option_ui(ctx, args, &ctx->bsize)) goto out_invalid_value; - ctx->bsize = option; break; case Opt_timeo: - if (nfs_get_option_ul_bound(args, &option, 1, INT_MAX)) + if (nfs_get_option_ui_bound(ctx, args, &ctx->timeo, 1, INT_MAX)) goto out_invalid_value; - ctx->timeo = option; break; case Opt_retrans: - if (nfs_get_option_ul_bound(args, &option, 0, INT_MAX)) + if (nfs_get_option_ui_bound(ctx, args, &ctx->retrans, 0, INT_MAX)) goto out_invalid_value; - ctx->retrans = option; break; case Opt_acregmin: - if (nfs_get_option_ul(args, &option)) + if (nfs_get_option_ui(ctx, args, &ctx->acregmin)) goto out_invalid_value; - ctx->acregmin = option; break; case Opt_acregmax: - if (nfs_get_option_ul(args, &option)) + if (nfs_get_option_ui(ctx, args, &ctx->acregmax)) goto out_invalid_value; - ctx->acregmax = option; break; case Opt_acdirmin: - if (nfs_get_option_ul(args, &option)) + if (nfs_get_option_ui(ctx, args, &ctx->acdirmin)) goto out_invalid_value; - ctx->acdirmin = option; break; case Opt_acdirmax: - if (nfs_get_option_ul(args, &option)) + if (nfs_get_option_ui(ctx, args, &ctx->acdirmax)) goto out_invalid_value; - ctx->acdirmax = option; break; case Opt_actimeo: - if (nfs_get_option_ul(args, &option)) + if (nfs_get_option_ui(ctx, args, &ctx->acdirmax)) goto out_invalid_value; ctx->acregmin = ctx->acregmax = - ctx->acdirmin = ctx->acdirmax = option; + ctx->acdirmin = ctx->acdirmax; break; case Opt_namelen: - if (nfs_get_option_ul(args, &option)) + if (nfs_get_option_ui(ctx, args, &ctx->namlen)) goto out_invalid_value; - ctx->namlen = option; break; case Opt_mountport: - if (nfs_get_option_ul(args, &option) || - option > USHRT_MAX) + if (nfs_get_option_ui_bound(ctx, args, &ctx->mount_server.port, + 0, USHRT_MAX)) goto out_invalid_value; - ctx->mount_server.port = option; break; case Opt_mountvers: - if (nfs_get_option_ul(args, &option) || - option < NFS_MNT_VERSION || - option > NFS_MNT3_VERSION) + if (nfs_get_option_ui_bound(ctx, args, &ctx->mount_server.version, + NFS_MNT_VERSION, NFS_MNT3_VERSION)) goto out_invalid_value; - ctx->mount_server.version = option; break; case Opt_minorversion: - if (nfs_get_option_ul(args, &option)) - goto out_invalid_value; - if (option > NFS4_MAX_MINOR_VERSION) + if (nfs_get_option_ui_bound(ctx, args, &ctx->minorversion, + 0, NFS4_MAX_MINOR_VERSION)) goto out_invalid_value; - ctx->minorversion = option; break; /* diff --git a/fs/nfs/internal.h b/fs/nfs/internal.h index c4a1203163ba..6efdbedeeee8 100644 --- a/fs/nfs/internal.h +++ b/fs/nfs/internal.h @@ -129,6 +129,8 @@ struct nfs_fs_context { void *lsm_opts; struct net *net; + + char buf[32]; /* Parse buffer */ }; /* mount_clnt.c */ From patchwork Thu May 23 16:18:57 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Howells X-Patchwork-Id: 10958335 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 5102213AD for ; Thu, 23 May 2019 16:19:07 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 3ABCC2808F for ; Thu, 23 May 2019 16:19:07 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 2F5B028384; Thu, 23 May 2019 16:19:07 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-7.9 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI, RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 3C3AE2808F for ; Thu, 23 May 2019 16:19:06 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1731394AbfEWQTB (ORCPT ); Thu, 23 May 2019 12:19:01 -0400 Received: from mx1.redhat.com ([209.132.183.28]:40222 "EHLO mx1.redhat.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1731273AbfEWQTA (ORCPT ); Thu, 23 May 2019 12:19:00 -0400 Received: from smtp.corp.redhat.com (int-mx02.intmail.prod.int.phx2.redhat.com [10.5.11.12]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 4300F307C945; Thu, 23 May 2019 16:19:00 +0000 (UTC) Received: from warthog.procyon.org.uk (ovpn-121-142.rdu2.redhat.com [10.10.121.142]) by smtp.corp.redhat.com (Postfix) with ESMTP id 82C89BA57; Thu, 23 May 2019 16:18:58 +0000 (UTC) Organization: Red Hat UK Ltd. Registered Address: Red Hat UK Ltd, Amberley Place, 107-111 Peascod Street, Windsor, Berkshire, SI4 1TE, United Kingdom. Registered in England and Wales under Company Registration No. 3798903 Subject: [PATCH 22/23] NFS: Do some tidying of the parsing code From: David Howells To: trond.myklebust@hammerspace.com, anna.schumaker@netapp.com Cc: Al Viro , dhowells@redhat.com, viro@zeniv.linux.org.uk, linux-nfs@vger.kernel.org, linux-fsdevel@vger.kernel.org, linux-kernel@vger.kernel.org Date: Thu, 23 May 2019 17:18:57 +0100 Message-ID: <155862833769.26654.15400933665829349780.stgit@warthog.procyon.org.uk> In-Reply-To: <155862813755.26654.563679411147031501.stgit@warthog.procyon.org.uk> References: <155862813755.26654.563679411147031501.stgit@warthog.procyon.org.uk> User-Agent: StGit/unknown-version MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.12 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.46]); Thu, 23 May 2019 16:19:00 +0000 (UTC) Sender: linux-fsdevel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-fsdevel@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP Do some tidying of the parsing code, including: (*) Returning 0/error rather than true/false. (*) Putting the nfs_fs_context pointer first in some arg lists. (*) Unwrap some lines that will now fit on one line. (*) Provide unioned sockaddr/sockaddr_storage fields to avoid casts. (*) nfs_parse_devname() can paste its return values directly into the nfs_fs_context struct as that's where the caller puts them. Signed-off-by: David Howells Signed-off-by: Al Viro --- fs/nfs/fs_context.c | 128 ++++++++++++++++++++++----------------------------- fs/nfs/internal.h | 16 ++++-- fs/nfs/super.c | 2 - 3 files changed, 67 insertions(+), 79 deletions(-) diff --git a/fs/nfs/fs_context.c b/fs/nfs/fs_context.c index 5ba534127c0b..3afacdee37c8 100644 --- a/fs/nfs/fs_context.c +++ b/fs/nfs/fs_context.c @@ -342,8 +342,9 @@ static void nfs_set_mount_transport_protocol(struct nfs_fs_context *ctx) * Add 'flavor' to 'auth_info' if not already present. * Returns true if 'flavor' ends up in the list, false otherwise */ -static bool nfs_auth_info_add(struct nfs_auth_info *auth_info, - rpc_authflavor_t flavor) +static int nfs_auth_info_add(struct nfs_fs_context *ctx, + struct nfs_auth_info *auth_info, + rpc_authflavor_t flavor) { unsigned int i; unsigned int max_flavor_len = ARRAY_SIZE(auth_info->flavors); @@ -351,26 +352,27 @@ static bool nfs_auth_info_add(struct nfs_auth_info *auth_info, /* make sure this flavor isn't already in the list */ for (i = 0; i < auth_info->flavor_len; i++) { if (flavor == auth_info->flavors[i]) - return true; + return 0; } if (auth_info->flavor_len + 1 >= max_flavor_len) { dfprintk(MOUNT, "NFS: too many sec= flavors\n"); - return false; + return -EINVAL; } auth_info->flavors[auth_info->flavor_len++] = flavor; - return true; + return 0; } /* * Parse the value of the 'sec=' option. */ -static int nfs_parse_security_flavors(char *value, struct nfs_fs_context *ctx) +static int nfs_parse_security_flavors(struct nfs_fs_context *ctx, char *value) { substring_t args[MAX_OPT_ARGS]; rpc_authflavor_t pseudoflavor; char *p; + int ret; dfprintk(MOUNT, "NFS: parsing sec=%s option\n", value); @@ -412,19 +414,20 @@ static int nfs_parse_security_flavors(char *value, struct nfs_fs_context *ctx) default: dfprintk(MOUNT, "NFS: sec= option '%s' not recognized\n", p); - return 0; + return -EINVAL; } - if (!nfs_auth_info_add(&ctx->auth_info, pseudoflavor)) - return 0; + ret = nfs_auth_info_add(ctx, &ctx->auth_info, pseudoflavor); + if (ret < 0) + return ret; } - return 1; + return 0; } -static int nfs_parse_version_string(char *string, - struct nfs_fs_context *ctx, - substring_t *args) +static int nfs_parse_version_string(struct nfs_fs_context *ctx, + char *string, + substring_t *args) { ctx->flags &= ~NFS_MOUNT_VER3; switch (match_token(string, nfs_vers_tokens, args)) { @@ -455,9 +458,10 @@ static int nfs_parse_version_string(char *string, ctx->minorversion = 2; break; default: - return 0; + dfprintk(MOUNT, "NFS: Unsupported NFS version\n"); + return -EINVAL; } - return 1; + return 0; } static int nfs_get_option_str(substring_t args[], char **option) @@ -496,7 +500,7 @@ static int nfs_fs_context_parse_option(struct nfs_fs_context *ctx, char *p) { substring_t args[MAX_OPT_ARGS]; char *string; - int token, rc; + int token, ret; dfprintk(MOUNT, "NFS: parsing nfs mount option '%s'\n", p); @@ -536,13 +540,11 @@ static int nfs_fs_context_parse_option(struct nfs_fs_context *ctx, char *p) break; case Opt_lock: ctx->flags &= ~NFS_MOUNT_NONLM; - ctx->flags &= ~(NFS_MOUNT_LOCAL_FLOCK | - NFS_MOUNT_LOCAL_FCNTL); + ctx->flags &= ~(NFS_MOUNT_LOCAL_FLOCK | NFS_MOUNT_LOCAL_FCNTL); break; case Opt_nolock: ctx->flags |= NFS_MOUNT_NONLM; - ctx->flags |= (NFS_MOUNT_LOCAL_FLOCK | - NFS_MOUNT_LOCAL_FCNTL); + ctx->flags |= (NFS_MOUNT_LOCAL_FLOCK | NFS_MOUNT_LOCAL_FCNTL); break; case Opt_udp: ctx->flags &= ~NFS_MOUNT_TCP; @@ -675,29 +677,25 @@ static int nfs_fs_context_parse_option(struct nfs_fs_context *ctx, char *p) string = match_strdup(args); if (string == NULL) goto out_nomem; - rc = nfs_parse_version_string(string, ctx, args); + ret = nfs_parse_version_string(ctx, string, args); kfree(string); - if (!rc) - goto out_invalid_value; + if (ret < 0) + return ret; break; case Opt_sec: string = match_strdup(args); if (string == NULL) goto out_nomem; - rc = nfs_parse_security_flavors(string, ctx); + ret = nfs_parse_security_flavors(ctx, string); kfree(string); - if (!rc) { - dfprintk(MOUNT, "NFS: unrecognized " - "security flavor\n"); - return -EINVAL; - } + if (ret < 0) + return ret; break; case Opt_proto: string = match_strdup(args); if (string == NULL) goto out_nomem; - token = match_token(string, - nfs_xprt_protocol_tokens, args); + token = match_token(string, nfs_xprt_protocol_tokens, args); ctx->protofamily = AF_INET; switch (token) { @@ -725,9 +723,8 @@ static int nfs_fs_context_parse_option(struct nfs_fs_context *ctx, char *p) xprt_load_transport(string); break; default: - dfprintk(MOUNT, "NFS: unrecognized " - "transport protocol\n"); kfree(string); + dfprintk(MOUNT, "NFS: unrecognized transport protocol\n"); return -EINVAL; } kfree(string); @@ -736,8 +733,7 @@ static int nfs_fs_context_parse_option(struct nfs_fs_context *ctx, char *p) string = match_strdup(args); if (string == NULL) goto out_nomem; - token = match_token(string, - nfs_xprt_protocol_tokens, args); + token = match_token(string, nfs_xprt_protocol_tokens, args); kfree(string); ctx->mountfamily = AF_INET; @@ -756,8 +752,7 @@ static int nfs_fs_context_parse_option(struct nfs_fs_context *ctx, char *p) break; case Opt_xprt_rdma: /* not used for side protocols */ default: - dfprintk(MOUNT, "NFS: unrecognized " - "transport protocol\n"); + dfprintk(MOUNT, "NFS: unrecognized transport protocol\n"); return -EINVAL; } break; @@ -767,9 +762,8 @@ static int nfs_fs_context_parse_option(struct nfs_fs_context *ctx, char *p) goto out_nomem; ctx->nfs_server.addrlen = rpc_pton(ctx->net, string, strlen(string), - (struct sockaddr *) &ctx->nfs_server.address, - sizeof(ctx->nfs_server.address)); + sizeof(ctx->nfs_server._address)); kfree(string); if (ctx->nfs_server.addrlen == 0) goto out_invalid_address; @@ -779,8 +773,7 @@ static int nfs_fs_context_parse_option(struct nfs_fs_context *ctx, char *p) goto out_nomem; break; case Opt_mounthost: - if (nfs_get_option_str(args, - &ctx->mount_server.hostname)) + if (nfs_get_option_str(args, &ctx->mount_server.hostname)) goto out_nomem; break; case Opt_mountaddr: @@ -789,9 +782,8 @@ static int nfs_fs_context_parse_option(struct nfs_fs_context *ctx, char *p) goto out_nomem; ctx->mount_server.addrlen = rpc_pton(ctx->net, string, strlen(string), - (struct sockaddr *) &ctx->mount_server.address, - sizeof(ctx->mount_server.address)); + sizeof(ctx->mount_server._address)); kfree(string); if (ctx->mount_server.addrlen == 0) goto out_invalid_address; @@ -800,8 +792,7 @@ static int nfs_fs_context_parse_option(struct nfs_fs_context *ctx, char *p) string = match_strdup(args); if (string == NULL) goto out_nomem; - token = match_token(string, - nfs_lookupcache_tokens, args); + token = match_token(string, nfs_lookupcache_tokens, args); kfree(string); switch (token) { case Opt_lookupcache_all: @@ -815,10 +806,9 @@ static int nfs_fs_context_parse_option(struct nfs_fs_context *ctx, char *p) ctx->flags |= NFS_MOUNT_LOOKUP_CACHE_NONEG|NFS_MOUNT_LOOKUP_CACHE_NONE; break; default: - dfprintk(MOUNT, "NFS: invalid " - "lookupcache argument\n"); + dfprintk(MOUNT, "NFS: invalid lookupcache argument\n"); return -EINVAL; - }; + } break; case Opt_fscache_uniq: if (nfs_get_option_str(args, &ctx->fscache_uniq)) @@ -829,8 +819,7 @@ static int nfs_fs_context_parse_option(struct nfs_fs_context *ctx, char *p) string = match_strdup(args); if (string == NULL) goto out_nomem; - token = match_token(string, nfs_local_lock_tokens, - args); + token = match_token(string, nfs_local_lock_tokens, args); kfree(string); switch (token) { case Opt_local_lock_all: @@ -848,8 +837,7 @@ static int nfs_fs_context_parse_option(struct nfs_fs_context *ctx, char *p) NFS_MOUNT_LOCAL_FCNTL); break; default: - dfprintk(MOUNT, "NFS: invalid " - "local_lock argument\n"); + dfprintk(MOUNT, "NFS: invalid local_lock argument\n"); return -EINVAL; }; break; @@ -863,13 +851,11 @@ static int nfs_fs_context_parse_option(struct nfs_fs_context *ctx, char *p) break; case Opt_userspace: case Opt_deprecated: - dfprintk(MOUNT, "NFS: ignoring mount option " - "'%s'\n", p); + dfprintk(MOUNT, "NFS: ignoring mount option '%s'\n", p); break; default: - dfprintk(MOUNT, "NFS: unrecognized mount option " - "'%s'\n", p); + dfprintk(MOUNT, "NFS: unrecognized mount option '%s'\n", p); return -EINVAL; } @@ -929,15 +915,15 @@ int nfs_parse_mount_options(char *raw, struct nfs_fs_context *ctx) * families in the addr=/mountaddr= options. */ if (ctx->protofamily != AF_UNSPEC && - ctx->protofamily != ctx->nfs_server.address.ss_family) + ctx->protofamily != ctx->nfs_server.address.sa_family) goto out_proto_mismatch; if (ctx->mountfamily != AF_UNSPEC) { if (ctx->mount_server.addrlen) { - if (ctx->mountfamily != ctx->mount_server.address.ss_family) + if (ctx->mountfamily != ctx->mount_server.address.sa_family) goto out_mountproto_mismatch; } else { - if (ctx->mountfamily != ctx->nfs_server.address.ss_family) + if (ctx->mountfamily != ctx->nfs_server.address.sa_family) goto out_mountproto_mismatch; } } @@ -973,9 +959,9 @@ int nfs_parse_mount_options(char *raw, struct nfs_fs_context *ctx) * * Note: caller frees hostname and export path, even on error. */ -static int nfs_parse_devname(const char *dev_name, - char **hostname, size_t maxnamlen, - char **export_path, size_t maxpathlen) +static int nfs_parse_devname(struct nfs_fs_context *ctx, + const char *dev_name, + size_t maxnamlen, size_t maxpathlen) { size_t len; char *end; @@ -1011,17 +997,17 @@ static int nfs_parse_devname(const char *dev_name, goto out_hostname; /* N.B. caller will free nfs_server.hostname in all cases */ - *hostname = kstrndup(dev_name, len, GFP_KERNEL); - if (*hostname == NULL) + ctx->nfs_server.hostname = kmemdup_nul(dev_name, len, GFP_KERNEL); + if (!ctx->nfs_server.hostname) goto out_nomem; len = strlen(++end); if (len > maxpathlen) goto out_path; - *export_path = kstrndup(end, len, GFP_KERNEL); - if (!*export_path) + ctx->nfs_server.export_path = kmemdup_nul(end, len, GFP_KERNEL); + if (!ctx->nfs_server.export_path) goto out_nomem; - dfprintk(MOUNT, "NFS: MNTPATH: '%s'\n", *export_path); + dfprintk(MOUNT, "NFS: MNTPATH: '%s'\n", ctx->nfs_server.export_path); return 0; out_bad_devname: @@ -1042,7 +1028,7 @@ static int nfs_parse_devname(const char *dev_name, } /* - * Validate the NFS2/NFS3 mount data + * Parse monolithic NFS2/NFS3 mount data * - fills in the mount root filehandle * * For option strings, user space handles the following behaviors: @@ -1371,11 +1357,7 @@ int nfs_validate_text_mount_data(void *options, nfs_set_port(sap, &ctx->nfs_server.port, port); - return nfs_parse_devname(dev_name, - &ctx->nfs_server.hostname, - max_namelen, - &ctx->nfs_server.export_path, - max_pathlen); + return nfs_parse_devname(ctx, dev_name, max_namelen, max_pathlen); #if !IS_ENABLED(CONFIG_NFS_V4) out_v4_not_compiled: diff --git a/fs/nfs/internal.h b/fs/nfs/internal.h index 6efdbedeeee8..481f370ab053 100644 --- a/fs/nfs/internal.h +++ b/fs/nfs/internal.h @@ -90,11 +90,11 @@ struct nfs_client_initdata { * In-kernel mount arguments */ struct nfs_fs_context { - int flags; + unsigned int flags; /* NFS{,4}_MOUNT_* flags */ unsigned int rsize, wsize; unsigned int timeo, retrans; - unsigned int acregmin, acregmax, - acdirmin, acdirmax; + unsigned int acregmin, acregmax; + unsigned int acdirmin, acdirmax; unsigned int namlen; unsigned int options; unsigned int bsize; @@ -110,7 +110,10 @@ struct nfs_fs_context { bool sloppy; struct { - struct sockaddr_storage address; + union { + struct sockaddr address; + struct sockaddr_storage _address; + }; size_t addrlen; char *hostname; u32 version; @@ -119,7 +122,10 @@ struct nfs_fs_context { } mount_server; struct { - struct sockaddr_storage address; + union { + struct sockaddr address; + struct sockaddr_storage _address; + }; size_t addrlen; char *hostname; char *export_path; diff --git a/fs/nfs/super.c b/fs/nfs/super.c index d7f99526ee73..5c8cf0e35141 100644 --- a/fs/nfs/super.c +++ b/fs/nfs/super.c @@ -804,7 +804,7 @@ static int nfs_request_mount(struct nfs_fs_context *cfg, /* * Construct the mount server's address. */ - if (cfg->mount_server.address.ss_family == AF_UNSPEC) { + if (cfg->mount_server.address.sa_family == AF_UNSPEC) { memcpy(request.sap, &cfg->nfs_server.address, cfg->nfs_server.addrlen); cfg->mount_server.addrlen = cfg->nfs_server.addrlen;