From patchwork Fri Dec 17 21:50:38 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Trond Myklebust X-Patchwork-Id: 12685715 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id EBADBC433F5 for ; Fri, 17 Dec 2021 21:57:16 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230382AbhLQV5Q (ORCPT ); Fri, 17 Dec 2021 16:57:16 -0500 Received: from ams.source.kernel.org ([145.40.68.75]:50824 "EHLO ams.source.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230314AbhLQV5P (ORCPT ); Fri, 17 Dec 2021 16:57:15 -0500 Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ams.source.kernel.org (Postfix) with ESMTPS id 934EBB82AE2 for ; Fri, 17 Dec 2021 21:57:14 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 17021C36AE2; Fri, 17 Dec 2021 21:57:13 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1639778233; bh=ZSaGVB9MGRi4QxDAfomgC2gmJ5GuOSC+sO/F8DFSkQA=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=qdfTQEOxD2yJ1s8JMYswLk72xLTErIBX824QriZBmJ6U4ZbdU6mz3FgFdL8WYDzgy 5jYKhvNow1hMIAEFD86J36tgaSjy/DD4aW/uNZidGMoJldg+hJPM6IGL3+Q7n0Ymgo q/P1QqxLjrXQMuHDRQbTPAtHm06XeqUnXt1trwyB9Ke4oNbm6iXMeoh2pmPDFgISZk iwmaXwSJQXQ1EiDQs8bf1Pmo8EY/MCvDw1R9Tzvu9LkzLXzpbdx60Sa93/L5krHWtY 9npuyW6JLxbVjhSxPIff/IePjX03gJGhQJEp2iJdSskhMUZU9riQ+gRl/xseEycS+B IYFSrNIUWYhLA== From: trondmy@kernel.org To: Chuck Lever , "J. Bruce Fields" Cc: linux-nfs@vger.kernel.org Subject: [PATCH 1/9] nfsd: map EBADF Date: Fri, 17 Dec 2021 16:50:38 -0500 Message-Id: <20211217215046.40316-2-trondmy@kernel.org> X-Mailer: git-send-email 2.33.1 In-Reply-To: <20211217215046.40316-1-trondmy@kernel.org> References: <20211217215046.40316-1-trondmy@kernel.org> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-nfs@vger.kernel.org From: Peng Tao Now that we have open file cache, it is possible that another client deletes the file and DP will not know about it. Then IO to MDS would fail with BADSTATEID and knfsd would start state recovery, which should fail as well and then nfs read/write will fail with EBADF. And it triggers a WARN() in nfserrno(). -----------[ cut here ]------------ WARNING: CPU: 0 PID: 13529 at fs/nfsd/nfsproc.c:758 nfserrno+0x58/0x70 [nfsd]() nfsd: non-standard errno: -9 modules linked in: nfsv3 nfs_layout_flexfiles rpcsec_gss_krb5 nfsv4 dns_resolver nfs fscache ip6t_rpfilter ip6t_REJECT nf_reject_ipv6 xt_connt pata_acpi floppy CPU: 0 PID: 13529 Comm: nfsd Tainted: G W 4.1.5-00307-g6e6579b #7 Hardware name: VMware, Inc. VMware Virtual Platform/440BX Desktop Reference Platform, BIOS 6.00 09/30/2014 0000000000000000 00000000464e6c9c ffff88079085fba8 ffffffff81789936 0000000000000000 ffff88079085fc00 ffff88079085fbe8 ffffffff810a08ea ffff88079085fbe8 ffff88080f45c900 ffff88080f627d50 ffff880790c46a48 all Trace: [] dump_stack+0x45/0x57 [] warn_slowpath_common+0x8a/0xc0 [] warn_slowpath_fmt+0x55/0x70 [] ? splice_direct_to_actor+0x148/0x230 [] ? fsid_source+0x60/0x60 [nfsd] [] nfserrno+0x58/0x70 [nfsd] [] nfsd_finish_read+0x97/0xb0 [nfsd] [] nfsd_splice_read+0x76/0xa0 [nfsd] [] nfsd_read+0xc1/0xd0 [nfsd] [] ? svc_tcp_adjust_wspace+0x12/0x30 [sunrpc] [] nfsd3_proc_read+0xba/0x150 [nfsd] [] nfsd_dispatch+0xc3/0x210 [nfsd] [] ? svc_tcp_adjust_wspace+0x12/0x30 [sunrpc] [] svc_process_common+0x453/0x6f0 [sunrpc] [] svc_process+0x113/0x1b0 [sunrpc] [] nfsd+0xff/0x170 [nfsd] [] ? nfsd_destroy+0x80/0x80 [nfsd] [] kthread+0xd8/0xf0 [] ? kthread_create_on_node+0x1b0/0x1b0 [] ret_from_fork+0x42/0x70 [] ? kthread_create_on_node+0x1b0/0x1b0 Signed-off-by: Peng Tao Signed-off-by: Lance Shelton Signed-off-by: Trond Myklebust --- fs/nfsd/nfsproc.c | 1 + 1 file changed, 1 insertion(+) diff --git a/fs/nfsd/nfsproc.c b/fs/nfsd/nfsproc.c index 90fcd6178823..c2afe1afb6d7 100644 --- a/fs/nfsd/nfsproc.c +++ b/fs/nfsd/nfsproc.c @@ -851,6 +851,7 @@ nfserrno (int errno) { nfserr_io, -EIO }, { nfserr_nxio, -ENXIO }, { nfserr_fbig, -E2BIG }, + { nfserr_stale, -EBADF }, { nfserr_acces, -EACCES }, { nfserr_exist, -EEXIST }, { nfserr_xdev, -EXDEV }, From patchwork Fri Dec 17 21:50:39 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Trond Myklebust X-Patchwork-Id: 12685719 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 7020AC43219 for ; Fri, 17 Dec 2021 21:57:18 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230368AbhLQV5R (ORCPT ); Fri, 17 Dec 2021 16:57:17 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:34872 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230398AbhLQV5Q (ORCPT ); Fri, 17 Dec 2021 16:57:16 -0500 Received: from ams.source.kernel.org (ams.source.kernel.org [IPv6:2604:1380:4601:e00::1]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 5F8A0C061574 for ; Fri, 17 Dec 2021 13:57:16 -0800 (PST) Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ams.source.kernel.org (Postfix) with ESMTPS id 2BF08B82AEA for ; Fri, 17 Dec 2021 21:57:15 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id A445BC36AE5; Fri, 17 Dec 2021 21:57:13 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1639778234; bh=tstlxK3l0PaunHUa6sz7SHVqA8TjoSkPIh6XZXJwl1U=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=HlEO/MF6A7VeZMi0la16QgOmgC3d7NYwLG0E1tmR/0aoJTE8xzzH0Z/CxBp8j1KMK 9ekY7Sng4CYItLEZkNA5BYg3JSSGDBn0j5gkwnjIqidViFwvD5+28IXQuNoBfPI6HU vbnjYu+aj/+oKwPYkAfivkWZVdcpLS0hH6f/tHm65QEqVhSuD0wxOXpVOMTDRSHCbK UEP3fRoiGpuPwgW9JglXUqflMPWl/8YB5I8YWlgY70vLyejp/5oyKhP1F2dPlShmzF x8jbqdiJli68cGlHiUbr2HdtQMgKFa+XRXBa8+outoEU3uzK2h0n3SlMH2RXHjgRff tuwJykaWxaWyw== From: trondmy@kernel.org To: Chuck Lever , "J. Bruce Fields" Cc: linux-nfs@vger.kernel.org Subject: [PATCH 2/9] nfsd: Add errno mapping for EREMOTEIO Date: Fri, 17 Dec 2021 16:50:39 -0500 Message-Id: <20211217215046.40316-3-trondmy@kernel.org> X-Mailer: git-send-email 2.33.1 In-Reply-To: <20211217215046.40316-2-trondmy@kernel.org> References: <20211217215046.40316-1-trondmy@kernel.org> <20211217215046.40316-2-trondmy@kernel.org> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-nfs@vger.kernel.org From: Jeff Layton The NFS client can occasionally return EREMOTEIO when signalling issues with the server. ...map to NFSERR_IO. Signed-off-by: Jeff Layton Signed-off-by: Lance Shelton Signed-off-by: Trond Myklebust --- fs/nfsd/nfsproc.c | 1 + 1 file changed, 1 insertion(+) diff --git a/fs/nfsd/nfsproc.c b/fs/nfsd/nfsproc.c index c2afe1afb6d7..1ebf02123368 100644 --- a/fs/nfsd/nfsproc.c +++ b/fs/nfsd/nfsproc.c @@ -880,6 +880,7 @@ nfserrno (int errno) { nfserr_toosmall, -ETOOSMALL }, { nfserr_serverfault, -ESERVERFAULT }, { nfserr_serverfault, -ENFILE }, + { nfserr_io, -EREMOTEIO }, { nfserr_io, -EUCLEAN }, { nfserr_perm, -ENOKEY }, { nfserr_no_grace, -ENOGRACE}, From patchwork Fri Dec 17 21:50:40 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Trond Myklebust X-Patchwork-Id: 12685717 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 4EB78C433FE for ; Fri, 17 Dec 2021 21:57:17 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230393AbhLQV5Q (ORCPT ); Fri, 17 Dec 2021 16:57:16 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:34870 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230364AbhLQV5P (ORCPT ); Fri, 17 Dec 2021 16:57:15 -0500 Received: from dfw.source.kernel.org (dfw.source.kernel.org [IPv6:2604:1380:4641:c500::1]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 88627C061574 for ; Fri, 17 Dec 2021 13:57:15 -0800 (PST) Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by dfw.source.kernel.org (Postfix) with ESMTPS id 274E4623C1 for ; Fri, 17 Dec 2021 21:57:15 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 3BAB7C36AE8; Fri, 17 Dec 2021 21:57:14 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1639778234; bh=XVLGTTpZHBH/Ie0RwNGUQ8kQJR+Jbm/swzH2/zsjdF4=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=AA7ucdqi1b6UkY05H3qREmxhHkEO/mrohlG+71AL5Am1+K2eDJSWOogaT2i0jhHhq Z9izqznwWdaICAwJwrV8PfxtbWwCcnj1QD+KeWzO9QxU709lHkAiEzrbS2q9aZDCq9 vCEGo0PegGX7p35SVfXgh9WJyRG3ekNR54WkFAVTCmehiph/4VSGyvlU5S1BwGHKTF ebMpA/btvXtjDpKzg523e+soUnx4AnT3Gend+jG0VnTm1/aeV4U5ioAJWIVp7gWsVs 9gY414I8bI5CAOs2vtd8o26ur5iB+y6lmVBuKaH6EEsnHm797J6czTfu05kunmZCgg rJXwqexkaOUhw== From: trondmy@kernel.org To: Chuck Lever , "J. Bruce Fields" Cc: linux-nfs@vger.kernel.org Subject: [PATCH 3/9] nfsd: Retry once in nfsd_open on an -EOPENSTALE return Date: Fri, 17 Dec 2021 16:50:40 -0500 Message-Id: <20211217215046.40316-4-trondmy@kernel.org> X-Mailer: git-send-email 2.33.1 In-Reply-To: <20211217215046.40316-3-trondmy@kernel.org> References: <20211217215046.40316-1-trondmy@kernel.org> <20211217215046.40316-2-trondmy@kernel.org> <20211217215046.40316-3-trondmy@kernel.org> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-nfs@vger.kernel.org From: Jeff Layton If we get back -EOPENSTALE from an NFSv4 open, then we either got some unhandled error or the inode we got back was not the same as the one associated with the dentry. We really have no recourse in that situation other than to retry the open, and if it fails to just return nfserr_stale back to the client. Signed-off-by: Jeff Layton Signed-off-by: Lance Shelton Signed-off-by: Trond Myklebust --- fs/nfsd/nfsproc.c | 1 + fs/nfsd/vfs.c | 10 +++++++++- 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/fs/nfsd/nfsproc.c b/fs/nfsd/nfsproc.c index 1ebf02123368..458307876ead 100644 --- a/fs/nfsd/nfsproc.c +++ b/fs/nfsd/nfsproc.c @@ -881,6 +881,7 @@ nfserrno (int errno) { nfserr_serverfault, -ESERVERFAULT }, { nfserr_serverfault, -ENFILE }, { nfserr_io, -EREMOTEIO }, + { nfserr_stale, -EOPENSTALE }, { nfserr_io, -EUCLEAN }, { nfserr_perm, -ENOKEY }, { nfserr_no_grace, -ENOGRACE}, diff --git a/fs/nfsd/vfs.c b/fs/nfsd/vfs.c index 738d564ca4ce..a90cc08211a3 100644 --- a/fs/nfsd/vfs.c +++ b/fs/nfsd/vfs.c @@ -779,6 +779,7 @@ nfsd_open(struct svc_rqst *rqstp, struct svc_fh *fhp, umode_t type, int may_flags, struct file **filp) { __be32 err; + bool retried = false; validate_process_creds(); /* @@ -794,9 +795,16 @@ nfsd_open(struct svc_rqst *rqstp, struct svc_fh *fhp, umode_t type, */ if (type == S_IFREG) may_flags |= NFSD_MAY_OWNER_OVERRIDE; +retry: err = fh_verify(rqstp, fhp, type, may_flags); - if (!err) + if (!err) { err = __nfsd_open(rqstp, fhp, type, may_flags, filp); + if (err == nfserr_stale && !retried) { + retried = true; + fh_put(fhp); + goto retry; + } + } validate_process_creds(); return err; } From patchwork Fri Dec 17 21:50:41 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Trond Myklebust X-Patchwork-Id: 12685723 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 28BB9C4332F for ; Fri, 17 Dec 2021 21:57:18 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230314AbhLQV5R (ORCPT ); Fri, 17 Dec 2021 16:57:17 -0500 Received: from ams.source.kernel.org ([145.40.68.75]:50834 "EHLO ams.source.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230368AbhLQV5Q (ORCPT ); Fri, 17 Dec 2021 16:57:16 -0500 Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ams.source.kernel.org (Postfix) with ESMTPS id 6F606B82AE1 for ; Fri, 17 Dec 2021 21:57:15 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id C52FBC36AE9; Fri, 17 Dec 2021 21:57:14 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1639778235; bh=kbXOWMHfDAatrQkEzimO/QP75+Rla1z/WzTHE3+sFfs=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=tXgcikOx4a4ymnO8VqpAsURyb+wMDomKcfCg4l+lgaTH9Bh2TjitbvDgWpLC/ICRs 6dCVyJ04Rsw5IH/d9/NEgipDbA1WR6FgIRfPLVAroedRPOtOv/fv00uN94jJ9eGhFM 3AWKvIZ0RkIJLqMpCbonjCBiVJ6BKxuiwjr70dN9gAztJbF4aet9G7bP3Kb1qabQxf tIPXl9xS970vWFQkph2AoLqzfIhEDmUkutRsflSgAQe/NzjHK1pUxbDc+J1E/QGI+x BUIiFw2QnqZNGyejfSNERgf/aubSelxPLXgfgJ8/Ef7oTrhn9OLFa4cJxup9ZBtvAG M15ib16WoU5Cw== From: trondmy@kernel.org To: Chuck Lever , "J. Bruce Fields" Cc: linux-nfs@vger.kernel.org Subject: [PATCH 4/9] nfs: Add export support for weak cache consistency attributes Date: Fri, 17 Dec 2021 16:50:41 -0500 Message-Id: <20211217215046.40316-5-trondmy@kernel.org> X-Mailer: git-send-email 2.33.1 In-Reply-To: <20211217215046.40316-4-trondmy@kernel.org> References: <20211217215046.40316-1-trondmy@kernel.org> <20211217215046.40316-2-trondmy@kernel.org> <20211217215046.40316-3-trondmy@kernel.org> <20211217215046.40316-4-trondmy@kernel.org> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-nfs@vger.kernel.org From: Trond Myklebust Allow knfsd to request weak cache consistency attributes on files that have delegations and/or have up to date attribute caches. Signed-off-by: Trond Myklebust Signed-off-by: Lance Shelton Signed-off-by: Trond Myklebust --- fs/nfs/export.c | 24 ++++++++++++ fs/nfsd/nfs3xdr.c | 83 +++++++++++++++++++++++++++------------- fs/nfsd/nfs4xdr.c | 6 +-- fs/nfsd/vfs.c | 14 +++++++ fs/nfsd/vfs.h | 5 ++- include/linux/exportfs.h | 3 ++ 6 files changed, 103 insertions(+), 32 deletions(-) diff --git a/fs/nfs/export.c b/fs/nfs/export.c index 171c424cb6d5..967f8902c49b 100644 --- a/fs/nfs/export.c +++ b/fs/nfs/export.c @@ -151,10 +151,34 @@ static u64 nfs_fetch_iversion(struct inode *inode) return inode_peek_iversion_raw(inode); } +static int nfs_exp_getattr(struct path *path, struct kstat *stat, bool force) +{ + const unsigned long check_valid = + NFS_INO_INVALID_CHANGE | NFS_INO_INVALID_ATIME | + NFS_INO_INVALID_CTIME | NFS_INO_INVALID_MTIME | + NFS_INO_INVALID_SIZE | /* NFS_INO_INVALID_BLOCKS | */ + NFS_INO_INVALID_OTHER | NFS_INO_INVALID_NLINK; + struct inode *inode = d_inode(path->dentry); + int flags = force ? AT_STATX_SYNC_AS_STAT : AT_STATX_DONT_SYNC; + int ret, ret2 = 0; + + if (!force && nfs_check_cache_invalid(inode, check_valid)) + ret2 = -EAGAIN; + ret = vfs_getattr(path, stat, STATX_BASIC_STATS & ~STATX_BLOCKS, flags); + if (ret < 0) + return ret; + stat->blocks = nfs_calc_block_size(stat->size); + if (S_ISDIR(inode->i_mode)) + stat->blksize = NFS_SERVER(inode)->dtsize; + stat->result_mask |= STATX_BLOCKS; + return ret2; +} + const struct export_operations nfs_export_ops = { .encode_fh = nfs_encode_fh, .fh_to_dentry = nfs_fh_to_dentry, .get_parent = nfs_get_parent, + .getattr = nfs_exp_getattr, .fetch_iversion = nfs_fetch_iversion, .flags = EXPORT_OP_NOWCC|EXPORT_OP_NOSUBTREECHK| EXPORT_OP_CLOSE_BEFORE_UNLINK|EXPORT_OP_REMOTE_FS| diff --git a/fs/nfsd/nfs3xdr.c b/fs/nfsd/nfs3xdr.c index 0a5ebc52e6a9..81b6cf228517 100644 --- a/fs/nfsd/nfs3xdr.c +++ b/fs/nfsd/nfs3xdr.c @@ -415,21 +415,14 @@ svcxdr_encode_pre_op_attr(struct xdr_stream *xdr, const struct svc_fh *fhp) return svcxdr_encode_wcc_attr(xdr, fhp); } -/** - * svcxdr_encode_post_op_attr - Encode NFSv3 post-op attributes - * @rqstp: Context of a completed RPC transaction - * @xdr: XDR stream - * @fhp: File handle to encode - * - * Return values: - * %false: Send buffer space was exhausted - * %true: Success - */ -bool -svcxdr_encode_post_op_attr(struct svc_rqst *rqstp, struct xdr_stream *xdr, - const struct svc_fh *fhp) +static bool +__svcxdr_encode_post_op_attr(struct svc_rqst *rqstp, struct xdr_stream *xdr, + const struct svc_fh *fhp, bool force) { struct dentry *dentry = fhp->fh_dentry; + struct path path = { + .dentry = dentry, + }; struct kstat stat; /* @@ -437,9 +430,10 @@ svcxdr_encode_post_op_attr(struct svc_rqst *rqstp, struct xdr_stream *xdr, * stale file handle. In this case, no attributes are * returned. */ - if (fhp->fh_no_wcc || !dentry || !d_really_is_positive(dentry)) + if (!dentry || !d_really_is_positive(dentry)) goto no_post_op_attrs; - if (fh_getattr(fhp, &stat) != nfs_ok) + path.mnt = fhp->fh_export->ex_path.mnt; + if (nfsd_getattr(&path, &stat, force) != nfs_ok) goto no_post_op_attrs; if (xdr_stream_encode_item_present(xdr) < 0) @@ -454,6 +448,31 @@ svcxdr_encode_post_op_attr(struct svc_rqst *rqstp, struct xdr_stream *xdr, return xdr_stream_encode_item_absent(xdr) > 0; } +/** + * svcxdr_encode_post_op_attr - Encode NFSv3 post-op attributes + * @rqstp: Context of a completed RPC transaction + * @xdr: XDR stream + * @fhp: File handle to encode + * + * Return values: + * %false: Send buffer space was exhausted + * %true: Success + */ +bool +svcxdr_encode_post_op_attr(struct svc_rqst *rqstp, struct xdr_stream *xdr, + const struct svc_fh *fhp) +{ + return __svcxdr_encode_post_op_attr(rqstp, xdr, fhp, true); +} + +static bool +svcxdr_encode_post_op_attr_opportunistic(struct svc_rqst *rqstp, + struct xdr_stream *xdr, + const struct svc_fh *fhp) +{ + return __svcxdr_encode_post_op_attr(rqstp, xdr, fhp, !fhp->fh_no_wcc); +} + /* * Encode weak cache consistency data */ @@ -481,7 +500,7 @@ svcxdr_encode_wcc_data(struct svc_rqst *rqstp, struct xdr_stream *xdr, neither: if (xdr_stream_encode_item_absent(xdr) < 0) return false; - if (!svcxdr_encode_post_op_attr(rqstp, xdr, fhp)) + if (!svcxdr_encode_post_op_attr_opportunistic(rqstp, xdr, fhp)) return false; return true; @@ -879,11 +898,13 @@ int nfs3svc_encode_lookupres(struct svc_rqst *rqstp, __be32 *p) return 0; if (!svcxdr_encode_post_op_attr(rqstp, xdr, &resp->fh)) return 0; - if (!svcxdr_encode_post_op_attr(rqstp, xdr, &resp->dirfh)) + if (!svcxdr_encode_post_op_attr_opportunistic(rqstp, xdr, + &resp->dirfh)) return 0; break; default: - if (!svcxdr_encode_post_op_attr(rqstp, xdr, &resp->dirfh)) + if (!svcxdr_encode_post_op_attr_opportunistic(rqstp, xdr, + &resp->dirfh)) return 0; } @@ -901,13 +922,15 @@ nfs3svc_encode_accessres(struct svc_rqst *rqstp, __be32 *p) return 0; switch (resp->status) { case nfs_ok: - if (!svcxdr_encode_post_op_attr(rqstp, xdr, &resp->fh)) + if (!svcxdr_encode_post_op_attr_opportunistic(rqstp, xdr, + &resp->fh)) return 0; if (xdr_stream_encode_u32(xdr, resp->access) < 0) return 0; break; default: - if (!svcxdr_encode_post_op_attr(rqstp, xdr, &resp->fh)) + if (!svcxdr_encode_post_op_attr_opportunistic(rqstp, xdr, + &resp->fh)) return 0; } @@ -926,7 +949,8 @@ nfs3svc_encode_readlinkres(struct svc_rqst *rqstp, __be32 *p) return 0; switch (resp->status) { case nfs_ok: - if (!svcxdr_encode_post_op_attr(rqstp, xdr, &resp->fh)) + if (!svcxdr_encode_post_op_attr_opportunistic(rqstp, xdr, + &resp->fh)) return 0; if (xdr_stream_encode_u32(xdr, resp->len) < 0) return 0; @@ -935,7 +959,8 @@ nfs3svc_encode_readlinkres(struct svc_rqst *rqstp, __be32 *p) return 0; break; default: - if (!svcxdr_encode_post_op_attr(rqstp, xdr, &resp->fh)) + if (!svcxdr_encode_post_op_attr_opportunistic(rqstp, xdr, + &resp->fh)) return 0; } @@ -954,7 +979,8 @@ nfs3svc_encode_readres(struct svc_rqst *rqstp, __be32 *p) return 0; switch (resp->status) { case nfs_ok: - if (!svcxdr_encode_post_op_attr(rqstp, xdr, &resp->fh)) + if (!svcxdr_encode_post_op_attr_opportunistic(rqstp, xdr, + &resp->fh)) return 0; if (xdr_stream_encode_u32(xdr, resp->count) < 0) return 0; @@ -968,7 +994,8 @@ nfs3svc_encode_readres(struct svc_rqst *rqstp, __be32 *p) return 0; break; default: - if (!svcxdr_encode_post_op_attr(rqstp, xdr, &resp->fh)) + if (!svcxdr_encode_post_op_attr_opportunistic(rqstp, xdr, + &resp->fh)) return 0; } @@ -1065,7 +1092,8 @@ nfs3svc_encode_readdirres(struct svc_rqst *rqstp, __be32 *p) return 0; switch (resp->status) { case nfs_ok: - if (!svcxdr_encode_post_op_attr(rqstp, xdr, &resp->fh)) + if (!svcxdr_encode_post_op_attr_opportunistic(rqstp, xdr, + &resp->fh)) return 0; if (!svcxdr_encode_cookieverf3(xdr, resp->verf)) return 0; @@ -1077,7 +1105,8 @@ nfs3svc_encode_readdirres(struct svc_rqst *rqstp, __be32 *p) return 0; break; default: - if (!svcxdr_encode_post_op_attr(rqstp, xdr, &resp->fh)) + if (!svcxdr_encode_post_op_attr_opportunistic(rqstp, xdr, + &resp->fh)) return 0; } @@ -1221,7 +1250,7 @@ svcxdr_encode_entry3_plus(struct nfsd3_readdirres *resp, const char *name, if (compose_entry_fh(resp, fhp, name, namlen, ino) != nfs_ok) goto out_noattrs; - if (!svcxdr_encode_post_op_attr(resp->rqstp, xdr, fhp)) + if (!svcxdr_encode_post_op_attr_opportunistic(resp->rqstp, xdr, fhp)) goto out; if (!svcxdr_encode_post_op_fh3(xdr, fhp)) goto out; diff --git a/fs/nfsd/nfs4xdr.c b/fs/nfsd/nfs4xdr.c index 7abeccb975b2..e14af0383b70 100644 --- a/fs/nfsd/nfs4xdr.c +++ b/fs/nfsd/nfs4xdr.c @@ -2865,9 +2865,9 @@ nfsd4_encode_fattr(struct xdr_stream *xdr, struct svc_fh *fhp, goto out; } - err = vfs_getattr(&path, &stat, STATX_BASIC_STATS, AT_STATX_SYNC_AS_STAT); - if (err) - goto out_nfserr; + status = nfsd_getattr(&path, &stat, true); + if (status) + goto out; if ((bmval0 & (FATTR4_WORD0_FILES_AVAIL | FATTR4_WORD0_FILES_FREE | FATTR4_WORD0_FILES_TOTAL | FATTR4_WORD0_MAXNAME)) || (bmval1 & (FATTR4_WORD1_SPACE_AVAIL | FATTR4_WORD1_SPACE_FREE | diff --git a/fs/nfsd/vfs.c b/fs/nfsd/vfs.c index a90cc08211a3..4d57befdac6e 100644 --- a/fs/nfsd/vfs.c +++ b/fs/nfsd/vfs.c @@ -2412,3 +2412,17 @@ nfsd_permission(struct svc_rqst *rqstp, struct svc_export *exp, return err? nfserrno(err) : 0; } + + +__be32 +nfsd_getattr(struct path *p, struct kstat *stat, bool force) +{ + const struct export_operations *ops = p->dentry->d_sb->s_export_op; + int err; + + if (ops->getattr) + err = ops->getattr(p, stat, force); + else + err = vfs_getattr(p, stat, STATX_BASIC_STATS, AT_STATX_SYNC_AS_STAT); + return err ? nfserrno(err) : 0; +} diff --git a/fs/nfsd/vfs.h b/fs/nfsd/vfs.h index b21b76e6b9a8..6edae1b9a96e 100644 --- a/fs/nfsd/vfs.h +++ b/fs/nfsd/vfs.h @@ -132,6 +132,8 @@ __be32 nfsd_statfs(struct svc_rqst *, struct svc_fh *, __be32 nfsd_permission(struct svc_rqst *, struct svc_export *, struct dentry *, int); +__be32 nfsd_getattr(struct path *p, struct kstat *, bool); + static inline int fh_want_write(struct svc_fh *fh) { int ret; @@ -156,8 +158,7 @@ static inline __be32 fh_getattr(const struct svc_fh *fh, struct kstat *stat) { struct path p = {.mnt = fh->fh_export->ex_path.mnt, .dentry = fh->fh_dentry}; - return nfserrno(vfs_getattr(&p, stat, STATX_BASIC_STATS, - AT_STATX_SYNC_AS_STAT)); + return nfsd_getattr(&p, stat, true); } static inline int nfsd_create_is_exclusive(int createmode) diff --git a/include/linux/exportfs.h b/include/linux/exportfs.h index 3260fe714846..58f36022787e 100644 --- a/include/linux/exportfs.h +++ b/include/linux/exportfs.h @@ -10,6 +10,8 @@ struct inode; struct iomap; struct super_block; struct vfsmount; +struct path; +struct kstat; /* limit the handle size to NFSv4 handle size now */ #define MAX_HANDLE_SZ 128 @@ -224,6 +226,7 @@ struct export_operations { #define EXPORT_OP_SYNC_LOCKS (0x20) /* Filesystem can't do asychronous blocking locks */ unsigned long flags; + int (*getattr)(struct path *, struct kstat *, bool); }; extern int exportfs_encode_inode_fh(struct inode *inode, struct fid *fid, From patchwork Fri Dec 17 21:50:42 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Trond Myklebust X-Patchwork-Id: 12685725 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 006E8C433EF for ; Fri, 17 Dec 2021 21:57:17 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230364AbhLQV5R (ORCPT ); Fri, 17 Dec 2021 16:57:17 -0500 Received: from dfw.source.kernel.org ([139.178.84.217]:48624 "EHLO dfw.source.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230314AbhLQV5Q (ORCPT ); Fri, 17 Dec 2021 16:57:16 -0500 Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by dfw.source.kernel.org (Postfix) with ESMTPS id 4CC72623EA for ; Fri, 17 Dec 2021 21:57:16 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 62FE4C36AE5; Fri, 17 Dec 2021 21:57:15 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1639778235; bh=Qoe4yenVzXa2m1jsiUD/mTu8Gvks+yzrcxCq6ohZs5U=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=QMd6LyLF+88zKv3QMPTq2meLnhDyqv1kXWjvtgq3I1lIDWx4C55+Nt1Q7w2XPnU1W O4mHNV8RMfBGVc+XFZuijjKvCcp7Db6/0K8zpGCapkoCAkn2TLn5wQyUWctyk0EEdi E4RSMiJw4CEKM/a9qXOVZUPMZidxfRVFau6D6yNZRHNWy4pEbA9X5xt1aCEOSwEGGP IEZHKLXptVsxtU3qim9KtFOMiFT605GaIn7O7fYJ5HSiuftYLoQ2v3MJRe0Vmf8k6D pKiooRZBHBqZ71YBiwM9DYbpcQAwfMTLhClr53e5Yc1PvTR3ycpgTJU/fUznczp3Nn Gf8myaAEkM1lw== From: trondmy@kernel.org To: Chuck Lever , "J. Bruce Fields" Cc: linux-nfs@vger.kernel.org Subject: [PATCH 5/9] nfsd: NFSv3 should allow zero length writes Date: Fri, 17 Dec 2021 16:50:42 -0500 Message-Id: <20211217215046.40316-6-trondmy@kernel.org> X-Mailer: git-send-email 2.33.1 In-Reply-To: <20211217215046.40316-5-trondmy@kernel.org> References: <20211217215046.40316-1-trondmy@kernel.org> <20211217215046.40316-2-trondmy@kernel.org> <20211217215046.40316-3-trondmy@kernel.org> <20211217215046.40316-4-trondmy@kernel.org> <20211217215046.40316-5-trondmy@kernel.org> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-nfs@vger.kernel.org From: Trond Myklebust According to RFC1813: "If count is 0, the WRITE will succeed and return a count of 0, barring errors due to permissions checking." Signed-off-by: Trond Myklebust --- fs/nfsd/vfs.c | 3 +++ net/sunrpc/svc.c | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/fs/nfsd/vfs.c b/fs/nfsd/vfs.c index 4d57befdac6e..38fdfcbb079e 100644 --- a/fs/nfsd/vfs.c +++ b/fs/nfsd/vfs.c @@ -969,6 +969,9 @@ nfsd_vfs_write(struct svc_rqst *rqstp, struct svc_fh *fhp, struct nfsd_file *nf, trace_nfsd_write_opened(rqstp, fhp, offset, *cnt); + if (!*cnt) + return nfs_ok; + if (sb->s_export_op) exp_op_flags = sb->s_export_op->flags; diff --git a/net/sunrpc/svc.c b/net/sunrpc/svc.c index a3bbe5ce4570..d1ccf37a4588 100644 --- a/net/sunrpc/svc.c +++ b/net/sunrpc/svc.c @@ -1692,7 +1692,7 @@ unsigned int svc_fill_write_vector(struct svc_rqst *rqstp, struct page **pages, * entirely in rq_arg.pages. In this case, @first is empty. */ i = 0; - if (first->iov_len) { + if (first->iov_len || !total) { vec[i].iov_base = first->iov_base; vec[i].iov_len = min_t(size_t, total, first->iov_len); total -= vec[i].iov_len; From patchwork Fri Dec 17 21:50:43 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Trond Myklebust X-Patchwork-Id: 12685721 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id A2A02C43217 for ; Fri, 17 Dec 2021 21:57:18 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230398AbhLQV5S (ORCPT ); Fri, 17 Dec 2021 16:57:18 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:34880 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230399AbhLQV5R (ORCPT ); Fri, 17 Dec 2021 16:57:17 -0500 Received: from dfw.source.kernel.org (dfw.source.kernel.org [IPv6:2604:1380:4641:c500::1]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 4C671C061574 for ; Fri, 17 Dec 2021 13:57:17 -0800 (PST) Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by dfw.source.kernel.org (Postfix) with ESMTPS id DC5B5623EF for ; Fri, 17 Dec 2021 21:57:16 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id EF408C36AE2; Fri, 17 Dec 2021 21:57:15 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1639778236; bh=Jiy0uxdc8XYXeU3WQ1Tp6LFVSfFJNYjZhenKirx8r/8=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=FThjeW0KKONYSAxKL3yn/dW5jjLq+l+MdR0f2KSpaPT9IImIM4TvB7GL/d6t/BZ0X OAQLUIfJ9sfRI1pWznfPF1b0R8RzwhqN5ztB68xZtlNGWrkhsfwfSaw/3+M6i2ALNx mYRQQn5IQUuwQFBPOVBuOFEzMGoH6TGG5Y2jwbBFGc4BeSFLbiVKq5zGASJdr8+giP UdA3Hx5eTJwg2NkfFDT6TsKzd1Qmi6FqSvkrrlrkD6RVJm7TJ3YcqpDYxQBzItjV8I pa9zBI3fYFjEaa84wvzJjVAtL64AmdblnIYwlKoGSmBLAKjWLf/ynBOLFzMSs9eaft ZTDfMTzC/fZQA== From: trondmy@kernel.org To: Chuck Lever , "J. Bruce Fields" Cc: linux-nfs@vger.kernel.org Subject: [PATCH 6/9] nfsd: Add a tracepoint for errors in nfsd4_clone_file_range() Date: Fri, 17 Dec 2021 16:50:43 -0500 Message-Id: <20211217215046.40316-7-trondmy@kernel.org> X-Mailer: git-send-email 2.33.1 In-Reply-To: <20211217215046.40316-6-trondmy@kernel.org> References: <20211217215046.40316-1-trondmy@kernel.org> <20211217215046.40316-2-trondmy@kernel.org> <20211217215046.40316-3-trondmy@kernel.org> <20211217215046.40316-4-trondmy@kernel.org> <20211217215046.40316-5-trondmy@kernel.org> <20211217215046.40316-6-trondmy@kernel.org> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-nfs@vger.kernel.org From: Trond Myklebust Since a clone error commit can cause the boot verifier to change, we should trace those errors. Signed-off-by: Trond Myklebust --- fs/nfsd/nfs4proc.c | 2 +- fs/nfsd/trace.h | 50 ++++++++++++++++++++++++++++++++++++++++++++++ fs/nfsd/vfs.c | 18 +++++++++++++++-- fs/nfsd/vfs.h | 3 ++- 4 files changed, 69 insertions(+), 4 deletions(-) diff --git a/fs/nfsd/nfs4proc.c b/fs/nfsd/nfs4proc.c index 486c5dba4b65..53c2a8f0d627 100644 --- a/fs/nfsd/nfs4proc.c +++ b/fs/nfsd/nfs4proc.c @@ -1102,7 +1102,7 @@ nfsd4_clone(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, if (status) goto out; - status = nfsd4_clone_file_range(src, clone->cl_src_pos, + status = nfsd4_clone_file_range(rqstp, src, clone->cl_src_pos, dst, clone->cl_dst_pos, clone->cl_count, EX_ISSYNC(cstate->current_fh.fh_export)); diff --git a/fs/nfsd/trace.h b/fs/nfsd/trace.h index f1e0d3c51bc2..001444d9829d 100644 --- a/fs/nfsd/trace.h +++ b/fs/nfsd/trace.h @@ -413,6 +413,56 @@ TRACE_EVENT(nfsd_dirent, ) ) +DECLARE_EVENT_CLASS(nfsd_copy_err_class, + TP_PROTO(struct svc_rqst *rqstp, + struct svc_fh *src_fhp, + loff_t src_offset, + struct svc_fh *dst_fhp, + loff_t dst_offset, + u64 count, + int status), + TP_ARGS(rqstp, src_fhp, src_offset, dst_fhp, dst_offset, count, status), + TP_STRUCT__entry( + __field(u32, xid) + __field(u32, src_fh_hash) + __field(loff_t, src_offset) + __field(u32, dst_fh_hash) + __field(loff_t, dst_offset) + __field(u64, count) + __field(int, status) + ), + TP_fast_assign( + __entry->xid = be32_to_cpu(rqstp->rq_xid); + __entry->src_fh_hash = knfsd_fh_hash(&src_fhp->fh_handle); + __entry->src_offset = src_offset; + __entry->dst_fh_hash = knfsd_fh_hash(&dst_fhp->fh_handle); + __entry->dst_offset = dst_offset; + __entry->count = count; + __entry->status = status; + ), + TP_printk("xid=0x%08x src_fh_hash=0x%08x src_offset=%lld " + "dst_fh_hash=0x%08x dst_offset=%lld " + "count=%llu status=%d", + __entry->xid, __entry->src_fh_hash, __entry->src_offset, + __entry->dst_fh_hash, __entry->dst_offset, + (unsigned long long)__entry->count, + __entry->status) +) + +#define DEFINE_NFSD_COPY_ERR_EVENT(name) \ +DEFINE_EVENT(nfsd_copy_err_class, nfsd_##name, \ + TP_PROTO(struct svc_rqst *rqstp, \ + struct svc_fh *src_fhp, \ + loff_t src_offset, \ + struct svc_fh *dst_fhp, \ + loff_t dst_offset, \ + u64 count, \ + int status), \ + TP_ARGS(rqstp, src_fhp, src_offset, dst_fhp, dst_offset, \ + count, status)) + +DEFINE_NFSD_COPY_ERR_EVENT(clone_file_range_err); + #include "state.h" #include "filecache.h" #include "vfs.h" diff --git a/fs/nfsd/vfs.c b/fs/nfsd/vfs.c index 38fdfcbb079e..e761b2eff415 100644 --- a/fs/nfsd/vfs.c +++ b/fs/nfsd/vfs.c @@ -40,6 +40,7 @@ #include "../internal.h" #include "acl.h" #include "idmap.h" +#include "xdr4.h" #endif /* CONFIG_NFSD_V4 */ #include "nfsd.h" @@ -516,8 +517,15 @@ __be32 nfsd4_set_nfs4_label(struct svc_rqst *rqstp, struct svc_fh *fhp, } #endif -__be32 nfsd4_clone_file_range(struct nfsd_file *nf_src, u64 src_pos, - struct nfsd_file *nf_dst, u64 dst_pos, u64 count, bool sync) +static struct nfsd4_compound_state *nfsd4_get_cstate(struct svc_rqst *rqstp) +{ + return &((struct nfsd4_compoundres *)rqstp->rq_resp)->cstate; +} + +__be32 nfsd4_clone_file_range(struct svc_rqst *rqstp, + struct nfsd_file *nf_src, u64 src_pos, + struct nfsd_file *nf_dst, u64 dst_pos, + u64 count, bool sync) { struct file *src = nf_src->nf_file; struct file *dst = nf_dst->nf_file; @@ -541,6 +549,12 @@ __be32 nfsd4_clone_file_range(struct nfsd_file *nf_src, u64 src_pos, if (!status) status = commit_inode_metadata(file_inode(src)); if (status < 0) { + trace_nfsd_clone_file_range_err(rqstp, + &nfsd4_get_cstate(rqstp)->save_fh, + src_pos, + &nfsd4_get_cstate(rqstp)->current_fh, + dst_pos, + count, status); nfsd_reset_boot_verifier(net_generic(nf_dst->nf_net, nfsd_net_id)); ret = nfserrno(status); diff --git a/fs/nfsd/vfs.h b/fs/nfsd/vfs.h index 6edae1b9a96e..3dba6397d452 100644 --- a/fs/nfsd/vfs.h +++ b/fs/nfsd/vfs.h @@ -57,7 +57,8 @@ __be32 nfsd4_set_nfs4_label(struct svc_rqst *, struct svc_fh *, struct xdr_netobj *); __be32 nfsd4_vfs_fallocate(struct svc_rqst *, struct svc_fh *, struct file *, loff_t, loff_t, int); -__be32 nfsd4_clone_file_range(struct nfsd_file *nf_src, u64 src_pos, +__be32 nfsd4_clone_file_range(struct svc_rqst *, + struct nfsd_file *nf_src, u64 src_pos, struct nfsd_file *nf_dst, u64 dst_pos, u64 count, bool sync); #endif /* CONFIG_NFSD_V4 */ From patchwork Fri Dec 17 21:50:44 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Trond Myklebust X-Patchwork-Id: 12685731 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id BD03BC433FE for ; Fri, 17 Dec 2021 21:57:22 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230399AbhLQV5V (ORCPT ); Fri, 17 Dec 2021 16:57:21 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:34890 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230405AbhLQV5U (ORCPT ); Fri, 17 Dec 2021 16:57:20 -0500 Received: from ams.source.kernel.org (ams.source.kernel.org [IPv6:2604:1380:4601:e00::1]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 75213C061574 for ; Fri, 17 Dec 2021 13:57:19 -0800 (PST) Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ams.source.kernel.org (Postfix) with ESMTPS id 12EACB82AEB for ; Fri, 17 Dec 2021 21:57:18 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 88E47C36AE8; Fri, 17 Dec 2021 21:57:16 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1639778236; bh=+FanleU/olQfZh7qKW9YwFohwTa4rJye7z7WnmYdufo=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=qGzWuya0DylcYyN/Q5NLGXs5KJIjnLPlMqDT/BwUUQFdKoucIiiS/XZBOms8rCw09 nY0w7V2gnkjtahq240ZsvE9oMQvKsIdBsoD7SDweDZNEBs5Wq3BdCofkOAgUxnzZ+D HzMRN24+U+R/4bksprN18XaZTcXCvhVYwEacbcQi1VQXH9MewVHb9t5+vj95NgZgG9 ENznTgvPk4t/Y1jFeP/FZPvOIr8LhWUNXv2rVoiCbltR4yoVhEATN3i0GtS/aZL95y L1ieQWLBud3nVP0EWoLwJ/mHDr7Z3+sDFDDmfS49YXXCGJ2Wkx4b2lVYYqk29LweKC PIfawvE7bsE1g== From: trondmy@kernel.org To: Chuck Lever , "J. Bruce Fields" Cc: linux-nfs@vger.kernel.org Subject: [PATCH 7/9] nfsd: Replace use of rwsem with errseq_t Date: Fri, 17 Dec 2021 16:50:44 -0500 Message-Id: <20211217215046.40316-8-trondmy@kernel.org> X-Mailer: git-send-email 2.33.1 In-Reply-To: <20211217215046.40316-7-trondmy@kernel.org> References: <20211217215046.40316-1-trondmy@kernel.org> <20211217215046.40316-2-trondmy@kernel.org> <20211217215046.40316-3-trondmy@kernel.org> <20211217215046.40316-4-trondmy@kernel.org> <20211217215046.40316-5-trondmy@kernel.org> <20211217215046.40316-6-trondmy@kernel.org> <20211217215046.40316-7-trondmy@kernel.org> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-nfs@vger.kernel.org From: Trond Myklebust The nfsd_file nf_rwsem is currently being used to separate file write and commit instances to ensure that we catch errors and apply them to the correct write/commit. We can improve scalability at the expense of a little accuracy (some extra false positives) by replacing the nf_rwsem with more careful use of the errseq_t mechanism to track errors across the different operations. Signed-off-by: Trond Myklebust --- fs/nfsd/filecache.c | 1 - fs/nfsd/filecache.h | 1 - fs/nfsd/nfs4proc.c | 16 +++++++++------- fs/nfsd/vfs.c | 40 +++++++++++++++------------------------- 4 files changed, 24 insertions(+), 34 deletions(-) diff --git a/fs/nfsd/filecache.c b/fs/nfsd/filecache.c index 7629248fdd53..1e894ddc7ac2 100644 --- a/fs/nfsd/filecache.c +++ b/fs/nfsd/filecache.c @@ -194,7 +194,6 @@ nfsd_file_alloc(struct inode *inode, unsigned int may, unsigned int hashval, __set_bit(NFSD_FILE_BREAK_READ, &nf->nf_flags); } nf->nf_mark = NULL; - init_rwsem(&nf->nf_rwsem); trace_nfsd_file_alloc(nf); } return nf; diff --git a/fs/nfsd/filecache.h b/fs/nfsd/filecache.h index 7872df5a0fe3..435ceab27897 100644 --- a/fs/nfsd/filecache.h +++ b/fs/nfsd/filecache.h @@ -46,7 +46,6 @@ struct nfsd_file { refcount_t nf_ref; unsigned char nf_may; struct nfsd_file_mark *nf_mark; - struct rw_semaphore nf_rwsem; }; int nfsd_file_cache_init(void); diff --git a/fs/nfsd/nfs4proc.c b/fs/nfsd/nfs4proc.c index 53c2a8f0d627..9ea2d2e554ce 100644 --- a/fs/nfsd/nfs4proc.c +++ b/fs/nfsd/nfs4proc.c @@ -1511,6 +1511,9 @@ static void nfsd4_init_copy_res(struct nfsd4_copy *copy, bool sync) static ssize_t _nfsd_copy_file_range(struct nfsd4_copy *copy) { + struct file *dst = copy->nf_dst->nf_file; + struct file *src = copy->nf_src->nf_file; + errseq_t since; ssize_t bytes_copied = 0; u64 bytes_total = copy->cp_count; u64 src_pos = copy->cp_src_pos; @@ -1523,9 +1526,8 @@ static ssize_t _nfsd_copy_file_range(struct nfsd4_copy *copy) do { if (kthread_should_stop()) break; - bytes_copied = nfsd_copy_file_range(copy->nf_src->nf_file, - src_pos, copy->nf_dst->nf_file, dst_pos, - bytes_total); + bytes_copied = nfsd_copy_file_range(src, src_pos, dst, dst_pos, + bytes_total); if (bytes_copied <= 0) break; bytes_total -= bytes_copied; @@ -1535,11 +1537,11 @@ static ssize_t _nfsd_copy_file_range(struct nfsd4_copy *copy) } while (bytes_total > 0 && !copy->cp_synchronous); /* for a non-zero asynchronous copy do a commit of data */ if (!copy->cp_synchronous && copy->cp_res.wr_bytes_written > 0) { - down_write(©->nf_dst->nf_rwsem); - status = vfs_fsync_range(copy->nf_dst->nf_file, - copy->cp_dst_pos, + since = READ_ONCE(dst->f_wb_err); + status = vfs_fsync_range(dst, copy->cp_dst_pos, copy->cp_res.wr_bytes_written, 0); - up_write(©->nf_dst->nf_rwsem); + if (!status) + status = filemap_check_wb_err(dst->f_mapping, since); if (!status) copy->committed = true; } diff --git a/fs/nfsd/vfs.c b/fs/nfsd/vfs.c index e761b2eff415..19215b9f768e 100644 --- a/fs/nfsd/vfs.c +++ b/fs/nfsd/vfs.c @@ -529,10 +529,11 @@ __be32 nfsd4_clone_file_range(struct svc_rqst *rqstp, { struct file *src = nf_src->nf_file; struct file *dst = nf_dst->nf_file; + errseq_t since; loff_t cloned; __be32 ret = 0; - down_write(&nf_dst->nf_rwsem); + since = READ_ONCE(dst->f_wb_err); cloned = vfs_clone_file_range(src, src_pos, dst, dst_pos, count, 0); if (cloned < 0) { ret = nfserrno(cloned); @@ -546,6 +547,8 @@ __be32 nfsd4_clone_file_range(struct svc_rqst *rqstp, loff_t dst_end = count ? dst_pos + count - 1 : LLONG_MAX; int status = vfs_fsync_range(dst, dst_pos, dst_end, 0); + if (!status) + status = filemap_check_wb_err(dst->f_mapping, since); if (!status) status = commit_inode_metadata(file_inode(src)); if (status < 0) { @@ -561,7 +564,6 @@ __be32 nfsd4_clone_file_range(struct svc_rqst *rqstp, } } out_err: - up_write(&nf_dst->nf_rwsem); return ret; } @@ -972,6 +974,7 @@ nfsd_vfs_write(struct svc_rqst *rqstp, struct svc_fh *fhp, struct nfsd_file *nf, struct super_block *sb = file_inode(file)->i_sb; struct svc_export *exp; struct iov_iter iter; + errseq_t since; __be32 nfserr; int host_err; int use_wgather; @@ -1012,21 +1015,18 @@ nfsd_vfs_write(struct svc_rqst *rqstp, struct svc_fh *fhp, struct nfsd_file *nf, flags |= RWF_SYNC; iov_iter_kvec(&iter, WRITE, vec, vlen, *cnt); + since = READ_ONCE(file->f_wb_err); if (flags & RWF_SYNC) { - down_write(&nf->nf_rwsem); host_err = vfs_iter_write(file, &iter, &pos, flags); if (host_err < 0) nfsd_reset_boot_verifier(net_generic(SVC_NET(rqstp), nfsd_net_id)); - up_write(&nf->nf_rwsem); } else { - down_read(&nf->nf_rwsem); if (verf) nfsd_copy_boot_verifier(verf, net_generic(SVC_NET(rqstp), nfsd_net_id)); host_err = vfs_iter_write(file, &iter, &pos, flags); - up_read(&nf->nf_rwsem); } if (host_err < 0) { nfsd_reset_boot_verifier(net_generic(SVC_NET(rqstp), @@ -1036,6 +1036,9 @@ nfsd_vfs_write(struct svc_rqst *rqstp, struct svc_fh *fhp, struct nfsd_file *nf, *cnt = host_err; nfsd_stats_io_write_add(exp, *cnt); fsnotify_modify(file); + host_err = filemap_check_wb_err(file->f_mapping, since); + if (host_err < 0) + goto out_nfserr; if (stable && use_wgather) { host_err = wait_for_concurrent_writes(file); @@ -1116,19 +1119,6 @@ nfsd_write(struct svc_rqst *rqstp, struct svc_fh *fhp, loff_t offset, } #ifdef CONFIG_NFSD_V3 -static int -nfsd_filemap_write_and_wait_range(struct nfsd_file *nf, loff_t offset, - loff_t end) -{ - struct address_space *mapping = nf->nf_file->f_mapping; - int ret = filemap_fdatawrite_range(mapping, offset, end); - - if (ret) - return ret; - filemap_fdatawait_range_keep_errors(mapping, offset, end); - return 0; -} - /* * Commit all pending writes to stable storage. * @@ -1159,25 +1149,25 @@ nfsd_commit(struct svc_rqst *rqstp, struct svc_fh *fhp, if (err) goto out; if (EX_ISSYNC(fhp->fh_export)) { - int err2 = nfsd_filemap_write_and_wait_range(nf, offset, end); + errseq_t since = READ_ONCE(nf->nf_file->f_wb_err); + int err2; - down_write(&nf->nf_rwsem); - if (!err2) - err2 = vfs_fsync_range(nf->nf_file, offset, end, 0); + err2 = vfs_fsync_range(nf->nf_file, offset, end, 0); switch (err2) { case 0: nfsd_copy_boot_verifier(verf, net_generic(nf->nf_net, nfsd_net_id)); + err2 = filemap_check_wb_err(nf->nf_file->f_mapping, + since); break; case -EINVAL: err = nfserr_notsupp; break; default: - err = nfserrno(err2); nfsd_reset_boot_verifier(net_generic(nf->nf_net, nfsd_net_id)); } - up_write(&nf->nf_rwsem); + err = nfserrno(err2); } else nfsd_copy_boot_verifier(verf, net_generic(nf->nf_net, nfsd_net_id)); From patchwork Fri Dec 17 21:50:45 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Trond Myklebust X-Patchwork-Id: 12685729 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 06FB8C433EF for ; Fri, 17 Dec 2021 21:57:22 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230407AbhLQV5V (ORCPT ); Fri, 17 Dec 2021 16:57:21 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:34892 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230399AbhLQV5U (ORCPT ); Fri, 17 Dec 2021 16:57:20 -0500 Received: from ams.source.kernel.org (ams.source.kernel.org [IPv6:2604:1380:4601:e00::1]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id DDD90C06173E for ; Fri, 17 Dec 2021 13:57:19 -0800 (PST) Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ams.source.kernel.org (Postfix) with ESMTPS id A70A4B82AEE for ; Fri, 17 Dec 2021 21:57:18 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 23F51C36AE9; Fri, 17 Dec 2021 21:57:17 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1639778237; bh=IkNzwSFFqwpXdDU6Cocf4WBRXCMmOwJMi5yFIjVVCAs=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=j0x+d2UnBStlDyXP8flJZKVJqkczwgxyiLOvLabpUNWMfrRqdexAYjrODOVl5Xbpj TiZOJ6teub0aDuJipqCGie3eG181MGqxcnzPWPGgIc+niZRLr45/KH01C9YpuraPfj oAUf1UCpNr4uUTfIYz+R/7wEDLZ+zvibwALAAkDneH5u5wEY7vl/Vrf4QZtrEceHiH R4ca9EK6gl8JzkdiL5r8zMBsSwbaq4gHpfRiuOvFBTAjEpxr9ntB/gV/UwBHCwEyqU L9qeRikp0l1jPMUx/LWwNcVR7KHjhzmygv5jPmBcHJiG2WtGTXWbnnLr2krSUYIVXC E81oN9tf6N0dw== From: trondmy@kernel.org To: Chuck Lever , "J. Bruce Fields" Cc: linux-nfs@vger.kernel.org Subject: [PATCH 8/9] nfsd: allow lockd to be forcibly disabled Date: Fri, 17 Dec 2021 16:50:45 -0500 Message-Id: <20211217215046.40316-9-trondmy@kernel.org> X-Mailer: git-send-email 2.33.1 In-Reply-To: <20211217215046.40316-8-trondmy@kernel.org> References: <20211217215046.40316-1-trondmy@kernel.org> <20211217215046.40316-2-trondmy@kernel.org> <20211217215046.40316-3-trondmy@kernel.org> <20211217215046.40316-4-trondmy@kernel.org> <20211217215046.40316-5-trondmy@kernel.org> <20211217215046.40316-6-trondmy@kernel.org> <20211217215046.40316-7-trondmy@kernel.org> <20211217215046.40316-8-trondmy@kernel.org> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-nfs@vger.kernel.org From: Jeff Layton In some cases, we may want to use a userland NLM server which will require that we turn off lockd. Signed-off-by: Jeff Layton Signed-off-by: Lance Shelton Signed-off-by: Trond Myklebust --- fs/nfsd/nfssvc.c | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/fs/nfsd/nfssvc.c b/fs/nfsd/nfssvc.c index ccb59e91011b..7486a6f5fc21 100644 --- a/fs/nfsd/nfssvc.c +++ b/fs/nfsd/nfssvc.c @@ -340,8 +340,19 @@ static void nfsd_shutdown_generic(void) nfsd_file_cache_shutdown(); } +/* + * Allow admin to disable lockd. This would typically be used to allow (e.g.) + * a userspace NLM server of some sort to be used. + */ +static bool nfsd_disable_lockd = false; +module_param(nfsd_disable_lockd, bool, 0644); +MODULE_PARM_DESC(nfsd_disable_lockd, "Allow lockd to be manually disabled."); + static bool nfsd_needs_lockd(struct nfsd_net *nn) { + if (nfsd_disable_lockd) + return false; + return nfsd_vers(nn, 2, NFSD_TEST) || nfsd_vers(nn, 3, NFSD_TEST); } From patchwork Fri Dec 17 21:50:46 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Trond Myklebust X-Patchwork-Id: 12685727 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id CD528C433F5 for ; Fri, 17 Dec 2021 21:57:20 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230400AbhLQV5T (ORCPT ); Fri, 17 Dec 2021 16:57:19 -0500 Received: from dfw.source.kernel.org ([139.178.84.217]:48646 "EHLO dfw.source.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230399AbhLQV5S (ORCPT ); Fri, 17 Dec 2021 16:57:18 -0500 Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by dfw.source.kernel.org (Postfix) with ESMTPS id A18AC623C1 for ; Fri, 17 Dec 2021 21:57:18 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id B3023C36AE5; Fri, 17 Dec 2021 21:57:17 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1639778238; bh=VfxF6h5GBW4gVLHYvHGPxRlpGOFS1+gmIxfpDZ/JuR0=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=RxlpDBLGmZZDgJkELQH4lrh9WOWdZfr3YqFJ2x+vuFdS58Nqeswx9kY+J9A3CW+rs WEsotucATN06RC+4HKd7EBRsVIvG41rwlxYKx6PsOKGu2nhMlfu7eGt+oGv3NruOJg YvdLJpYKs6YfEm73GX7EL/RxJ1t0/P3Fq6F1OAzS32KGJ4axOj7o+20CxQAHnrNitS NC2nrDTJUVPGC0CpfCyuNTnQZiURocmRu8sAVBOYxHycSnSkGYg9PJwV6oDLEwE2w2 XBj0lT5hlQw5Fv7jId/SL2p5irWibKEAcPHLQPKrvQo5rtZm2dYKP+tPQBpj8v6cLd MXpQy13PKmRPw== From: trondmy@kernel.org To: Chuck Lever , "J. Bruce Fields" Cc: linux-nfs@vger.kernel.org Subject: [PATCH 9/9] nfsd: Ignore rpcbind errors on nfsd startup Date: Fri, 17 Dec 2021 16:50:46 -0500 Message-Id: <20211217215046.40316-10-trondmy@kernel.org> X-Mailer: git-send-email 2.33.1 In-Reply-To: <20211217215046.40316-9-trondmy@kernel.org> References: <20211217215046.40316-1-trondmy@kernel.org> <20211217215046.40316-2-trondmy@kernel.org> <20211217215046.40316-3-trondmy@kernel.org> <20211217215046.40316-4-trondmy@kernel.org> <20211217215046.40316-5-trondmy@kernel.org> <20211217215046.40316-6-trondmy@kernel.org> <20211217215046.40316-7-trondmy@kernel.org> <20211217215046.40316-8-trondmy@kernel.org> <20211217215046.40316-9-trondmy@kernel.org> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-nfs@vger.kernel.org From: Trond Myklebust NFSv4 doesn't need rpcbind, so let's not refuse to start up just because the rpcbind registration failed. Signed-off-by: Trond Myklebust --- fs/nfsd/nfsctl.c | 7 ++++++- fs/nfsd/nfsd.h | 1 + fs/nfsd/nfssvc.c | 18 ++++++++++++++++-- include/linux/sunrpc/svcsock.h | 5 +++-- net/sunrpc/svcsock.c | 14 ++++++++------ 5 files changed, 34 insertions(+), 11 deletions(-) diff --git a/fs/nfsd/nfsctl.c b/fs/nfsd/nfsctl.c index c2c3d9077dc5..50f1db5ce59b 100644 --- a/fs/nfsd/nfsctl.c +++ b/fs/nfsd/nfsctl.c @@ -727,6 +727,7 @@ static ssize_t __write_ports_addfd(char *buf, struct net *net, const struct cred char *mesg = buf; int fd, err; struct nfsd_net *nn = net_generic(net, nfsd_net_id); + int flags = SVC_SOCK_DEFAULTS; err = get_int(&mesg, &fd); if (err != 0 || fd < 0) @@ -741,7 +742,11 @@ static ssize_t __write_ports_addfd(char *buf, struct net *net, const struct cred if (err != 0) return err; - err = svc_addsock(nn->nfsd_serv, fd, buf, SIMPLE_TRANSACTION_LIMIT, cred); + if (!nfsd_rpcbind_error_is_fatal()) + flags |= SVC_SOCK_RPCBIND_NOERR; + + err = svc_addsock(nn->nfsd_serv, fd, buf, SIMPLE_TRANSACTION_LIMIT, + flags, cred); if (err < 0) { nfsd_destroy(net); return err; diff --git a/fs/nfsd/nfsd.h b/fs/nfsd/nfsd.h index 9664303afdaf..ebb87e43b965 100644 --- a/fs/nfsd/nfsd.h +++ b/fs/nfsd/nfsd.h @@ -132,6 +132,7 @@ int nfsd_vers(struct nfsd_net *nn, int vers, enum vers_op change); int nfsd_minorversion(struct nfsd_net *nn, u32 minorversion, enum vers_op change); void nfsd_reset_versions(struct nfsd_net *nn); int nfsd_create_serv(struct net *net); +extern bool nfsd_rpcbind_error_is_fatal(void); extern int nfsd_max_blksize; diff --git a/fs/nfsd/nfssvc.c b/fs/nfsd/nfssvc.c index 7486a6f5fc21..9e27e3c842a6 100644 --- a/fs/nfsd/nfssvc.c +++ b/fs/nfsd/nfssvc.c @@ -289,17 +289,21 @@ static int nfsd_init_socks(struct net *net, const struct cred *cred) { int error; struct nfsd_net *nn = net_generic(net, nfsd_net_id); + int flags = SVC_SOCK_DEFAULTS; if (!list_empty(&nn->nfsd_serv->sv_permsocks)) return 0; + if (!nfsd_rpcbind_error_is_fatal()) + flags |= SVC_SOCK_RPCBIND_NOERR; + error = svc_create_xprt(nn->nfsd_serv, "udp", net, PF_INET, NFS_PORT, - SVC_SOCK_DEFAULTS, cred); + flags, cred); if (error < 0) return error; error = svc_create_xprt(nn->nfsd_serv, "tcp", net, PF_INET, NFS_PORT, - SVC_SOCK_DEFAULTS, cred); + flags, cred); if (error < 0) return error; @@ -340,6 +344,16 @@ static void nfsd_shutdown_generic(void) nfsd_file_cache_shutdown(); } +static bool nfsd_rpcbind_error_fatal = false; +module_param(nfsd_rpcbind_error_fatal, bool, 0644); +MODULE_PARM_DESC(nfsd_rpcbind_error_fatal, + "rpcbind errors are fatal when starting nfsd."); + +bool nfsd_rpcbind_error_is_fatal(void) +{ + return nfsd_rpcbind_error_fatal; +} + /* * Allow admin to disable lockd. This would typically be used to allow (e.g.) * a userspace NLM server of some sort to be used. diff --git a/include/linux/sunrpc/svcsock.h b/include/linux/sunrpc/svcsock.h index bcc555c7ae9c..f34c222cee9d 100644 --- a/include/linux/sunrpc/svcsock.h +++ b/include/linux/sunrpc/svcsock.h @@ -61,8 +61,8 @@ void svc_drop(struct svc_rqst *); void svc_sock_update_bufs(struct svc_serv *serv); bool svc_alien_sock(struct net *net, int fd); int svc_addsock(struct svc_serv *serv, const int fd, - char *name_return, const size_t len, - const struct cred *cred); + char *name_return, const size_t len, int flags, + const struct cred *cred); void svc_init_xprt_sock(void); void svc_cleanup_xprt_sock(void); struct svc_xprt *svc_sock_create(struct svc_serv *serv, int prot); @@ -74,5 +74,6 @@ void svc_sock_destroy(struct svc_xprt *); #define SVC_SOCK_DEFAULTS (0U) #define SVC_SOCK_ANONYMOUS (1U << 0) /* don't register with pmap */ #define SVC_SOCK_TEMPORARY (1U << 1) /* flag socket as temporary */ +#define SVC_SOCK_RPCBIND_NOERR (1U << 2) /* Ignore pmap errors */ #endif /* SUNRPC_SVCSOCK_H */ diff --git a/net/sunrpc/svcsock.c b/net/sunrpc/svcsock.c index 478f857cdaed..7f5b12a50bf9 100644 --- a/net/sunrpc/svcsock.c +++ b/net/sunrpc/svcsock.c @@ -1309,14 +1309,15 @@ static struct svc_sock *svc_setup_socket(struct svc_serv *serv, inet = sock->sk; /* Register socket with portmapper */ - if (pmap_register) + if (pmap_register) { err = svc_register(serv, sock_net(sock->sk), inet->sk_family, inet->sk_protocol, ntohs(inet_sk(inet)->inet_sport)); - if (err < 0) { - kfree(svsk); - return ERR_PTR(err); + if (err < 0 && !(flags & SVC_SOCK_RPCBIND_NOERR)) { + kfree(svsk); + return ERR_PTR(err); + } } svsk->sk_sock = sock; @@ -1364,6 +1365,7 @@ EXPORT_SYMBOL_GPL(svc_alien_sock); * @fd: file descriptor of the new listener * @name_return: pointer to buffer to fill in with name of listener * @len: size of the buffer + * @flags: flags argument for svc_setup_socket() * @cred: credential * * Fills in socket name and returns positive length of name if successful. @@ -1371,7 +1373,7 @@ EXPORT_SYMBOL_GPL(svc_alien_sock); * value. */ int svc_addsock(struct svc_serv *serv, const int fd, char *name_return, - const size_t len, const struct cred *cred) + const size_t len, int flags, const struct cred *cred) { int err = 0; struct socket *so = sockfd_lookup(fd, &err); @@ -1395,7 +1397,7 @@ int svc_addsock(struct svc_serv *serv, const int fd, char *name_return, err = -ENOENT; if (!try_module_get(THIS_MODULE)) goto out; - svsk = svc_setup_socket(serv, so, SVC_SOCK_DEFAULTS); + svsk = svc_setup_socket(serv, so, flags); if (IS_ERR(svsk)) { module_put(THIS_MODULE); err = PTR_ERR(svsk);