From patchwork Fri Nov 8 23:39:44 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mike Snitzer X-Patchwork-Id: 13869041 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 9C2AD1E1C07 for ; Fri, 8 Nov 2024 23:40:05 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1731109205; cv=none; b=KZBiOVCAP2jhBzOy5MbmWOoqjyeGVQ4I+otL1hnUEymERYnt8IOKQ79pEU8y/Cro+bgyKkTf2licx+jGlfr5iDsbb0i6WDzd2SENY1RCQUxxKwPR+KXqCAWdKyhXuTPnquHPfhHKJ8lLSsF1URWMPkCdiZMcLxnLKlR7vj40Fnw= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1731109205; c=relaxed/simple; bh=1bz1oRimYkuZRUsqEVHEp1zaBPwmKys67gE15v4tO6I=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=mhoCzVO/T8Wt+DZeFqM5Km4oCkzPbph+pC0S8RlTA2GbA0Z23dWLfMbYoc11HmzAWILuBoReKqftCP7u61ejkWD0HUjwJBmYUWPMI9lbDer+DL8lf0c6QWFekiNIFdtivUrlLjfu2ONLSQPvznb7OxHQPg7FjY/fL+xgIpFgBAc= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=iRbvGpwa; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="iRbvGpwa" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 3ED79C4CED3; Fri, 8 Nov 2024 23:40:05 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1731109205; bh=1bz1oRimYkuZRUsqEVHEp1zaBPwmKys67gE15v4tO6I=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=iRbvGpwacx8wohoA0T+Xp7gmpLic873hAVVmMGhTBjvcbAJWWRWFlt8n2ObKw8fLY 4oWGPCprRL80uW+9pgBRklF7ME4G73ApMQ1/v2Okdhxwx7saFhfBubFezuajmJI8D7 JHM4hBi+Jc5Op6KSxeIwSS/tceEjFd+JW++KYvfz8Xu+w7QwsFTb/sbsKwABF3OpQL p8BqPguPhuqd1v1kF4C+VIbRAIzSzDgSC8H+mSOAR0SZ8HEFmBAFKazxaPEeAfQvow xWQORAx+xS5+89I8erC5elMk5CcLH9USjTAW4bjs651O5bTe+6XUq8FKnMBhRs/sYf WuCzGhm2tVAlg== From: Mike Snitzer To: linux-nfs@vger.kernel.org Cc: Anna Schumaker , Trond Myklebust , Chuck Lever , Jeff Layton , NeilBrown Subject: [for-6.13 PATCH 01/19] nfs/localio: must clear res.replen in nfs_local_read_done Date: Fri, 8 Nov 2024 18:39:44 -0500 Message-ID: <20241108234002.16392-2-snitzer@kernel.org> X-Mailer: git-send-email 2.44.0 In-Reply-To: <20241108234002.16392-1-snitzer@kernel.org> References: <20241108234002.16392-1-snitzer@kernel.org> Precedence: bulk X-Mailing-List: linux-nfs@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 From: NeilBrown Otherwise memory corruption can occur due to NFSv3 LOCALIO reads leaving garbage in res.replen: - nfs3_read_done() copies that into server->read_hdrsize; from there nfs3_proc_read_setup() copies it to args.replen in new requests. - nfs3_xdr_enc_read3args() passes that to rpc_prepare_reply_pages() which includes it in hdrsize for xdr_init_pages, so that rq_rcv_buf contains a ridiculous len. - This is copied to rq_private_buf and xs_read_stream_request() eventually passes the kvec to sock_recvmsg() which receives incoming data into entirely the wrong place. This is easily reproduced with NFSv3 LOCALIO that is servicing reads when it is made to pivot back to using normal RPC. This switch back to using normal NFSv3 with RPC can occur for a few reasons but this issue was exposed with a test that stops and then restarts the NFSv3 server while LOCALIO is performing heavy read IO. Fixes: 70ba381e1a43 ("nfs: add LOCALIO support") Reported-by: Mike Snitzer Signed-off-by: NeilBrown Co-developed-by: Mike Snitzer Signed-off-by: Mike Snitzer --- fs/nfs/localio.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/fs/nfs/localio.c b/fs/nfs/localio.c index 8f0ce82a677e..637528e6368e 100644 --- a/fs/nfs/localio.c +++ b/fs/nfs/localio.c @@ -354,6 +354,12 @@ nfs_local_read_done(struct nfs_local_kiocb *iocb, long status) nfs_local_pgio_done(hdr, status); + /* + * Must clear replen otherwise NFSv3 data corruption will occur + * if/when switching from LOCALIO back to using normal RPC. + */ + hdr->res.replen = 0; + if (hdr->res.count != hdr->args.count || hdr->args.offset + hdr->res.count >= i_size_read(file_inode(filp))) hdr->res.eof = true; From patchwork Fri Nov 8 23:39:45 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mike Snitzer X-Patchwork-Id: 13869042 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 385391E1C07 for ; Fri, 8 Nov 2024 23:40:06 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1731109207; cv=none; b=rMqPi2MxrufGzCo9OWjqoVi2jInj75lbW3W0a3w49cjDEHwa9gEHOG1tpB3uC2nxqfvpaG0gQZoHSiikTfCa0KDV35kYvzkkYzkRvHCyVVBcMvr1D0LneRcD3tjzBKZu/yPKoU8fXn6yMzZ+sIDZQOIeFwaHJVpdi0ya8hL4nGI= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1731109207; c=relaxed/simple; bh=GaGEV7rWDTrwTF45V3pFKioiq3NFJqACq5nBjidSw9g=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=BQCuOr164e3zq5sM/MNkqkJP4NDA7Fuu103rgK2wsMnV4BHrIX66Sg9tbcbrAIrpygwlu18lMkXeNLWGTA6PL+hzoNAfXXgTvw1scoWkhCG14aVRqYDWzTCE+hlkkqwZ7yeA7WYiCTIrGa+u8uX/Gub7q1EIj/yp62aPEl3qx5E= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=GgEUYWcr; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="GgEUYWcr" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 856F6C4CED2; Fri, 8 Nov 2024 23:40:06 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1731109206; bh=GaGEV7rWDTrwTF45V3pFKioiq3NFJqACq5nBjidSw9g=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=GgEUYWcr3W7r8HSGRPru6lT8qMVrD8ZORAqkLCxO/MDe4ZdFf177Shj5eUF7osKX0 Xo7KD8yXN/i6M31+YYTZi6qE2zWFJOy6EJjHLpzE01AkIzQb3k3pi5jckXtThM6Kie bRmG3RlGO+5Y9obLORWZKsq9lOJIgrBEUo7qK70qxSjW+v2YlHLNNiSWSLyIHHY+qJ DIjAeKpphJUZYfe8wFQlvorKOGyvOuq4hnBoL4oBTmQJhQZ90Usg95kITFX070nzf3 RQuFu9166V6nbFDF0AnaGLnyZiDldlIBTUrYAgK8iKxuBlN2XoULW2BhzNYNkSHVEr Zf2Vv8MK5v8aA== From: Mike Snitzer To: linux-nfs@vger.kernel.org Cc: Anna Schumaker , Trond Myklebust , Chuck Lever , Jeff Layton , NeilBrown Subject: [for-6.13 PATCH 02/19] nfs_common: must not hold RCU while calling nfsd_file_put_local Date: Fri, 8 Nov 2024 18:39:45 -0500 Message-ID: <20241108234002.16392-3-snitzer@kernel.org> X-Mailer: git-send-email 2.44.0 In-Reply-To: <20241108234002.16392-1-snitzer@kernel.org> References: <20241108234002.16392-1-snitzer@kernel.org> Precedence: bulk X-Mailing-List: linux-nfs@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Move holding the RCU from nfs_to_nfsd_file_put_local to nfs_to_nfsd_net_put. It is the call to nfs_to->nfsd_serv_put that requires the RCU anyway (the puts for nfsd_file and netns were combined to avoid an extra indirect reference but that micro-optimization isn't possible now). This fixes xfstests generic/013 and it triggering: "Voluntary context switch within RCU read-side critical section!" [ 143.545738] Call Trace: [ 143.546206] [ 143.546625] ? show_regs+0x6d/0x80 [ 143.547267] ? __warn+0x91/0x140 [ 143.547951] ? rcu_note_context_switch+0x496/0x5d0 [ 143.548856] ? report_bug+0x193/0x1a0 [ 143.549557] ? handle_bug+0x63/0xa0 [ 143.550214] ? exc_invalid_op+0x1d/0x80 [ 143.550938] ? asm_exc_invalid_op+0x1f/0x30 [ 143.551736] ? rcu_note_context_switch+0x496/0x5d0 [ 143.552634] ? wakeup_preempt+0x62/0x70 [ 143.553358] __schedule+0xaa/0x1380 [ 143.554025] ? _raw_spin_unlock_irqrestore+0x12/0x40 [ 143.554958] ? try_to_wake_up+0x1fe/0x6b0 [ 143.555715] ? wake_up_process+0x19/0x20 [ 143.556452] schedule+0x2e/0x120 [ 143.557066] schedule_preempt_disabled+0x19/0x30 [ 143.557933] rwsem_down_read_slowpath+0x24d/0x4a0 [ 143.558818] ? xfs_efi_item_format+0x50/0xc0 [xfs] [ 143.559894] down_read+0x4e/0xb0 [ 143.560519] xlog_cil_commit+0x1b2/0xbc0 [xfs] [ 143.561460] ? _raw_spin_unlock+0x12/0x30 [ 143.562212] ? xfs_inode_item_precommit+0xc7/0x220 [xfs] [ 143.563309] ? xfs_trans_run_precommits+0x69/0xd0 [xfs] [ 143.564394] __xfs_trans_commit+0xb5/0x330 [xfs] [ 143.565367] xfs_trans_roll+0x48/0xc0 [xfs] [ 143.566262] xfs_defer_trans_roll+0x57/0x100 [xfs] [ 143.567278] xfs_defer_finish_noroll+0x27a/0x490 [xfs] [ 143.568342] xfs_defer_finish+0x1a/0x80 [xfs] [ 143.569267] xfs_bunmapi_range+0x4d/0xb0 [xfs] [ 143.570208] xfs_itruncate_extents_flags+0x13d/0x230 [xfs] [ 143.571353] xfs_free_eofblocks+0x12e/0x190 [xfs] [ 143.572359] xfs_file_release+0x12d/0x140 [xfs] [ 143.573324] __fput+0xe8/0x2d0 [ 143.573922] __fput_sync+0x1d/0x30 [ 143.574574] nfsd_filp_close+0x33/0x60 [nfsd] [ 143.575430] nfsd_file_free+0x96/0x150 [nfsd] [ 143.576274] nfsd_file_put+0xf7/0x1a0 [nfsd] [ 143.577104] nfsd_file_put_local+0x18/0x30 [nfsd] [ 143.578070] nfs_close_local_fh+0x101/0x110 [nfs_localio] [ 143.579079] __put_nfs_open_context+0xc9/0x180 [nfs] [ 143.580031] nfs_file_clear_open_context+0x4a/0x60 [nfs] [ 143.581038] nfs_file_release+0x3e/0x60 [nfs] [ 143.581879] __fput+0xe8/0x2d0 [ 143.582464] __fput_sync+0x1d/0x30 [ 143.583108] __x64_sys_close+0x41/0x80 [ 143.583823] x64_sys_call+0x189a/0x20d0 [ 143.584552] do_syscall_64+0x64/0x170 [ 143.585240] entry_SYSCALL_64_after_hwframe+0x76/0x7e [ 143.586185] RIP: 0033:0x7f3c5153efd7 Signed-off-by: Mike Snitzer Reviewed-by: NeilBrown --- fs/nfs_common/nfslocalio.c | 8 +++----- fs/nfsd/filecache.c | 14 +++++++------- fs/nfsd/filecache.h | 2 +- include/linux/nfslocalio.h | 18 +++++++++++++++--- 4 files changed, 26 insertions(+), 16 deletions(-) diff --git a/fs/nfs_common/nfslocalio.c b/fs/nfs_common/nfslocalio.c index 09404d142d1a..a74ec08f6c96 100644 --- a/fs/nfs_common/nfslocalio.c +++ b/fs/nfs_common/nfslocalio.c @@ -155,11 +155,9 @@ struct nfsd_file *nfs_open_local_fh(nfs_uuid_t *uuid, /* We have an implied reference to net thanks to nfsd_serv_try_get */ localio = nfs_to->nfsd_open_local_fh(net, uuid->dom, rpc_clnt, cred, nfs_fh, fmode); - if (IS_ERR(localio)) { - rcu_read_lock(); - nfs_to->nfsd_serv_put(net); - rcu_read_unlock(); - } + if (IS_ERR(localio)) + nfs_to_nfsd_net_put(net); + return localio; } EXPORT_SYMBOL_GPL(nfs_open_local_fh); diff --git a/fs/nfsd/filecache.c b/fs/nfsd/filecache.c index c16671135d17..9a62b4da89bb 100644 --- a/fs/nfsd/filecache.c +++ b/fs/nfsd/filecache.c @@ -391,19 +391,19 @@ nfsd_file_put(struct nfsd_file *nf) } /** - * nfsd_file_put_local - put the reference to nfsd_file and local nfsd_serv - * @nf: nfsd_file of which to put the references + * nfsd_file_put_local - put nfsd_file reference and arm nfsd_serv_put in caller + * @nf: nfsd_file of which to put the reference * - * First put the reference of the nfsd_file and then put the - * reference to the associated nn->nfsd_serv. + * First save the associated net to return to caller, then put + * the reference of the nfsd_file. */ -void -nfsd_file_put_local(struct nfsd_file *nf) __must_hold(rcu) +struct net * +nfsd_file_put_local(struct nfsd_file *nf) { struct net *net = nf->nf_net; nfsd_file_put(nf); - nfsd_serv_put(net); + return net; } /** diff --git a/fs/nfsd/filecache.h b/fs/nfsd/filecache.h index cadf3c2689c4..d5db6b34ba30 100644 --- a/fs/nfsd/filecache.h +++ b/fs/nfsd/filecache.h @@ -55,7 +55,7 @@ void nfsd_file_cache_shutdown(void); int nfsd_file_cache_start_net(struct net *net); void nfsd_file_cache_shutdown_net(struct net *net); void nfsd_file_put(struct nfsd_file *nf); -void nfsd_file_put_local(struct nfsd_file *nf); +struct net *nfsd_file_put_local(struct nfsd_file *nf); struct nfsd_file *nfsd_file_get(struct nfsd_file *nf); struct file *nfsd_file_file(struct nfsd_file *nf); void nfsd_file_close_inode_sync(struct inode *inode); diff --git a/include/linux/nfslocalio.h b/include/linux/nfslocalio.h index 3982fea79919..9202f4b24343 100644 --- a/include/linux/nfslocalio.h +++ b/include/linux/nfslocalio.h @@ -55,7 +55,7 @@ struct nfsd_localio_operations { const struct cred *, const struct nfs_fh *, const fmode_t); - void (*nfsd_file_put_local)(struct nfsd_file *); + struct net *(*nfsd_file_put_local)(struct nfsd_file *); struct file *(*nfsd_file_file)(struct nfsd_file *); } ____cacheline_aligned; @@ -66,7 +66,7 @@ struct nfsd_file *nfs_open_local_fh(nfs_uuid_t *, struct rpc_clnt *, const struct cred *, const struct nfs_fh *, const fmode_t); -static inline void nfs_to_nfsd_file_put_local(struct nfsd_file *localio) +static inline void nfs_to_nfsd_net_put(struct net *net) { /* * Once reference to nfsd_serv is dropped, NFSD could be @@ -74,10 +74,22 @@ static inline void nfs_to_nfsd_file_put_local(struct nfsd_file *localio) * by always taking RCU. */ rcu_read_lock(); - nfs_to->nfsd_file_put_local(localio); + nfs_to->nfsd_serv_put(net); rcu_read_unlock(); } +static inline void nfs_to_nfsd_file_put_local(struct nfsd_file *localio) +{ + /* + * Must not hold RCU otherwise nfsd_file_put() can easily trigger: + * "Voluntary context switch within RCU read-side critical section!" + * by scheduling deep in underlying filesystem (e.g. XFS). + */ + struct net *net = nfs_to->nfsd_file_put_local(localio); + + nfs_to_nfsd_net_put(net); +} + #else /* CONFIG_NFS_LOCALIO */ static inline void nfsd_localio_ops_init(void) { From patchwork Fri Nov 8 23:39:46 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mike Snitzer X-Patchwork-Id: 13869043 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 4DCA81E1C07 for ; Fri, 8 Nov 2024 23:40:08 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1731109208; cv=none; b=NP5ADdcf5spAewSM9xCmdGUpjbfBucTLGyBiM8MhZfnxeGA6+Nmp6HH7sGW1dTgdjO/Nm3z5wXD6pa6XjiEZyOr0Kw96XO5yJtij55nP7VyBuEFvrHTF1TE7HiXD5mwBT9X5RXNBm6eRKIvae3XHNGGmCXUUuSr8gXPcJXM6H2A= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1731109208; c=relaxed/simple; bh=FzOLyeaGBvt9On5a9zfpPiVNqNEPSXph8kLfTfie5iE=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=rrne6HV1mctA7fLr6Qjb3tVYOSipTBccywdddeHT+JX6Tp60QqwGpuYK2HJVbtqHfRKRp17njH/EGnmEEnCywOIVHIDopNC7IYe82vfOehSrjScqshyVYXe39LZQj/W9MWxgTjY+OyuOtuXb1eol5ENplHTVVuxVuJG3HE5pSBE= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=d8zV/JoT; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="d8zV/JoT" Received: by smtp.kernel.org (Postfix) with ESMTPSA id E2D29C4CED2; Fri, 8 Nov 2024 23:40:07 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1731109208; bh=FzOLyeaGBvt9On5a9zfpPiVNqNEPSXph8kLfTfie5iE=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=d8zV/JoT6QyyP4VR2kyueJKXPYi4//Ex7ElU8sMtsbYTmCApofLyTTGQw8/4BMYDG lS7pM+XKzBPmEGLnFd2E1+sE+KqihNDocMMUCmDFWqJPJbTk0/mrk5OnRK0gpHaB9O nJm91RUd7p56UHwIqy5+mJ6G8ZSztojAW1jlotGJPn73BAIdocuUILMiFMd2hO3hOf UGyfLDMQ43HPkJ8XPyNG2mH8V94HSgRG16HT7BlUs8BWDU9DgkiHESe4kIUYkRZC+t auSUZG28Kyc/qPlKGBUz25yMkEp2ZUtNeb0FZEPWhETp56jgkNTRI2A4aUC/vqCbBK 6QH6yBpNy62Eg== From: Mike Snitzer To: linux-nfs@vger.kernel.org Cc: Anna Schumaker , Trond Myklebust , Chuck Lever , Jeff Layton , NeilBrown Subject: [for-6.13 PATCH 03/19] nfs/localio: remove redundant suid/sgid handling Date: Fri, 8 Nov 2024 18:39:46 -0500 Message-ID: <20241108234002.16392-4-snitzer@kernel.org> X-Mailer: git-send-email 2.44.0 In-Reply-To: <20241108234002.16392-1-snitzer@kernel.org> References: <20241108234002.16392-1-snitzer@kernel.org> Precedence: bulk X-Mailing-List: linux-nfs@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 From: Mike Snitzer nfs_writeback_done() will take care of suid/sgid corner case. Signed-off-by: Mike Snitzer Reviewed-by: NeilBrown --- fs/nfs/localio.c | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/fs/nfs/localio.c b/fs/nfs/localio.c index 637528e6368e..4b24933093b6 100644 --- a/fs/nfs/localio.c +++ b/fs/nfs/localio.c @@ -527,12 +527,7 @@ nfs_local_write_done(struct nfs_local_kiocb *iocb, long status) } if (status < 0) nfs_reset_boot_verifier(inode); - else if (nfs_should_remove_suid(inode)) { - /* Deal with the suid/sgid bit corner case */ - spin_lock(&inode->i_lock); - nfs_set_cache_invalid(inode, NFS_INO_INVALID_MODE); - spin_unlock(&inode->i_lock); - } + nfs_local_pgio_done(hdr, status); } From patchwork Fri Nov 8 23:39:47 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mike Snitzer X-Patchwork-Id: 13869044 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 033848F54 for ; Fri, 8 Nov 2024 23:40:09 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1731109210; cv=none; b=o2DdfUAtmX5txithVcO3/3q050FecIqahCngUnbttHa1vPQpUX+uGsxHDJvH11o8IEqDDWnOl9/bAhnhdtJfMlBbJfdWlUcSczkYPJDV7LNokkt94f3h3GBc3nvkUOqUc8IZOoD65sCasd3BYPBK7xElr5FO5z+yxqIS/CQmk8c= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1731109210; c=relaxed/simple; bh=bn5mwiijpdOy4SciTU3enJgrIX4vhWuUxDZQeVlPoWk=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=GWLfcbhVn0kCZjSibwZAP7ESGWAkiQsQrna3WXeBD7whopA2cjdPyBHBx91LppNFBSijcUucWX7Ip2IophDflmP1vPt87iKODUrJlBeG9zRMr466WZYY3CilqxW7+v1BcZq1ayPdQ0Fn1GCUUnsKUNQYLDyRVZYin67rKN9zrAk= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=dD6fK7Jw; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="dD6fK7Jw" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 6F165C4CECE; Fri, 8 Nov 2024 23:40:09 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1731109209; bh=bn5mwiijpdOy4SciTU3enJgrIX4vhWuUxDZQeVlPoWk=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=dD6fK7JwbzBxqOSpOvi/5EB0QXbE9jD6iR7qP5Ea7vD8Fjr4fv1hhFMf7GbfC5xis lLC8U+46RO3nYvoRZinbd/KVs3kYrJTLEDazEJzevIe0rfJJmS1MRPnYcVa6Ut8Jih QYOUbolh3nnIbvgk3pCMcD6m3eSnnkdgJxUgivYLrHivhfSQ0V1wcNAxhh4PvL9nqM mIbhGUzgQjlfPkAdTdXn5kHAfdfd41Ylc/hagHsxHEgLQuebKaK1JEI4dKjO/dDryN BXeuQhBb5nAr0qxFCndKOdFzPiQvUT17SK2Pxv4rvrcoLQFHK5xFNmXUsW/3Pn5Vdm XPQmBIpxKjtDw== From: Mike Snitzer To: linux-nfs@vger.kernel.org Cc: Anna Schumaker , Trond Myklebust , Chuck Lever , Jeff Layton , NeilBrown Subject: [for-6.13 PATCH 04/19] nfs/localio: eliminate unnecessary kref in nfs_local_fsync_ctx Date: Fri, 8 Nov 2024 18:39:47 -0500 Message-ID: <20241108234002.16392-5-snitzer@kernel.org> X-Mailer: git-send-email 2.44.0 In-Reply-To: <20241108234002.16392-1-snitzer@kernel.org> References: <20241108234002.16392-1-snitzer@kernel.org> Precedence: bulk X-Mailing-List: linux-nfs@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 nfs_local_commit() doesn't need async cleanup of nfs_local_fsync_ctx, so there is no need to use a kref. Signed-off-by: Mike Snitzer Reviewed-by: NeilBrown --- fs/nfs/localio.c | 20 +++----------------- 1 file changed, 3 insertions(+), 17 deletions(-) diff --git a/fs/nfs/localio.c b/fs/nfs/localio.c index 4b24933093b6..a7eb83a604d0 100644 --- a/fs/nfs/localio.c +++ b/fs/nfs/localio.c @@ -42,7 +42,6 @@ struct nfs_local_fsync_ctx { struct nfsd_file *localio; struct nfs_commit_data *data; struct work_struct work; - struct kref kref; struct completion *done; }; static void nfs_local_fsync_work(struct work_struct *work); @@ -689,30 +688,17 @@ nfs_local_fsync_ctx_alloc(struct nfs_commit_data *data, ctx->localio = localio; ctx->data = data; INIT_WORK(&ctx->work, nfs_local_fsync_work); - kref_init(&ctx->kref); ctx->done = NULL; } return ctx; } -static void -nfs_local_fsync_ctx_kref_free(struct kref *kref) -{ - kfree(container_of(kref, struct nfs_local_fsync_ctx, kref)); -} - -static void -nfs_local_fsync_ctx_put(struct nfs_local_fsync_ctx *ctx) -{ - kref_put(&ctx->kref, nfs_local_fsync_ctx_kref_free); -} - static void nfs_local_fsync_ctx_free(struct nfs_local_fsync_ctx *ctx) { nfs_local_release_commit_data(ctx->localio, ctx->data, ctx->data->task.tk_ops); - nfs_local_fsync_ctx_put(ctx); + kfree(ctx); } static void @@ -745,7 +731,7 @@ int nfs_local_commit(struct nfsd_file *localio, } nfs_local_init_commit(data, call_ops); - kref_get(&ctx->kref); + if (how & FLUSH_SYNC) { DECLARE_COMPLETION_ONSTACK(done); ctx->done = &done; @@ -753,6 +739,6 @@ int nfs_local_commit(struct nfsd_file *localio, wait_for_completion(&done); } else queue_work(nfsiod_workqueue, &ctx->work); - nfs_local_fsync_ctx_put(ctx); + return 0; } From patchwork Fri Nov 8 23:39:48 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mike Snitzer X-Patchwork-Id: 13869045 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 69DE38F54 for ; Fri, 8 Nov 2024 23:40:11 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1731109211; cv=none; b=bmkCngGcS652PZtG3m1SA61amNopIwFq94WtINqE0PphTAhSC0q+OWuoYJq47IGPhcEKqmUFywrmcT8hafwhmqJ1bg4dZwYEy03SmIjgbTzHWgB7x1wzLqzFMmrjvhgQXtE2+5w5+u/fjhBLRGud0SzPyu+sajtKUeAq07ojrts= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1731109211; c=relaxed/simple; bh=5BmG4OCg4OVD58XhXnViDbyH7/D/pzxz3ok8fBo9Qw4=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=GgTnIkcEeuEexYbhC4zdS5/uJkoJaQhRLpG/EQyx+EtyfvS8rl7rNfjsRAYcSF889P67HoloyS1RknpbBgylKjkWr2Jna5HBPL6kqoKPZ99YjNWfkkBd9xXbl7dKIEtlgpcHW0RONsZ/0ek3pJ5P7Z0EIPHba3JErRInNHfdDK0= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=pOnu4rKY; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="pOnu4rKY" Received: by smtp.kernel.org (Postfix) with ESMTPSA id C5CA1C4CECE; Fri, 8 Nov 2024 23:40:10 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1731109211; bh=5BmG4OCg4OVD58XhXnViDbyH7/D/pzxz3ok8fBo9Qw4=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=pOnu4rKYN1umH7areacqmaVwSKbjZUNJByuAWchQ7IuREcVZODY07gUnyCwxsuSlc hgo6F6gbE0YnODbO9ZBLYHhvKnMnlg0eOPDUF0PDOVd9nElCkHogElLhniDMyaSK3b hnXtOqxYCwZgPbIMHKeqCZ+WoIUAhm0/ya2lXaqt4by8E9ZcLgwwpQSawd1yy4/jFV +B2a1Hmfa/9em9WlNVkfYnW14n27q7+bAqVFIPLmSnk5ofV0v5sCWICGEaugFNQs4P gId9St1hibUzvk/rWupVoY2IyyDkxaPrsE2hm6KBSsYbc2HCGt7mpOoA1ocHVczEXW WDQ0U5Wnmq4vA== From: Mike Snitzer To: linux-nfs@vger.kernel.org Cc: Anna Schumaker , Trond Myklebust , Chuck Lever , Jeff Layton , NeilBrown Subject: [for-6.13 PATCH 05/19] nfs/localio: remove extra indirect nfs_to call to check {read,write}_iter Date: Fri, 8 Nov 2024 18:39:48 -0500 Message-ID: <20241108234002.16392-6-snitzer@kernel.org> X-Mailer: git-send-email 2.44.0 In-Reply-To: <20241108234002.16392-1-snitzer@kernel.org> References: <20241108234002.16392-1-snitzer@kernel.org> Precedence: bulk X-Mailing-List: linux-nfs@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Push the read_iter and write_iter availability checks down to nfs_do_local_read and nfs_do_local_write respectively. This eliminates a redundant nfs_to->nfsd_file_file() call. Signed-off-by: Mike Snitzer --- fs/nfs/localio.c | 32 +++++++++++++++++++------------- 1 file changed, 19 insertions(+), 13 deletions(-) diff --git a/fs/nfs/localio.c b/fs/nfs/localio.c index a7eb83a604d0..a77ac7e8a05c 100644 --- a/fs/nfs/localio.c +++ b/fs/nfs/localio.c @@ -273,7 +273,7 @@ nfs_local_iocb_free(struct nfs_local_kiocb *iocb) static struct nfs_local_kiocb * nfs_local_iocb_alloc(struct nfs_pgio_header *hdr, - struct nfsd_file *localio, gfp_t flags) + struct file *file, gfp_t flags) { struct nfs_local_kiocb *iocb; @@ -286,9 +286,8 @@ nfs_local_iocb_alloc(struct nfs_pgio_header *hdr, kfree(iocb); return NULL; } - init_sync_kiocb(&iocb->kiocb, nfs_to->nfsd_file_file(localio)); + init_sync_kiocb(&iocb->kiocb, file); iocb->kiocb.ki_pos = hdr->args.offset; - iocb->localio = localio; iocb->hdr = hdr; iocb->kiocb.ki_flags &= ~IOCB_APPEND; return iocb; @@ -395,13 +394,19 @@ nfs_do_local_read(struct nfs_pgio_header *hdr, const struct rpc_call_ops *call_ops) { struct nfs_local_kiocb *iocb; + struct file *file = nfs_to->nfsd_file_file(localio); + + /* Don't support filesystems without read_iter */ + if (!file->f_op->read_iter) + return -EAGAIN; dprintk("%s: vfs_read count=%u pos=%llu\n", __func__, hdr->args.count, hdr->args.offset); - iocb = nfs_local_iocb_alloc(hdr, localio, GFP_KERNEL); + iocb = nfs_local_iocb_alloc(hdr, file, GFP_KERNEL); if (iocb == NULL) return -ENOMEM; + iocb->localio = localio; nfs_local_pgio_init(hdr, call_ops); hdr->res.eof = false; @@ -564,14 +569,20 @@ nfs_do_local_write(struct nfs_pgio_header *hdr, const struct rpc_call_ops *call_ops) { struct nfs_local_kiocb *iocb; + struct file *file = nfs_to->nfsd_file_file(localio); + + /* Don't support filesystems without write_iter */ + if (!file->f_op->write_iter) + return -EAGAIN; dprintk("%s: vfs_write count=%u pos=%llu %s\n", __func__, hdr->args.count, hdr->args.offset, (hdr->args.stable == NFS_UNSTABLE) ? "unstable" : "stable"); - iocb = nfs_local_iocb_alloc(hdr, localio, GFP_NOIO); + iocb = nfs_local_iocb_alloc(hdr, file, GFP_NOIO); if (iocb == NULL) return -ENOMEM; + iocb->localio = localio; switch (hdr->args.stable) { default: @@ -597,16 +608,9 @@ int nfs_local_doio(struct nfs_client *clp, struct nfsd_file *localio, const struct rpc_call_ops *call_ops) { int status = 0; - struct file *filp = nfs_to->nfsd_file_file(localio); if (!hdr->args.count) return 0; - /* Don't support filesystems without read_iter/write_iter */ - if (!filp->f_op->read_iter || !filp->f_op->write_iter) { - nfs_local_disable(clp); - status = -EAGAIN; - goto out; - } switch (hdr->rw_mode) { case FMODE_READ: @@ -620,8 +624,10 @@ int nfs_local_doio(struct nfs_client *clp, struct nfsd_file *localio, hdr->rw_mode); status = -EINVAL; } -out: + if (status != 0) { + if (status == -EAGAIN) + nfs_local_disable(clp); nfs_to_nfsd_file_put_local(localio); hdr->task.tk_status = status; nfs_local_hdr_release(hdr, call_ops); From patchwork Fri Nov 8 23:39:49 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mike Snitzer X-Patchwork-Id: 13869046 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id BBED3610D for ; Fri, 8 Nov 2024 23:40:12 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1731109212; cv=none; b=Xqe1WniQdtbfBAbUbjc8EGgGeB590srPryILq7g1UuW2GlX1MhFOJCRD3rbAdAb9HZUAiT/evyRNWSVBZ3lX98pMxY+sQT8AixDQl2dKNpVyBqmCT5jzuhXIWAWlq+YR/5ZJGHJ0URv4sZPGTXmA2szVU0DzwFxcHqPPofhTX7E= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1731109212; c=relaxed/simple; bh=Q8g8UICpZs7iT3g1RfNyW2/Auufa40rgpzRtnpgNkEc=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=TClpXusqeL5UTVI/GdYFnH7yaEYOem/5wXEHGhD3v1QxrP/B5Sm5Tlh/vqHuAkJYmTmL/UUMPHfnd6caDFqGUNFr40lRQ9G5aQP9tMHi3Nt2yE1CrmEwsCFJPBN58MWi2LucZWj+DwrPOAKEja2/AIzTTWm90sPFxrw15wPyQEI= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=Ra0PigWX; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="Ra0PigWX" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 2ED02C4CECE; Fri, 8 Nov 2024 23:40:12 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1731109212; bh=Q8g8UICpZs7iT3g1RfNyW2/Auufa40rgpzRtnpgNkEc=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=Ra0PigWXRV7uG8v0kogAUVHkYEVB4YARxkBvmemKtKyY1pMHhCmR3TbukEZiomUYY S9UsqdJkTnyTJnRoETu36IjIFFy/lSiXIW8dfmbVzJ99mixs/9EKG6A0orVAbNVSz0 Wk6fKDfEmdHEsjG9+GdIvt0CvZ9lp/JxDd1drRdzOBLdoZzn0r0GMNZyXVh4LjX8S3 bn1jWG5mVPzJU14iRwIbPPrXNC4ei1mzl1SUCUFykIH/pPER5Z+IdpJEZm5NAn70IA qP0gaJXfuqfsBkXg2t9OHvpW4iHQrjw/WJTmVbqWWERUm2fhwjYLWNz9r+vv2TWSPg HmxBTO13MaXSQ== From: Mike Snitzer To: linux-nfs@vger.kernel.org Cc: Anna Schumaker , Trond Myklebust , Chuck Lever , Jeff Layton , NeilBrown Subject: [for-6.13 PATCH 06/19] nfs/localio: eliminate need for nfs_local_fsync_work forward declaration Date: Fri, 8 Nov 2024 18:39:49 -0500 Message-ID: <20241108234002.16392-7-snitzer@kernel.org> X-Mailer: git-send-email 2.44.0 In-Reply-To: <20241108234002.16392-1-snitzer@kernel.org> References: <20241108234002.16392-1-snitzer@kernel.org> Precedence: bulk X-Mailing-List: linux-nfs@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Move nfs_local_fsync_ctx_alloc() after nfs_local_fsync_work(). Signed-off-by: Mike Snitzer Reviewed-by: NeilBrown --- fs/nfs/localio.c | 31 +++++++++++++++---------------- 1 file changed, 15 insertions(+), 16 deletions(-) diff --git a/fs/nfs/localio.c b/fs/nfs/localio.c index a77ac7e8a05c..4b8618cf114c 100644 --- a/fs/nfs/localio.c +++ b/fs/nfs/localio.c @@ -44,7 +44,6 @@ struct nfs_local_fsync_ctx { struct work_struct work; struct completion *done; }; -static void nfs_local_fsync_work(struct work_struct *work); static bool localio_enabled __read_mostly = true; module_param(localio_enabled, bool, 0644); @@ -684,21 +683,6 @@ nfs_local_release_commit_data(struct nfsd_file *localio, call_ops->rpc_release(data); } -static struct nfs_local_fsync_ctx * -nfs_local_fsync_ctx_alloc(struct nfs_commit_data *data, - struct nfsd_file *localio, gfp_t flags) -{ - struct nfs_local_fsync_ctx *ctx = kmalloc(sizeof(*ctx), flags); - - if (ctx != NULL) { - ctx->localio = localio; - ctx->data = data; - INIT_WORK(&ctx->work, nfs_local_fsync_work); - ctx->done = NULL; - } - return ctx; -} - static void nfs_local_fsync_ctx_free(struct nfs_local_fsync_ctx *ctx) { @@ -723,6 +707,21 @@ nfs_local_fsync_work(struct work_struct *work) nfs_local_fsync_ctx_free(ctx); } +static struct nfs_local_fsync_ctx * +nfs_local_fsync_ctx_alloc(struct nfs_commit_data *data, + struct nfsd_file *localio, gfp_t flags) +{ + struct nfs_local_fsync_ctx *ctx = kmalloc(sizeof(*ctx), flags); + + if (ctx != NULL) { + ctx->localio = localio; + ctx->data = data; + INIT_WORK(&ctx->work, nfs_local_fsync_work); + ctx->done = NULL; + } + return ctx; +} + int nfs_local_commit(struct nfsd_file *localio, struct nfs_commit_data *data, const struct rpc_call_ops *call_ops, int how) From patchwork Fri Nov 8 23:39:50 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mike Snitzer X-Patchwork-Id: 13869047 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 4B6341F26E0 for ; Fri, 8 Nov 2024 23:40:13 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1731109214; cv=none; b=Tcliarz7cDSmhWidJ5DBdydOCuUmoN35TvzpTL4X3EX2ljdLae4BEe3Ixbg1b4A1uMu0z5YQQxMisgCbb/PDsI4fNHbd4JAZdnMp5anYx8gncjEduFeIc+x5/gFrEHX6o5tSXtGa529FHT6z4lP5Kw+nx4AAiDNHowoKha7Y95M= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1731109214; c=relaxed/simple; bh=9gjhMrEuA9ZA9K5kKsTIeYaHi6xW2/DlMbaKV4nDF+8=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=g1KyuSaStoo3QWe0sowFSPVLjZtlgUikKnkYeiyr+6s7+O9zKL5h/dWHKWs+WlXnrqpDcIQxRp15CB0np34t8IKzOyrLPM0kcmhJXzup2MfaC/P3utziYSUjhJA1wQEpTONHwrPm2L7R21sNvk0iRWTsjlf/dhoCzEsrhfAUm+s= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=rClBk5iX; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="rClBk5iX" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 82BD4C4CED2; Fri, 8 Nov 2024 23:40:13 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1731109213; bh=9gjhMrEuA9ZA9K5kKsTIeYaHi6xW2/DlMbaKV4nDF+8=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=rClBk5iX+e98H+c+9UfqY3k0KYzGjHM7GcFGK3A+jAatsrrbZgjDxGmaxi9Ynu3bE avjnKn7WZlieYqnbizA5G5cGSUZaOwCc4lm1lWWqWmGz/BOj9OZdUslcGsaauH9Oom ZOITQlTiWbpQ3lYOOZvxBqsG3tvP6ehrVoUL7iM28biO37CRt4uc2WhWkk3LEAf855 dyTAGmy+yy+MHVQEVlfYDuVosSiyN5UsX43GWlBnKavoj9/PtzngCXhafyvmi0NsOA Tugmb+INO9hVZZejq9JkteoXbSYce2dZw5W6SgBaJ7pDCyLHGu45vpCjVbEOS9RD08 ajoJbVJJLUS4A== From: Mike Snitzer To: linux-nfs@vger.kernel.org Cc: Anna Schumaker , Trond Myklebust , Chuck Lever , Jeff Layton , NeilBrown Subject: [for-6.13 PATCH 07/19] nfs/localio: add direct IO enablement with sync and async IO support Date: Fri, 8 Nov 2024 18:39:50 -0500 Message-ID: <20241108234002.16392-8-snitzer@kernel.org> X-Mailer: git-send-email 2.44.0 In-Reply-To: <20241108234002.16392-1-snitzer@kernel.org> References: <20241108234002.16392-1-snitzer@kernel.org> Precedence: bulk X-Mailing-List: linux-nfs@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 This commit simply adds the required O_DIRECT plumbing. It doesn't address the fact that NFS doesn't ensure all writes are page aligned (nor device logical block size aligned as required by O_DIRECT). Because NFS will read-modify-write for IO that isn't aligned, LOCALIO will not use O_DIRECT semantics by default if/when an application requests the use of O_DIRECT. Allow the use of O_DIRECT semantics by: 1: Adding a flag to the nfs_pgio_header struct to allow the NFS O_DIRECT layer to signal that O_DIRECT was used by the application 2: Adding a 'localio_O_DIRECT_semantics' NFS module parameter that when enabled will cause LOCALIO to use O_DIRECT semantics (this may cause IO to fail if applications do not properly align their IO). Adding Direct IO support helps side-step the problem that LOCALIO currently double buffers buffered IO (by using page cache in both NFS and the underlying filesystem). More care is needed to craft a proper solution for LOCALIO's redundant use of page cache for buffered IO, e.g.: https://marc.info/?l=linux-nfs&m=171996211625151&w=2 This commit is derived from code developed by Weston Andros Adamson. Signed-off-by: Mike Snitzer --- fs/nfs/direct.c | 1 + fs/nfs/localio.c | 92 ++++++++++++++++++++++++++++++++++++----- include/linux/nfs_xdr.h | 1 + 3 files changed, 84 insertions(+), 10 deletions(-) diff --git a/fs/nfs/direct.c b/fs/nfs/direct.c index 90079ca134dd..4b92493d6ff0 100644 --- a/fs/nfs/direct.c +++ b/fs/nfs/direct.c @@ -303,6 +303,7 @@ static void nfs_read_sync_pgio_error(struct list_head *head, int error) static void nfs_direct_pgio_init(struct nfs_pgio_header *hdr) { get_dreq(hdr->dreq); + set_bit(NFS_IOHDR_ODIRECT, &hdr->flags); } static const struct nfs_pgio_completion_ops nfs_direct_read_completion_ops = { diff --git a/fs/nfs/localio.c b/fs/nfs/localio.c index 4b8618cf114c..de0dcd76d84d 100644 --- a/fs/nfs/localio.c +++ b/fs/nfs/localio.c @@ -35,6 +35,7 @@ struct nfs_local_kiocb { struct bio_vec *bvec; struct nfs_pgio_header *hdr; struct work_struct work; + void (*aio_complete_work)(struct work_struct *); struct nfsd_file *localio; }; @@ -48,6 +49,10 @@ struct nfs_local_fsync_ctx { static bool localio_enabled __read_mostly = true; module_param(localio_enabled, bool, 0644); +static bool localio_O_DIRECT_semantics __read_mostly = false; +module_param(localio_O_DIRECT_semantics, bool, 0644); +MODULE_PARM_DESC(localio_O_DIRECT_semantics, "Use O_DIRECT semantics"); + static inline bool nfs_client_is_local(const struct nfs_client *clp) { return !!test_bit(NFS_CS_LOCAL_IO, &clp->cl_flags); @@ -285,10 +290,19 @@ nfs_local_iocb_alloc(struct nfs_pgio_header *hdr, kfree(iocb); return NULL; } - init_sync_kiocb(&iocb->kiocb, file); + + if (localio_O_DIRECT_semantics && + test_bit(NFS_IOHDR_ODIRECT, &hdr->flags)) { + iocb->kiocb.ki_filp = file; + iocb->kiocb.ki_flags = IOCB_DIRECT; + } else + init_sync_kiocb(&iocb->kiocb, file); + iocb->kiocb.ki_pos = hdr->args.offset; iocb->hdr = hdr; iocb->kiocb.ki_flags &= ~IOCB_APPEND; + iocb->aio_complete_work = NULL; + return iocb; } @@ -343,6 +357,18 @@ nfs_local_pgio_release(struct nfs_local_kiocb *iocb) nfs_local_hdr_release(hdr, hdr->task.tk_ops); } +/* + * Complete the I/O from iocb->kiocb.ki_complete() + * + * Note that this function can be called from a bottom half context, + * hence we need to queue the rpc_call_done() etc to a workqueue + */ +static inline void nfs_local_pgio_aio_complete(struct nfs_local_kiocb *iocb) +{ + INIT_WORK(&iocb->work, iocb->aio_complete_work); + queue_work(nfsiod_workqueue, &iocb->work); +} + static void nfs_local_read_done(struct nfs_local_kiocb *iocb, long status) { @@ -365,6 +391,23 @@ nfs_local_read_done(struct nfs_local_kiocb *iocb, long status) status > 0 ? status : 0, hdr->res.eof); } +static void nfs_local_read_aio_complete_work(struct work_struct *work) +{ + struct nfs_local_kiocb *iocb = + container_of(work, struct nfs_local_kiocb, work); + + nfs_local_pgio_release(iocb); +} + +static void nfs_local_read_aio_complete(struct kiocb *kiocb, long ret) +{ + struct nfs_local_kiocb *iocb = + container_of(kiocb, struct nfs_local_kiocb, kiocb); + + nfs_local_read_done(iocb, ret); + nfs_local_pgio_aio_complete(iocb); /* Calls nfs_local_read_aio_complete_work */ +} + static void nfs_local_call_read(struct work_struct *work) { struct nfs_local_kiocb *iocb = @@ -379,10 +422,10 @@ static void nfs_local_call_read(struct work_struct *work) nfs_local_iter_init(&iter, iocb, READ); status = filp->f_op->read_iter(&iocb->kiocb, &iter); - WARN_ON_ONCE(status == -EIOCBQUEUED); - - nfs_local_read_done(iocb, status); - nfs_local_pgio_release(iocb); + if (status != -EIOCBQUEUED) { + nfs_local_read_done(iocb, status); + nfs_local_pgio_release(iocb); + } revert_creds(save_cred); } @@ -410,6 +453,11 @@ nfs_do_local_read(struct nfs_pgio_header *hdr, nfs_local_pgio_init(hdr, call_ops); hdr->res.eof = false; + if (iocb->kiocb.ki_flags & IOCB_DIRECT) { + iocb->kiocb.ki_complete = nfs_local_read_aio_complete; + iocb->aio_complete_work = nfs_local_read_aio_complete_work; + } + INIT_WORK(&iocb->work, nfs_local_call_read); queue_work(nfslocaliod_workqueue, &iocb->work); @@ -534,6 +582,24 @@ nfs_local_write_done(struct nfs_local_kiocb *iocb, long status) nfs_local_pgio_done(hdr, status); } +static void nfs_local_write_aio_complete_work(struct work_struct *work) +{ + struct nfs_local_kiocb *iocb = + container_of(work, struct nfs_local_kiocb, work); + + nfs_local_vfs_getattr(iocb); + nfs_local_pgio_release(iocb); +} + +static void nfs_local_write_aio_complete(struct kiocb *kiocb, long ret) +{ + struct nfs_local_kiocb *iocb = + container_of(kiocb, struct nfs_local_kiocb, kiocb); + + nfs_local_write_done(iocb, ret); + nfs_local_pgio_aio_complete(iocb); /* Calls nfs_local_write_aio_complete_work */ +} + static void nfs_local_call_write(struct work_struct *work) { struct nfs_local_kiocb *iocb = @@ -552,11 +618,11 @@ static void nfs_local_call_write(struct work_struct *work) file_start_write(filp); status = filp->f_op->write_iter(&iocb->kiocb, &iter); file_end_write(filp); - WARN_ON_ONCE(status == -EIOCBQUEUED); - - nfs_local_write_done(iocb, status); - nfs_local_vfs_getattr(iocb); - nfs_local_pgio_release(iocb); + if (status != -EIOCBQUEUED) { + nfs_local_write_done(iocb, status); + nfs_local_vfs_getattr(iocb); + nfs_local_pgio_release(iocb); + } revert_creds(save_cred); current->flags = old_flags; @@ -592,10 +658,16 @@ nfs_do_local_write(struct nfs_pgio_header *hdr, case NFS_FILE_SYNC: iocb->kiocb.ki_flags |= IOCB_DSYNC|IOCB_SYNC; } + nfs_local_pgio_init(hdr, call_ops); nfs_set_local_verifier(hdr->inode, hdr->res.verf, hdr->args.stable); + if (iocb->kiocb.ki_flags & IOCB_DIRECT) { + iocb->kiocb.ki_complete = nfs_local_write_aio_complete; + iocb->aio_complete_work = nfs_local_write_aio_complete_work; + } + INIT_WORK(&iocb->work, nfs_local_call_write); queue_work(nfslocaliod_workqueue, &iocb->work); diff --git a/include/linux/nfs_xdr.h b/include/linux/nfs_xdr.h index e0ae0a14257f..f30e94d105b7 100644 --- a/include/linux/nfs_xdr.h +++ b/include/linux/nfs_xdr.h @@ -1632,6 +1632,7 @@ enum { NFS_IOHDR_RESEND_PNFS, NFS_IOHDR_RESEND_MDS, NFS_IOHDR_UNSTABLE_WRITES, + NFS_IOHDR_ODIRECT, }; struct nfs_io_completion; From patchwork Fri Nov 8 23:39:51 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mike Snitzer X-Patchwork-Id: 13869048 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 869E61F26E0 for ; Fri, 8 Nov 2024 23:40:15 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1731109215; cv=none; b=G8Bu4/gFUkHgDa45epWQISUp4Py5GVgWLErOmbGKqPdep3m8iGA+zD4SjH95dLT7Tk4co/iE1ogqzdp4jLEopxE0RZDB4/I5vdd2Ov+jf/qeMbXZTEczFn6VqNEtW5Wy3jft5kTqvrHExQp/zzaHz6KZM3xPQDZXRiy0Lp36yQs= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1731109215; c=relaxed/simple; bh=h0SS3CCZHoeqzEPK7IHmjOFtaoS+rIdOsWwUD7Uufg4=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=OnUnOrNqxrgz/4/Dd5ySVFCUSWKoHk2NXFTSDgAEqVJW09yhD6X3NUmAzbQHjIUs64MFoukJT/jxl1J21758sb5Fp5Mc+uMb12wSgMxZtTi7EkN1gwhYMpHEu+DYw1W91CTPV0qaSFl/jt62imdw5PKI9Hfls8dmVghn6VogcIc= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=rZvHOBIu; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="rZvHOBIu" Received: by smtp.kernel.org (Postfix) with ESMTPSA id DB853C4CECE; Fri, 8 Nov 2024 23:40:14 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1731109215; bh=h0SS3CCZHoeqzEPK7IHmjOFtaoS+rIdOsWwUD7Uufg4=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=rZvHOBIun7gLLes/t5kMLmTMPYHf0e1iytmspv3sntCFMrpdWsCTJrOSVhXvfcb7l j7YHBAxgVuDA07yUlc844hTIqz4B0rcbXxCFAcOX0OHa2hg8gPom5BO9UyvvoXG7Wv tKyWABfU5GdguEXBQ4a5JABy54RztlIhmzLLDLw0KpLZnQne7oVEn0WGCNpIuxcv5o QpaSCB4e2GmdTppmLSGEqoWN05+gZaPynkN0RJw2Yy3hBeuCnOzn9xhyG1s8GqPEwZ V0v+jy2gw5+Fq2/6z6QVD6GCC5ZeG9qC4FVJVl9P/+5tzWHp4kEI41mSKm22KLBexg dh04Bur+9fDQA== From: Mike Snitzer To: linux-nfs@vger.kernel.org Cc: Anna Schumaker , Trond Myklebust , Chuck Lever , Jeff Layton , NeilBrown Subject: [for-6.13 PATCH 08/19] nfsd: add nfsd_file_{get,put} to 'nfs_to' nfsd_localio_operations Date: Fri, 8 Nov 2024 18:39:51 -0500 Message-ID: <20241108234002.16392-9-snitzer@kernel.org> X-Mailer: git-send-email 2.44.0 In-Reply-To: <20241108234002.16392-1-snitzer@kernel.org> References: <20241108234002.16392-1-snitzer@kernel.org> Precedence: bulk X-Mailing-List: linux-nfs@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 In later a commit LOCALIO must call both nfsd_file_get and nfsd_file_put to manage extra nfsd_file references. Signed-off-by: Mike Snitzer --- fs/nfsd/localio.c | 2 ++ include/linux/nfslocalio.h | 2 ++ 2 files changed, 4 insertions(+) diff --git a/fs/nfsd/localio.c b/fs/nfsd/localio.c index f441cb9f74d5..8beda4c85111 100644 --- a/fs/nfsd/localio.c +++ b/fs/nfsd/localio.c @@ -29,6 +29,8 @@ static const struct nfsd_localio_operations nfsd_localio_ops = { .nfsd_serv_put = nfsd_serv_put, .nfsd_open_local_fh = nfsd_open_local_fh, .nfsd_file_put_local = nfsd_file_put_local, + .nfsd_file_get = nfsd_file_get, + .nfsd_file_put = nfsd_file_put, .nfsd_file_file = nfsd_file_file, }; diff --git a/include/linux/nfslocalio.h b/include/linux/nfslocalio.h index 9202f4b24343..ab6a2a53f505 100644 --- a/include/linux/nfslocalio.h +++ b/include/linux/nfslocalio.h @@ -56,6 +56,8 @@ struct nfsd_localio_operations { const struct nfs_fh *, const fmode_t); struct net *(*nfsd_file_put_local)(struct nfsd_file *); + struct nfsd_file *(*nfsd_file_get)(struct nfsd_file *); + void (*nfsd_file_put)(struct nfsd_file *); struct file *(*nfsd_file_file)(struct nfsd_file *); } ____cacheline_aligned; From patchwork Fri Nov 8 23:39:52 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mike Snitzer X-Patchwork-Id: 13869049 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 8EE2C1F26E0 for ; Fri, 8 Nov 2024 23:40:16 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1731109216; cv=none; b=S9anjoC2WYi64NkYY10/PgHyoUmStgN0HqkND56Qka19d2BBy3QRYs7QgLMZc0gHSpfPABKyNDM9OCzjXM/TtaMUzK130A25L2nHWEkEqxgThngUxe4Qvsov4Z8bRTHWhbe9Zkm13wRhmys12mGh+Aa14b5P6GVngfpYYhKbZTI= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1731109216; c=relaxed/simple; bh=uiujbxYKPAJkwKdQoUJnHAuEOxEUTcAr2LazvNUwFO8=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=U+v/tY+cRSEOYX/PwqjFYKpTLfg5zbZdVWUnGtySvNX0F8dkQqYaB8rqlxrpholFf4KjgqxT2q469LwpP6aJKwuwNkndEmm4V3mR03Pxejcmew9KUleZNFGJWgbs3KbrDDbYri5vlMekm7lOWpZAu6+s10kyHqBV+RgRCb5o8pQ= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=SqRtlQIV; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="SqRtlQIV" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 3B98AC4CECE; Fri, 8 Nov 2024 23:40:16 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1731109216; bh=uiujbxYKPAJkwKdQoUJnHAuEOxEUTcAr2LazvNUwFO8=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=SqRtlQIVROzPeGG7a9hL88p11pNRaE3j2k2vjCd+w9CoAvOLJ1LPnKlK+UsE39rfy 6tx5JQ4WGY4IuX51nWNcddDzs9CJ/Rhd/NsjB+SpEiDvEynppTjQlDFN4oxqenEfKC cvySNPlWDEy2q8sRkJahtghq2GIkOcHFqXHcidnUnJnMtebCC6/cJ81O7MrCZu1QTn VJ8BSCgN7cjhbOd0ZHZdcVv4m45VSI6KwQsl0FJLQRQkin4cuA+NBvqslMqp5hidpL 5SdkilxTABqR+oD9ewXmE5JGdQF/utOq5akY63Oper9BznXO+WE+TVzhWX0sX6vrGn +DHu9TqKU0ciQ== From: Mike Snitzer To: linux-nfs@vger.kernel.org Cc: Anna Schumaker , Trond Myklebust , Chuck Lever , Jeff Layton , NeilBrown Subject: [for-6.13 PATCH 09/19] nfs_common: rename functions that invalidate LOCALIO nfs_clients Date: Fri, 8 Nov 2024 18:39:52 -0500 Message-ID: <20241108234002.16392-10-snitzer@kernel.org> X-Mailer: git-send-email 2.44.0 In-Reply-To: <20241108234002.16392-1-snitzer@kernel.org> References: <20241108234002.16392-1-snitzer@kernel.org> Precedence: bulk X-Mailing-List: linux-nfs@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Rename nfs_uuid_invalidate_one_client to nfs_localio_disable_client. Rename nfs_uuid_invalidate_clients to nfs_localio_invalidate_clients. Signed-off-by: Mike Snitzer Reviewed-by: NeilBrown --- fs/nfs/localio.c | 2 +- fs/nfs_common/nfslocalio.c | 8 ++++---- fs/nfsd/nfsctl.c | 4 ++-- include/linux/nfslocalio.h | 5 +++-- 4 files changed, 10 insertions(+), 9 deletions(-) diff --git a/fs/nfs/localio.c b/fs/nfs/localio.c index de0dcd76d84d..cab2a8819259 100644 --- a/fs/nfs/localio.c +++ b/fs/nfs/localio.c @@ -139,7 +139,7 @@ void nfs_local_disable(struct nfs_client *clp) spin_lock(&clp->cl_localio_lock); if (test_and_clear_bit(NFS_CS_LOCAL_IO, &clp->cl_flags)) { trace_nfs_local_disable(clp); - nfs_uuid_invalidate_one_client(&clp->cl_uuid); + nfs_localio_disable_client(&clp->cl_uuid); } spin_unlock(&clp->cl_localio_lock); } diff --git a/fs/nfs_common/nfslocalio.c b/fs/nfs_common/nfslocalio.c index a74ec08f6c96..904439e4bb85 100644 --- a/fs/nfs_common/nfslocalio.c +++ b/fs/nfs_common/nfslocalio.c @@ -107,7 +107,7 @@ static void nfs_uuid_put_locked(nfs_uuid_t *nfs_uuid) list_del_init(&nfs_uuid->list); } -void nfs_uuid_invalidate_clients(struct list_head *list) +void nfs_localio_invalidate_clients(struct list_head *list) { nfs_uuid_t *nfs_uuid, *tmp; @@ -116,9 +116,9 @@ void nfs_uuid_invalidate_clients(struct list_head *list) nfs_uuid_put_locked(nfs_uuid); spin_unlock(&nfs_uuid_lock); } -EXPORT_SYMBOL_GPL(nfs_uuid_invalidate_clients); +EXPORT_SYMBOL_GPL(nfs_localio_invalidate_clients); -void nfs_uuid_invalidate_one_client(nfs_uuid_t *nfs_uuid) +void nfs_localio_disable_client(nfs_uuid_t *nfs_uuid) { if (nfs_uuid->net) { spin_lock(&nfs_uuid_lock); @@ -126,7 +126,7 @@ void nfs_uuid_invalidate_one_client(nfs_uuid_t *nfs_uuid) spin_unlock(&nfs_uuid_lock); } } -EXPORT_SYMBOL_GPL(nfs_uuid_invalidate_one_client); +EXPORT_SYMBOL_GPL(nfs_localio_disable_client); struct nfsd_file *nfs_open_local_fh(nfs_uuid_t *uuid, struct rpc_clnt *rpc_clnt, const struct cred *cred, diff --git a/fs/nfsd/nfsctl.c b/fs/nfsd/nfsctl.c index 3adbc05ebaac..727904d8a4d0 100644 --- a/fs/nfsd/nfsctl.c +++ b/fs/nfsd/nfsctl.c @@ -2276,14 +2276,14 @@ static __net_init int nfsd_net_init(struct net *net) * nfsd_net_pre_exit - Disconnect localio clients from net namespace * @net: a network namespace that is about to be destroyed * - * This invalidated ->net pointers held by localio clients + * This invalidates ->net pointers held by localio clients * while they can still safely access nn->counter. */ static __net_exit void nfsd_net_pre_exit(struct net *net) { struct nfsd_net *nn = net_generic(net, nfsd_net_id); - nfs_uuid_invalidate_clients(&nn->local_clients); + nfs_localio_invalidate_clients(&nn->local_clients); } #endif diff --git a/include/linux/nfslocalio.h b/include/linux/nfslocalio.h index ab6a2a53f505..a05d1043f2b0 100644 --- a/include/linux/nfslocalio.h +++ b/include/linux/nfslocalio.h @@ -37,8 +37,9 @@ bool nfs_uuid_begin(nfs_uuid_t *); void nfs_uuid_end(nfs_uuid_t *); void nfs_uuid_is_local(const uuid_t *, struct list_head *, struct net *, struct auth_domain *, struct module *); -void nfs_uuid_invalidate_clients(struct list_head *list); -void nfs_uuid_invalidate_one_client(nfs_uuid_t *nfs_uuid); + +void nfs_localio_disable_client(nfs_uuid_t *nfs_uuid); +void nfs_localio_invalidate_clients(struct list_head *list); /* localio needs to map filehandle -> struct nfsd_file */ extern struct nfsd_file * From patchwork Fri Nov 8 23:39:53 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mike Snitzer X-Patchwork-Id: 13869050 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 3D7B4610D for ; Fri, 8 Nov 2024 23:40:17 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1731109218; cv=none; b=i7qXrDnfE9HrbsdVVEfQ5DbONg+EgahQbeBA8EzhqfyrxYvf+AiCQ3qYZPk2z9vRwQC8PvcTzlcwI94R8UzfTK4jcV8JSDuKBrZrae9WOHLvQ/3XOgjunPe8iUennhqlo3KUZ+2mPMNFIdtpGKucwx+KnNGA/Iyv+OglCOFd4ls= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1731109218; c=relaxed/simple; bh=4M0Eys7VcHvPWAGYLi5wd5QcD99fOfKAkg5m2yCcTvM=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=uEXS7FBJBwp6I/dkIdURTJiysD+rNgosSzzCYVK3USkC8vX2Fm9R0sM3JhQ+teDZAwZS0z++J/I/2b8NucEOSAy0hNjX7aj3zAsE/DjWujxBWmx/gI6qa/6jsGY9seN9hdBcvu6cPbeSuTpHgo7hrEmjdHqWdfj1TUh8xiGQv0g= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=n2JkHtPk; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="n2JkHtPk" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 8EC61C4CECE; Fri, 8 Nov 2024 23:40:17 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1731109217; bh=4M0Eys7VcHvPWAGYLi5wd5QcD99fOfKAkg5m2yCcTvM=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=n2JkHtPkiSq8xtVVvFyf6guQBuz7aKzJJTsGknKZki6pv/DHHXPAggrBqbHMgq6eW rUoGI2Z2MLBD2RuGCcsMaFXyi/aSNNAuYQ1fYvK4k9v+nymSOK7tg1VpdEbKuXvU+k enTApImVLxHRl3BW5kkCxx11dP5ctGLA8VEZAqmTL+CbiBmK6It2krLrH1o81jsoFi 1raAjfE9ZQAbqEWz804I/5QqthzNSlMqK7xiOZMSZHyn/7ayi4Nfoh8SjjXIanIYHv AvsiDFuyWoje4I15Id3YLDG5of/uoFmATi4sMhasmiUS1KTM1roebzA9JeJg+m7shk ClsVDZxRVR/gA== From: Mike Snitzer To: linux-nfs@vger.kernel.org Cc: Anna Schumaker , Trond Myklebust , Chuck Lever , Jeff Layton , NeilBrown Subject: [for-6.13 PATCH 10/19] nfs_common: move localio_lock to new lock member of nfs_uuid_t Date: Fri, 8 Nov 2024 18:39:53 -0500 Message-ID: <20241108234002.16392-11-snitzer@kernel.org> X-Mailer: git-send-email 2.44.0 In-Reply-To: <20241108234002.16392-1-snitzer@kernel.org> References: <20241108234002.16392-1-snitzer@kernel.org> Precedence: bulk X-Mailing-List: linux-nfs@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Remove cl_localio_lock from 'struct nfs_client' in favor of adding a lock to the nfs_uuid_t struct (which is embedded in each nfs_client). Push nfs_local_{enable,disable} implementation down to nfs_common. Those methods now call nfs_localio_{enable,disable}_client. This allows implementing nfs_localio_invalidate_clients in terms of nfs_localio_disable_client. Signed-off-by: Mike Snitzer --- fs/nfs/client.c | 1 - fs/nfs/localio.c | 18 ++++++------ fs/nfs_common/nfslocalio.c | 57 ++++++++++++++++++++++++++------------ include/linux/nfs_fs_sb.h | 1 - include/linux/nfslocalio.h | 8 +++++- 5 files changed, 55 insertions(+), 30 deletions(-) diff --git a/fs/nfs/client.c b/fs/nfs/client.c index 03ecc7765615..124232054807 100644 --- a/fs/nfs/client.c +++ b/fs/nfs/client.c @@ -182,7 +182,6 @@ struct nfs_client *nfs_alloc_client(const struct nfs_client_initdata *cl_init) seqlock_init(&clp->cl_boot_lock); ktime_get_real_ts64(&clp->cl_nfssvc_boot); nfs_uuid_init(&clp->cl_uuid); - spin_lock_init(&clp->cl_localio_lock); #endif /* CONFIG_NFS_LOCALIO */ clp->cl_principal = "*"; diff --git a/fs/nfs/localio.c b/fs/nfs/localio.c index cab2a8819259..4c75ffc5efa2 100644 --- a/fs/nfs/localio.c +++ b/fs/nfs/localio.c @@ -125,10 +125,8 @@ const struct rpc_program nfslocalio_program = { */ static void nfs_local_enable(struct nfs_client *clp) { - spin_lock(&clp->cl_localio_lock); - set_bit(NFS_CS_LOCAL_IO, &clp->cl_flags); trace_nfs_local_enable(clp); - spin_unlock(&clp->cl_localio_lock); + nfs_localio_enable_client(clp); } /* @@ -136,12 +134,8 @@ static void nfs_local_enable(struct nfs_client *clp) */ void nfs_local_disable(struct nfs_client *clp) { - spin_lock(&clp->cl_localio_lock); - if (test_and_clear_bit(NFS_CS_LOCAL_IO, &clp->cl_flags)) { - trace_nfs_local_disable(clp); - nfs_localio_disable_client(&clp->cl_uuid); - } - spin_unlock(&clp->cl_localio_lock); + trace_nfs_local_disable(clp); + nfs_localio_disable_client(clp); } /* @@ -183,8 +177,12 @@ static bool nfs_server_uuid_is_local(struct nfs_client *clp) rpc_shutdown_client(rpcclient_localio); /* Server is only local if it initialized required struct members */ - if (status || !clp->cl_uuid.net || !clp->cl_uuid.dom) + rcu_read_lock(); + if (status || !rcu_access_pointer(clp->cl_uuid.net) || !clp->cl_uuid.dom) { + rcu_read_unlock(); return false; + } + rcu_read_unlock(); return true; } diff --git a/fs/nfs_common/nfslocalio.c b/fs/nfs_common/nfslocalio.c index 904439e4bb85..cf2f47ea4f8d 100644 --- a/fs/nfs_common/nfslocalio.c +++ b/fs/nfs_common/nfslocalio.c @@ -7,6 +7,9 @@ #include #include #include +#include +#include +#include #include MODULE_LICENSE("GPL"); @@ -25,6 +28,7 @@ void nfs_uuid_init(nfs_uuid_t *nfs_uuid) nfs_uuid->net = NULL; nfs_uuid->dom = NULL; INIT_LIST_HEAD(&nfs_uuid->list); + spin_lock_init(&nfs_uuid->lock); } EXPORT_SYMBOL_GPL(nfs_uuid_init); @@ -94,12 +98,23 @@ void nfs_uuid_is_local(const uuid_t *uuid, struct list_head *list, } EXPORT_SYMBOL_GPL(nfs_uuid_is_local); +void nfs_localio_enable_client(struct nfs_client *clp) +{ + nfs_uuid_t *nfs_uuid = &clp->cl_uuid; + + spin_lock(&nfs_uuid->lock); + set_bit(NFS_CS_LOCAL_IO, &clp->cl_flags); + spin_unlock(&nfs_uuid->lock); +} +EXPORT_SYMBOL_GPL(nfs_localio_enable_client); + static void nfs_uuid_put_locked(nfs_uuid_t *nfs_uuid) { - if (nfs_uuid->net) { - module_put(nfsd_mod); - nfs_uuid->net = NULL; - } + if (!nfs_uuid->net) + return; + module_put(nfsd_mod); + rcu_assign_pointer(nfs_uuid->net, NULL); + if (nfs_uuid->dom) { auth_domain_put(nfs_uuid->dom); nfs_uuid->dom = NULL; @@ -107,27 +122,35 @@ static void nfs_uuid_put_locked(nfs_uuid_t *nfs_uuid) list_del_init(&nfs_uuid->list); } -void nfs_localio_invalidate_clients(struct list_head *list) +void nfs_localio_disable_client(struct nfs_client *clp) +{ + nfs_uuid_t *nfs_uuid = &clp->cl_uuid; + + spin_lock(&nfs_uuid->lock); + if (test_and_clear_bit(NFS_CS_LOCAL_IO, &clp->cl_flags)) { + spin_lock(&nfs_uuid_lock); + nfs_uuid_put_locked(nfs_uuid); + spin_unlock(&nfs_uuid_lock); + } + spin_unlock(&nfs_uuid->lock); +} +EXPORT_SYMBOL_GPL(nfs_localio_disable_client); + +void nfs_localio_invalidate_clients(struct list_head *cl_uuid_list) { nfs_uuid_t *nfs_uuid, *tmp; spin_lock(&nfs_uuid_lock); - list_for_each_entry_safe(nfs_uuid, tmp, list, list) - nfs_uuid_put_locked(nfs_uuid); + list_for_each_entry_safe(nfs_uuid, tmp, cl_uuid_list, list) { + struct nfs_client *clp = + container_of(nfs_uuid, struct nfs_client, cl_uuid); + + nfs_localio_disable_client(clp); + } spin_unlock(&nfs_uuid_lock); } EXPORT_SYMBOL_GPL(nfs_localio_invalidate_clients); -void nfs_localio_disable_client(nfs_uuid_t *nfs_uuid) -{ - if (nfs_uuid->net) { - spin_lock(&nfs_uuid_lock); - nfs_uuid_put_locked(nfs_uuid); - spin_unlock(&nfs_uuid_lock); - } -} -EXPORT_SYMBOL_GPL(nfs_localio_disable_client); - struct nfsd_file *nfs_open_local_fh(nfs_uuid_t *uuid, struct rpc_clnt *rpc_clnt, const struct cred *cred, const struct nfs_fh *nfs_fh, const fmode_t fmode) diff --git a/include/linux/nfs_fs_sb.h b/include/linux/nfs_fs_sb.h index b804346a9741..239d86ef166c 100644 --- a/include/linux/nfs_fs_sb.h +++ b/include/linux/nfs_fs_sb.h @@ -132,7 +132,6 @@ struct nfs_client { struct timespec64 cl_nfssvc_boot; seqlock_t cl_boot_lock; nfs_uuid_t cl_uuid; - spinlock_t cl_localio_lock; #endif /* CONFIG_NFS_LOCALIO */ }; diff --git a/include/linux/nfslocalio.h b/include/linux/nfslocalio.h index a05d1043f2b0..4d5583873f41 100644 --- a/include/linux/nfslocalio.h +++ b/include/linux/nfslocalio.h @@ -6,6 +6,7 @@ #ifndef __LINUX_NFSLOCALIO_H #define __LINUX_NFSLOCALIO_H + /* nfsd_file structure is purposely kept opaque to NFS client */ struct nfsd_file; @@ -19,6 +20,8 @@ struct nfsd_file; #include #include +struct nfs_client; + /* * Useful to allow a client to negotiate if localio * possible with its server. @@ -27,6 +30,8 @@ struct nfsd_file; */ typedef struct { uuid_t uuid; + /* sadly this struct is just over a cacheline, avoid bouncing */ + spinlock_t ____cacheline_aligned lock; struct list_head list; struct net __rcu *net; /* nfsd's network namespace */ struct auth_domain *dom; /* auth_domain for localio */ @@ -38,7 +43,8 @@ void nfs_uuid_end(nfs_uuid_t *); void nfs_uuid_is_local(const uuid_t *, struct list_head *, struct net *, struct auth_domain *, struct module *); -void nfs_localio_disable_client(nfs_uuid_t *nfs_uuid); +void nfs_localio_enable_client(struct nfs_client *clp); +void nfs_localio_disable_client(struct nfs_client *clp); void nfs_localio_invalidate_clients(struct list_head *list); /* localio needs to map filehandle -> struct nfsd_file */ From patchwork Fri Nov 8 23:39:54 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mike Snitzer X-Patchwork-Id: 13869051 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 33FB5610D for ; Fri, 8 Nov 2024 23:40:19 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1731109219; cv=none; b=IKoOIUN/rG14ACFBN9pU3dZxO9i9U0ithaV7hdPQSEKlwUx/62u24QiPgBUt7f/rp1fELYzCGtYnD8wxjcw2vhsHje8YG0MTfLcwEOgjGyJoZmJRw08iMUrDGSLD8xm0gjvUJkfwjHSRSUMykgZLbEK2XPaDptq5BNBFTODMuaA= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1731109219; c=relaxed/simple; bh=oUPZ+eI0ubYRl6T/HkBJD/KJBXOCJbUamsOVEfdrxq8=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=SDPsZ8QOEKSaCRYXftJPIR84avaUaodMroLPGhr50nl2QcaJL7ed+mhH+j6906Xfwu1nkb68RA+UHBFNiRsXDGqEw/LcyWjXfcimcyM0IY9IOyb0hEVvzDYHn93wusz4aNWUvQb6iZxGY9cOduF6UT2O85aNZcNsCjZRmUXAH38= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=KBXOaMhb; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="KBXOaMhb" Received: by smtp.kernel.org (Postfix) with ESMTPSA id D337DC4CED2; Fri, 8 Nov 2024 23:40:18 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1731109219; bh=oUPZ+eI0ubYRl6T/HkBJD/KJBXOCJbUamsOVEfdrxq8=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=KBXOaMhbxFJ4adJxBjqDhIhBBkz5aWIqryII5NhP0fy2kbhTtNdd1cUl5TWVs3Pj2 YcNkdfouXScrul4HeG2vAyZtH7C4kEiHwJdE7uGpAfwVb9Rfm/Q5+/GwJ4OEz9zMmh BBdZSSS3sO02LsJnIR2lSTwQjnNKZpe3D6HA5h2SEZe/bR9FJ9xKNSD3UD/I5ccsKZ 0NUBmKGMDXrbVJgb9ZfpzeO18CBjRcvZA5NbqkH+og6qiuf1ajCKzdQLxFp/B2Txr6 ZJSENr/5huf5na0IXmdsX0R/kNSXbKLGwF+tITgGjfR/4MRBMQw0srd2/tj5D+BLa0 xMiLCZq5tl78g== From: Mike Snitzer To: linux-nfs@vger.kernel.org Cc: Anna Schumaker , Trond Myklebust , Chuck Lever , Jeff Layton , NeilBrown Subject: [for-6.13 PATCH 11/19] nfs: cache all open LOCALIO nfsd_file(s) in client Date: Fri, 8 Nov 2024 18:39:54 -0500 Message-ID: <20241108234002.16392-12-snitzer@kernel.org> X-Mailer: git-send-email 2.44.0 In-Reply-To: <20241108234002.16392-1-snitzer@kernel.org> References: <20241108234002.16392-1-snitzer@kernel.org> Precedence: bulk X-Mailing-List: linux-nfs@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 This commit switches from leaning heavily on NFSD's filecache (in terms of GC'd nfsd_files) back to caching nfsd_files in the client. A later commit will add the callback mechanism needed to allow NFSD to force the NFS client to cleanup all caches files. Add nfs_fh_localio_init() and 'struct nfs_fh_localio' to cache opened nfsd_file(s) (both a RO and RW nfsd_file is able to be opened and cached for a given nfs_fh). Update nfs_local_open_fh() to cache the nfsd_file once it is opened using __nfs_local_open_fh(). Introduce nfs_close_local_fh() to clear the cached open nfsd_files and call nfs_to_nfsd_file_put_local(). Refcounting is such that: - nfs_local_open_fh() is paired with nfs_close_local_fh(). - __nfs_local_open_fh() is paired with nfs_to_nfsd_file_put_local(). - nfs_local_file_get() is paired with nfs_local_file_put(). Signed-off-by: Mike Snitzer --- fs/nfs/flexfilelayout/flexfilelayout.c | 29 +++++---- fs/nfs/flexfilelayout/flexfilelayout.h | 1 + fs/nfs/inode.c | 3 + fs/nfs/internal.h | 4 +- fs/nfs/localio.c | 89 +++++++++++++++++++++----- fs/nfs/pagelist.c | 5 +- fs/nfs/write.c | 3 +- fs/nfs_common/nfslocalio.c | 52 ++++++++++++++- include/linux/nfs_fs.h | 22 ++++++- include/linux/nfslocalio.h | 18 +++--- 10 files changed, 181 insertions(+), 45 deletions(-) diff --git a/fs/nfs/flexfilelayout/flexfilelayout.c b/fs/nfs/flexfilelayout/flexfilelayout.c index f78115c6c2c1..451f168d882b 100644 --- a/fs/nfs/flexfilelayout/flexfilelayout.c +++ b/fs/nfs/flexfilelayout/flexfilelayout.c @@ -164,18 +164,17 @@ decode_name(struct xdr_stream *xdr, u32 *id) } static struct nfsd_file * -ff_local_open_fh(struct nfs_client *clp, const struct cred *cred, +ff_local_open_fh(struct pnfs_layout_segment *lseg, u32 ds_idx, + struct nfs_client *clp, const struct cred *cred, struct nfs_fh *fh, fmode_t mode) { - if (mode & FMODE_WRITE) { - /* - * Always request read and write access since this corresponds - * to a rw layout. - */ - mode |= FMODE_READ; - } +#if IS_ENABLED(CONFIG_NFS_LOCALIO) + struct nfs4_ff_layout_mirror *mirror = FF_LAYOUT_COMP(lseg, ds_idx); - return nfs_local_open_fh(clp, cred, fh, mode); + return nfs_local_open_fh(clp, cred, fh, &mirror->nfl, mode); +#else + return NULL; +#endif } static bool ff_mirror_match_fh(const struct nfs4_ff_layout_mirror *m1, @@ -247,6 +246,9 @@ static struct nfs4_ff_layout_mirror *ff_layout_alloc_mirror(gfp_t gfp_flags) spin_lock_init(&mirror->lock); refcount_set(&mirror->ref, 1); INIT_LIST_HEAD(&mirror->mirrors); +#if IS_ENABLED(CONFIG_NFS_LOCALIO) + nfs_localio_file_init(&mirror->nfl); +#endif } return mirror; } @@ -257,6 +259,9 @@ static void ff_layout_free_mirror(struct nfs4_ff_layout_mirror *mirror) ff_layout_remove_mirror(mirror); kfree(mirror->fh_versions); +#if IS_ENABLED(CONFIG_NFS_LOCALIO) + nfs_close_local_fh(&mirror->nfl); +#endif cred = rcu_access_pointer(mirror->ro_cred); put_cred(cred); cred = rcu_access_pointer(mirror->rw_cred); @@ -1820,7 +1825,7 @@ ff_layout_read_pagelist(struct nfs_pgio_header *hdr) hdr->mds_offset = offset; /* Start IO accounting for local read */ - localio = ff_local_open_fh(ds->ds_clp, ds_cred, fh, FMODE_READ); + localio = ff_local_open_fh(lseg, idx, ds->ds_clp, ds_cred, fh, FMODE_READ); if (localio) { hdr->task.tk_start = ktime_get(); ff_layout_read_record_layoutstats_start(&hdr->task, hdr); @@ -1896,7 +1901,7 @@ ff_layout_write_pagelist(struct nfs_pgio_header *hdr, int sync) hdr->args.offset = offset; /* Start IO accounting for local write */ - localio = ff_local_open_fh(ds->ds_clp, ds_cred, fh, + localio = ff_local_open_fh(lseg, idx, ds->ds_clp, ds_cred, fh, FMODE_READ|FMODE_WRITE); if (localio) { hdr->task.tk_start = ktime_get(); @@ -1981,7 +1986,7 @@ static int ff_layout_initiate_commit(struct nfs_commit_data *data, int how) data->args.fh = fh; /* Start IO accounting for local commit */ - localio = ff_local_open_fh(ds->ds_clp, ds_cred, fh, + localio = ff_local_open_fh(lseg, idx, ds->ds_clp, ds_cred, fh, FMODE_READ|FMODE_WRITE); if (localio) { data->task.tk_start = ktime_get(); diff --git a/fs/nfs/flexfilelayout/flexfilelayout.h b/fs/nfs/flexfilelayout/flexfilelayout.h index f84b3fb0dddd..095df09017a5 100644 --- a/fs/nfs/flexfilelayout/flexfilelayout.h +++ b/fs/nfs/flexfilelayout/flexfilelayout.h @@ -83,6 +83,7 @@ struct nfs4_ff_layout_mirror { nfs4_stateid stateid; const struct cred __rcu *ro_cred; const struct cred __rcu *rw_cred; + struct nfs_file_localio nfl; refcount_t ref; spinlock_t lock; unsigned long flags; diff --git a/fs/nfs/inode.c b/fs/nfs/inode.c index 596f35170137..1aa67fca69b2 100644 --- a/fs/nfs/inode.c +++ b/fs/nfs/inode.c @@ -1137,6 +1137,8 @@ struct nfs_open_context *alloc_nfs_open_context(struct dentry *dentry, ctx->lock_context.open_context = ctx; INIT_LIST_HEAD(&ctx->list); ctx->mdsthreshold = NULL; + nfs_localio_file_init(&ctx->nfl); + return ctx; } EXPORT_SYMBOL_GPL(alloc_nfs_open_context); @@ -1168,6 +1170,7 @@ static void __put_nfs_open_context(struct nfs_open_context *ctx, int is_sync) nfs_sb_deactive(sb); put_rpccred(rcu_dereference_protected(ctx->ll_cred, 1)); kfree(ctx->mdsthreshold); + nfs_close_local_fh(&ctx->nfl); kfree_rcu(ctx, rcu_head); } diff --git a/fs/nfs/internal.h b/fs/nfs/internal.h index 430733e3eff2..57af3ab3adbe 100644 --- a/fs/nfs/internal.h +++ b/fs/nfs/internal.h @@ -459,6 +459,7 @@ extern void nfs_local_probe(struct nfs_client *); extern struct nfsd_file *nfs_local_open_fh(struct nfs_client *, const struct cred *, struct nfs_fh *, + struct nfs_file_localio *, const fmode_t); extern int nfs_local_doio(struct nfs_client *, struct nfsd_file *, @@ -474,7 +475,8 @@ static inline void nfs_local_disable(struct nfs_client *clp) {} static inline void nfs_local_probe(struct nfs_client *clp) {} static inline struct nfsd_file * nfs_local_open_fh(struct nfs_client *clp, const struct cred *cred, - struct nfs_fh *fh, const fmode_t mode) + struct nfs_fh *fh, struct nfs_file_localio *nfl, + const fmode_t mode) { return NULL; } diff --git a/fs/nfs/localio.c b/fs/nfs/localio.c index 4c75ffc5efa2..d10d863aaf23 100644 --- a/fs/nfs/localio.c +++ b/fs/nfs/localio.c @@ -214,27 +214,33 @@ void nfs_local_probe(struct nfs_client *clp) } EXPORT_SYMBOL_GPL(nfs_local_probe); +static inline struct nfsd_file *nfs_local_file_get(struct nfsd_file *nf) +{ + return nfs_to->nfsd_file_get(nf); +} + +static inline void nfs_local_file_put(struct nfsd_file *nf) +{ + nfs_to->nfsd_file_put(nf); +} + /* - * nfs_local_open_fh - open a local filehandle in terms of nfsd_file + * __nfs_local_open_fh - open a local filehandle in terms of nfsd_file. * - * Returns a pointer to a struct nfsd_file or NULL + * Returns a pointer to a struct nfsd_file or ERR_PTR. + * Caller must release returned nfsd_file with nfs_to_nfsd_file_put_local(). */ -struct nfsd_file * -nfs_local_open_fh(struct nfs_client *clp, const struct cred *cred, - struct nfs_fh *fh, const fmode_t mode) +static struct nfsd_file * +__nfs_local_open_fh(struct nfs_client *clp, const struct cred *cred, + struct nfs_fh *fh, struct nfs_file_localio *nfl, + const fmode_t mode) { struct nfsd_file *localio; - int status; - - if (!nfs_server_is_local(clp)) - return NULL; - if (mode & ~(FMODE_READ | FMODE_WRITE)) - return NULL; localio = nfs_open_local_fh(&clp->cl_uuid, clp->cl_rpcclient, - cred, fh, mode); + cred, fh, nfl, mode); if (IS_ERR(localio)) { - status = PTR_ERR(localio); + int status = PTR_ERR(localio); trace_nfs_local_open_fh(fh, mode, status); switch (status) { case -ENOMEM: @@ -243,10 +249,59 @@ nfs_local_open_fh(struct nfs_client *clp, const struct cred *cred, /* Revalidate localio, will disable if unsupported */ nfs_local_probe(clp); } - return NULL; } return localio; } + +/* + * nfs_local_open_fh - open a local filehandle in terms of nfsd_file. + * First checking if the open nfsd_file is already cached, otherwise + * must __nfs_local_open_fh and insert the nfsd_file in nfs_file_localio. + * + * Returns a pointer to a struct nfsd_file or NULL. + */ +struct nfsd_file * +nfs_local_open_fh(struct nfs_client *clp, const struct cred *cred, + struct nfs_fh *fh, struct nfs_file_localio *nfl, + const fmode_t mode) +{ + struct nfsd_file *nf, *new, __rcu **pnf; + + if (!nfs_server_is_local(clp)) + return NULL; + if (mode & ~(FMODE_READ | FMODE_WRITE)) + return NULL; + + if (mode & FMODE_WRITE) + pnf = &nfl->rw_file; + else + pnf = &nfl->ro_file; + + new = NULL; + rcu_read_lock(); + nf = rcu_dereference(*pnf); + if (!nf) { + rcu_read_unlock(); + new = __nfs_local_open_fh(clp, cred, fh, nfl, mode); + if (IS_ERR(new)) + return NULL; + /* try to swap in the pointer */ + spin_lock(&clp->cl_uuid.lock); + nf = rcu_dereference_protected(*pnf, 1); + if (!nf) { + nf = new; + new = NULL; + rcu_assign_pointer(*pnf, nf); + } + spin_unlock(&clp->cl_uuid.lock); + rcu_read_lock(); + } + nf = nfs_local_file_get(nf); + rcu_read_unlock(); + if (new) + nfs_to_nfsd_file_put_local(new); + return nf; +} EXPORT_SYMBOL_GPL(nfs_local_open_fh); static struct bio_vec * @@ -350,7 +405,7 @@ nfs_local_pgio_release(struct nfs_local_kiocb *iocb) { struct nfs_pgio_header *hdr = iocb->hdr; - nfs_to_nfsd_file_put_local(iocb->localio); + nfs_local_file_put(iocb->localio); nfs_local_iocb_free(iocb); nfs_local_hdr_release(hdr, hdr->task.tk_ops); } @@ -697,7 +752,7 @@ int nfs_local_doio(struct nfs_client *clp, struct nfsd_file *localio, if (status != 0) { if (status == -EAGAIN) nfs_local_disable(clp); - nfs_to_nfsd_file_put_local(localio); + nfs_local_file_put(localio); hdr->task.tk_status = status; nfs_local_hdr_release(hdr, call_ops); } @@ -748,7 +803,7 @@ nfs_local_release_commit_data(struct nfsd_file *localio, struct nfs_commit_data *data, const struct rpc_call_ops *call_ops) { - nfs_to_nfsd_file_put_local(localio); + nfs_local_file_put(localio); call_ops->rpc_call_done(&data->task, data); call_ops->rpc_release(data); } diff --git a/fs/nfs/pagelist.c b/fs/nfs/pagelist.c index e27c07bd8929..11968dcb7243 100644 --- a/fs/nfs/pagelist.c +++ b/fs/nfs/pagelist.c @@ -961,8 +961,9 @@ static int nfs_generic_pg_pgios(struct nfs_pageio_descriptor *desc) struct nfs_client *clp = NFS_SERVER(hdr->inode)->nfs_client; struct nfsd_file *localio = - nfs_local_open_fh(clp, hdr->cred, - hdr->args.fh, hdr->args.context->mode); + nfs_local_open_fh(clp, hdr->cred, hdr->args.fh, + &hdr->args.context->nfl, + hdr->args.context->mode); if (NFS_SERVER(hdr->inode)->nfs_client->cl_minorversion) task_flags = RPC_TASK_MOVEABLE; diff --git a/fs/nfs/write.c b/fs/nfs/write.c index ead2dc55952d..8d4dbb69b7c0 100644 --- a/fs/nfs/write.c +++ b/fs/nfs/write.c @@ -1815,7 +1815,8 @@ nfs_commit_list(struct inode *inode, struct list_head *head, int how, task_flags = RPC_TASK_MOVEABLE; localio = nfs_local_open_fh(NFS_SERVER(inode)->nfs_client, data->cred, - data->args.fh, data->context->mode); + data->args.fh, &data->context->nfl, + data->context->mode); return nfs_initiate_commit(NFS_CLIENT(inode), data, NFS_PROTO(inode), data->mds_ops, how, RPC_TASK_CRED_NOREF | task_flags, localio); diff --git a/fs/nfs_common/nfslocalio.c b/fs/nfs_common/nfslocalio.c index cf2f47ea4f8d..345f3c55aa9c 100644 --- a/fs/nfs_common/nfslocalio.c +++ b/fs/nfs_common/nfslocalio.c @@ -9,7 +9,7 @@ #include #include #include -#include +#include #include MODULE_LICENSE("GPL"); @@ -151,9 +151,18 @@ void nfs_localio_invalidate_clients(struct list_head *cl_uuid_list) } EXPORT_SYMBOL_GPL(nfs_localio_invalidate_clients); +static void nfs_uuid_add_file(nfs_uuid_t *nfs_uuid, struct nfs_file_localio *nfl) +{ + spin_lock(&nfs_uuid_lock); + if (!nfl->nfs_uuid) + rcu_assign_pointer(nfl->nfs_uuid, nfs_uuid); + spin_unlock(&nfs_uuid_lock); +} + struct nfsd_file *nfs_open_local_fh(nfs_uuid_t *uuid, struct rpc_clnt *rpc_clnt, const struct cred *cred, - const struct nfs_fh *nfs_fh, const fmode_t fmode) + const struct nfs_fh *nfs_fh, struct nfs_file_localio *nfl, + const fmode_t fmode) { struct net *net; struct nfsd_file *localio; @@ -180,11 +189,50 @@ struct nfsd_file *nfs_open_local_fh(nfs_uuid_t *uuid, cred, nfs_fh, fmode); if (IS_ERR(localio)) nfs_to_nfsd_net_put(net); + else + nfs_uuid_add_file(uuid, nfl); return localio; } EXPORT_SYMBOL_GPL(nfs_open_local_fh); +void nfs_close_local_fh(struct nfs_file_localio *nfl) +{ + struct nfsd_file *ro_nf = NULL; + struct nfsd_file *rw_nf = NULL; + nfs_uuid_t *nfs_uuid; + + rcu_read_lock(); + nfs_uuid = rcu_dereference(nfl->nfs_uuid); + if (!nfs_uuid) { + /* regular (non-LOCALIO) NFS will hammer this */ + rcu_read_unlock(); + return; + } + + ro_nf = rcu_access_pointer(nfl->ro_file); + rw_nf = rcu_access_pointer(nfl->rw_file); + if (ro_nf || rw_nf) { + spin_lock(&nfs_uuid_lock); + if (ro_nf) + ro_nf = rcu_dereference_protected(xchg(&nfl->ro_file, NULL), 1); + if (rw_nf) + rw_nf = rcu_dereference_protected(xchg(&nfl->rw_file, NULL), 1); + + rcu_assign_pointer(nfl->nfs_uuid, NULL); + spin_unlock(&nfs_uuid_lock); + rcu_read_unlock(); + + if (ro_nf) + nfs_to_nfsd_file_put_local(ro_nf); + if (rw_nf) + nfs_to_nfsd_file_put_local(rw_nf); + return; + } + rcu_read_unlock(); +} +EXPORT_SYMBOL_GPL(nfs_close_local_fh); + /* * The NFS LOCALIO code needs to call into NFSD using various symbols, * but cannot be statically linked, because that will make the NFS diff --git a/include/linux/nfs_fs.h b/include/linux/nfs_fs.h index 039898d70954..67ae2c3f41d2 100644 --- a/include/linux/nfs_fs.h +++ b/include/linux/nfs_fs.h @@ -77,6 +77,23 @@ struct nfs_lock_context { struct rcu_head rcu_head; }; +struct nfs_file_localio { + struct nfsd_file __rcu *ro_file; + struct nfsd_file __rcu *rw_file; + struct list_head list; + void __rcu *nfs_uuid; /* opaque pointer to 'nfs_uuid_t' */ +}; + +static inline void nfs_localio_file_init(struct nfs_file_localio *nfl) +{ +#if IS_ENABLED(CONFIG_NFS_LOCALIO) + nfl->ro_file = NULL; + nfl->rw_file = NULL; + INIT_LIST_HEAD(&nfl->list); + nfl->nfs_uuid = NULL; +#endif +} + struct nfs4_state; struct nfs_open_context { struct nfs_lock_context lock_context; @@ -87,15 +104,16 @@ struct nfs_open_context { struct nfs4_state *state; fmode_t mode; + int error; unsigned long flags; #define NFS_CONTEXT_BAD (2) #define NFS_CONTEXT_UNLOCK (3) #define NFS_CONTEXT_FILE_OPEN (4) - int error; - struct list_head list; struct nfs4_threshold *mdsthreshold; + struct list_head list; struct rcu_head rcu_head; + struct nfs_file_localio nfl; }; struct nfs_open_dir_context { diff --git a/include/linux/nfslocalio.h b/include/linux/nfslocalio.h index 4d5583873f41..7cfc6720ed26 100644 --- a/include/linux/nfslocalio.h +++ b/include/linux/nfslocalio.h @@ -6,10 +6,6 @@ #ifndef __LINUX_NFSLOCALIO_H #define __LINUX_NFSLOCALIO_H - -/* nfsd_file structure is purposely kept opaque to NFS client */ -struct nfsd_file; - #if IS_ENABLED(CONFIG_NFS_LOCALIO) #include @@ -21,6 +17,7 @@ struct nfsd_file; #include struct nfs_client; +struct nfs_file_localio; /* * Useful to allow a client to negotiate if localio @@ -52,6 +49,7 @@ extern struct nfsd_file * nfsd_open_local_fh(struct net *, struct auth_domain *, struct rpc_clnt *, const struct cred *, const struct nfs_fh *, const fmode_t) __must_hold(rcu); +void nfs_close_local_fh(struct nfs_file_localio *); struct nfsd_localio_operations { bool (*nfsd_serv_try_get)(struct net *); @@ -73,7 +71,8 @@ extern const struct nfsd_localio_operations *nfs_to; struct nfsd_file *nfs_open_local_fh(nfs_uuid_t *, struct rpc_clnt *, const struct cred *, - const struct nfs_fh *, const fmode_t); + const struct nfs_fh *, struct nfs_file_localio *, + const fmode_t); static inline void nfs_to_nfsd_net_put(struct net *net) { @@ -100,12 +99,15 @@ static inline void nfs_to_nfsd_file_put_local(struct nfsd_file *localio) } #else /* CONFIG_NFS_LOCALIO */ + +struct nfs_file_localio; +static inline void nfs_close_local_fh(struct nfs_file_localio *nfl) +{ +} static inline void nfsd_localio_ops_init(void) { } -static inline void nfs_to_nfsd_file_put_local(struct nfsd_file *localio) -{ -} + #endif /* CONFIG_NFS_LOCALIO */ #endif /* __LINUX_NFSLOCALIO_H */ From patchwork Fri Nov 8 23:39:55 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mike Snitzer X-Patchwork-Id: 13869052 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 8DE918F54 for ; Fri, 8 Nov 2024 23:40:20 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1731109220; cv=none; b=f/QXJn4SRA4B77A/krmZJgjAqGgcZb265ApM14FRMykUir3ZgaQ+TB5kqPJAZ1LHmL+8Cv/kBRbFg4d1O3E4ehMAQbDaw5wrMrD8DrRN92sDErKxIJ9XxWjvS8sE6OvPCxytKmoyrUpSHZD8YWM7rWFzMaetOz0iJO41SSVPECc= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1731109220; c=relaxed/simple; bh=rS8Vb+2wUBiz+5WD6JzP4ncWfdtNJzKRa3JbIgo9h3A=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=gMTQduDjcFZhlX8LysqbZmblqqxawj6tbSfpJu53/b2g9UEh+d7ozq+ZM8Pf13n0nik2ybzRJG7AwTvSnmCTgIeeYNR0dgupBhiEgYBzvlcr0nGzjEZM9gXChjinFHyI4LGao+hhtG0rzTahBCpmCJb6VAukz+pVluagFqg4grs= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=uUgu1Rq3; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="uUgu1Rq3" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 3912CC4CECE; Fri, 8 Nov 2024 23:40:20 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1731109220; bh=rS8Vb+2wUBiz+5WD6JzP4ncWfdtNJzKRa3JbIgo9h3A=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=uUgu1Rq3Drig4eNb4Mzh1ZhwynYcoec3kHg1kpiRlzh9j+wj2BMwQxupH0NO562ch /5Uuj9ABXc0Dgmwi8VaWIs3gI/cF6KGU1vfXN/d/0xdTL/j+/raN+KPXuCIZjuS0VY vZdGxDNUdlKRTiNjJJaB0H02SSOGRuT07MNYt9Ne9bB60+Kch7V7Xzo/8ZeUWblpCy WuMW7hb2d3BAuIBagw/celBpV7ieN9HA6Pb/IiZAzbbzhDfsfjv6VDg3CRlJtRTiW/ 4n4w7e/sSqRDdZ3D4BvnNiPoi2Z11EeDQPzdwzJ5h8mLpV6RPzKxGhsxi7FWD4JtTu 8WlXQPD8KTJsw== From: Mike Snitzer To: linux-nfs@vger.kernel.org Cc: Anna Schumaker , Trond Myklebust , Chuck Lever , Jeff Layton , NeilBrown Subject: [for-6.13 PATCH 12/19] nfsd: update percpu_ref to manage references on nfsd_net Date: Fri, 8 Nov 2024 18:39:55 -0500 Message-ID: <20241108234002.16392-13-snitzer@kernel.org> X-Mailer: git-send-email 2.44.0 In-Reply-To: <20241108234002.16392-1-snitzer@kernel.org> References: <20241108234002.16392-1-snitzer@kernel.org> Precedence: bulk X-Mailing-List: linux-nfs@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Holding a reference on nfsd_net is what is required, it was never actually about ensuring nn->nfsd_serv available. Move waiting for outstanding percpu references from nfsd_destroy_serv() to nfsd_shutdown_net(). By moving it later it will be possible to invalidate localio clients during nfsd_file_cache_shutdown_net() via __nfsd_file_cache_purge(). Signed-off-by: Mike Snitzer --- fs/nfsd/nfssvc.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/fs/nfsd/nfssvc.c b/fs/nfsd/nfssvc.c index 49e2f32102ab..6ca554042426 100644 --- a/fs/nfsd/nfssvc.c +++ b/fs/nfsd/nfssvc.c @@ -436,6 +436,10 @@ static void nfsd_shutdown_net(struct net *net) if (!nn->nfsd_net_up) return; + + percpu_ref_kill_and_confirm(&nn->nfsd_serv_ref, nfsd_serv_done); + wait_for_completion(&nn->nfsd_serv_confirm_done); + nfsd_export_flush(net); nfs4_state_shutdown_net(net); nfsd_reply_cache_shutdown(nn); @@ -444,7 +448,10 @@ static void nfsd_shutdown_net(struct net *net) lockd_down(net); nn->lockd_up = false; } + + wait_for_completion(&nn->nfsd_serv_free_done); percpu_ref_exit(&nn->nfsd_serv_ref); + nn->nfsd_net_up = false; nfsd_shutdown_generic(); } @@ -526,11 +533,6 @@ void nfsd_destroy_serv(struct net *net) lockdep_assert_held(&nfsd_mutex); - percpu_ref_kill_and_confirm(&nn->nfsd_serv_ref, nfsd_serv_done); - wait_for_completion(&nn->nfsd_serv_confirm_done); - wait_for_completion(&nn->nfsd_serv_free_done); - /* percpu_ref_exit is called in nfsd_shutdown_net */ - spin_lock(&nfsd_notifier_lock); nn->nfsd_serv = NULL; spin_unlock(&nfsd_notifier_lock); From patchwork Fri Nov 8 23:39:56 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mike Snitzer X-Patchwork-Id: 13869053 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 0347A1F26ED for ; Fri, 8 Nov 2024 23:40:21 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1731109222; cv=none; b=PI8iL9Nzr74Ke270O6BAA/qFv9046YKTgr59uTgsiu0ZAOzuGH30KvkcQaD0kyRRNszDhdyKTuoGX/cZimPMQtRSIKHAHxXNbY7OeKPXrExftHTVvxV7/wnx/HWH1HZD3WE8Z7jVGh6Y7NmkNl7HC/BJ+3S1SHGf1lo9pDH7nKo= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1731109222; c=relaxed/simple; bh=hoQvtBZFVvHGVly2EHdLwGYBy7K7knQB1FARaLwzztQ=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=BaQrZh0FbrL1sDRb5Kts5Qm1A01UlCwd0UjZrH+asMXhkddM/uw34ZI9+NBGMtWYyarW2BFCKc72Y0PQCZSIjIv4gJWstVcmOkjVbncQrzIjyi+x6hXyGX8Ei3bfERii4WE0T3VlNeTpOnDehtvTFxefM1aQk42A7tjfT+6WH8k= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=PLM1d6Ay; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="PLM1d6Ay" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 983FEC4CECE; Fri, 8 Nov 2024 23:40:21 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1731109221; bh=hoQvtBZFVvHGVly2EHdLwGYBy7K7knQB1FARaLwzztQ=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=PLM1d6AyO/ZppvX7w6LElZTVb74kgPP/Jsx+bxI9rmDXWfafVpqRfw0raAN7zeGdt AYun5hcaoZzXBYCbMzdIE+ISJVNnV4Xw1E++ckcHYDouSopey5yZn7FJ4+MsMkbQ9N S/IbD4XSKLuuvLQyxL9oYT6/TVy42P43m4ilU0YcBOyNKmpX03C6bgeMAoHgTqv2iB A7sHE0z3BuM62YGiDTd4MrSD8STQVtje6HNyeZTzTH0pyMvB1ViblthcXrpDjw51pa EnkcppTNwwkrLHwXRN/15LpsYjWhmAkdEoGpMNHcpM+xa4rktAf/5hkzxFrzV0Q+Ht 4XBpdty0nyhlw== From: Mike Snitzer To: linux-nfs@vger.kernel.org Cc: Anna Schumaker , Trond Myklebust , Chuck Lever , Jeff Layton , NeilBrown Subject: [for-6.13 PATCH 13/19] nfsd: rename nfsd_serv_ prefixed methods and variables with nfsd_net_ Date: Fri, 8 Nov 2024 18:39:56 -0500 Message-ID: <20241108234002.16392-14-snitzer@kernel.org> X-Mailer: git-send-email 2.44.0 In-Reply-To: <20241108234002.16392-1-snitzer@kernel.org> References: <20241108234002.16392-1-snitzer@kernel.org> Precedence: bulk X-Mailing-List: linux-nfs@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Signed-off-by: Mike Snitzer --- fs/nfs_common/nfslocalio.c | 10 +++++++--- fs/nfsd/filecache.c | 2 +- fs/nfsd/localio.c | 4 ++-- fs/nfsd/netns.h | 11 ++++++----- fs/nfsd/nfssvc.c | 34 +++++++++++++++++----------------- include/linux/nfslocalio.h | 12 ++++++------ 6 files changed, 39 insertions(+), 34 deletions(-) diff --git a/fs/nfs_common/nfslocalio.c b/fs/nfs_common/nfslocalio.c index 345f3c55aa9c..0935bdcaa940 100644 --- a/fs/nfs_common/nfslocalio.c +++ b/fs/nfs_common/nfslocalio.c @@ -159,6 +159,10 @@ static void nfs_uuid_add_file(nfs_uuid_t *nfs_uuid, struct nfs_file_localio *nfl spin_unlock(&nfs_uuid_lock); } +/* + * Caller is responsible for calling nfsd_net_put and + * nfsd_file_put (via nfs_to_nfsd_file_put_local). + */ struct nfsd_file *nfs_open_local_fh(nfs_uuid_t *uuid, struct rpc_clnt *rpc_clnt, const struct cred *cred, const struct nfs_fh *nfs_fh, struct nfs_file_localio *nfl, @@ -171,7 +175,7 @@ struct nfsd_file *nfs_open_local_fh(nfs_uuid_t *uuid, * Not running in nfsd context, so must safely get reference on nfsd_serv. * But the server may already be shutting down, if so disallow new localio. * uuid->net is NOT a counted reference, but rcu_read_lock() ensures that - * if uuid->net is not NULL, then calling nfsd_serv_try_get() is safe + * if uuid->net is not NULL, then calling nfsd_net_try_get() is safe * and if it succeeds we will have an implied reference to the net. * * Otherwise NFS may not have ref on NFSD and therefore cannot safely @@ -179,12 +183,12 @@ struct nfsd_file *nfs_open_local_fh(nfs_uuid_t *uuid, */ rcu_read_lock(); net = rcu_dereference(uuid->net); - if (!net || !nfs_to->nfsd_serv_try_get(net)) { + if (!net || !nfs_to->nfsd_net_try_get(net)) { rcu_read_unlock(); return ERR_PTR(-ENXIO); } rcu_read_unlock(); - /* We have an implied reference to net thanks to nfsd_serv_try_get */ + /* We have an implied reference to net thanks to nfsd_net_try_get */ localio = nfs_to->nfsd_open_local_fh(net, uuid->dom, rpc_clnt, cred, nfs_fh, fmode); if (IS_ERR(localio)) diff --git a/fs/nfsd/filecache.c b/fs/nfsd/filecache.c index 9a62b4da89bb..fac98b2cb463 100644 --- a/fs/nfsd/filecache.c +++ b/fs/nfsd/filecache.c @@ -391,7 +391,7 @@ nfsd_file_put(struct nfsd_file *nf) } /** - * nfsd_file_put_local - put nfsd_file reference and arm nfsd_serv_put in caller + * nfsd_file_put_local - put nfsd_file reference and arm nfsd_net_put in caller * @nf: nfsd_file of which to put the reference * * First save the associated net to return to caller, then put diff --git a/fs/nfsd/localio.c b/fs/nfsd/localio.c index 8beda4c85111..f9a91cd3b5ec 100644 --- a/fs/nfsd/localio.c +++ b/fs/nfsd/localio.c @@ -25,8 +25,8 @@ #include "cache.h" static const struct nfsd_localio_operations nfsd_localio_ops = { - .nfsd_serv_try_get = nfsd_serv_try_get, - .nfsd_serv_put = nfsd_serv_put, + .nfsd_net_try_get = nfsd_net_try_get, + .nfsd_net_put = nfsd_net_put, .nfsd_open_local_fh = nfsd_open_local_fh, .nfsd_file_put_local = nfsd_file_put_local, .nfsd_file_get = nfsd_file_get, diff --git a/fs/nfsd/netns.h b/fs/nfsd/netns.h index 26f7b34d1a03..8faef59d7122 100644 --- a/fs/nfsd/netns.h +++ b/fs/nfsd/netns.h @@ -140,9 +140,10 @@ struct nfsd_net { struct svc_info nfsd_info; #define nfsd_serv nfsd_info.serv - struct percpu_ref nfsd_serv_ref; - struct completion nfsd_serv_confirm_done; - struct completion nfsd_serv_free_done; + + struct percpu_ref nfsd_net_ref; + struct completion nfsd_net_confirm_done; + struct completion nfsd_net_free_done; /* * clientid and stateid data for construction of net unique COPY @@ -229,8 +230,8 @@ struct nfsd_net { extern bool nfsd_support_version(int vers); extern unsigned int nfsd_net_id; -bool nfsd_serv_try_get(struct net *net); -void nfsd_serv_put(struct net *net); +bool nfsd_net_try_get(struct net *net); +void nfsd_net_put(struct net *net); void nfsd_copy_write_verifier(__be32 verf[2], struct nfsd_net *nn); void nfsd_reset_write_verifier(struct nfsd_net *nn); diff --git a/fs/nfsd/nfssvc.c b/fs/nfsd/nfssvc.c index 6ca554042426..e937e2d0ce62 100644 --- a/fs/nfsd/nfssvc.c +++ b/fs/nfsd/nfssvc.c @@ -214,32 +214,32 @@ int nfsd_minorversion(struct nfsd_net *nn, u32 minorversion, enum vers_op change return 0; } -bool nfsd_serv_try_get(struct net *net) __must_hold(rcu) +bool nfsd_net_try_get(struct net *net) __must_hold(rcu) { struct nfsd_net *nn = net_generic(net, nfsd_net_id); - return (nn && percpu_ref_tryget_live(&nn->nfsd_serv_ref)); + return (nn && percpu_ref_tryget_live(&nn->nfsd_net_ref)); } -void nfsd_serv_put(struct net *net) __must_hold(rcu) +void nfsd_net_put(struct net *net) __must_hold(rcu) { struct nfsd_net *nn = net_generic(net, nfsd_net_id); - percpu_ref_put(&nn->nfsd_serv_ref); + percpu_ref_put(&nn->nfsd_net_ref); } -static void nfsd_serv_done(struct percpu_ref *ref) +static void nfsd_net_done(struct percpu_ref *ref) { - struct nfsd_net *nn = container_of(ref, struct nfsd_net, nfsd_serv_ref); + struct nfsd_net *nn = container_of(ref, struct nfsd_net, nfsd_net_ref); - complete(&nn->nfsd_serv_confirm_done); + complete(&nn->nfsd_net_confirm_done); } -static void nfsd_serv_free(struct percpu_ref *ref) +static void nfsd_net_free(struct percpu_ref *ref) { - struct nfsd_net *nn = container_of(ref, struct nfsd_net, nfsd_serv_ref); + struct nfsd_net *nn = container_of(ref, struct nfsd_net, nfsd_net_ref); - complete(&nn->nfsd_serv_free_done); + complete(&nn->nfsd_net_free_done); } /* @@ -437,8 +437,8 @@ static void nfsd_shutdown_net(struct net *net) if (!nn->nfsd_net_up) return; - percpu_ref_kill_and_confirm(&nn->nfsd_serv_ref, nfsd_serv_done); - wait_for_completion(&nn->nfsd_serv_confirm_done); + percpu_ref_kill_and_confirm(&nn->nfsd_net_ref, nfsd_net_done); + wait_for_completion(&nn->nfsd_net_confirm_done); nfsd_export_flush(net); nfs4_state_shutdown_net(net); @@ -449,8 +449,8 @@ static void nfsd_shutdown_net(struct net *net) nn->lockd_up = false; } - wait_for_completion(&nn->nfsd_serv_free_done); - percpu_ref_exit(&nn->nfsd_serv_ref); + wait_for_completion(&nn->nfsd_net_free_done); + percpu_ref_exit(&nn->nfsd_net_ref); nn->nfsd_net_up = false; nfsd_shutdown_generic(); @@ -654,12 +654,12 @@ int nfsd_create_serv(struct net *net) if (nn->nfsd_serv) return 0; - error = percpu_ref_init(&nn->nfsd_serv_ref, nfsd_serv_free, + error = percpu_ref_init(&nn->nfsd_net_ref, nfsd_net_free, 0, GFP_KERNEL); if (error) return error; - init_completion(&nn->nfsd_serv_free_done); - init_completion(&nn->nfsd_serv_confirm_done); + init_completion(&nn->nfsd_net_free_done); + init_completion(&nn->nfsd_net_confirm_done); if (nfsd_max_blksize == 0) nfsd_max_blksize = nfsd_get_default_max_blksize(); diff --git a/include/linux/nfslocalio.h b/include/linux/nfslocalio.h index 7cfc6720ed26..aa2b5c6561ab 100644 --- a/include/linux/nfslocalio.h +++ b/include/linux/nfslocalio.h @@ -52,8 +52,8 @@ nfsd_open_local_fh(struct net *, struct auth_domain *, struct rpc_clnt *, void nfs_close_local_fh(struct nfs_file_localio *); struct nfsd_localio_operations { - bool (*nfsd_serv_try_get)(struct net *); - void (*nfsd_serv_put)(struct net *); + bool (*nfsd_net_try_get)(struct net *); + void (*nfsd_net_put)(struct net *); struct nfsd_file *(*nfsd_open_local_fh)(struct net *, struct auth_domain *, struct rpc_clnt *, @@ -77,12 +77,12 @@ struct nfsd_file *nfs_open_local_fh(nfs_uuid_t *, static inline void nfs_to_nfsd_net_put(struct net *net) { /* - * Once reference to nfsd_serv is dropped, NFSD could be - * unloaded, so ensure safe return from nfsd_file_put_local() - * by always taking RCU. + * Once reference to net (and associated nfsd_serv) is dropped, NFSD + * could be unloaded, so ensure safe return from nfsd_net_put() by + * always taking RCU. */ rcu_read_lock(); - nfs_to->nfsd_serv_put(net); + nfs_to->nfsd_net_put(net); rcu_read_unlock(); } From patchwork Fri Nov 8 23:39:57 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mike Snitzer X-Patchwork-Id: 13869054 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 45EC21F26C7 for ; Fri, 8 Nov 2024 23:40:23 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1731109223; cv=none; b=dYPv8wvewTyKDejP0xjy4OeJYPr6aTFdx84ilyCWIAii+5MvlBLKnVUyZzRXSbT02HI+dGk41HLyrSPi7Rkl7b8Suct2Y5gm5n8xS8G7hikXeVZA7wns9iNT8kAHVgT9FeXav7j84pmZF9p2jRHmLqlm9U90DnDj4UMqSYeKRmk= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1731109223; c=relaxed/simple; bh=fwqHCDnVEEiG1LcWsLeB504CZmExgi5cxZc9NR+RKg8=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=KMjj9t9bT+UKZ3UvN/kr0tKTV+9b8BvGX1QVq9RDNijvo7iTAUI9WJJMnhlFBCun8FO4lG6nXX1h/TXSBmRaC55apjOFYw29/FLRkAa42iSeqGWS9KIrBOFQ1H0zw2PjT4qrX19ZJERjv1P0Bx0ATX3gRAhWef4xrZw/ZVJLPp0= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=BHs5bGUu; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="BHs5bGUu" Received: by smtp.kernel.org (Postfix) with ESMTPSA id EA50FC4CECE; Fri, 8 Nov 2024 23:40:22 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1731109223; bh=fwqHCDnVEEiG1LcWsLeB504CZmExgi5cxZc9NR+RKg8=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=BHs5bGUuB+W7ex2F0n2EuTh8svESm3R8Y4AhHsMq/79tPT9g9UWBK738ekufYzwIy 617g4kVISefF4uVQcHn+BAH94Dz+4cjUO9X/tdQoNckRN3FmshMaKdyqHWHP4rFmqc W1ACSkMXGMnKD+PVsSDLW4iXedhchQMSI2mC70PvdYTF1wQ7vsOTalPmxvM23gNQ5j 5Dz134ng/Mp/e2CfrIPof3zZ54uf9TWbTVwlie2ZzrKQudQayWpqNPXauOGApoIEdu g88QnoH5bYIB+Er2ov3aoxbECkE7YMnUwZWGQMJyexdgreix+wQcPmm3HGI+NMOvCd uF0qpq6/gMCAg== From: Mike Snitzer To: linux-nfs@vger.kernel.org Cc: Anna Schumaker , Trond Myklebust , Chuck Lever , Jeff Layton , NeilBrown Subject: [for-6.13 PATCH 14/19] nfsd: nfsd_file_acquire_local no longer returns GC'd nfsd_file Date: Fri, 8 Nov 2024 18:39:57 -0500 Message-ID: <20241108234002.16392-15-snitzer@kernel.org> X-Mailer: git-send-email 2.44.0 In-Reply-To: <20241108234002.16392-1-snitzer@kernel.org> References: <20241108234002.16392-1-snitzer@kernel.org> Precedence: bulk X-Mailing-List: linux-nfs@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Now that LOCALIO no longer leans on NFSD's filecache for caching open files (and instead uses NFS client-side open nfsd_file caching) there is no need to use NFSD filecache's GC feature. Avoiding GC will speed up nfsd_file initial opens. Signed-off-by: Mike Snitzer --- fs/nfsd/filecache.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/fs/nfsd/filecache.c b/fs/nfsd/filecache.c index fac98b2cb463..ab9942e42054 100644 --- a/fs/nfsd/filecache.c +++ b/fs/nfsd/filecache.c @@ -1225,10 +1225,9 @@ nfsd_file_acquire(struct svc_rqst *rqstp, struct svc_fh *fhp, * a file. The security implications of this should be carefully * considered before use. * - * The nfsd_file object returned by this API is reference-counted - * and garbage-collected. The object is retained for a few - * seconds after the final nfsd_file_put() in case the caller - * wants to re-use it. + * The nfsd_file_object returned by this API is reference-counted + * but not garbage-collected. The object is unhashed after the + * final nfsd_file_put(). * * Return values: * %nfs_ok - @pnf points to an nfsd_file with its reference @@ -1250,7 +1249,7 @@ nfsd_file_acquire_local(struct net *net, struct svc_cred *cred, __be32 beres; beres = nfsd_file_do_acquire(NULL, net, cred, client, - fhp, may_flags, NULL, pnf, true); + fhp, may_flags, NULL, pnf, false); revert_creds(save_cred); return beres; } From patchwork Fri Nov 8 23:39:58 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mike Snitzer X-Patchwork-Id: 13869055 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id DE07A1FB8BF for ; Fri, 8 Nov 2024 23:40:24 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1731109224; cv=none; b=MN0//NBu1fl3x+D3tb3cf8DT5ZogQQ+H3yyJ0aDGiKs0P56ZVJoSGGANSTv9IA7BCsN7j0lgKTpE5msreQ3W3ioeFInhUBLaameXqJ7cpHK1iQGQPDhuo0TLrLVhrQrGMZ+3zFP5vUgcV8jQj9VrRkxQcXGUWt1CFYOhmsHlDJ4= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1731109224; c=relaxed/simple; bh=QbDgsD4uB2iXNimXUYtxhG3wWClwrbP8GliwGEOJ7i0=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=HhL3wIWekgTkGAxAuRUtKfUOIag3/3t/MGTF3IrqEWBcEKZvGa3sumv7S4I2YWnXgjNCS4ZJ9f94hiba9nZwjb9S9+iIvpwpkanovY1qtnD/OpNBvX4Y9j/oaBJniriHcaC94s/uNEBFvGTvmTpqNJVZLukCZ+piRpAbr3cuonw= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=mt/qQDvs; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="mt/qQDvs" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 36477C4CECE; Fri, 8 Nov 2024 23:40:24 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1731109224; bh=QbDgsD4uB2iXNimXUYtxhG3wWClwrbP8GliwGEOJ7i0=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=mt/qQDvsNXpZgTsx12+5jqrjOAZZxiwhLQ7B6tmYY3OpaJR+xpgYIkXcXDMDOykhs 5t/CvHQWCXt012J+LIOi9aSoiX91WnoQ4WpfcY1UCGkw29EaC1HuJjccqr68ptcLoQ zthuJKsez7HrkiV8faS6Ly3GE3Sm4ZFjt/JU+VoY5YPIhGQz/9mpXTPVvibXe6qAN8 CZuf19JL7QluL+Qw88vGPhyutomMiPCoJkf/Z/Mpow/cLDST7ZinL3iqo7xANj6hbP KX8xkY3xSG9R+zba8Hz4+k6cZnxi6fyneclwQEZz9/zbqsxb3mYGIp9Zj7WuZSh8vo fwUS9LUtxZ7ZQ== From: Mike Snitzer To: linux-nfs@vger.kernel.org Cc: Anna Schumaker , Trond Myklebust , Chuck Lever , Jeff Layton , NeilBrown Subject: [for-6.13 PATCH 15/19] nfs_common: rename nfslocalio nfs_uuid_lock to nfs_uuids_lock Date: Fri, 8 Nov 2024 18:39:58 -0500 Message-ID: <20241108234002.16392-16-snitzer@kernel.org> X-Mailer: git-send-email 2.44.0 In-Reply-To: <20241108234002.16392-1-snitzer@kernel.org> References: <20241108234002.16392-1-snitzer@kernel.org> Precedence: bulk X-Mailing-List: linux-nfs@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 This global spinlock protects all nfs_uuid_t relative to the global nfs_uuids list. A later commit will split this global spinlock so prepare by renaming this lock to reflect its intended narrow scope. Signed-off-by: Mike Snitzer --- fs/nfs_common/nfslocalio.c | 34 +++++++++++++++++----------------- fs/nfsd/localio.c | 2 +- 2 files changed, 18 insertions(+), 18 deletions(-) diff --git a/fs/nfs_common/nfslocalio.c b/fs/nfs_common/nfslocalio.c index 0935bdcaa940..e58b5b4b4c3a 100644 --- a/fs/nfs_common/nfslocalio.c +++ b/fs/nfs_common/nfslocalio.c @@ -15,11 +15,11 @@ MODULE_LICENSE("GPL"); MODULE_DESCRIPTION("NFS localio protocol bypass support"); -static DEFINE_SPINLOCK(nfs_uuid_lock); +static DEFINE_SPINLOCK(nfs_uuids_lock); /* * Global list of nfs_uuid_t instances - * that is protected by nfs_uuid_lock. + * that is protected by nfs_uuids_lock. */ static LIST_HEAD(nfs_uuids); @@ -34,15 +34,15 @@ EXPORT_SYMBOL_GPL(nfs_uuid_init); bool nfs_uuid_begin(nfs_uuid_t *nfs_uuid) { - spin_lock(&nfs_uuid_lock); + spin_lock(&nfs_uuids_lock); /* Is this nfs_uuid already in use? */ if (!list_empty(&nfs_uuid->list)) { - spin_unlock(&nfs_uuid_lock); + spin_unlock(&nfs_uuids_lock); return false; } uuid_gen(&nfs_uuid->uuid); list_add_tail(&nfs_uuid->list, &nfs_uuids); - spin_unlock(&nfs_uuid_lock); + spin_unlock(&nfs_uuids_lock); return true; } @@ -51,10 +51,10 @@ EXPORT_SYMBOL_GPL(nfs_uuid_begin); void nfs_uuid_end(nfs_uuid_t *nfs_uuid) { if (nfs_uuid->net == NULL) { - spin_lock(&nfs_uuid_lock); + spin_lock(&nfs_uuids_lock); if (nfs_uuid->net == NULL) list_del_init(&nfs_uuid->list); - spin_unlock(&nfs_uuid_lock); + spin_unlock(&nfs_uuids_lock); } } EXPORT_SYMBOL_GPL(nfs_uuid_end); @@ -78,7 +78,7 @@ void nfs_uuid_is_local(const uuid_t *uuid, struct list_head *list, { nfs_uuid_t *nfs_uuid; - spin_lock(&nfs_uuid_lock); + spin_lock(&nfs_uuids_lock); nfs_uuid = nfs_uuid_lookup_locked(uuid); if (nfs_uuid) { kref_get(&dom->ref); @@ -94,7 +94,7 @@ void nfs_uuid_is_local(const uuid_t *uuid, struct list_head *list, __module_get(mod); nfsd_mod = mod; } - spin_unlock(&nfs_uuid_lock); + spin_unlock(&nfs_uuids_lock); } EXPORT_SYMBOL_GPL(nfs_uuid_is_local); @@ -128,9 +128,9 @@ void nfs_localio_disable_client(struct nfs_client *clp) spin_lock(&nfs_uuid->lock); if (test_and_clear_bit(NFS_CS_LOCAL_IO, &clp->cl_flags)) { - spin_lock(&nfs_uuid_lock); + spin_lock(&nfs_uuids_lock); nfs_uuid_put_locked(nfs_uuid); - spin_unlock(&nfs_uuid_lock); + spin_unlock(&nfs_uuids_lock); } spin_unlock(&nfs_uuid->lock); } @@ -140,23 +140,23 @@ void nfs_localio_invalidate_clients(struct list_head *cl_uuid_list) { nfs_uuid_t *nfs_uuid, *tmp; - spin_lock(&nfs_uuid_lock); + spin_lock(&nfs_uuids_lock); list_for_each_entry_safe(nfs_uuid, tmp, cl_uuid_list, list) { struct nfs_client *clp = container_of(nfs_uuid, struct nfs_client, cl_uuid); nfs_localio_disable_client(clp); } - spin_unlock(&nfs_uuid_lock); + spin_unlock(&nfs_uuids_lock); } EXPORT_SYMBOL_GPL(nfs_localio_invalidate_clients); static void nfs_uuid_add_file(nfs_uuid_t *nfs_uuid, struct nfs_file_localio *nfl) { - spin_lock(&nfs_uuid_lock); + spin_lock(&nfs_uuids_lock); if (!nfl->nfs_uuid) rcu_assign_pointer(nfl->nfs_uuid, nfs_uuid); - spin_unlock(&nfs_uuid_lock); + spin_unlock(&nfs_uuids_lock); } /* @@ -217,14 +217,14 @@ void nfs_close_local_fh(struct nfs_file_localio *nfl) ro_nf = rcu_access_pointer(nfl->ro_file); rw_nf = rcu_access_pointer(nfl->rw_file); if (ro_nf || rw_nf) { - spin_lock(&nfs_uuid_lock); + spin_lock(&nfs_uuids_lock); if (ro_nf) ro_nf = rcu_dereference_protected(xchg(&nfl->ro_file, NULL), 1); if (rw_nf) rw_nf = rcu_dereference_protected(xchg(&nfl->rw_file, NULL), 1); rcu_assign_pointer(nfl->nfs_uuid, NULL); - spin_unlock(&nfs_uuid_lock); + spin_unlock(&nfs_uuids_lock); rcu_read_unlock(); if (ro_nf) diff --git a/fs/nfsd/localio.c b/fs/nfsd/localio.c index f9a91cd3b5ec..2ae07161b919 100644 --- a/fs/nfsd/localio.c +++ b/fs/nfsd/localio.c @@ -54,7 +54,7 @@ void nfsd_localio_ops_init(void) * avoid all the NFS overhead with reads, writes and commits. * * On successful return, returned nfsd_file will have its nf_net member - * set. Caller (NFS client) is responsible for calling nfsd_serv_put and + * set. Caller (NFS client) is responsible for calling nfsd_net_put and * nfsd_file_put (via nfs_to_nfsd_file_put_local). */ struct nfsd_file * From patchwork Fri Nov 8 23:39:59 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mike Snitzer X-Patchwork-Id: 13869056 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id D1E88206E61 for ; Fri, 8 Nov 2024 23:40:25 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1731109225; cv=none; b=ftVJ8hlZk2BMr6jzhyiNCqL4mAhNU1hnAtNhHSTqBlSM9a1UY1ys4DdSwz+zTTAuRZRuXwXDvJ6UsNbSPFxm6jFTl6DCwk7R0KFa3yiF/5QYHrWd9cgFcKGz61mcaT+D12T68A4BEHtjv8xQuRMgk9mFolgIiuK5j1fVd2uAius= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1731109225; c=relaxed/simple; bh=dhfddZZWrhJ0UTImqGb+IUSWjuB/Yn4bsiLGZb02AFY=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=UBaaT7Ctu52AtxhczeaPLqSWXqGboG0M5vNHi0C/GVpR/eUuz5pDjOdg/SMtTEzHfQI3lEqO6d8qaV40gmD/ZownniTvVg/YyYx32tFIxOGd2uhxCY0yI1iLY7e5x5vnV5BqDcQ/JI0Lp1v845yhBVnu9cNiqpk3XUkdVl+wpv0= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=fdPQeLxU; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="fdPQeLxU" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 81AEBC4CED2; Fri, 8 Nov 2024 23:40:25 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1731109225; bh=dhfddZZWrhJ0UTImqGb+IUSWjuB/Yn4bsiLGZb02AFY=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=fdPQeLxUnWVOdi3mB2VFQ23dEibu48BRlK/PDkNIA847z3URo/9vtP2bQZmS0v9Td 06szSwRHC4O60Xm2zo0pEr63NRQQX/bigLdiKbXzebCMtjKV4630C+0/lZNAwyE3Rb pF4bR3JfdWYNN4IEkG+9YI2gBmTlUITm3lPVK+tLRM7UXC9Z+hnttsbUkM4Pc0Kx9r 4QyX4cVUEYdm/Dv8ZgdUDvdzqUx3mWo5RlSswh2MTLqWx8R7EZ+OoG2dpxPb/YK+c5 elSZL/Yx7mwaLtJhaJpgauN/YsrBl/POngZtoIklnexoz1DDIb7eu8+2Tv27LSlt8q NqYJ9Svq9bqcA== From: Mike Snitzer To: linux-nfs@vger.kernel.org Cc: Anna Schumaker , Trond Myklebust , Chuck Lever , Jeff Layton , NeilBrown Subject: [for-6.13 PATCH 16/19] nfs_common: track all open nfsd_files per LOCALIO nfs_client Date: Fri, 8 Nov 2024 18:39:59 -0500 Message-ID: <20241108234002.16392-17-snitzer@kernel.org> X-Mailer: git-send-email 2.44.0 In-Reply-To: <20241108234002.16392-1-snitzer@kernel.org> References: <20241108234002.16392-1-snitzer@kernel.org> Precedence: bulk X-Mailing-List: linux-nfs@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 This tracking enables __nfsd_file_cache_purge() to call nfs_localio_invalidate_clients(), upon shutdown or export change, to nfs_close_local_fh() all open nfsd_files that are still cached by the LOCALIO nfs clients associated with nfsd_net that is being shutdown. Now that the client must track all open nfsd_files there was more work than necessary being done with the global nfs_uuids_lock contended. This manifested in various RCU issues, e.g.: hrtimer: interrupt took 47969440 ns rcu: INFO: rcu_sched detected stalls on CPUs/tasks: Use nfs_uuid->lock to protect all nfs_uuid_t members, instead of nfs_uuids_lock, once nfs_uuid_is_local() adds the client to nn->local_clients. Also add 'local_clients_lock' to 'struct nfsd_net' to protect nn->local_clients. And store a pointer to spinlock in the 'list_lock' member of nfs_uuid_t so nfs_localio_disable_client() can use it to avoid taking the global nfs_uuids_lock. In combination, these split out locks eliminate the use of the single nfslocalio.c global nfs_uuids_lock in the IO paths (open and close). Also refactored associated fs/nfs_common/nfslocalio.c methods' locking to reduce work performed with spinlocks held in general. Signed-off-by: Mike Snitzer --- fs/nfs_common/nfslocalio.c | 166 +++++++++++++++++++++++++++---------- fs/nfsd/filecache.c | 9 ++ fs/nfsd/localio.c | 1 + fs/nfsd/netns.h | 1 + fs/nfsd/nfsctl.c | 4 +- include/linux/nfslocalio.h | 8 +- 6 files changed, 143 insertions(+), 46 deletions(-) diff --git a/fs/nfs_common/nfslocalio.c b/fs/nfs_common/nfslocalio.c index e58b5b4b4c3a..c8d18f671bcb 100644 --- a/fs/nfs_common/nfslocalio.c +++ b/fs/nfs_common/nfslocalio.c @@ -23,27 +23,49 @@ static DEFINE_SPINLOCK(nfs_uuids_lock); */ static LIST_HEAD(nfs_uuids); +/* + * Lock ordering: + * 1: nfs_uuid->lock + * 2: nfs_uuids_lock + * 3: nfs_uuid->list_lock (aka nn->local_clients_lock) + * + * May skip locks in select cases, but never hold multiple + * locks out of order. + */ + void nfs_uuid_init(nfs_uuid_t *nfs_uuid) { nfs_uuid->net = NULL; nfs_uuid->dom = NULL; + nfs_uuid->list_lock = NULL; INIT_LIST_HEAD(&nfs_uuid->list); + INIT_LIST_HEAD(&nfs_uuid->files); spin_lock_init(&nfs_uuid->lock); } EXPORT_SYMBOL_GPL(nfs_uuid_init); bool nfs_uuid_begin(nfs_uuid_t *nfs_uuid) { + spin_lock(&nfs_uuid->lock); + if (nfs_uuid->net) { + /* This nfs_uuid is already in use */ + spin_unlock(&nfs_uuid->lock); + return false; + } + spin_lock(&nfs_uuids_lock); - /* Is this nfs_uuid already in use? */ if (!list_empty(&nfs_uuid->list)) { + /* This nfs_uuid is already in use */ spin_unlock(&nfs_uuids_lock); + spin_unlock(&nfs_uuid->lock); return false; } - uuid_gen(&nfs_uuid->uuid); list_add_tail(&nfs_uuid->list, &nfs_uuids); spin_unlock(&nfs_uuids_lock); + uuid_gen(&nfs_uuid->uuid); + spin_unlock(&nfs_uuid->lock); + return true; } EXPORT_SYMBOL_GPL(nfs_uuid_begin); @@ -51,11 +73,15 @@ EXPORT_SYMBOL_GPL(nfs_uuid_begin); void nfs_uuid_end(nfs_uuid_t *nfs_uuid) { if (nfs_uuid->net == NULL) { - spin_lock(&nfs_uuids_lock); - if (nfs_uuid->net == NULL) + spin_lock(&nfs_uuid->lock); + if (nfs_uuid->net == NULL) { + /* Not local, remove from nfs_uuids */ + spin_lock(&nfs_uuids_lock); list_del_init(&nfs_uuid->list); - spin_unlock(&nfs_uuids_lock); - } + spin_unlock(&nfs_uuids_lock); + } + spin_unlock(&nfs_uuid->lock); + } } EXPORT_SYMBOL_GPL(nfs_uuid_end); @@ -73,28 +99,39 @@ static nfs_uuid_t * nfs_uuid_lookup_locked(const uuid_t *uuid) static struct module *nfsd_mod; void nfs_uuid_is_local(const uuid_t *uuid, struct list_head *list, - struct net *net, struct auth_domain *dom, - struct module *mod) + spinlock_t *list_lock, struct net *net, + struct auth_domain *dom, struct module *mod) { nfs_uuid_t *nfs_uuid; spin_lock(&nfs_uuids_lock); nfs_uuid = nfs_uuid_lookup_locked(uuid); - if (nfs_uuid) { - kref_get(&dom->ref); - nfs_uuid->dom = dom; - /* - * We don't hold a ref on the net, but instead put - * ourselves on a list so the net pointer can be - * invalidated. - */ - list_move(&nfs_uuid->list, list); - rcu_assign_pointer(nfs_uuid->net, net); - - __module_get(mod); - nfsd_mod = mod; + if (!nfs_uuid) { + spin_unlock(&nfs_uuids_lock); + return; } + + /* + * We don't hold a ref on the net, but instead put + * ourselves on @list (nn->local_clients) so the net + * pointer can be invalidated. + */ + spin_lock(list_lock); /* list_lock is nn->local_clients_lock */ + list_move(&nfs_uuid->list, list); + spin_unlock(list_lock); + spin_unlock(&nfs_uuids_lock); + /* Once nfs_uuid is parented to @list, avoid global nfs_uuids_lock */ + spin_lock(&nfs_uuid->lock); + + __module_get(mod); + nfsd_mod = mod; + + nfs_uuid->list_lock = list_lock; + kref_get(&dom->ref); + nfs_uuid->dom = dom; + rcu_assign_pointer(nfs_uuid->net, net); + spin_unlock(&nfs_uuid->lock); } EXPORT_SYMBOL_GPL(nfs_uuid_is_local); @@ -108,55 +145,96 @@ void nfs_localio_enable_client(struct nfs_client *clp) } EXPORT_SYMBOL_GPL(nfs_localio_enable_client); -static void nfs_uuid_put_locked(nfs_uuid_t *nfs_uuid) +/* + * Cleanup the nfs_uuid_t embedded in an nfs_client. + * This is the long-form of nfs_uuid_init(). + */ +static void nfs_uuid_put(nfs_uuid_t *nfs_uuid) { - if (!nfs_uuid->net) + LIST_HEAD(local_files); + struct nfs_file_localio *nfl, *tmp; + + spin_lock(&nfs_uuid->lock); + if (unlikely(!nfs_uuid->net)) { + spin_unlock(&nfs_uuid->lock); return; - module_put(nfsd_mod); + } rcu_assign_pointer(nfs_uuid->net, NULL); if (nfs_uuid->dom) { auth_domain_put(nfs_uuid->dom); nfs_uuid->dom = NULL; } - list_del_init(&nfs_uuid->list); + + list_splice_init(&nfs_uuid->files, &local_files); + spin_unlock(&nfs_uuid->lock); + + /* Walk list of files and ensure their last references dropped */ + list_for_each_entry_safe(nfl, tmp, &local_files, list) { + nfs_close_local_fh(nfl); + cond_resched(); + } + + spin_lock(&nfs_uuid->lock); + BUG_ON(!list_empty(&nfs_uuid->files)); + + /* Remove client from nn->local_clients */ + if (nfs_uuid->list_lock) { + spin_lock(nfs_uuid->list_lock); + BUG_ON(list_empty(&nfs_uuid->list)); + list_del_init(&nfs_uuid->list); + spin_unlock(nfs_uuid->list_lock); + nfs_uuid->list_lock = NULL; + } + + module_put(nfsd_mod); + spin_unlock(&nfs_uuid->lock); } void nfs_localio_disable_client(struct nfs_client *clp) { - nfs_uuid_t *nfs_uuid = &clp->cl_uuid; + nfs_uuid_t *nfs_uuid = NULL; - spin_lock(&nfs_uuid->lock); + spin_lock(&clp->cl_uuid.lock); /* aka &nfs_uuid->lock */ if (test_and_clear_bit(NFS_CS_LOCAL_IO, &clp->cl_flags)) { - spin_lock(&nfs_uuids_lock); - nfs_uuid_put_locked(nfs_uuid); - spin_unlock(&nfs_uuids_lock); + /* &clp->cl_uuid is always not NULL, using as bool here */ + nfs_uuid = &clp->cl_uuid; } - spin_unlock(&nfs_uuid->lock); + spin_unlock(&clp->cl_uuid.lock); + + if (nfs_uuid) + nfs_uuid_put(nfs_uuid); } EXPORT_SYMBOL_GPL(nfs_localio_disable_client); -void nfs_localio_invalidate_clients(struct list_head *cl_uuid_list) +void nfs_localio_invalidate_clients(struct list_head *nn_local_clients, + spinlock_t *nn_local_clients_lock) { + LIST_HEAD(local_clients); nfs_uuid_t *nfs_uuid, *tmp; + struct nfs_client *clp; - spin_lock(&nfs_uuids_lock); - list_for_each_entry_safe(nfs_uuid, tmp, cl_uuid_list, list) { - struct nfs_client *clp = - container_of(nfs_uuid, struct nfs_client, cl_uuid); - + spin_lock(nn_local_clients_lock); + list_splice_init(nn_local_clients, &local_clients); + spin_unlock(nn_local_clients_lock); + list_for_each_entry_safe(nfs_uuid, tmp, &local_clients, list) { + if (WARN_ON(nfs_uuid->list_lock != nn_local_clients_lock)) + break; + clp = container_of(nfs_uuid, struct nfs_client, cl_uuid); nfs_localio_disable_client(clp); } - spin_unlock(&nfs_uuids_lock); } EXPORT_SYMBOL_GPL(nfs_localio_invalidate_clients); static void nfs_uuid_add_file(nfs_uuid_t *nfs_uuid, struct nfs_file_localio *nfl) { - spin_lock(&nfs_uuids_lock); - if (!nfl->nfs_uuid) + /* Add nfl to nfs_uuid->files if it isn't already */ + spin_lock(&nfs_uuid->lock); + if (list_empty(&nfl->list)) { rcu_assign_pointer(nfl->nfs_uuid, nfs_uuid); - spin_unlock(&nfs_uuids_lock); + list_add_tail(&nfl->list, &nfs_uuid->files); + } + spin_unlock(&nfs_uuid->lock); } /* @@ -217,14 +295,16 @@ void nfs_close_local_fh(struct nfs_file_localio *nfl) ro_nf = rcu_access_pointer(nfl->ro_file); rw_nf = rcu_access_pointer(nfl->rw_file); if (ro_nf || rw_nf) { - spin_lock(&nfs_uuids_lock); + spin_lock(&nfs_uuid->lock); if (ro_nf) ro_nf = rcu_dereference_protected(xchg(&nfl->ro_file, NULL), 1); if (rw_nf) rw_nf = rcu_dereference_protected(xchg(&nfl->rw_file, NULL), 1); + /* Remove nfl from nfs_uuid->files list */ rcu_assign_pointer(nfl->nfs_uuid, NULL); - spin_unlock(&nfs_uuids_lock); + list_del_init(&nfl->list); + spin_unlock(&nfs_uuid->lock); rcu_read_unlock(); if (ro_nf) diff --git a/fs/nfsd/filecache.c b/fs/nfsd/filecache.c index ab9942e42054..c9ab64e3732c 100644 --- a/fs/nfsd/filecache.c +++ b/fs/nfsd/filecache.c @@ -39,6 +39,7 @@ #include #include #include +#include #include "vfs.h" #include "nfsd.h" @@ -836,6 +837,14 @@ __nfsd_file_cache_purge(struct net *net) struct nfsd_file *nf; LIST_HEAD(dispose); +#if IS_ENABLED(CONFIG_NFS_LOCALIO) + if (net) { + struct nfsd_net *nn = net_generic(net, nfsd_net_id); + nfs_localio_invalidate_clients(&nn->local_clients, + &nn->local_clients_lock); + } +#endif + rhltable_walk_enter(&nfsd_file_rhltable, &iter); do { rhashtable_walk_start(&iter); diff --git a/fs/nfsd/localio.c b/fs/nfsd/localio.c index 2ae07161b919..238647fa379e 100644 --- a/fs/nfsd/localio.c +++ b/fs/nfsd/localio.c @@ -116,6 +116,7 @@ static __be32 localio_proc_uuid_is_local(struct svc_rqst *rqstp) struct nfsd_net *nn = net_generic(net, nfsd_net_id); nfs_uuid_is_local(&argp->uuid, &nn->local_clients, + &nn->local_clients_lock, net, rqstp->rq_client, THIS_MODULE); return rpc_success; diff --git a/fs/nfsd/netns.h b/fs/nfsd/netns.h index 8faef59d7122..187c4140b191 100644 --- a/fs/nfsd/netns.h +++ b/fs/nfsd/netns.h @@ -220,6 +220,7 @@ struct nfsd_net { #if IS_ENABLED(CONFIG_NFS_LOCALIO) /* Local clients to be invalidated when net is shut down */ + spinlock_t local_clients_lock; struct list_head local_clients; #endif }; diff --git a/fs/nfsd/nfsctl.c b/fs/nfsd/nfsctl.c index 727904d8a4d0..70347b0ecdc4 100644 --- a/fs/nfsd/nfsctl.c +++ b/fs/nfsd/nfsctl.c @@ -2259,6 +2259,7 @@ static __net_init int nfsd_net_init(struct net *net) seqlock_init(&nn->writeverf_lock); nfsd_proc_stat_init(net); #if IS_ENABLED(CONFIG_NFS_LOCALIO) + spin_lock_init(&nn->local_clients_lock); INIT_LIST_HEAD(&nn->local_clients); #endif return 0; @@ -2283,7 +2284,8 @@ static __net_exit void nfsd_net_pre_exit(struct net *net) { struct nfsd_net *nn = net_generic(net, nfsd_net_id); - nfs_localio_invalidate_clients(&nn->local_clients); + nfs_localio_invalidate_clients(&nn->local_clients, + &nn->local_clients_lock); } #endif diff --git a/include/linux/nfslocalio.h b/include/linux/nfslocalio.h index aa2b5c6561ab..c68a529230c1 100644 --- a/include/linux/nfslocalio.h +++ b/include/linux/nfslocalio.h @@ -30,19 +30,23 @@ typedef struct { /* sadly this struct is just over a cacheline, avoid bouncing */ spinlock_t ____cacheline_aligned lock; struct list_head list; + spinlock_t *list_lock; /* nn->local_clients_lock */ struct net __rcu *net; /* nfsd's network namespace */ struct auth_domain *dom; /* auth_domain for localio */ + /* Local files to close when net is shut down or exports change */ + struct list_head files; } nfs_uuid_t; void nfs_uuid_init(nfs_uuid_t *); bool nfs_uuid_begin(nfs_uuid_t *); void nfs_uuid_end(nfs_uuid_t *); -void nfs_uuid_is_local(const uuid_t *, struct list_head *, +void nfs_uuid_is_local(const uuid_t *, struct list_head *, spinlock_t *, struct net *, struct auth_domain *, struct module *); void nfs_localio_enable_client(struct nfs_client *clp); void nfs_localio_disable_client(struct nfs_client *clp); -void nfs_localio_invalidate_clients(struct list_head *list); +void nfs_localio_invalidate_clients(struct list_head *nn_local_clients, + spinlock_t *nn_local_clients_lock); /* localio needs to map filehandle -> struct nfsd_file */ extern struct nfsd_file * From patchwork Fri Nov 8 23:40:00 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mike Snitzer X-Patchwork-Id: 13869057 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 332B12071E4 for ; Fri, 8 Nov 2024 23:40:27 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1731109227; cv=none; b=W0w+cLmNt0oEjw2VfiduryLQ0jUMonuNTMneX2yF4LebfDypBJeegvPgHwbIusr4RByIm+aRU5H2SrPR0Hh1I8URprN3oHz9a5n+/W6wXDGoo1JUOpHyoLj8rqBgE5ngAf7JYd4MgHmuKyJRgivOWgYWtKhhbb7F64QCoCWun54= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1731109227; c=relaxed/simple; bh=4Aqn+okpoHa+SrrnTKpvrPSkC5QbnnDS5CEVHlAGKi4=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=u4cuI0RlQQ7dKPzbKiIB30lR3/d9dwlDAFxX+aZ+9riy3aJiTK5r5nxHGA0paoi/ebR23QOk6MjtbLqKCzc+1pkswY/8hsxnyfE2GpMcPlB/9ANBBrxF5x/KAzBjKIH6M3Aj5ebetFwVmqyJ4DsurnsuZNDOJYAMWt4zdBYziHs= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=eI8Mr8vR; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="eI8Mr8vR" Received: by smtp.kernel.org (Postfix) with ESMTPSA id CF4BAC4CECE; Fri, 8 Nov 2024 23:40:26 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1731109227; bh=4Aqn+okpoHa+SrrnTKpvrPSkC5QbnnDS5CEVHlAGKi4=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=eI8Mr8vRgWKkdZrXwtZiMR5dFdIDFZ16ObRnK2GDmAv0B52MMMVuIVKOdFLZ/S+4i H4MhBIFOImKJ2nSSh0fEA5mvBO5NvL7nie5plglrdtGE+SRExdwVXUo6wy9tlBoxTu iUoTIOroXQz9B5IfxDQf5q9CreZGhR/xsKWEr/YgWwxUIRaSwY4XnG4VvjdKO3JZwE eqRFByBn3nvaWSwqYsvsR7pejM9Zu8DMDjdRGp/20O4TLRddTH38I3lc14u0wj3GwR o1HrnhYYS/5O0gLbqMxFxNu4ic31M4T0jqEwkjykVK02VPd13MzyUPb7m64kzgtJFQ 1TfM1B6firDFg== From: Mike Snitzer To: linux-nfs@vger.kernel.org Cc: Anna Schumaker , Trond Myklebust , Chuck Lever , Jeff Layton , NeilBrown Subject: [for-6.13 PATCH 17/19] nfs_common: add nfs_localio trace events Date: Fri, 8 Nov 2024 18:40:00 -0500 Message-ID: <20241108234002.16392-18-snitzer@kernel.org> X-Mailer: git-send-email 2.44.0 In-Reply-To: <20241108234002.16392-1-snitzer@kernel.org> References: <20241108234002.16392-1-snitzer@kernel.org> Precedence: bulk X-Mailing-List: linux-nfs@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 The nfs_localio.ko now exposes /sys/kernel/tracing/events/nfs_localio with nfs_localio_enable_client and nfs_localio_disable_client events. These complement the existing nfs/nfs_local_{enable,disable} events to convey things like if/when nfs_localio_invalidate_clients calls nfs_localio_disable_client followed by nfs_local_probe_aync calling nfs_local_enable which calls nfs_localio_enable_client. Signed-off-by: Mike Snitzer --- fs/nfs_common/Makefile | 3 +- fs/nfs_common/localio_trace.c | 10 +++++++ fs/nfs_common/localio_trace.h | 56 +++++++++++++++++++++++++++++++++++ fs/nfs_common/nfslocalio.c | 4 +++ 4 files changed, 72 insertions(+), 1 deletion(-) create mode 100644 fs/nfs_common/localio_trace.c create mode 100644 fs/nfs_common/localio_trace.h diff --git a/fs/nfs_common/Makefile b/fs/nfs_common/Makefile index a5e54809701e..c10ead273ff2 100644 --- a/fs/nfs_common/Makefile +++ b/fs/nfs_common/Makefile @@ -6,8 +6,9 @@ obj-$(CONFIG_NFS_ACL_SUPPORT) += nfs_acl.o nfs_acl-objs := nfsacl.o +CFLAGS_localio_trace.o += -I$(src) obj-$(CONFIG_NFS_COMMON_LOCALIO_SUPPORT) += nfs_localio.o -nfs_localio-objs := nfslocalio.o +nfs_localio-objs := nfslocalio.o localio_trace.o obj-$(CONFIG_GRACE_PERIOD) += grace.o obj-$(CONFIG_NFS_V4_2_SSC_HELPER) += nfs_ssc.o diff --git a/fs/nfs_common/localio_trace.c b/fs/nfs_common/localio_trace.c new file mode 100644 index 000000000000..7decfe57abeb --- /dev/null +++ b/fs/nfs_common/localio_trace.c @@ -0,0 +1,10 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2024 Trond Myklebust + * Copyright (C) 2024 Mike Snitzer + */ +#include +#include + +#define CREATE_TRACE_POINTS +#include "localio_trace.h" diff --git a/fs/nfs_common/localio_trace.h b/fs/nfs_common/localio_trace.h new file mode 100644 index 000000000000..4055aec9ff8d --- /dev/null +++ b/fs/nfs_common/localio_trace.h @@ -0,0 +1,56 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) 2024 Trond Myklebust + * Copyright (C) 2024 Mike Snitzer + */ +#undef TRACE_SYSTEM +#define TRACE_SYSTEM nfs_localio + +#if !defined(_TRACE_NFS_COMMON_LOCALIO_H) || defined(TRACE_HEADER_MULTI_READ) +#define _TRACE_NFS_COMMON_LOCALIO_H + +#include + +#include +#include +#include + +DECLARE_EVENT_CLASS(nfs_local_client_event, + TP_PROTO( + const struct nfs_client *clp + ), + + TP_ARGS(clp), + + TP_STRUCT__entry( + __field(unsigned int, protocol) + __string(server, clp->cl_hostname) + ), + + TP_fast_assign( + __entry->protocol = clp->rpc_ops->version; + __assign_str(server); + ), + + TP_printk( + "server=%s NFSv%u", __get_str(server), __entry->protocol + ) +); + +#define DEFINE_NFS_LOCAL_CLIENT_EVENT(name) \ + DEFINE_EVENT(nfs_local_client_event, name, \ + TP_PROTO( \ + const struct nfs_client *clp \ + ), \ + TP_ARGS(clp)) + +DEFINE_NFS_LOCAL_CLIENT_EVENT(nfs_localio_enable_client); +DEFINE_NFS_LOCAL_CLIENT_EVENT(nfs_localio_disable_client); + +#endif /* _TRACE_NFS_COMMON_LOCALIO_H */ + +#undef TRACE_INCLUDE_PATH +#define TRACE_INCLUDE_PATH . +#define TRACE_INCLUDE_FILE localio_trace +/* This part must be outside protection */ +#include diff --git a/fs/nfs_common/nfslocalio.c b/fs/nfs_common/nfslocalio.c index c8d18f671bcb..fb376d38ac9a 100644 --- a/fs/nfs_common/nfslocalio.c +++ b/fs/nfs_common/nfslocalio.c @@ -12,6 +12,8 @@ #include #include +#include "localio_trace.h" + MODULE_LICENSE("GPL"); MODULE_DESCRIPTION("NFS localio protocol bypass support"); @@ -141,6 +143,7 @@ void nfs_localio_enable_client(struct nfs_client *clp) spin_lock(&nfs_uuid->lock); set_bit(NFS_CS_LOCAL_IO, &clp->cl_flags); + trace_nfs_localio_enable_client(clp); spin_unlock(&nfs_uuid->lock); } EXPORT_SYMBOL_GPL(nfs_localio_enable_client); @@ -199,6 +202,7 @@ void nfs_localio_disable_client(struct nfs_client *clp) if (test_and_clear_bit(NFS_CS_LOCAL_IO, &clp->cl_flags)) { /* &clp->cl_uuid is always not NULL, using as bool here */ nfs_uuid = &clp->cl_uuid; + trace_nfs_localio_disable_client(clp); } spin_unlock(&clp->cl_uuid.lock); From patchwork Fri Nov 8 23:40:01 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mike Snitzer X-Patchwork-Id: 13869058 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 8C70C1F7568 for ; Fri, 8 Nov 2024 23:40:28 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1731109228; cv=none; b=cfr3PROUCZiew09RAlnfmYqfbtS+pJruSiXQiNBuRt8MfzQOkCmyMkqLPpmH8jXdCWUcUTamaJjnYGWJpWfQZOTMsGZODpHdqejIdswkBL+VOkXtKtl0STbbO0Fn0oehi3LluAZVYpjN2Gv5T3+VRyqgHrgeeTTlpQ8cwMzCUow= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1731109228; c=relaxed/simple; bh=mhJ74S92bHkgHVyB2t8drBz+1krFb56JlKM6706TYZ4=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=rQF03vV8leQlPVceK/fxhTvL+GjvNC61wNmZKJvlG1Yc1ubQRpCp+XgQl8kUkgmxjESBm+CPQp+wUkvqwgnZNht/4Ap8lpZAMkqqZcKbV4iWWDtdTT0p/zGGQ2uofECBJa6x3/tcCIRLZzjFeOm7LRPcrO5pt6FQ31YG8D9zlHQ= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=RaSLmFUS; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="RaSLmFUS" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 3A8E9C4CECE; Fri, 8 Nov 2024 23:40:28 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1731109228; bh=mhJ74S92bHkgHVyB2t8drBz+1krFb56JlKM6706TYZ4=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=RaSLmFUS2D9xwayP3+40igwSGpDBqxbVsm4DLpW1GQ2ZLUHW+UYhV24fk579FH+5K 2FONETycDWsghQCS3VS/sRvcsrN1y90YgVTjSyaxObbbUlLIH8EHbabavCGb7GjFaM yt2rCkmxePwh+v1tczyGZfRFHE5vwGRP+HnlnkhV+myyg4XKouD0Ahh7N9VGqNlD/p YLFxnlC5Lg3QPvM31e0GzednH0tz+zX1Pa09HSMZRToYRMvkgDOq5ViFP7v12LKrJU INWuLT8jfBI4WbBFh/6acuqPAi1LA3C1/y0o2lUJ/kDGReTnzQOn19vZQxEFHUXnrG 2PoHqMW+T/blw== From: Mike Snitzer To: linux-nfs@vger.kernel.org Cc: Anna Schumaker , Trond Myklebust , Chuck Lever , Jeff Layton , NeilBrown Subject: [for-6.13 PATCH 18/19] nfs: probe for LOCALIO when v4 client reconnects to server Date: Fri, 8 Nov 2024 18:40:01 -0500 Message-ID: <20241108234002.16392-19-snitzer@kernel.org> X-Mailer: git-send-email 2.44.0 In-Reply-To: <20241108234002.16392-1-snitzer@kernel.org> References: <20241108234002.16392-1-snitzer@kernel.org> Precedence: bulk X-Mailing-List: linux-nfs@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Introduce nfs_local_probe_async() for the NFS client to initiate if/when it reconnects with server. For NFSv4 it is a simple matter to call nfs_local_probe_async() from nfs4_do_reclaim (during NFSv4 grace). [NFSv3 also needs to reestablish LOCALIO if/when a client reconnects to server, but the stateless nature of v3 means the implementation is more tricky so its been factored out to the following commit.] Signed-off-by: Mike Snitzer --- fs/nfs/internal.h | 2 ++ fs/nfs/localio.c | 15 +++++++++++++++ fs/nfs/nfs4state.c | 1 + include/linux/nfs_fs_sb.h | 1 + 4 files changed, 19 insertions(+) diff --git a/fs/nfs/internal.h b/fs/nfs/internal.h index 57af3ab3adbe..efd42efd9405 100644 --- a/fs/nfs/internal.h +++ b/fs/nfs/internal.h @@ -456,6 +456,7 @@ extern int nfs_wait_bit_killable(struct wait_bit_key *key, int mode); /* localio.c */ extern void nfs_local_disable(struct nfs_client *); extern void nfs_local_probe(struct nfs_client *); +extern void nfs_local_probe_async(struct nfs_client *); extern struct nfsd_file *nfs_local_open_fh(struct nfs_client *, const struct cred *, struct nfs_fh *, @@ -473,6 +474,7 @@ extern bool nfs_server_is_local(const struct nfs_client *clp); #else /* CONFIG_NFS_LOCALIO */ static inline void nfs_local_disable(struct nfs_client *clp) {} static inline void nfs_local_probe(struct nfs_client *clp) {} +static inline void nfs_local_probe_async(struct nfs_client *clp) {} static inline struct nfsd_file * nfs_local_open_fh(struct nfs_client *clp, const struct cred *cred, struct nfs_fh *fh, struct nfs_file_localio *nfl, diff --git a/fs/nfs/localio.c b/fs/nfs/localio.c index d10d863aaf23..710e537b3402 100644 --- a/fs/nfs/localio.c +++ b/fs/nfs/localio.c @@ -214,6 +214,21 @@ void nfs_local_probe(struct nfs_client *clp) } EXPORT_SYMBOL_GPL(nfs_local_probe); +static void nfs_local_probe_async_work(struct work_struct *work) +{ + struct nfs_client *clp = + container_of(work, struct nfs_client, cl_local_probe_work); + + nfs_local_probe(clp); +} + +void nfs_local_probe_async(struct nfs_client *clp) +{ + INIT_WORK(&clp->cl_local_probe_work, nfs_local_probe_async_work); + queue_work(nfsiod_workqueue, &clp->cl_local_probe_work); +} +EXPORT_SYMBOL_GPL(nfs_local_probe_async); + static inline struct nfsd_file *nfs_local_file_get(struct nfsd_file *nf) { return nfs_to->nfsd_file_get(nf); diff --git a/fs/nfs/nfs4state.c b/fs/nfs/nfs4state.c index dafd61186557..2ebb9ac56b7b 100644 --- a/fs/nfs/nfs4state.c +++ b/fs/nfs/nfs4state.c @@ -1957,6 +1957,7 @@ static int nfs4_do_reclaim(struct nfs_client *clp, const struct nfs4_state_recov } rcu_read_unlock(); nfs4_free_state_owners(&freeme); + nfs_local_probe_async(clp); if (lost_locks) pr_warn("NFS: %s: lost %d locks\n", clp->cl_hostname, lost_locks); diff --git a/include/linux/nfs_fs_sb.h b/include/linux/nfs_fs_sb.h index 239d86ef166c..63d7e0f478d8 100644 --- a/include/linux/nfs_fs_sb.h +++ b/include/linux/nfs_fs_sb.h @@ -132,6 +132,7 @@ struct nfs_client { struct timespec64 cl_nfssvc_boot; seqlock_t cl_boot_lock; nfs_uuid_t cl_uuid; + struct work_struct cl_local_probe_work; #endif /* CONFIG_NFS_LOCALIO */ }; From patchwork Fri Nov 8 23:40:02 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mike Snitzer X-Patchwork-Id: 13869059 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 187531E1C07 for ; Fri, 8 Nov 2024 23:40:29 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1731109230; cv=none; b=B2B9yZDFYfpDHsNB4SkfOZAyPR3DFXvZaEHk8IfTPX6IJ4IgICSQHUThHJ/Ms4cMFkM93aNFI5kRZY/6Du77G/quhDcC6shcZnsH3iHRNgdqoREpq+D1Uc63MC9RDjGM2g6L6NzClsxmkryLXdj5f4w3UY05sCwjejqpKu+v1nE= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1731109230; c=relaxed/simple; bh=mm1+iCta5fSPnpTxY2nr6E1fk0ZpDMRlX1+NogjX0vw=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=DP3jT114MCMf2L61UXMkcV6+W75fh+4peDUUL0H+cqL0PsivrkNDe2WU63bUPERI1BahuV6gMKrJPmWsr+5tG/EAEFfkWdbLp6+6otHymzpjdTwUu0+TJB8OM1Y/d5dBc2LBu38a2S+wxvRqMD3g22MrC8uX08U2kibBSdIP9tk= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=RBQR+cy+; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="RBQR+cy+" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 7C0F0C4CECE; Fri, 8 Nov 2024 23:40:29 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1731109229; bh=mm1+iCta5fSPnpTxY2nr6E1fk0ZpDMRlX1+NogjX0vw=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=RBQR+cy+njgK/vi0c228rrJ054OdVsVTpi4crJwral8kmi9bkRnp4tB72Sooi6vpQ OKpxPAhiRlLOXiFEF1u/JXT55WtkY7Z7w/t1u3gYyNq5wtpq+4L8fgtVoH+KXgybYn ighuTheMUuvJWvsESrKCBngpmZcXQlq9xo0EvmNyDmyUYGeVa72aYUt0ur7k765AfU vkE5MqxRArGnBVzhZggUF+Cy2mcLIlmshDoPjjaugr4TefrZz1TXhzmKtD5hr15Spw EhrnS6xZypUvC7QltRZcMPZfe6F9DmSo7Ye46EXQ5foh+Qdk0GA4csRyahvzaECwko DajRx+YpJwbQQ== From: Mike Snitzer To: linux-nfs@vger.kernel.org Cc: Anna Schumaker , Trond Myklebust , Chuck Lever , Jeff Layton , NeilBrown Subject: [for-6.13 PATCH 19/19] nfs: probe for LOCALIO when v3 client reconnects to server Date: Fri, 8 Nov 2024 18:40:02 -0500 Message-ID: <20241108234002.16392-20-snitzer@kernel.org> X-Mailer: git-send-email 2.44.0 In-Reply-To: <20241108234002.16392-1-snitzer@kernel.org> References: <20241108234002.16392-1-snitzer@kernel.org> Precedence: bulk X-Mailing-List: linux-nfs@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Re-enabling NFSv3 LOCALIO is made more complex (than NFSv4) because v3 is stateless. As such, the hueristic used to identify a LOCALIO probe point is more adhoc by nature: if/when NFSv3 client IO begins to complete again in terms of normal RPC-based NFSv3 server IO, attempt nfs_local_probe_async(). Care is taken to throttle the frequency of nfs_local_probe_async(), otherwise there could be a flood of repeat calls to nfs_local_probe_async(). Signed-off-by: Mike Snitzer --- fs/nfs/internal.h | 5 +++++ fs/nfs/localio.c | 11 +++++++++++ fs/nfs/nfs3proc.c | 34 +++++++++++++++++++++++++++++++--- fs/nfs_common/nfslocalio.c | 4 ++++ include/linux/nfs_fs_sb.h | 1 + include/linux/nfslocalio.h | 4 +++- 6 files changed, 55 insertions(+), 4 deletions(-) diff --git a/fs/nfs/internal.h b/fs/nfs/internal.h index efd42efd9405..fb1ab7cee6b9 100644 --- a/fs/nfs/internal.h +++ b/fs/nfs/internal.h @@ -470,6 +470,7 @@ extern int nfs_local_commit(struct nfsd_file *, struct nfs_commit_data *, const struct rpc_call_ops *, int); extern bool nfs_server_is_local(const struct nfs_client *clp); +extern bool nfs_server_was_local(const struct nfs_client *clp); #else /* CONFIG_NFS_LOCALIO */ static inline void nfs_local_disable(struct nfs_client *clp) {} @@ -499,6 +500,10 @@ static inline bool nfs_server_is_local(const struct nfs_client *clp) { return false; } +static inline bool nfs_server_was_local(const struct nfs_client *clp) +{ + return false; +} #endif /* CONFIG_NFS_LOCALIO */ /* super.c */ diff --git a/fs/nfs/localio.c b/fs/nfs/localio.c index 710e537b3402..1559dc2f1850 100644 --- a/fs/nfs/localio.c +++ b/fs/nfs/localio.c @@ -64,6 +64,17 @@ bool nfs_server_is_local(const struct nfs_client *clp) } EXPORT_SYMBOL_GPL(nfs_server_is_local); +static inline bool nfs_client_was_local(const struct nfs_client *clp) +{ + return !!test_bit(NFS_CS_LOCAL_IO_CAPABLE, &clp->cl_flags); +} + +bool nfs_server_was_local(const struct nfs_client *clp) +{ + return nfs_client_was_local(clp) && localio_enabled; +} +EXPORT_SYMBOL_GPL(nfs_server_was_local); + /* * UUID_IS_LOCAL XDR functions */ diff --git a/fs/nfs/nfs3proc.c b/fs/nfs/nfs3proc.c index 1566163c6d85..4d2018760e9b 100644 --- a/fs/nfs/nfs3proc.c +++ b/fs/nfs/nfs3proc.c @@ -844,6 +844,29 @@ nfs3_proc_pathconf(struct nfs_server *server, struct nfs_fh *fhandle, return status; } +static void nfs3_local_probe(struct nfs_server *server) +{ +#if IS_ENABLED(CONFIG_NFS_LOCALIO) + struct nfs_client *clp = server->nfs_client; + nfs_uuid_t *nfs_uuid = &clp->cl_uuid; + + if (likely(!nfs_server_was_local(clp))) + return; + /* + * Try re-enabling LOCALIO if it was previously enabled, but + * was disabled due to server restart, and IO has successfully + * completed in terms of normal RPC. + */ + mutex_lock(&nfs_uuid->local_probe_mutex); + /* Arbitrary throttle to reduce nfs_local_probe_async() frequency */ + if ((nfs_uuid->local_probe_count++ & 255) == 0) { + if (unlikely(!nfs_server_is_local(clp) && nfs_server_was_local(clp))) + nfs_local_probe_async(clp); + } + mutex_unlock(&nfs_uuid->local_probe_mutex); +#endif +} + static int nfs3_read_done(struct rpc_task *task, struct nfs_pgio_header *hdr) { struct inode *inode = hdr->inode; @@ -855,8 +878,11 @@ static int nfs3_read_done(struct rpc_task *task, struct nfs_pgio_header *hdr) if (nfs3_async_handle_jukebox(task, inode)) return -EAGAIN; - if (task->tk_status >= 0 && !server->read_hdrsize) - cmpxchg(&server->read_hdrsize, 0, hdr->res.replen); + if (task->tk_status >= 0) { + if (!server->read_hdrsize) + cmpxchg(&server->read_hdrsize, 0, hdr->res.replen); + nfs3_local_probe(server); + } nfs_invalidate_atime(inode); nfs_refresh_inode(inode, &hdr->fattr); @@ -886,8 +912,10 @@ static int nfs3_write_done(struct rpc_task *task, struct nfs_pgio_header *hdr) if (nfs3_async_handle_jukebox(task, inode)) return -EAGAIN; - if (task->tk_status >= 0) + if (task->tk_status >= 0) { nfs_writeback_update_inode(hdr); + nfs3_local_probe(NFS_SERVER(inode)); + } return 0; } diff --git a/fs/nfs_common/nfslocalio.c b/fs/nfs_common/nfslocalio.c index fb376d38ac9a..852ba8fd73f3 100644 --- a/fs/nfs_common/nfslocalio.c +++ b/fs/nfs_common/nfslocalio.c @@ -43,6 +43,8 @@ void nfs_uuid_init(nfs_uuid_t *nfs_uuid) INIT_LIST_HEAD(&nfs_uuid->list); INIT_LIST_HEAD(&nfs_uuid->files); spin_lock_init(&nfs_uuid->lock); + mutex_init(&nfs_uuid->local_probe_mutex); + nfs_uuid->local_probe_count = 0; } EXPORT_SYMBOL_GPL(nfs_uuid_init); @@ -143,6 +145,8 @@ void nfs_localio_enable_client(struct nfs_client *clp) spin_lock(&nfs_uuid->lock); set_bit(NFS_CS_LOCAL_IO, &clp->cl_flags); + /* Also set hint that client and server are LOCALIO capable */ + set_bit(NFS_CS_LOCAL_IO_CAPABLE, &clp->cl_flags); trace_nfs_localio_enable_client(clp); spin_unlock(&nfs_uuid->lock); } diff --git a/include/linux/nfs_fs_sb.h b/include/linux/nfs_fs_sb.h index 63d7e0f478d8..45906c402c98 100644 --- a/include/linux/nfs_fs_sb.h +++ b/include/linux/nfs_fs_sb.h @@ -51,6 +51,7 @@ struct nfs_client { #define NFS_CS_REUSEPORT 8 /* - reuse src port on reconnect */ #define NFS_CS_PNFS 9 /* - Server used for pnfs */ #define NFS_CS_LOCAL_IO 10 /* - client is local */ +#define NFS_CS_LOCAL_IO_CAPABLE 11 /* - client was previously local */ struct sockaddr_storage cl_addr; /* server identifier */ size_t cl_addrlen; char * cl_hostname; /* hostname of server */ diff --git a/include/linux/nfslocalio.h b/include/linux/nfslocalio.h index c68a529230c1..3dfef0bb18fe 100644 --- a/include/linux/nfslocalio.h +++ b/include/linux/nfslocalio.h @@ -27,7 +27,9 @@ struct nfs_file_localio; */ typedef struct { uuid_t uuid; - /* sadly this struct is just over a cacheline, avoid bouncing */ + struct mutex local_probe_mutex; + unsigned local_probe_count; + /* sadly this struct is over a cacheline, avoid bouncing */ spinlock_t ____cacheline_aligned lock; struct list_head list; spinlock_t *list_lock; /* nn->local_clients_lock */