From nobody Thu Dec 18 14:10:55 2025 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 597E3224245; Mon, 2 Jun 2025 14:02: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=1748872944; cv=none; b=pyQ+/S/TOtnpp09KhNyWBXNrUGJDaLXQDXcuwfggbJ+uO9yJNKNIASPZ1w5JXotCA2wMDdhhlDGQk31ZNlNPR288Dc5jxYzdE3myiuAj1DwPnp5IvDTjaN8iq2DkPjxBIB7y9rmQ6YpsH4qozYWzin/qpcyvX1dNMYIgk8G92MY= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1748872944; c=relaxed/simple; bh=ZrFup30IUUI62IhIRTGdtQyA3ni1qkUHKiEvsunwAIc=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=jBpzpBggOeVtG9BEyXo+UTaesmJ29TvUwCTrkbNHcpZq3OTtMNzROCTQDcNWWbjbJyh9wwa2zTwEke2z8HVnzmk7gNrBO3/zvjFjQoMSbzvtxOi++dGSWgoBSkyyuWDYOnZdGwASjho5bdkvJ0Wt2++IYdBt1gtQFd5Mhg2xQsc= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=bOllxQD0; 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="bOllxQD0" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 3ACF1C4CEF5; Mon, 2 Jun 2025 14:02:22 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1748872944; bh=ZrFup30IUUI62IhIRTGdtQyA3ni1qkUHKiEvsunwAIc=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=bOllxQD0QutP185Tx+5m080NYaVFu/O8IYq4VMDolty/P/OSOenm0IFy/5qjX2YH1 YgAmwfzQUR3pN1VHhT5OP1ESmeA1tz9QLmLiauh8CC7OjrwJCwAqXlWaMYjOtZTXpi 8mXs4qcJncvNH3LyKlPiZydfldKGUEl1qJQ34tEe7EdCu3nYG8Klv6oq0AjuvsyEWW W0xt5u/THz5svq3SMg/YUAZAreWLy+SS12qq3oERDKZDrG6F3N5qiNBNcQDoN8+R2Z GPnFJx0s+wWszvs43irEtRrB6utXaGwtgsQMhvZ8VtB+Tsq1cYiPjCUGHuoESr2cSR YUf7p3u9/4Ucw== From: Jeff Layton Date: Mon, 02 Jun 2025 10:01:44 -0400 Subject: [PATCH RFC v2 01/28] filelock: push the S_ISREG check down to ->setlease handlers Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20250602-dir-deleg-v2-1-a7919700de86@kernel.org> References: <20250602-dir-deleg-v2-0-a7919700de86@kernel.org> In-Reply-To: <20250602-dir-deleg-v2-0-a7919700de86@kernel.org> To: Alexander Viro , Christian Brauner , Jan Kara , Chuck Lever , Alexander Aring , Trond Myklebust , Anna Schumaker , Steve French , Paulo Alcantara , Ronnie Sahlberg , Shyam Prasad N , Tom Talpey , Bharath SM , NeilBrown , Olga Kornievskaia , Dai Ngo , Jonathan Corbet , Amir Goldstein , Miklos Szeredi Cc: linux-fsdevel@vger.kernel.org, linux-kernel@vger.kernel.org, linux-nfs@vger.kernel.org, linux-cifs@vger.kernel.org, samba-technical@lists.samba.org, linux-doc@vger.kernel.org, Jeff Layton X-Mailer: b4 0.14.2 X-Developer-Signature: v=1; a=openpgp-sha256; l=3149; i=jlayton@kernel.org; h=from:subject:message-id; bh=ZrFup30IUUI62IhIRTGdtQyA3ni1qkUHKiEvsunwAIc=; b=owEBbQKS/ZANAwAKAQAOaEEZVoIVAcsmYgBoPa7kbGXbFK+2MezlY3MJ/Xtzr/ggiQYYbxlfc LXfkYQCqF+JAjMEAAEKAB0WIQRLwNeyRHGyoYTq9dMADmhBGVaCFQUCaD2u5AAKCRAADmhBGVaC FbHvD/9vSTVF8NJ7ALqyShqeu2mSuoidlK+DgJlsHzCpSFoJ4QmMFY53YntfUE6tg4GYQgGRxv6 eL8ix5GzWuQCu/aZ9F5Fpno+yDZ9DbZPumGZDUQy3pWpfSfeiqtV648XILPtQMZdzH6l75LVnut 4DrL0vRNg4UTjJP4hHXTKrt6O1hYmX3XNlyk6m24CMa/Pv9D/hVoOk1h7Q6EUyG8Gq6BsY5uIyT 0z1KH1Ok5xg9uj1Xj5RyB4N2lHrBMbucFWTh74ug0L2ebnKve7dh/WiIQgpTaf8L3AQ7yHj5OrA Or+8t0/98p1RRVq57i/uShY7+gMgzLPBzJSq6kMVDaMODvfcTLY09XMYypKTDEN2etAifXPTz7/ kgLw7P2IVuME5DpLTXpH7VGyod/qbu+f/lu05uBLf7z+gexzz6Xesf6eHkIenCDJ0JBTX33GHmg Lb7hazPie+DtN0CWxTBzjzB6HqeOq9xgh0VNEI5MemTkcCgsnidLu/UebrKhhqHOfvsqvk160pV hFSUV9a9+FLTcLFebW5qAclhoKvi9oWOvby2qoQCwyNpqly+NJEkzwu3sYwjlenXz2bHspYTYsc 7x2I3jSCyKW7eN7Gecmy4Wgf6okjfult8w114tBEVjgLSGyC38PNSiukTa+C/k9mOMdjMZbvfQC /n5RRBGG/tMRkHw== X-Developer-Key: i=jlayton@kernel.org; a=openpgp; fpr=4BC0D7B24471B2A184EAF5D3000E684119568215 When nfsd starts requesting directory delegations, setlease handlers may see requests for leases on directories. Push the !S_ISREG check down into the non-trivial setlease handlers, so we can selectively enable them where they're supported. FUSE is specialr:. It's the only filesystem that supports atomic_open and allow kernel-internal leases. Ensure that we don't allow directory leases by default going forward by explicitly disabling them there. Signed-off-by: Jeff Layton --- fs/fuse/dir.c | 1 + fs/locks.c | 5 +++-- fs/nfs/nfs4file.c | 2 ++ fs/smb/client/cifsfs.c | 3 +++ 4 files changed, 9 insertions(+), 2 deletions(-) diff --git a/fs/fuse/dir.c b/fs/fuse/dir.c index 33b82529cb6e4bffa607e1b20bd09ac489b0667f..c83e61b52e0fff106ef2a3d62ef= cc3949ccf39e7 100644 --- a/fs/fuse/dir.c +++ b/fs/fuse/dir.c @@ -2218,6 +2218,7 @@ static const struct file_operations fuse_dir_operatio= ns =3D { .fsync =3D fuse_dir_fsync, .unlocked_ioctl =3D fuse_dir_ioctl, .compat_ioctl =3D fuse_dir_compat_ioctl, + .setlease =3D simple_nosetlease, }; =20 static const struct inode_operations fuse_common_inode_operations =3D { diff --git a/fs/locks.c b/fs/locks.c index 1619cddfa7a4d799f0f84f0bc8f28458d8d280db..a35d033dcaf0b604b7339526056= 2af08f7711c12 100644 --- a/fs/locks.c +++ b/fs/locks.c @@ -1929,6 +1929,9 @@ static int generic_delete_lease(struct file *filp, vo= id *owner) int generic_setlease(struct file *filp, int arg, struct file_lease **flp, void **priv) { + if (!S_ISREG(file_inode(filp)->i_mode)) + return -EINVAL; + switch (arg) { case F_UNLCK: return generic_delete_lease(filp, *priv); @@ -2018,8 +2021,6 @@ vfs_setlease(struct file *filp, int arg, struct file_= lease **lease, void **priv) =20 if ((!vfsuid_eq_kuid(vfsuid, current_fsuid())) && !capable(CAP_LEASE)) return -EACCES; - if (!S_ISREG(inode->i_mode)) - return -EINVAL; error =3D security_file_lock(filp, arg); if (error) return error; diff --git a/fs/nfs/nfs4file.c b/fs/nfs/nfs4file.c index 1cd9652f3c280358209f22503ea573a906a6194e..b7630a437ad22fbfb658086953b= 25b9ae6b4f057 100644 --- a/fs/nfs/nfs4file.c +++ b/fs/nfs/nfs4file.c @@ -442,6 +442,8 @@ void nfs42_ssc_unregister_ops(void) static int nfs4_setlease(struct file *file, int arg, struct file_lease **l= ease, void **priv) { + if (!S_ISREG(file_inode(file)->i_mode)) + return -EINVAL; return nfs4_proc_setlease(file, arg, lease, priv); } =20 diff --git a/fs/smb/client/cifsfs.c b/fs/smb/client/cifsfs.c index fb04e263611cadaea210f5c1d90c05bea37fb496..991583b0b77e480c002974b410f= 06853740e4b1b 100644 --- a/fs/smb/client/cifsfs.c +++ b/fs/smb/client/cifsfs.c @@ -1094,6 +1094,9 @@ cifs_setlease(struct file *file, int arg, struct file= _lease **lease, void **priv struct inode *inode =3D file_inode(file); struct cifsFileInfo *cfile =3D file->private_data; =20 + if (!S_ISREG(inode->i_mode)) + return -EINVAL; + /* Check if file is oplocked if this is request for new lease */ if (arg =3D=3D F_UNLCK || ((arg =3D=3D F_RDLCK) && CIFS_CACHE_READ(CIFS_I(inode))) || --=20 2.49.0 From nobody Thu Dec 18 14:10:55 2025 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 81546221734; Mon, 2 Jun 2025 14:02:26 +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=1748872946; cv=none; b=rBQd3Nc+lVn/dQK9sAqEpxIg/QklUHhHdh8VyGNCiBG3lPp1kTa3hSt+zUceXgkQvj0ucA/HvHXeY8Qj6xnP42seH6JfnzILsZCnafOBI0u8YZjRsq5CSJQjRs7YVIV6LcdQAGV6LXT6eJ1S3tn/4FO6TiHQmDspDCtZpl+xTfc= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1748872946; c=relaxed/simple; bh=wKewAHiWEOFgW1QoZgyrA6fB86FGLbmTYq4l0Dsqejg=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=hML5CqhT74deZF352JZ9wr7Up9tBJdQJD8HA3NzU+R7N8OhbkarXZX3hMnvhu3285aqt6Ky9+RvI7A0d/JPayELL0eYeI6LgFBvIzM8OCBfDQsm4b0CBgJ+bYJ5iHTZq4JnSpUIQHkqP8MzBiU/MorXRjnpwXpLd9q1jQZEuFpY= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=Rinaoyqr; 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="Rinaoyqr" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 5B600C4CEEB; Mon, 2 Jun 2025 14:02:24 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1748872946; bh=wKewAHiWEOFgW1QoZgyrA6fB86FGLbmTYq4l0Dsqejg=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=Rinaoyqr8dFUIHU+2oX/+zGLFrjFCxSPXPRpA0opXWxf8xD19TnKgfawdWspMbWVJ BiiZaeFd5Q1bg9qv9lSizor7M+SPMmB28dt2j11gElaTZvJweT9Njhgmmd8qXSBaPD x/7JK1TpYdzffDtuUU0iZAZ4QDMIM5pLLNbFfBUZE7iLba7rOKHXBNtmrlE+9CjXcO UaPzLbh5TNF2FEklEEhZIKzzW7ybmf6cBM7skYIypi7Szh0iSIvqrAyrRSSw00G/Qg Qnt8bnwYHTlJnrie08MT0wYaQwxY5S0gZ4dr4r77cieFar25Qwo/AIxE5/Coii5Zmg /mvYe8Jk0+y7A== From: Jeff Layton Date: Mon, 02 Jun 2025 10:01:45 -0400 Subject: [PATCH RFC v2 02/28] filelock: add a lm_may_setlease lease_manager callback Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20250602-dir-deleg-v2-2-a7919700de86@kernel.org> References: <20250602-dir-deleg-v2-0-a7919700de86@kernel.org> In-Reply-To: <20250602-dir-deleg-v2-0-a7919700de86@kernel.org> To: Alexander Viro , Christian Brauner , Jan Kara , Chuck Lever , Alexander Aring , Trond Myklebust , Anna Schumaker , Steve French , Paulo Alcantara , Ronnie Sahlberg , Shyam Prasad N , Tom Talpey , Bharath SM , NeilBrown , Olga Kornievskaia , Dai Ngo , Jonathan Corbet , Amir Goldstein , Miklos Szeredi Cc: linux-fsdevel@vger.kernel.org, linux-kernel@vger.kernel.org, linux-nfs@vger.kernel.org, linux-cifs@vger.kernel.org, samba-technical@lists.samba.org, linux-doc@vger.kernel.org, Jeff Layton X-Mailer: b4 0.14.2 X-Developer-Signature: v=1; a=openpgp-sha256; l=2064; i=jlayton@kernel.org; h=from:subject:message-id; bh=wKewAHiWEOFgW1QoZgyrA6fB86FGLbmTYq4l0Dsqejg=; b=owEBbQKS/ZANAwAKAQAOaEEZVoIVAcsmYgBoPa7kN5gi6pOdlRySs6JiHUrX2MqFH9UXBVhMR ohl4xsXruaJAjMEAAEKAB0WIQRLwNeyRHGyoYTq9dMADmhBGVaCFQUCaD2u5AAKCRAADmhBGVaC FbSxD/sExPaSZIy1Y7QararXr9H5CHtdKGclmI8nbRacdoCige095AhYGj+5qnQdgKtUm9n+TFw sT84eYzC5Y9J2olo5RGVR54QmUGiOFNcHp8pfCbuCCCTKpFc3xl0tpf6BzTaEvy+hFF2EauiSNM dP0iKMcTCuNWMzKl3pfLlBLHfHHWHFTeflKlTSlBi2OXpx8ljgldHWsjzUCqel+Ia/kp0PT+fIX SteUln8fh9gDv2apF0+cQTv6UuqLrOXUCEpcgI+YWAOXqShD0luQspQhP8J6arEBQ5tweddRVw/ JY72OYSuEYPnh3FxE4uNuZrsRdfs4uk6kwg2HX5XUUIdRXZR3zLVXz4rC3H+3zWYdPxENGHan0t E7o0OCzpqkysBnB5P5eWNYJ/me9zIc9tL6zakv3EA6TxCK+CuDn0bfoogDOplSzRapYQTt5M9EN djzgaDxBbHauKCpLBHa0wMgjsne9kbRpJmpYHiM3b96aPQeV+4tbyHRdUgCvOqfrE7ClGf5TApt FC86i8vomhc+388xTyYshqczJrRz26bGo1s7lplVVYXZt1vZg3iuT5OgA168Lj0tceXDjp/jvIX u3VjwYEXuq16cbRt+kn8fly4oS8+/dQR/Z9T8EwbYZ2ADZrOzD9yUcu2mjwd5RtEJp70By0qCo7 2O4KwH3SpRDLl/Q== X-Developer-Key: i=jlayton@kernel.org; a=openpgp; fpr=4BC0D7B24471B2A184EAF5D3000E684119568215 The NFSv4.1 protocol adds support for directory delegations, but it specifies that if you already have a delegation and try to request a new one on the same filehandle, the server must reply that the delegation is unavailable. Add a new lease manager callback to allow the lease manager (nfsd in this case) to impose this extra check when performing a setlease. Signed-off-by: Jeff Layton --- fs/locks.c | 5 +++++ include/linux/filelock.h | 14 ++++++++++++++ 2 files changed, 19 insertions(+) diff --git a/fs/locks.c b/fs/locks.c index a35d033dcaf0b604b73395260562af08f7711c12..1985f38d326d938f58009e0880b= 45e588af6a422 100644 --- a/fs/locks.c +++ b/fs/locks.c @@ -1826,6 +1826,11 @@ generic_add_lease(struct file *filp, int arg, struct= file_lease **flp, void **pr continue; } =20 + /* Allow the lease manager to veto the setlease */ + if (lease->fl_lmops->lm_may_setlease && + !lease->fl_lmops->lm_may_setlease(lease, fl)) + goto out; + /* * No exclusive leases if someone else has a lease on * this file: diff --git a/include/linux/filelock.h b/include/linux/filelock.h index c412ded9171ed781ebe9e8d2e0426dcd10793292..60c76c8fb4dfdcaaa2cfa3f41f0= f26ffcb3db29f 100644 --- a/include/linux/filelock.h +++ b/include/linux/filelock.h @@ -49,6 +49,20 @@ struct lease_manager_operations { int (*lm_change)(struct file_lease *, int, struct list_head *); void (*lm_setup)(struct file_lease *, void **); bool (*lm_breaker_owns_lease)(struct file_lease *); + + /** + * lm_may_setlease - extra conditions for setlease + * @new: new file_lease being set + * @old: old (extant) file_lease + * + * This allows the lease manager to add extra conditions when + * setting a lease, based on the presence of an existing lease. + * + * Return values: + * %false: @new and @old conflict + * %true: No conflict detected + */ + bool (*lm_may_setlease)(struct file_lease *new, struct file_lease *old); }; =20 struct lock_manager { --=20 2.49.0 From nobody Thu Dec 18 14:10:55 2025 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 E77C0224B0D; Mon, 2 Jun 2025 14:02: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=1748872949; cv=none; b=S7BayKwJ+ETxkLwiNQnv8r5Dhp0g+gA+K3CH3pX9xsPbwyLNEz/VTch53Za1YB2Xln7BREgjK2bs4/QUpHZWvBV8+6sYsgPbSpL0BH9VYOmKIRiEOIJwILdk7ZJ1+wsOBUeX+V/6Ls+THvbFC/f5d0+rIYUenUvdULhtmFTBaHk= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1748872949; c=relaxed/simple; bh=x7aiTOFWz2bzqHo5/KSyfTkqfew35Z2CcU5pcuEOZks=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=hitZ+RHXXVMIRCn18QPqOxLIZCkOPMrCV/39VjSliWetD7y7JnQHvoJMR/aCVSgkmFxouvAFO+Ul+fdqysWZBkjZVyAmWw1DwvWL/RmAIicC3fO0SoZsdPPFH9AB4WA8hpdx1OhGP05rV51JJojmaiH8YX8L9HrC0jLjlF70jaA= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=bzifuCHC; 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="bzifuCHC" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 7A0D6C4CEEE; Mon, 2 Jun 2025 14:02:26 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1748872948; bh=x7aiTOFWz2bzqHo5/KSyfTkqfew35Z2CcU5pcuEOZks=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=bzifuCHCS/WZCVd9UJkV/NtmB3Bb8whCyDanGcQKy0JqZg9r1orGjp56Ds1/bwHsq DtTnIevfiSgzUv2HKLCIQETTcRfMJCWvOYJELxCmrKqXdWG/2c8gbaekJMznKhO0y9 H1IXMnq2PH/1RVeRKYj/O7n4bWM4/k7ib3S85tlOdko/4uwNVBN2A18Nd6NahETYXH J6sVupQPlI/PYxN8qWn72/hD44zbVrWpl+8sj/O8r4tvgG1JbGw0K5+Gtohl+iTRGP VaBA7XyPNnCN5y/eAmHiJ3/4rtxZeTTCksuNQb8Oif/U2UNBoaZlUovP6Zv8gTReh2 RK7AFbATVC6OQ== From: Jeff Layton Date: Mon, 02 Jun 2025 10:01:46 -0400 Subject: [PATCH RFC v2 03/28] vfs: add try_break_deleg calls for parents to vfs_{link,rename,unlink} Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20250602-dir-deleg-v2-3-a7919700de86@kernel.org> References: <20250602-dir-deleg-v2-0-a7919700de86@kernel.org> In-Reply-To: <20250602-dir-deleg-v2-0-a7919700de86@kernel.org> To: Alexander Viro , Christian Brauner , Jan Kara , Chuck Lever , Alexander Aring , Trond Myklebust , Anna Schumaker , Steve French , Paulo Alcantara , Ronnie Sahlberg , Shyam Prasad N , Tom Talpey , Bharath SM , NeilBrown , Olga Kornievskaia , Dai Ngo , Jonathan Corbet , Amir Goldstein , Miklos Szeredi Cc: linux-fsdevel@vger.kernel.org, linux-kernel@vger.kernel.org, linux-nfs@vger.kernel.org, linux-cifs@vger.kernel.org, samba-technical@lists.samba.org, linux-doc@vger.kernel.org, Jeff Layton X-Mailer: b4 0.14.2 X-Developer-Signature: v=1; a=openpgp-sha256; l=1835; i=jlayton@kernel.org; h=from:subject:message-id; bh=x7aiTOFWz2bzqHo5/KSyfTkqfew35Z2CcU5pcuEOZks=; b=owEBbQKS/ZANAwAKAQAOaEEZVoIVAcsmYgBoPa7kzTqGni5Ja5kAcAQpI0svqT+14uiOlWvyh NxdnTsxBO2JAjMEAAEKAB0WIQRLwNeyRHGyoYTq9dMADmhBGVaCFQUCaD2u5AAKCRAADmhBGVaC Fc6yD/wKBJg9QCb43FABMtBsjLoBcnpwlMFHkEulA5zhX5uLV59pfNnhk7JCY/iEgBf+yMgBgTT hd/PKS0Ioa3IOw7Q6Gu8L5Ao/e9H9+RP2nxGmKQB7vjdcD5WMEbNMlgzQv2Kw7TxjufA5kZA99R EGI6AAnVut3h60GYW4FfPxthQAy7SQvhQl9rilLkYMgdDSH/O/iZyY2QVLk6Ijooa1ubGMpUSPa pJgSTh3wDRgYDO61bBH3uN75EGxdPZ9nTEdu5MEfieddxr0fNkUv1lmDTHGgpfXJvD6haWbGqmU yTvR8ro7PrJCd69vkl8x9JgR4PR2hzd6671kJ9/P8RS/Gw56hFezomI5HTNPdmdZga5l8LACSgj Er2krGYblOhoSGxof3b21DqMzM/V3SJWttF21Y3Tf03XhzTuWe6rckb4hRpwgVx34iSNuOJBotk +luYzfvap3t9B4+77W1a1B/he8AMMprJDzyGh7xCLmaa3a6/DoxZyvWDGdjwdx0lYt1WKSc5V+K fU+rM+zorEYICtUgvae5kLCrJhPoInfxIJyAUIGFhKWTAKJHn94s6j8T0WEgRFEDXOVOkWqWG3A ESffo86gu55A5zImpPgdTpVNX9Hydl1r3MIF2F4ubZ5lJLGKAsCYaYDtty+ab43rv3U+DRloQ5u UpMrwc8kemdbBAg== X-Developer-Key: i=jlayton@kernel.org; a=openpgp; fpr=4BC0D7B24471B2A184EAF5D3000E684119568215 In order to add directory delegation support, we need to break delegations on the parent whenever there is going to be a change in the directory. vfs_link, vfs_unlink, and vfs_rename all have existing delegation break handling for the children in the rename. Add the necessary calls for breaking delegations in the parent(s) as well. Signed-off-by: Jeff Layton --- fs/namei.c | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/fs/namei.c b/fs/namei.c index 4bb889fc980b7d44914e11ec38ae3e8fdfbafadd..0fea12860036162c01a291558e0= 68fde9c986142 100644 --- a/fs/namei.c +++ b/fs/namei.c @@ -4580,6 +4580,9 @@ int vfs_unlink(struct mnt_idmap *idmap, struct inode = *dir, else { error =3D security_inode_unlink(dir, dentry); if (!error) { + error =3D try_break_deleg(dir, delegated_inode); + if (error) + goto out; error =3D try_break_deleg(target, delegated_inode); if (error) goto out; @@ -4849,7 +4852,9 @@ int vfs_link(struct dentry *old_dentry, struct mnt_id= map *idmap, else if (max_links && inode->i_nlink >=3D max_links) error =3D -EMLINK; else { - error =3D try_break_deleg(inode, delegated_inode); + error =3D try_break_deleg(dir, delegated_inode); + if (!error) + error =3D try_break_deleg(inode, delegated_inode); if (!error) error =3D dir->i_op->link(old_dentry, dir, new_dentry); } @@ -5115,6 +5120,14 @@ int vfs_rename(struct renamedata *rd) old_dir->i_nlink >=3D max_links) goto out; } + error =3D try_break_deleg(old_dir, delegated_inode); + if (error) + goto out; + if (new_dir !=3D old_dir) { + error =3D try_break_deleg(new_dir, delegated_inode); + if (error) + goto out; + } if (!is_dir) { error =3D try_break_deleg(source, delegated_inode); if (error) --=20 2.49.0 From nobody Thu Dec 18 14:10:55 2025 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 C1083225417; Mon, 2 Jun 2025 14:02:30 +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=1748872950; cv=none; b=AvJa7KsZXYpGtWrZwNeJXq0MD1xAg81WI63nIQXT6scT6x+AB/OVfpGJUgx9zZ9Ej5/JIIubXNulht7VBJjcQgIgPnkCh013e6aWEVPmo78Jq1L5U/HWeBsuFakO2FoIxMGhtxStrO7vqVdXr+6aBU4mVohsnu95KY2tAzikvYw= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1748872950; c=relaxed/simple; bh=xMuOkareOjJkjyUfBS4IvfeElA0FAadf3AwmfN0gZJU=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=CUHF5SJEE6BNh0ji/AfwS/B8sJH3H4TB+wxauaclfApPeUTgKoUYswwJPvEIyYwiut4KFjncM8Gduu1XEmWYM3qmd0WqLeqhgIn8aQNRUmmHgybob+FwHBuqt+jRZVJAANhodewHryi0RrJKjaSwNE6iz4B5HNwEmaMyWgkIyac= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=pv1/3uw/; 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="pv1/3uw/" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 98690C4CEEB; Mon, 2 Jun 2025 14:02:28 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1748872950; bh=xMuOkareOjJkjyUfBS4IvfeElA0FAadf3AwmfN0gZJU=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=pv1/3uw/IpTYy0uOvTHgd5Fh0TaY2AIcpny39eMSm2IdvsIbLlBpYrshtIfgWv9s6 MLbIvTI/QTJx/j7rliqjAe19yTJBcQJtpPTsFST5QaFclmawTrslbOQlBASbxoUpvO vVjq/U5HuWZ4xv0WZOYMR3Yxpxoo49ueArvPSwxhK7QPTPMRuhgDNZa6DpaErvm5Ml PEOA+lMIxJrjlZUlVEtA7pXODt6v4sDm07aknH3o8VUb/85OZpJiZwOiO3SAMWfx9R 0HxvIwCgnTL8UyFUu17dIPNsHDcQYFQVPr6QIQ5AGudJoBRSilpnc2SftLh8fFhWcE jeVO9k0cSGkpQ== From: Jeff Layton Date: Mon, 02 Jun 2025 10:01:47 -0400 Subject: [PATCH RFC v2 04/28] vfs: allow mkdir to wait for delegation break on parent Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20250602-dir-deleg-v2-4-a7919700de86@kernel.org> References: <20250602-dir-deleg-v2-0-a7919700de86@kernel.org> In-Reply-To: <20250602-dir-deleg-v2-0-a7919700de86@kernel.org> To: Alexander Viro , Christian Brauner , Jan Kara , Chuck Lever , Alexander Aring , Trond Myklebust , Anna Schumaker , Steve French , Paulo Alcantara , Ronnie Sahlberg , Shyam Prasad N , Tom Talpey , Bharath SM , NeilBrown , Olga Kornievskaia , Dai Ngo , Jonathan Corbet , Amir Goldstein , Miklos Szeredi Cc: linux-fsdevel@vger.kernel.org, linux-kernel@vger.kernel.org, linux-nfs@vger.kernel.org, linux-cifs@vger.kernel.org, samba-technical@lists.samba.org, linux-doc@vger.kernel.org, Jeff Layton X-Mailer: b4 0.14.2 X-Developer-Signature: v=1; a=openpgp-sha256; l=4897; i=jlayton@kernel.org; h=from:subject:message-id; bh=xMuOkareOjJkjyUfBS4IvfeElA0FAadf3AwmfN0gZJU=; b=owEBbQKS/ZANAwAKAQAOaEEZVoIVAcsmYgBoPa7k4bw5YQLN8ucaXbTAdLj/XT1eNL9+G4ufs MDSnEU1B1yJAjMEAAEKAB0WIQRLwNeyRHGyoYTq9dMADmhBGVaCFQUCaD2u5AAKCRAADmhBGVaC FZx1D/9C40qh8CQhavJ78Mw8gLubF5wF1xv1dj4OWwtN5GDDSpAuhx2DaqqE2deCyBhm3KWxCBR xrlnOxGc+OsnzC4utibTSIbwNMpsUFgyLK2G+FEnLGlKcntIAP0iw97EH7njrI+d6LTAWg1pUQy irJJkfpMAhp2fEqMM3k0+rTJjBilBsrQyDgHYf3GYu4PxLupM892bvNURmvxcmYIdgMVNtwmN5P ScAeecqkiIKaLk/WJtloF/X7fDwbApNhU2pGa/AC9a9abdLL2gSQS6fTEwnuGTa1yUXBycIGd2c uvqIKwtICMgy1BjC6WRII6mOJ6MQ7Zr2bIvMDCpAcYDZmEbhDLAnl1cZnLyGakxmaAGv+79dD7Q d6c87sBzX+AkURnJoSqUZtbVN7zHovADkWvbTHjnNI3fAHny5DytNAmEOzdPe0UJbReJw38vk3i TFgsGVw/RAOj1P1jUSaoZvRB1RFyfOxpPguEaACtDxz79yQOKuWWyoTvjKVMfvt1Z88uOEiiUZN STKoGtBZZpTuNW2a3MhtFvvoxSe4DHk/kKfh2qyk+C7cYjQlogSRED55JwIbRoNSoWXzer+iIie tTXSe4SS/7kJ3CSGfaP+lN2F5H3hSSub12O1Ayhpqm2eZd7h15qqjQLchxx0hCppJGi7IHbYqoV GrQO1uz4hrcxIvA== X-Developer-Key: i=jlayton@kernel.org; a=openpgp; fpr=4BC0D7B24471B2A184EAF5D3000E684119568215 In order to add directory delegation support, we need to break delegations on the parent whenever there is going to be a change in the directory. Rename the existing vfs_mkdir to __vfs_mkdir, make it static and add a new delegated_inode parameter. Add a new exported vfs_mkdir wrapper around it that passes a NULL pointer for delegated_inode. Signed-off-by: Jeff Layton --- fs/namei.c | 67 +++++++++++++++++++++++++++++++++++++++-------------------= ---- 1 file changed, 42 insertions(+), 25 deletions(-) diff --git a/fs/namei.c b/fs/namei.c index 0fea12860036162c01a291558e068fde9c986142..7c9e237ed1b1a535934ffe5e523= 424bb035e7ae0 100644 --- a/fs/namei.c +++ b/fs/namei.c @@ -4318,29 +4318,9 @@ SYSCALL_DEFINE3(mknod, const char __user *, filename= , umode_t, mode, unsigned, d return do_mknodat(AT_FDCWD, getname(filename), mode, dev); } =20 -/** - * vfs_mkdir - create directory returning correct dentry if possible - * @idmap: idmap of the mount the inode was found from - * @dir: inode of the parent directory - * @dentry: dentry of the child directory - * @mode: mode of the child directory - * - * Create a directory. - * - * If the inode has been found through an idmapped mount the idmap of - * the vfsmount must be passed through @idmap. This function will then take - * care to map the inode according to @idmap before checking permissions. - * On non-idmapped mounts or if permission checking is to be performed on = the - * raw inode simply pass @nop_mnt_idmap. - * - * In the event that the filesystem does not use the *@dentry but leaves it - * negative or unhashes it and possibly splices a different one returning = it, - * the original dentry is dput() and the alternate is returned. - * - * In case of an error the dentry is dput() and an ERR_PTR() is returned. - */ -struct dentry *vfs_mkdir(struct mnt_idmap *idmap, struct inode *dir, - struct dentry *dentry, umode_t mode) +static struct dentry *__vfs_mkdir(struct mnt_idmap *idmap, struct inode *d= ir, + struct dentry *dentry, umode_t mode, + struct inode **delegated_inode) { int error; unsigned max_links =3D dir->i_sb->s_max_links; @@ -4363,6 +4343,10 @@ struct dentry *vfs_mkdir(struct mnt_idmap *idmap, st= ruct inode *dir, if (max_links && dir->i_nlink >=3D max_links) goto err; =20 + error =3D try_break_deleg(dir, delegated_inode); + if (error) + goto err; + de =3D dir->i_op->mkdir(idmap, dir, dentry, mode); error =3D PTR_ERR(de); if (IS_ERR(de)) @@ -4378,6 +4362,33 @@ struct dentry *vfs_mkdir(struct mnt_idmap *idmap, st= ruct inode *dir, dput(dentry); return ERR_PTR(error); } + +/** + * vfs_mkdir - create directory returning correct dentry if possible + * @idmap: idmap of the mount the inode was found from + * @dir: inode of the parent directory + * @dentry: dentry of the child directory + * @mode: mode of the child directory + * + * Create a directory. + * + * If the inode has been found through an idmapped mount the idmap of + * the vfsmount must be passed through @idmap. This function will then take + * care to map the inode according to @idmap before checking permissions. + * On non-idmapped mounts or if permission checking is to be performed on = the + * raw inode simply pass @nop_mnt_idmap. + * + * In the event that the filesystem does not use the *@dentry but leaves it + * negative or unhashes it and possibly splices a different one returning = it, + * the original dentry is dput() and the alternate is returned. + * + * In case of an error the dentry is dput() and an ERR_PTR() is returned. + */ +struct dentry *vfs_mkdir(struct mnt_idmap *idmap, struct inode *dir, + struct dentry *dentry, umode_t mode) +{ + return __vfs_mkdir(idmap, dir, dentry, mode, NULL); +} EXPORT_SYMBOL(vfs_mkdir); =20 int do_mkdirat(int dfd, struct filename *name, umode_t mode) @@ -4386,6 +4397,7 @@ int do_mkdirat(int dfd, struct filename *name, umode_= t mode) struct path path; int error; unsigned int lookup_flags =3D LOOKUP_DIRECTORY; + struct inode *delegated_inode =3D NULL; =20 retry: dentry =3D filename_create(dfd, name, &path, lookup_flags); @@ -4396,12 +4408,17 @@ int do_mkdirat(int dfd, struct filename *name, umod= e_t mode) error =3D security_path_mkdir(&path, dentry, mode_strip_umask(path.dentry->d_inode, mode)); if (!error) { - dentry =3D vfs_mkdir(mnt_idmap(path.mnt), path.dentry->d_inode, - dentry, mode); + dentry =3D __vfs_mkdir(mnt_idmap(path.mnt), path.dentry->d_inode, + dentry, mode, &delegated_inode); if (IS_ERR(dentry)) error =3D PTR_ERR(dentry); } done_path_create(&path, dentry); + if (delegated_inode) { + error =3D break_deleg_wait(&delegated_inode); + if (!error) + goto retry; + } if (retry_estale(error, lookup_flags)) { lookup_flags |=3D LOOKUP_REVAL; goto retry; --=20 2.49.0 From nobody Thu Dec 18 14:10:55 2025 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 D2FF1227EB9; Mon, 2 Jun 2025 14:02:32 +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=1748872953; cv=none; b=D2ecVe82rShgF033BAU48eRMcjq3Owwkz80Rw3OYBXOpB6BMmIdUJ/5R8ogE7NcfcPIcPdYxP9CKjKmDLr4jDUsnt4mt71qHiuNiz+L0UTp74Mu4cyBZewIMvTWhy/TUvuQxSdSXmUI1gEWZG4dOohjA06atEl5/uWa2MS6lhEo= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1748872953; c=relaxed/simple; bh=hq54trMBQfOBExEaJCPkyc60i4ZI5QVe6/7T7Saw+Bw=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=uERW9Go+vzWGHytOYXvI2igNc935+9a3hnOIBY5pfxVRjJMnCkNbOhllze5dy2nOyNeaIu8lIHENvu7opE5iMQk3j95OT5bPgTOnT8aXkRLtOsmLMbcyfjYuKGCFbvEyrMxqMDODcRMZtt1pHXWu/tCa+F7/uDAvpR72K/Y4DeY= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=e8n5BTMW; 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="e8n5BTMW" Received: by smtp.kernel.org (Postfix) with ESMTPSA id B8D52C4CEF5; Mon, 2 Jun 2025 14:02:30 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1748872952; bh=hq54trMBQfOBExEaJCPkyc60i4ZI5QVe6/7T7Saw+Bw=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=e8n5BTMWqm9rH+yOhZheCg6a1BBv02LOeszJqMwoYB7fD9zcElbTKKUN+knAl6VGP sJ1jzvjljWnVAAEg9/FjLY1voQy7MJzt9uX/yDajbUwD9xY1+llsiUg/e6SsbhSKrL nz1OmAkuAdXi1042hft8BtTDPzok2Qb6acU6NGU0lmmApw9h/EKGXIxaOOpsCdBuTb S+8YwGJwWJzt4o3ijWGx0p6Ngu8/x4vATNwh65BKU7Ak5l/sHvR2w+xOiSiP/CbtlJ wyvovlNW5q23lrXZNi1Pea4ohv0Pi23n2qEKIQL/Ivs+PMw7PfZ6I9Rbte5q57Bl+E GbbAF84wgIMhg== From: Jeff Layton Date: Mon, 02 Jun 2025 10:01:48 -0400 Subject: [PATCH RFC v2 05/28] vfs: allow rmdir to wait for delegation break on parent Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20250602-dir-deleg-v2-5-a7919700de86@kernel.org> References: <20250602-dir-deleg-v2-0-a7919700de86@kernel.org> In-Reply-To: <20250602-dir-deleg-v2-0-a7919700de86@kernel.org> To: Alexander Viro , Christian Brauner , Jan Kara , Chuck Lever , Alexander Aring , Trond Myklebust , Anna Schumaker , Steve French , Paulo Alcantara , Ronnie Sahlberg , Shyam Prasad N , Tom Talpey , Bharath SM , NeilBrown , Olga Kornievskaia , Dai Ngo , Jonathan Corbet , Amir Goldstein , Miklos Szeredi Cc: linux-fsdevel@vger.kernel.org, linux-kernel@vger.kernel.org, linux-nfs@vger.kernel.org, linux-cifs@vger.kernel.org, samba-technical@lists.samba.org, linux-doc@vger.kernel.org, Jeff Layton X-Mailer: b4 0.14.2 X-Developer-Signature: v=1; a=openpgp-sha256; l=4012; i=jlayton@kernel.org; h=from:subject:message-id; bh=hq54trMBQfOBExEaJCPkyc60i4ZI5QVe6/7T7Saw+Bw=; b=owEBbQKS/ZANAwAKAQAOaEEZVoIVAcsmYgBoPa7lWGnbULXucj0fCehfGYQ3sLRbedLR7Sm1Q GjuO3AFDqeJAjMEAAEKAB0WIQRLwNeyRHGyoYTq9dMADmhBGVaCFQUCaD2u5QAKCRAADmhBGVaC FXNMD/9jRqeOyIiQhocqTsdyPQa1pLi521eSfX5vDTVGnF0pQGHmyz1UAra13z/vYzBEwZnL0U3 K/XUDmz8tmqV5fUc8qXqLKNjXoFNhW+pGkFNNX08FkYcNSAfdDRk293Yd2V8SIr3dO1zTlJcmJM ukPiMpFIl/0GssxnwShZclq6z7vnS9Tb/oW1JIPlVHPvLdpG8eNFZr6KHoYI1BKrXSN0u4U59q6 lVsUNeYNWnpVtYdMBSMzGZrh/PQWIUETTDw/pqj3FYqfgZWciZpgS384z5U9G5yaJmWcrMydO5i x03KHJN2ElrO0lyaM/STc5pCLgjuIqbU6ge4NctPWN7/ga/kfn0uHcstqqK4BkxhBwcGY706/Tg NesQZT+2rJ4Xclqvt4U07ozs24IZTUNgiE3DPE0WIegCJS/T4+oaQwQnGDkvgwYNIjSMa17AI9s c0ESYFIbV+XuI9RBiOKv4P9e2l6czOD9fiVfvwbFWtMeXoZmQXkO/dn1qZE7893jlAsHQRZwWUZ JXUYb767M5L1UnUG9R5zmGyWg3jRJKkPxtT4pAJq++v34qrjqGKWeRgqagLljGxXGDf2XQwGXyv WM2j5j6GJ/BDERDcunPpBOdL3DvQR+o1o/Zy40oClaGrfkfnUPnw9qJw5o6JibJGmCaBcgLvhCL rs5j4UJyiclmNbA== X-Developer-Key: i=jlayton@kernel.org; a=openpgp; fpr=4BC0D7B24471B2A184EAF5D3000E684119568215 In order to add directory delegation support, we need to break delegations on the parent whenever there is going to be a change in the directory. Rename vfs_rmdir as __vfs_rmdir, make it static and add a new delegated_inode parameter. Add a vfs_rmdir wrapper that passes in a NULL pointer for it. Add the necessary try_break_deleg calls to __vfs_rmdir(). Convert do_rmdir to use __vfs_rmdir and wait for the delegation break to complete before proceeding. Signed-off-by: Jeff Layton --- fs/namei.c | 51 ++++++++++++++++++++++++++++++++++----------------- 1 file changed, 34 insertions(+), 17 deletions(-) diff --git a/fs/namei.c b/fs/namei.c index 7c9e237ed1b1a535934ffe5e523424bb035e7ae0..2211ed9f427cc97391d068b1a33= ce388266a3e02 100644 --- a/fs/namei.c +++ b/fs/namei.c @@ -4438,22 +4438,8 @@ SYSCALL_DEFINE2(mkdir, const char __user *, pathname= , umode_t, mode) return do_mkdirat(AT_FDCWD, getname(pathname), mode); } =20 -/** - * vfs_rmdir - remove directory - * @idmap: idmap of the mount the inode was found from - * @dir: inode of the parent directory - * @dentry: dentry of the child directory - * - * Remove a directory. - * - * If the inode has been found through an idmapped mount the idmap of - * the vfsmount must be passed through @idmap. This function will then take - * care to map the inode according to @idmap before checking permissions. - * On non-idmapped mounts or if permission checking is to be performed on = the - * raw inode simply pass @nop_mnt_idmap. - */ -int vfs_rmdir(struct mnt_idmap *idmap, struct inode *dir, - struct dentry *dentry) +static int __vfs_rmdir(struct mnt_idmap *idmap, struct inode *dir, + struct dentry *dentry, struct inode **delegated_inode) { int error =3D may_delete(idmap, dir, dentry, 1); =20 @@ -4475,6 +4461,10 @@ int vfs_rmdir(struct mnt_idmap *idmap, struct inode = *dir, if (error) goto out; =20 + error =3D try_break_deleg(dir, delegated_inode); + if (error) + goto out; + error =3D dir->i_op->rmdir(dir, dentry); if (error) goto out; @@ -4491,6 +4481,26 @@ int vfs_rmdir(struct mnt_idmap *idmap, struct inode = *dir, d_delete_notify(dir, dentry); return error; } + +/** + * vfs_rmdir - remove directory + * @idmap: idmap of the mount the inode was found from + * @dir: inode of the parent directory + * @dentry: dentry of the child directory + * + * Remove a directory. + * + * If the inode has been found through an idmapped mount the idmap of + * the vfsmount must be passed through @idmap. This function will then take + * care to map the inode according to @idmap before checking permissions. + * On non-idmapped mounts or if permission checking is to be performed on = the + * raw inode simply pass @nop_mnt_idmap. + */ +int vfs_rmdir(struct mnt_idmap *idmap, struct inode *dir, + struct dentry *dentry) +{ + return __vfs_rmdir(idmap, dir, dentry, NULL); +} EXPORT_SYMBOL(vfs_rmdir); =20 int do_rmdir(int dfd, struct filename *name) @@ -4501,6 +4511,7 @@ int do_rmdir(int dfd, struct filename *name) struct qstr last; int type; unsigned int lookup_flags =3D 0; + struct inode *delegated_inode =3D NULL; retry: error =3D filename_parentat(dfd, name, lookup_flags, &path, &last, &type); if (error) @@ -4530,7 +4541,8 @@ int do_rmdir(int dfd, struct filename *name) error =3D security_path_rmdir(&path, dentry); if (error) goto exit4; - error =3D vfs_rmdir(mnt_idmap(path.mnt), path.dentry->d_inode, dentry); + error =3D __vfs_rmdir(mnt_idmap(path.mnt), path.dentry->d_inode, + dentry, &delegated_inode); exit4: dput(dentry); exit3: @@ -4538,6 +4550,11 @@ int do_rmdir(int dfd, struct filename *name) mnt_drop_write(path.mnt); exit2: path_put(&path); + if (delegated_inode) { + error =3D break_deleg_wait(&delegated_inode); + if (!error) + goto retry; + } if (retry_estale(error, lookup_flags)) { lookup_flags |=3D LOOKUP_REVAL; goto retry; --=20 2.49.0 From nobody Thu Dec 18 14:10:55 2025 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 DBAB5229B36; Mon, 2 Jun 2025 14:02:34 +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=1748872955; cv=none; b=M1xs+Du5tvMqjDKPznMVfxlYXQCt+EGY09CGZScZ8IyT7K4CkB6SKjjAQ2Yn7gf3GtHuyhxO1cUrhXuxn/JEdbW1ZFMufbeP06HFqJY/Ldfftvpx4HQxNHHdZlApNBUp4uMs3YM6Bv1bADhLPC5Ag0XRoUhMRUqtW4/lPjW4EWc= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1748872955; c=relaxed/simple; bh=T94FDtoTtbYpTjGCzZH79quGDn7pSbDy81dX+17IVpQ=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=GE94LvmrL2LkDwr26ZL2A83bMQO4aZ0EzmF7sBeKTRQxHU+t6wR4tPoQVZh3XTVXZNjdN8bnu1LINx9DWAOQdTCZAMGz+83+gty0wV66WWZ62kVb4rePQP9BxexYtUizjknOeWkju7gP+zZcHiTKC/wEFdD7ZJ/21Pmbg7HstEA= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=FCvjZxmr; 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="FCvjZxmr" Received: by smtp.kernel.org (Postfix) with ESMTPSA id D79C7C4CEEB; Mon, 2 Jun 2025 14:02:32 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1748872954; bh=T94FDtoTtbYpTjGCzZH79quGDn7pSbDy81dX+17IVpQ=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=FCvjZxmrXPRKqP9fjB09AhKpJ1s8ezYUH7qDZHn62yg6FWjyTIahWKevQ6ONtoDhj oNsTCa22wMrTL7CT71kCfYGn3IVkH5JfGwE+tgkBKwPNqJ2SoaZTzbcaEU2nnmEQ6/ gJKZAy8pUuf7esRXJfgNJJstQRllQBj1h0RIUBrtuLYOoySdAMGku/0BA25KzfZcX9 DeG3Jh3rNyERqq3iQTTZmbXVxqTvhL7rHuzG4CSq/WXkm3zv8RV98nAySxvK6oaFSp Fm5Z4EE+wNKG29ujFsACJkmk7R7lLRXzankuy+sr59Z74/F+gjMgrz87vOFtCXitPG ydM6fR1nXpxMA== From: Jeff Layton Date: Mon, 02 Jun 2025 10:01:49 -0400 Subject: [PATCH RFC v2 06/28] vfs: break parent dir delegations in open(..., O_CREAT) codepath Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20250602-dir-deleg-v2-6-a7919700de86@kernel.org> References: <20250602-dir-deleg-v2-0-a7919700de86@kernel.org> In-Reply-To: <20250602-dir-deleg-v2-0-a7919700de86@kernel.org> To: Alexander Viro , Christian Brauner , Jan Kara , Chuck Lever , Alexander Aring , Trond Myklebust , Anna Schumaker , Steve French , Paulo Alcantara , Ronnie Sahlberg , Shyam Prasad N , Tom Talpey , Bharath SM , NeilBrown , Olga Kornievskaia , Dai Ngo , Jonathan Corbet , Amir Goldstein , Miklos Szeredi Cc: linux-fsdevel@vger.kernel.org, linux-kernel@vger.kernel.org, linux-nfs@vger.kernel.org, linux-cifs@vger.kernel.org, samba-technical@lists.samba.org, linux-doc@vger.kernel.org, Jeff Layton X-Mailer: b4 0.14.2 X-Developer-Signature: v=1; a=openpgp-sha256; l=2938; i=jlayton@kernel.org; h=from:subject:message-id; bh=T94FDtoTtbYpTjGCzZH79quGDn7pSbDy81dX+17IVpQ=; b=owEBbQKS/ZANAwAKAQAOaEEZVoIVAcsmYgBoPa7lDHCHXDtRTgcsP29dczBxlTCC3zLfhHy37 Y3wjJ9G9r2JAjMEAAEKAB0WIQRLwNeyRHGyoYTq9dMADmhBGVaCFQUCaD2u5QAKCRAADmhBGVaC FW6LD/9qJP89ewOUrBbOy2ZEUZwFXLnFUTqIpFdhTVyOLsHuqdI+aYIVUxWvbSMhzxt8wm+ukq/ +xri6d0S72UtabzktdUrxp+x7dNUhV+Jb0+81RyQID++S5rLvgL2q1qZNgEyte18gvnh3a9xY10 YApueces7xvftACob86hu0KWEqT2P3Rz38tH5aU9xkhKLkAf0DN1poU/ic2CD/BUjQgh1axEEOz yJCjJjeBTTnczbKCiqRe0VI781IHWVXHAVCCagfnTWPcdG7q7xdKwVaeU4SP4aLZDIRNnPog916 +3xp9q9hzM98Knfz/dvVJIQTg+UTI5HYPjDPTwMXztF075J02FioF875r74785Q7zhNG9pWtrUx crMdJ3K+67bsm8X0wBr8dtpG21hreRzB1Ep9L7kuDtBBR9XTJh9yrgbf9SXlOxgHM+XALS3o6CP wLCxhmWc4mwOzqonY8RvEvajsWaLBWVUGIENUz1bnfqKBxXtWMmYuPpeJACa8D4TtV15h9Pehaq x9YYIw72rsyx1DZVbr43TMj54Ms4U5C0ooWQVOPuTOdByChPnQtC+5kx5wSjgH8HziR6S789JMZ 9TNzWkrx1DSiNY0WtjYB0Omba3kjej0Sje3DXWWRPfkFJ/LfHv3aZwodsA2vSTWRcT30eEdgje3 HvXgdaE3btVVjEw== X-Developer-Key: i=jlayton@kernel.org; a=openpgp; fpr=4BC0D7B24471B2A184EAF5D3000E684119568215 In order to add directory delegation support, we need to break delegations on the parent whenever there is going to be a change in the directory. Add a delegated_inode parameter to lookup_open and have it break the delegation. Then, open_last_lookups can wait for the delegation break and retry the call to lookup_open once it's done. Signed-off-by: Jeff Layton --- fs/namei.c | 22 ++++++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-) diff --git a/fs/namei.c b/fs/namei.c index 2211ed9f427cc97391d068b1a33ce388266a3e02..c8fe924cbb7dcefac9a4930df9f= 8303d9a478508 100644 --- a/fs/namei.c +++ b/fs/namei.c @@ -3609,7 +3609,7 @@ static struct dentry *atomic_open(struct nameidata *n= d, struct dentry *dentry, */ static struct dentry *lookup_open(struct nameidata *nd, struct file *file, const struct open_flags *op, - bool got_write) + bool got_write, struct inode **delegated_inode) { struct mnt_idmap *idmap; struct dentry *dir =3D nd->path.dentry; @@ -3698,6 +3698,11 @@ static struct dentry *lookup_open(struct nameidata *= nd, struct file *file, =20 /* Negative dentry, just create the file */ if (!dentry->d_inode && (open_flag & O_CREAT)) { + /* but break the directory lease first! */ + error =3D try_break_deleg(dir_inode, delegated_inode); + if (error) + goto out_dput; + file->f_mode |=3D FMODE_CREATED; audit_inode_child(dir_inode, dentry, AUDIT_TYPE_CHILD_CREATE); if (!dir_inode->i_op->create) { @@ -3761,6 +3766,7 @@ static const char *open_last_lookups(struct nameidata= *nd, struct file *file, const struct open_flags *op) { struct dentry *dir =3D nd->path.dentry; + struct inode *delegated_inode =3D NULL; int open_flag =3D op->open_flag; bool got_write =3D false; struct dentry *dentry; @@ -3791,7 +3797,7 @@ static const char *open_last_lookups(struct nameidata= *nd, return ERR_PTR(-ECHILD); } } - +retry: if (open_flag & (O_CREAT | O_TRUNC | O_WRONLY | O_RDWR)) { got_write =3D !mnt_want_write(nd->path.mnt); /* @@ -3804,7 +3810,7 @@ static const char *open_last_lookups(struct nameidata= *nd, inode_lock(dir->d_inode); else inode_lock_shared(dir->d_inode); - dentry =3D lookup_open(nd, file, op, got_write); + dentry =3D lookup_open(nd, file, op, got_write, &delegated_inode); if (!IS_ERR(dentry)) { if (file->f_mode & FMODE_CREATED) fsnotify_create(dir->d_inode, dentry); @@ -3819,8 +3825,16 @@ static const char *open_last_lookups(struct nameidat= a *nd, if (got_write) mnt_drop_write(nd->path.mnt); =20 - if (IS_ERR(dentry)) + if (IS_ERR(dentry)) { + if (delegated_inode) { + int error =3D break_deleg_wait(&delegated_inode); + + if (!error) + goto retry; + return ERR_PTR(error); + } return ERR_CAST(dentry); + } =20 if (file->f_mode & (FMODE_OPENED | FMODE_CREATED)) { dput(nd->path.dentry); --=20 2.49.0 From nobody Thu Dec 18 14:10:55 2025 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 6E93122A7EB; Mon, 2 Jun 2025 14:02:37 +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=1748872957; cv=none; b=ns/QmLAtVg/plQ57k7I/qiNJdXZuHj+OB2TGyku3LfxttgDy2SDXZkRbWKmoHy++jtKLRmtiIY0JtMQmgOMyqk891rhKklz+VLanM5HYcDux+61Yk1xJdSUIIpgNBcWlYu0bdtBUVhZb1obZIfpdP6Dx1gQf7b0M5NC1LeC01so= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1748872957; c=relaxed/simple; bh=s06Ae4PELaiY01FI16RBzFSeo5l8K3g8hpxK/GqIpnQ=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=EVht2rx/crZ3xrmT7+E5P+E9kwPM6INvglqGve4NMxR+sV/b3n0WN7nz0gzn/fX2qaysNF/k9b4EKsRDfYQ5PlW4OsTd4AQbxL9p05R+BvQ1HHfJI+dQwkdfLvX9YxBUMtWCapRo8/g/yX0ipuxK5AjQh70s8BtkjQXpCwA1Oaw= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=hdVUcxMe; 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="hdVUcxMe" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 01296C4CEEE; Mon, 2 Jun 2025 14:02:34 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1748872956; bh=s06Ae4PELaiY01FI16RBzFSeo5l8K3g8hpxK/GqIpnQ=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=hdVUcxMeGlBRZ7kihzm8hrCdTnznSoWbpdncHT46AENaLkbSeXbVNirbiDcW3lVxz 5Nf6+SvKVyfOMrQMXnynqeNCUz2KXX/8rbUTe2TK2rbm1+kRO5pvp1DfKAUS7NK7hL fIBmZNjBJDYtXwH1zkUt//4uhgQsO0OtqXWgC3CAIZrcz/X3HZPK7GqEhC7+T5hQSc 0DzwJWr4sVNExBNKGzaFQC1LkqEjRLtH5KnMPrCOQhx3YhprOKBF9kSlqKsOkdtl0f Zq40EoomOB4an9/UJknDdtgleZlmXl8KiW9k5JZ+660v3Uns39LvcnXFVrUBDoCYV1 qhTxjpL5sBfUA== From: Jeff Layton Date: Mon, 02 Jun 2025 10:01:50 -0400 Subject: [PATCH RFC v2 07/28] vfs: make vfs_create break delegations on parent directory Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20250602-dir-deleg-v2-7-a7919700de86@kernel.org> References: <20250602-dir-deleg-v2-0-a7919700de86@kernel.org> In-Reply-To: <20250602-dir-deleg-v2-0-a7919700de86@kernel.org> To: Alexander Viro , Christian Brauner , Jan Kara , Chuck Lever , Alexander Aring , Trond Myklebust , Anna Schumaker , Steve French , Paulo Alcantara , Ronnie Sahlberg , Shyam Prasad N , Tom Talpey , Bharath SM , NeilBrown , Olga Kornievskaia , Dai Ngo , Jonathan Corbet , Amir Goldstein , Miklos Szeredi Cc: linux-fsdevel@vger.kernel.org, linux-kernel@vger.kernel.org, linux-nfs@vger.kernel.org, linux-cifs@vger.kernel.org, samba-technical@lists.samba.org, linux-doc@vger.kernel.org, Jeff Layton X-Mailer: b4 0.14.2 X-Developer-Signature: v=1; a=openpgp-sha256; l=3532; i=jlayton@kernel.org; h=from:subject:message-id; bh=s06Ae4PELaiY01FI16RBzFSeo5l8K3g8hpxK/GqIpnQ=; b=owEBbQKS/ZANAwAKAQAOaEEZVoIVAcsmYgBoPa7l8YXO/GV+iK0bIwIx8M+FiK6b8G89HnRU6 WHcQw5Po6WJAjMEAAEKAB0WIQRLwNeyRHGyoYTq9dMADmhBGVaCFQUCaD2u5QAKCRAADmhBGVaC FUq1EADPZoJ+TKPhpk3m+iZfs7CRmFoQzvtp5HirrfFRd7pyg03bLq9LS5RiRcClOPxmZ4IQakJ RNYBfIAeK0tBAGP9n/8aVntkngLoz6heNS756YT1H4NHGXE+SPbdTBu81+l03fyi6x7Uwh7iCH2 C+Hau/Bt7OpfN4JHjsmzxRFkQBLPmXlh8TdzhpVysbo1KKImbacyLnLiiGhVZc2DrazVkF+t1O3 YZLpoa0LOhMnXbvXIeqxraHViBWqMmR6pvJ4/htKbltFQM0CrTUQVrG/GWCz9/TzOatskTWip7Y hM6/LTINps7sKXLpU5WbdubLSjWgxK8zmIqE+x7MKK6iRhpi9tRR0kZx82D5NiEnJKW1dcxXZYE VnRXe4g3onGqxCfnjGxvPSLNA14Hp/fEGzpQ6fC/0LeDokbxNXuIgsAXcz6GMabeCuGucWtDFfJ E0tW32kWXxNrB/r6GLSswIKEqBWClRSUJCAjXr5AO4CqeZy86QK1kJ0sJbpu09g/MqXSInJCCvo ib9qtW3z+c/1vi+trxIHOP8bH5Jrtzk12Rrz6FDVavnonNKLdlqTAGGipVsJISOKiqSn2mp86Ek vV+7giOxYE1Jpgmbh/alW1itRZMdWpyhukgWtqv+Mb4Kj8LuDZCVOq5y73ML4c906uL//I7o35c cFZ9/VHV7pr7l0Q== X-Developer-Key: i=jlayton@kernel.org; a=openpgp; fpr=4BC0D7B24471B2A184EAF5D3000E684119568215 In order to add directory delegation support, we need to break delegations on the parent whenever there is going to be a change in the directory. Rename vfs_create as __vfs_create, make it static, and add a new delegated_inode parameter. Fix do_mknodat to call __vfs_create and wait for a delegation break if there is one. Add a new exported vfs_create wrapper that passes in NULL for delegated_inode. Signed-off-by: Jeff Layton --- fs/namei.c | 55 ++++++++++++++++++++++++++++++++++++------------------- 1 file changed, 36 insertions(+), 19 deletions(-) diff --git a/fs/namei.c b/fs/namei.c index c8fe924cbb7dcefac9a4930df9f8303d9a478508..7b27a9bc4616d3880d6365f1e37= f13f7f45bc2c9 100644 --- a/fs/namei.c +++ b/fs/namei.c @@ -3370,6 +3370,32 @@ static inline umode_t vfs_prepare_mode(struct mnt_id= map *idmap, return mode; } =20 +static int __vfs_create(struct mnt_idmap *idmap, struct inode *dir, + struct dentry *dentry, umode_t mode, bool want_excl, + struct inode **delegated_inode) +{ + int error; + + error =3D may_create(idmap, dir, dentry); + if (error) + return error; + + if (!dir->i_op->create) + return -EACCES; /* shouldn't it be ENOSYS? */ + + mode =3D vfs_prepare_mode(idmap, dir, mode, S_IALLUGO, S_IFREG); + error =3D security_inode_create(dir, dentry, mode); + if (error) + return error; + error =3D try_break_deleg(dir, delegated_inode); + if (error) + return error; + error =3D dir->i_op->create(idmap, dir, dentry, mode, want_excl); + if (!error) + fsnotify_create(dir, dentry); + return error; +} + /** * vfs_create - create new file * @idmap: idmap of the mount the inode was found from @@ -3389,23 +3415,7 @@ static inline umode_t vfs_prepare_mode(struct mnt_id= map *idmap, int vfs_create(struct mnt_idmap *idmap, struct inode *dir, struct dentry *dentry, umode_t mode, bool want_excl) { - int error; - - error =3D may_create(idmap, dir, dentry); - if (error) - return error; - - if (!dir->i_op->create) - return -EACCES; /* shouldn't it be ENOSYS? */ - - mode =3D vfs_prepare_mode(idmap, dir, mode, S_IALLUGO, S_IFREG); - error =3D security_inode_create(dir, dentry, mode); - if (error) - return error; - error =3D dir->i_op->create(idmap, dir, dentry, mode, want_excl); - if (!error) - fsnotify_create(dir, dentry); - return error; + return __vfs_create(idmap, dir, dentry, mode, want_excl, NULL); } EXPORT_SYMBOL(vfs_create); =20 @@ -4278,6 +4288,7 @@ static int do_mknodat(int dfd, struct filename *name,= umode_t mode, struct path path; int error; unsigned int lookup_flags =3D 0; + struct inode *delegated_inode =3D NULL; =20 error =3D may_mknod(mode); if (error) @@ -4296,8 +4307,9 @@ static int do_mknodat(int dfd, struct filename *name,= umode_t mode, idmap =3D mnt_idmap(path.mnt); switch (mode & S_IFMT) { case 0: case S_IFREG: - error =3D vfs_create(idmap, path.dentry->d_inode, - dentry, mode, true); + error =3D __vfs_create(idmap, path.dentry->d_inode, + dentry, mode, true, + &delegated_inode); if (!error) security_path_post_mknod(idmap, dentry); break; @@ -4312,6 +4324,11 @@ static int do_mknodat(int dfd, struct filename *name= , umode_t mode, } out2: done_path_create(&path, dentry); + if (delegated_inode) { + error =3D break_deleg_wait(&delegated_inode); + if (!error) + goto retry; + } if (retry_estale(error, lookup_flags)) { lookup_flags |=3D LOOKUP_REVAL; goto retry; --=20 2.49.0 From nobody Thu Dec 18 14:10:55 2025 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 40FE2221FB1; Mon, 2 Jun 2025 14:02:39 +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=1748872959; cv=none; b=AJWdjqhIbNS64PFBps06tIAhvDMxZ3Cb8calJHaxyRaguaAUVwGi36vJAfqC4fA1h8OcliWePYJ8lhP1Vl/TnwXCawz2x5UgBzIuipGbGphDNU17wiYylWSaMYAtdIHjy9SXcrZDnq05eHwY5Stfnxs88BCRe/saqquVGwdRlP0= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1748872959; c=relaxed/simple; bh=LL9hPGs8JOfm/3852E6F/kJJzUCWzKIPIPUHPbH2s5s=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=kK8Dbulkiq6WRXTf05tAS5k/6bXn31yuC6rh98rz2f9cRuoEDBEbvd28dqT/Af6etQpL5h0eOnwMw5PJ902tWPCSIo/3kIvR1ivoQ80d59f8jDilJzWtpciHwzlUwDYY5KH0l+6X2dmFqb6fjDlZI5w8yOrnp+uJ6XVXR9cYmgs= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=efnvxsvP; 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="efnvxsvP" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 1F2D2C4CEF4; Mon, 2 Jun 2025 14:02:37 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1748872959; bh=LL9hPGs8JOfm/3852E6F/kJJzUCWzKIPIPUHPbH2s5s=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=efnvxsvP/gIr20jjHLqh+gpIs7S96DLp3GDq91bcayoh75mrDrGkmXY6pN2dPCtfq UbARkMn7A1SAkfVCzW/q32dspvaeSJJTnvIJyLyBmUzPB7OI255l6xWrni2GRZ49jT I+hZhrt22waCy+44t1+KeLeJjuHEbV5qMdlljoiXcqOKvFJOH3geUwXT1Px0we/ZHQ AgV1ctvlE2FlP3fZFI/6gAM3z5irpbWdWhCylIK67852WIdjLzzdpjFsWamr2XTZya 27L4TcAbjNGhpXXd+Sk2cijJLf6ZncJg2yg/slAwmzmwaAvpEsQPkLWB4u51hos+B1 NDjWSTz01qjXA== From: Jeff Layton Date: Mon, 02 Jun 2025 10:01:51 -0400 Subject: [PATCH RFC v2 08/28] vfs: make vfs_mknod break delegations on parent directory Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20250602-dir-deleg-v2-8-a7919700de86@kernel.org> References: <20250602-dir-deleg-v2-0-a7919700de86@kernel.org> In-Reply-To: <20250602-dir-deleg-v2-0-a7919700de86@kernel.org> To: Alexander Viro , Christian Brauner , Jan Kara , Chuck Lever , Alexander Aring , Trond Myklebust , Anna Schumaker , Steve French , Paulo Alcantara , Ronnie Sahlberg , Shyam Prasad N , Tom Talpey , Bharath SM , NeilBrown , Olga Kornievskaia , Dai Ngo , Jonathan Corbet , Amir Goldstein , Miklos Szeredi Cc: linux-fsdevel@vger.kernel.org, linux-kernel@vger.kernel.org, linux-nfs@vger.kernel.org, linux-cifs@vger.kernel.org, samba-technical@lists.samba.org, linux-doc@vger.kernel.org, Jeff Layton X-Mailer: b4 0.14.2 X-Developer-Signature: v=1; a=openpgp-sha256; l=3972; i=jlayton@kernel.org; h=from:subject:message-id; bh=LL9hPGs8JOfm/3852E6F/kJJzUCWzKIPIPUHPbH2s5s=; b=owEBbQKS/ZANAwAKAQAOaEEZVoIVAcsmYgBoPa7lToSEk9cSNhHcBXPahgPt6wLf6CzscMey/ eMXhBKLUXKJAjMEAAEKAB0WIQRLwNeyRHGyoYTq9dMADmhBGVaCFQUCaD2u5QAKCRAADmhBGVaC FVfREACKsgoGrCzFIaWVTptASQ5M/6y05BlTGkJQFFPdNN2q6m+UqXQjkMAPF3DkJ2nOAHlTzAq rvvcaQ+C/EUknWfJqx+vTi+KgKyMBmBF2DTnDrS5Q+1PcfPLtJRuJ28936Z0udb5Q0+7vrKHsXa Iuq6NtLNXP7vtbyc1w/F0CYQBr4b0XOI6Bc1M48L8WHPbKKGnv1fkcanNzOpEBhl13m+oSNbgV3 SUfIWYJKDorozx9s8TwYhBxwCsl9hY08wfWFRxUGy6fe5wZ+xbqaVe+K2zsMDs52LXOH4DRZ8DF jL+9GRNLIMtpHFBtgx33BOA+MiQbHO9QbkRlBIT7z9Ezu3Pyk5EQIiIONDSeL4gbe4Ev22qHWxo Q036DtyWwHgKYUoOKAvzEk1fT1PzKAaPa9Nf30mX92cFnUnWe5DDm/p/eXNx+SgO4sFdT6lGHiU xN7q6hXGOXPJFF3/8ThHB+wlkAcUnZ5BMPB+uVktEyIV8WyOeYSw3ZriFKLqT6Yjfcy3SUJI6iY 67H42x0jw0q3KHhX+6MLIIC3zv4fv0OrZ8WlI/Zi+9emqn/s2Vu/AuM9EgEbBx1SMiEz/CMkx2E JbUshOjeUJsCAYBLn3dOEi5mnNRKZst2sjvZBAcBKnUjGSqyCRtFmtCmHtlvujwKhBBDpmppNhC rVMqk36Ds9MAeZg== X-Developer-Key: i=jlayton@kernel.org; a=openpgp; fpr=4BC0D7B24471B2A184EAF5D3000E684119568215 In order to add directory delegation support, we need to break delegations on the parent whenever there is going to be a change in the directory. Rename vfs_mknod as __vfs_mknod, make it static, and add a new delegated_inode parameter. Make do_mknodat call __vfs_mknod and wait synchronously for delegation breaks to complete. Add a new exported vfs_mknod wrapper that calls __vfs_mknod with a NULL delegated_inode pointer. Signed-off-by: Jeff Layton --- fs/namei.c | 57 +++++++++++++++++++++++++++++++++++---------------------- 1 file changed, 35 insertions(+), 22 deletions(-) diff --git a/fs/namei.c b/fs/namei.c index 7b27a9bc4616d3880d6365f1e37f13f7f45bc2c9..8f0517ade308134ed6566566d9b= 575c4e9fb0d4e 100644 --- a/fs/namei.c +++ b/fs/namei.c @@ -4215,24 +4215,9 @@ inline struct dentry *user_path_create(int dfd, cons= t char __user *pathname, } EXPORT_SYMBOL(user_path_create); =20 -/** - * vfs_mknod - create device node or file - * @idmap: idmap of the mount the inode was found from - * @dir: inode of the parent directory - * @dentry: dentry of the child device node - * @mode: mode of the child device node - * @dev: device number of device to create - * - * Create a device node or file. - * - * If the inode has been found through an idmapped mount the idmap of - * the vfsmount must be passed through @idmap. This function will then take - * care to map the inode according to @idmap before checking permissions. - * On non-idmapped mounts or if permission checking is to be performed on = the - * raw inode simply pass @nop_mnt_idmap. - */ -int vfs_mknod(struct mnt_idmap *idmap, struct inode *dir, - struct dentry *dentry, umode_t mode, dev_t dev) +static int __vfs_mknod(struct mnt_idmap *idmap, struct inode *dir, + struct dentry *dentry, umode_t mode, dev_t dev, + struct inode **delegated_inode) { bool is_whiteout =3D S_ISCHR(mode) && dev =3D=3D WHITEOUT_DEV; int error =3D may_create(idmap, dir, dentry); @@ -4256,11 +4241,37 @@ int vfs_mknod(struct mnt_idmap *idmap, struct inode= *dir, if (error) return error; =20 + error =3D try_break_deleg(dir, delegated_inode); + if (error) + return error; + error =3D dir->i_op->mknod(idmap, dir, dentry, mode, dev); if (!error) fsnotify_create(dir, dentry); return error; } + +/** + * vfs_mknod - create device node or file + * @idmap: idmap of the mount the inode was found from + * @dir: inode of the parent directory + * @dentry: dentry of the child device node + * @mode: mode of the child device node + * @dev: device number of device to create + * + * Create a device node or file. + * + * If the inode has been found through an idmapped mount the idmap of + * the vfsmount must be passed through @idmap. This function will then take + * care to map the inode according to @idmap before checking permissions. + * On non-idmapped mounts or if permission checking is to be performed on = the + * raw inode simply pass @nop_mnt_idmap. + */ +int vfs_mknod(struct mnt_idmap *idmap, struct inode *dir, + struct dentry *dentry, umode_t mode, dev_t dev) +{ + return __vfs_mknod(idmap, dir, dentry, mode, dev, NULL); +} EXPORT_SYMBOL(vfs_mknod); =20 static int may_mknod(umode_t mode) @@ -4314,12 +4325,14 @@ static int do_mknodat(int dfd, struct filename *nam= e, umode_t mode, security_path_post_mknod(idmap, dentry); break; case S_IFCHR: case S_IFBLK: - error =3D vfs_mknod(idmap, path.dentry->d_inode, - dentry, mode, new_decode_dev(dev)); + error =3D __vfs_mknod(idmap, path.dentry->d_inode, + dentry, mode, new_decode_dev(dev), + &delegated_inode); break; case S_IFIFO: case S_IFSOCK: - error =3D vfs_mknod(idmap, path.dentry->d_inode, - dentry, mode, 0); + error =3D __vfs_mknod(idmap, path.dentry->d_inode, + dentry, mode, 0, + &delegated_inode); break; } out2: --=20 2.49.0 From nobody Thu Dec 18 14:10:55 2025 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 4160822D4DC; Mon, 2 Jun 2025 14:02:41 +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=1748872961; cv=none; b=m5cak7eNS6lChRaxSYm3Z9SJp732NgnY63GSWk2QLbsRnJBfIVLXf/eD/rnOHV71bSPVwhlKTuqubwWN0DZ1+t/0qaQZBu27LEDOMaVn8NvDvWAvDsaJAujYh1Cu9P5GQrptojl+IU6nfJ9rCjTEbNz1jKyHPPU61E+WT8X+2Vs= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1748872961; c=relaxed/simple; bh=sCsTeakzmLBzU55l4qTabH3TVaofSjNDyRcERU8TUrA=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=NS53pOXoCAUbBMHIfOtCOazuj+ilCWKLXVdOUT4ve+BQWhzs6Sv0G2kJruVUtDjsqlYH2ohBXA9MtElqHhuTnoFXqKzmktDv5QiitPbrvngjsUR9KB13w1od26uCxVxV+RhMdE+Q22d47frexf5m0NKvx+dWBV6+0jV0kXrql5Q= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=nJpFQuRZ; 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="nJpFQuRZ" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 3C4DAC4CEEB; Mon, 2 Jun 2025 14:02:39 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1748872961; bh=sCsTeakzmLBzU55l4qTabH3TVaofSjNDyRcERU8TUrA=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=nJpFQuRZC9Bp7IUbrhVZ7dAy0TNpGw4Lw1NrsMVOoVShi2WImzXOcf3x47t4cDUiY nQB4FqEosgWxM+ByVUeI2wxTEJANgvXgygDvbmawNq3Rekt93tI+2gmvTssdg1nRny N6PTqWV8S6HfXE+pyGFWU5XoUIQiKwkxGrjYzqWBvSdYCY/vvEcxBdWAKHze/J4woR kvaIG+VypIjaHPWPvDFBuVqTmLI+8CkIgesA36Yr/VnzpBSU1rQliQQnoJ7mi26Y4J CONEuuzIercH/Tq9ziRAjAtOlQBHy/Ju+Rpm1bh6VIL0eX75pGzdbWdLM/jZQ6CmJx C7tMeCqIPkcCA== From: Jeff Layton Date: Mon, 02 Jun 2025 10:01:52 -0400 Subject: [PATCH RFC v2 09/28] filelock: lift the ban on directory leases in generic_setlease Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20250602-dir-deleg-v2-9-a7919700de86@kernel.org> References: <20250602-dir-deleg-v2-0-a7919700de86@kernel.org> In-Reply-To: <20250602-dir-deleg-v2-0-a7919700de86@kernel.org> To: Alexander Viro , Christian Brauner , Jan Kara , Chuck Lever , Alexander Aring , Trond Myklebust , Anna Schumaker , Steve French , Paulo Alcantara , Ronnie Sahlberg , Shyam Prasad N , Tom Talpey , Bharath SM , NeilBrown , Olga Kornievskaia , Dai Ngo , Jonathan Corbet , Amir Goldstein , Miklos Szeredi Cc: linux-fsdevel@vger.kernel.org, linux-kernel@vger.kernel.org, linux-nfs@vger.kernel.org, linux-cifs@vger.kernel.org, samba-technical@lists.samba.org, linux-doc@vger.kernel.org, Jeff Layton X-Mailer: b4 0.14.2 X-Developer-Signature: v=1; a=openpgp-sha256; l=1023; i=jlayton@kernel.org; h=from:subject:message-id; bh=sCsTeakzmLBzU55l4qTabH3TVaofSjNDyRcERU8TUrA=; b=owEBbQKS/ZANAwAKAQAOaEEZVoIVAcsmYgBoPa7mg/CU9cxONu7wXEylEjIwRT5FCqxpjkF1j 9V5N4aHR7WJAjMEAAEKAB0WIQRLwNeyRHGyoYTq9dMADmhBGVaCFQUCaD2u5gAKCRAADmhBGVaC FecmD/4rTaNg5RZIP6ruF+A7YjAsnEIyAaPD2SK7nfgwQ+xe9hbNyovhbDTKoeDxuYJMuLIh1nd RQDQLHSDLa1ZTR8TU65vxgFt0t3KtyLzDus0p+1Ht8f3vzbgt8hkP6NzObppNXBrsiOWGWDQ5va B2ORUcafxjFRbYYAaEApJUft6nLBbhIj3ZNcEEsn6GhB89MPHM9KfJQl3MyaAh4RQvVr0205NDr 5ibhgUX/EOwgglZ1vUvfbwTqpdDg4PIBauu/K3APlrghSzQk89R39caolXdwkK9nAOO1mzLAb9m AhgRK9nKV9Hs2A2xfoCVu4x3k3zDlDjOB9hBsP/8B46DLwGU8OFaF7KhOMELAtbgD8kcvTYYkLT UVadauu/x9XqjW1ac+jL+/JF2PEfD9uE2p4Q1UFC7JlnvHsEwkA5XwFIawAtAakyOzjnUP7QIEP /QwWKBGuU4uG/ICRJLKyrXX8uNid2xUBcM5VbIJLiYOq0IkiGoc4tKZx6XeR298doDerrbqune1 Shnw174hsiSptya4YjZwQ1NhOFtA4NO0SXXryRK80NgJcdF9yKgqloP/96fBKIZHgCZdXHZNs/V N5w5EwhN1Kmf/owisRyuyt+Y3W8D/LQ+AdrbZAAUlLr5iyGbv870xHLw8F9+9X4BBh6uqvEVAa4 eUVJxGwC24fh9Hw== X-Developer-Key: i=jlayton@kernel.org; a=openpgp; fpr=4BC0D7B24471B2A184EAF5D3000E684119568215 With the addition of the try_break_lease calls in directory changing operations, allow generic_setlease to hand them out. Note that this also makes directory leases available to userland via fcntl(). I don't see a real reason to prevent userland from acquiring one, but we could reinstate the prohibition if that's preferable. Signed-off-by: Jeff Layton --- fs/locks.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/fs/locks.c b/fs/locks.c index 1985f38d326d938f58009e0880b45e588af6a422..82a1b528dc9dae8c1f3a8108407= 2e649d481e8f1 100644 --- a/fs/locks.c +++ b/fs/locks.c @@ -1934,7 +1934,9 @@ static int generic_delete_lease(struct file *filp, vo= id *owner) int generic_setlease(struct file *filp, int arg, struct file_lease **flp, void **priv) { - if (!S_ISREG(file_inode(filp)->i_mode)) + struct inode *inode =3D file_inode(filp); + + if (!S_ISREG(inode->i_mode) && !S_ISDIR(inode->i_mode)) return -EINVAL; =20 switch (arg) { --=20 2.49.0 From nobody Thu Dec 18 14:10:55 2025 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 5D9D022DA0A; Mon, 2 Jun 2025 14:02:43 +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=1748872963; cv=none; b=BbC+BLKKRGMbTB3JmavDdcfPkYFw5p5/8kCp703+CXefzaqQ68DTG/fOv0VQv7w0YqP21GvWVOZGGz4YHmalyyMPaEWHux/6a6/YiHEF8vj3cGOj7Fr/FYVxcr5binZdhsnKZFJlxFLe076T/SQVWRDysyUaThMWtLtUqhW+Szg= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1748872963; c=relaxed/simple; bh=HFJHWJi84TTPKc7nmrml/lL59s4gaFQy4JwaEdapKZ0=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=hl6C5v+EOY0gvy1MF5O3IG07wNIaMnJk+hmDDUiGspmy7of7HFbpM5dPXgTMEsjXT0isqb5jO8SQ3Pex0Oj1oeeXmgzWK0sP9qax1QR0O/hEf27J2A5eM8KU/bMgnPJ1xx5rtP24MlNG50u8V9OvDKDGfrgwyn6zj38J+TGM/us= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=dNR8jV4W; 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="dNR8jV4W" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 58E9BC4CEF0; Mon, 2 Jun 2025 14:02:41 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1748872963; bh=HFJHWJi84TTPKc7nmrml/lL59s4gaFQy4JwaEdapKZ0=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=dNR8jV4WE4MbEezDv20JfW6YS2CaxdbudQKtcKsMdb3PxWioWLhrDnCjZUmapBz/n Y4CbYEpKxk9oiv84PgeLz5f5PbhIoWif2NPGukXw1BpkLNNRkPko2XYSlAbVaf+kN0 MdWeuZCgbgsMRfMYhF41okDgyIQmFlKIOMet9eyyvit6moRhSsDn4eOMFdVymlb1w2 FkNyY4YQpUp9QswTNE/RriMM1j9C0GA8BIvcE4DQkqcSvxSpgomjIqlds4/K2ad/yR uCHwFNQjIuspiTl15rklgrcfao4l2wz9u+5MSCnEMEhHGZr/NuELqVfpKrBriuwPT6 ynJNjQazXzDOg== From: Jeff Layton Date: Mon, 02 Jun 2025 10:01:53 -0400 Subject: [PATCH RFC v2 10/28] nfsd: allow filecache to hold S_IFDIR files Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20250602-dir-deleg-v2-10-a7919700de86@kernel.org> References: <20250602-dir-deleg-v2-0-a7919700de86@kernel.org> In-Reply-To: <20250602-dir-deleg-v2-0-a7919700de86@kernel.org> To: Alexander Viro , Christian Brauner , Jan Kara , Chuck Lever , Alexander Aring , Trond Myklebust , Anna Schumaker , Steve French , Paulo Alcantara , Ronnie Sahlberg , Shyam Prasad N , Tom Talpey , Bharath SM , NeilBrown , Olga Kornievskaia , Dai Ngo , Jonathan Corbet , Amir Goldstein , Miklos Szeredi Cc: linux-fsdevel@vger.kernel.org, linux-kernel@vger.kernel.org, linux-nfs@vger.kernel.org, linux-cifs@vger.kernel.org, samba-technical@lists.samba.org, linux-doc@vger.kernel.org, Jeff Layton X-Mailer: b4 0.14.2 X-Developer-Signature: v=1; a=openpgp-sha256; l=6750; i=jlayton@kernel.org; h=from:subject:message-id; bh=HFJHWJi84TTPKc7nmrml/lL59s4gaFQy4JwaEdapKZ0=; b=owEBbQKS/ZANAwAKAQAOaEEZVoIVAcsmYgBoPa7m2B0qMl+YoYQk7CbK4lrc0eCc0x/jhp4Hi eDmEzxS3XKJAjMEAAEKAB0WIQRLwNeyRHGyoYTq9dMADmhBGVaCFQUCaD2u5gAKCRAADmhBGVaC FRBAD/455TVU7wVdpQ/sp7ZQsS22TJiIVbBSDwnTVU++mrqcrNnNZCXQDBv8UrrWgGxprRg1+jd +5AIaEF/yS6SkwlgXG7vvmK2tBhk79C0BnyDXJdx+8LE/KNFWw0KmreXemS/Z5XOXVofMRlNMv5 sHRgtR2LgzNYdzuUQAZSW2WXmb7qEpsT65NlraioYWSCCsJ7tJDhyKwmBxNSnZRV6L3oN27Vl91 8ZHN4AufqE8HoqPmDMvRN2WhsKefpCTr78bo8IhSIgL/AIWImTqS6CewCeEE2DmQzpLwdMWbvRB 3hm+X7OlP1/XVMqK5skBMzTVjhGUExNUjEtE26IPr1n4JEy0FgEpqweIjt5rfXxWT0XP6+DCB83 0oisiAgm1BEXpzUHNeQxj9yA10QgdeFnHONHYDOU6EXv62BdQEQxB+p6F3t8klsGt4XNEfsxnnU gaVmL79uVWpCSh80hElLgTI3vxytaR8TH4SpM/rrpNXwSAhHqlEutUoT7TQQC44ne08LhKK5YQT bYjp+cAphF8DnI+JBFrJryWhFX9Y6c7AUAVArQ7Ei4H1fddUntbVk4w2tFLgHP8ZehwDKv0FTX+ FHe+tos+fymibHWbAuKdiTY74jOR/JT9BBomi9PitOD4O+V3AyOa0G4+1LU9OB3xJgoFBV/ePST ZKwDv2jHPtdUhsA== X-Developer-Key: i=jlayton@kernel.org; a=openpgp; fpr=4BC0D7B24471B2A184EAF5D3000E684119568215 The filecache infrastructure will only handle S_ISREG files at the moment. Plumb a "type" variable into nfsd_file_do_acquire and have all of the existing callers set it to S_ISREG. Add a new nfsd_file_acquire_dir() wrapper that we can then call to request a nfsd_file that holds a directory open. Signed-off-by: Jeff Layton --- fs/nfsd/filecache.c | 50 ++++++++++++++++++++++++++++++++++++++------------ fs/nfsd/filecache.h | 2 ++ fs/nfsd/vfs.c | 5 +++-- fs/nfsd/vfs.h | 2 +- 4 files changed, 44 insertions(+), 15 deletions(-) diff --git a/fs/nfsd/filecache.c b/fs/nfsd/filecache.c index ab85e6a2454f4c783fcb1175ebbeb63a31519c18..3468883146afc080d2b4862e600= 2b2c6ff7315b9 100644 --- a/fs/nfsd/filecache.c +++ b/fs/nfsd/filecache.c @@ -1049,7 +1049,7 @@ nfsd_file_do_acquire(struct svc_rqst *rqstp, struct n= et *net, struct auth_domain *client, struct svc_fh *fhp, unsigned int may_flags, struct file *file, - struct nfsd_file **pnf, bool want_gc) + umode_t type, bool want_gc, struct nfsd_file **pnf) { unsigned char need =3D may_flags & NFSD_FILE_MAY_MASK; struct nfsd_file *new, *nf; @@ -1060,13 +1060,13 @@ nfsd_file_do_acquire(struct svc_rqst *rqstp, struct= net *net, int ret; =20 retry: - if (rqstp) { - status =3D fh_verify(rqstp, fhp, S_IFREG, + if (rqstp) + status =3D fh_verify(rqstp, fhp, type, may_flags|NFSD_MAY_OWNER_OVERRIDE); - } else { - status =3D fh_verify_local(net, cred, client, fhp, S_IFREG, + else + status =3D fh_verify_local(net, cred, client, fhp, type, may_flags|NFSD_MAY_OWNER_OVERRIDE); - } + if (status !=3D nfs_ok) return status; inode =3D d_inode(fhp->fh_dentry); @@ -1147,7 +1147,7 @@ nfsd_file_do_acquire(struct svc_rqst *rqstp, struct n= et *net, status =3D nfs_ok; trace_nfsd_file_opened(nf, status); } else { - ret =3D nfsd_open_verified(fhp, may_flags, &nf->nf_file); + ret =3D nfsd_open_verified(fhp, type, may_flags, &nf->nf_file); if (ret =3D=3D -EOPENSTALE && stale_retry) { stale_retry =3D false; nfsd_file_unhash(nf); @@ -1207,7 +1207,7 @@ nfsd_file_acquire_gc(struct svc_rqst *rqstp, struct s= vc_fh *fhp, unsigned int may_flags, struct nfsd_file **pnf) { return nfsd_file_do_acquire(rqstp, SVC_NET(rqstp), NULL, NULL, - fhp, may_flags, NULL, pnf, true); + fhp, may_flags, NULL, S_IFREG, true, pnf); } =20 /** @@ -1232,7 +1232,7 @@ nfsd_file_acquire(struct svc_rqst *rqstp, struct svc_= fh *fhp, unsigned int may_flags, struct nfsd_file **pnf) { return nfsd_file_do_acquire(rqstp, SVC_NET(rqstp), NULL, NULL, - fhp, may_flags, NULL, pnf, false); + fhp, may_flags, NULL, S_IFREG, false, pnf); } =20 /** @@ -1275,8 +1275,8 @@ nfsd_file_acquire_local(struct net *net, struct svc_c= red *cred, const struct cred *save_cred =3D get_current_cred(); __be32 beres; =20 - beres =3D nfsd_file_do_acquire(NULL, net, cred, client, - fhp, may_flags, NULL, pnf, false); + beres =3D nfsd_file_do_acquire(NULL, net, cred, client, fhp, may_flags, + NULL, S_IFREG, false, pnf); put_cred(revert_creds(save_cred)); return beres; } @@ -1305,7 +1305,33 @@ nfsd_file_acquire_opened(struct svc_rqst *rqstp, str= uct svc_fh *fhp, struct nfsd_file **pnf) { return nfsd_file_do_acquire(rqstp, SVC_NET(rqstp), NULL, NULL, - fhp, may_flags, file, pnf, false); + fhp, may_flags, file, S_IFREG, false, pnf); +} + +/** + * nfsd_file_acquire_dir - Get a struct nfsd_file with an open directory + * @rqstp: the RPC transaction being executed + * @fhp: the NFS filehandle of the file to be opened + * @pnf: OUT: new or found "struct nfsd_file" object + * + * 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(). This opens directories only, and only + * in O_RDONLY mode. + * + * Return values: + * %nfs_ok - @pnf points to an nfsd_file with its reference + * count boosted. + * + * On error, an nfsstat value in network byte order is returned. + */ +__be32 +nfsd_file_acquire_dir(struct svc_rqst *rqstp, struct svc_fh *fhp, + struct nfsd_file **pnf) +{ + return nfsd_file_do_acquire(rqstp, SVC_NET(rqstp), NULL, NULL, fhp, + NFSD_MAY_READ|NFSD_MAY_64BIT_COOKIE, + NULL, S_IFDIR, false, pnf); } =20 /* diff --git a/fs/nfsd/filecache.h b/fs/nfsd/filecache.h index 5865f9c7271214de7269ab33480689cd61c1c552..3717503f6b75462c7afca6216d9= c915e055b117d 100644 --- a/fs/nfsd/filecache.h +++ b/fs/nfsd/filecache.h @@ -78,5 +78,7 @@ __be32 nfsd_file_acquire_opened(struct svc_rqst *rqstp, s= truct svc_fh *fhp, __be32 nfsd_file_acquire_local(struct net *net, struct svc_cred *cred, struct auth_domain *client, struct svc_fh *fhp, unsigned int may_flags, struct nfsd_file **pnf); +__be32 nfsd_file_acquire_dir(struct svc_rqst *rqstp, struct svc_fh *fhp, + struct nfsd_file **pnf); int nfsd_file_cache_stats_show(struct seq_file *m, void *v); #endif /* _FS_NFSD_FILECACHE_H */ diff --git a/fs/nfsd/vfs.c b/fs/nfsd/vfs.c index cd689df2ca5d7396cffb5ed9dc14f774a8f3881c..86873662925e2f50823d4ce371f= 1018b749b4c6d 100644 --- a/fs/nfsd/vfs.c +++ b/fs/nfsd/vfs.c @@ -949,15 +949,16 @@ nfsd_open(struct svc_rqst *rqstp, struct svc_fh *fhp,= umode_t type, /** * nfsd_open_verified - Open a regular file for the filecache * @fhp: NFS filehandle of the file to open + * @type: S_IFMT inode type allowed (0 means any type is allowed) * @may_flags: internal permission flags * @filp: OUT: open "struct file *" * * Returns zero on success, or a negative errno value. */ int -nfsd_open_verified(struct svc_fh *fhp, int may_flags, struct file **filp) +nfsd_open_verified(struct svc_fh *fhp, umode_t type, int may_flags, struct= file **filp) { - return __nfsd_open(fhp, S_IFREG, may_flags, filp); + return __nfsd_open(fhp, type, may_flags, filp); } =20 /* diff --git a/fs/nfsd/vfs.h b/fs/nfsd/vfs.h index eff04959606fe55c141ab4a2eed97c7e0716a5f5..9c309cdee6c491d445d56cdc613= 3f37248ab4b46 100644 --- a/fs/nfsd/vfs.h +++ b/fs/nfsd/vfs.h @@ -114,7 +114,7 @@ __be32 nfsd_setxattr(struct svc_rqst *rqstp, struct sv= c_fh *fhp, int nfsd_open_break_lease(struct inode *, int); __be32 nfsd_open(struct svc_rqst *, struct svc_fh *, umode_t, int, struct file **); -int nfsd_open_verified(struct svc_fh *fhp, int may_flags, +int nfsd_open_verified(struct svc_fh *fhp, umode_t type, int may_flags, struct file **filp); __be32 nfsd_splice_read(struct svc_rqst *rqstp, struct svc_fh *fhp, struct file *file, loff_t offset, --=20 2.49.0 From nobody Thu Dec 18 14:10:55 2025 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 7911822E3E0; Mon, 2 Jun 2025 14:02:45 +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=1748872965; cv=none; b=a7+rJYYL3TBCQE8wBlMn01GoJ2vDTqVeKGWd9vVbkd136r+xvtuI00HWN1LoiSxaxDCPgdFPJ4v//Er5c5JoLR65g/h3UwngWVi9L311e1ejt9hCE1R7gRnT/rqGpIS+rL0lW6W1+IPpbONsv5UtWLzzRxPsYa87u6l+eCcHybA= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1748872965; c=relaxed/simple; bh=Wvyvgvm5DbaEUEvlZdhyahV78iFdXKqVNAP9xbePNLg=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=uUzEL4OSVol4K1/4ybAf0ioI3bMKStFkzEHMZkZlGxsuAaEF+Uw1jJ/SELojX9zrLC62OMg4XLwAMVTczqZTMDeGrFqV4GmBOxZECHNk8ZCzEtRKxuOqFa9YrbsgQKLD1OLg0bWNIlYLzb5o6vYHhL0RXVWuUjS000A109j78NY= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=pk5q+lvc; 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="pk5q+lvc" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 763E8C4CEEE; Mon, 2 Jun 2025 14:02:43 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1748872965; bh=Wvyvgvm5DbaEUEvlZdhyahV78iFdXKqVNAP9xbePNLg=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=pk5q+lvcXliXhkrasbOVg0SeYu1MNGi9RtdTiwn6iPVzG9ixuzDt5bcGamrlzMfXj SA3Q2UqRfNWTV2GkK3aI/O40454Wg8wbgLgorLfeTIrg4CuNcBxvsCeeKN/L/js9F2 gWym0goJsg+rK/vl3K/eSU5PYmw8DaopoapFxs2imBqApWtCEVIrBmNcccJpNeb1as QriFr/sCRlUjE/zjAvVBG6lRkRZEj/8kxm8IvAuGGA2OLPk95i6p3Y/TupNf7Xci63 biA3ttj1VV4WWWvNGQl/0c/ssOVRcwuqnJrwrTUlVUV0mLEMW6bczuFZHYc4oCLNND PBFWyTapMLbyg== From: Jeff Layton Date: Mon, 02 Jun 2025 10:01:54 -0400 Subject: [PATCH RFC v2 11/28] nfsd: allow DELEGRETURN on directories Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20250602-dir-deleg-v2-11-a7919700de86@kernel.org> References: <20250602-dir-deleg-v2-0-a7919700de86@kernel.org> In-Reply-To: <20250602-dir-deleg-v2-0-a7919700de86@kernel.org> To: Alexander Viro , Christian Brauner , Jan Kara , Chuck Lever , Alexander Aring , Trond Myklebust , Anna Schumaker , Steve French , Paulo Alcantara , Ronnie Sahlberg , Shyam Prasad N , Tom Talpey , Bharath SM , NeilBrown , Olga Kornievskaia , Dai Ngo , Jonathan Corbet , Amir Goldstein , Miklos Szeredi Cc: linux-fsdevel@vger.kernel.org, linux-kernel@vger.kernel.org, linux-nfs@vger.kernel.org, linux-cifs@vger.kernel.org, samba-technical@lists.samba.org, linux-doc@vger.kernel.org, Jeff Layton X-Mailer: b4 0.14.2 X-Developer-Signature: v=1; a=openpgp-sha256; l=1135; i=jlayton@kernel.org; h=from:subject:message-id; bh=Wvyvgvm5DbaEUEvlZdhyahV78iFdXKqVNAP9xbePNLg=; b=owEBbQKS/ZANAwAKAQAOaEEZVoIVAcsmYgBoPa7miLI68gh65Xc2YZM2jK9ip/h1PbaLvR2Zu qmRu0wk/pOJAjMEAAEKAB0WIQRLwNeyRHGyoYTq9dMADmhBGVaCFQUCaD2u5gAKCRAADmhBGVaC FRkWD/9kMkvE7E3diNqJBXsV+jj5lJbXjdESLbVzqaddlyytM8qcw7Q04w6FoKKCAljsp6U9R9z 3tJOG5vLnfKMluvFM4ZIOafFqEqCIuT9kfGv4L4os48qgSNSeRzs9GFizPB5yAtk/3CjQd8V95y 1KkufwFWkJtSN7Pxf2AbQA4rjsvQEtVwmE4/xScYlAK6t105Zvq9mkTqlzZToUoNoOtK+adYhiu dC2kdm6WCD5Qo8tY8zfZUb40JRxd888FHzb/y/giv5xBMxfkWNO1XZ6JgdQe5vK66/nO2GqxoCy Hej3+AflC4iFr0jZl5MeFt119P1AcbSOp59+V6et2hEsJ9BMOBa+jLbwGciCzdDN6W4g1meE8fR AhmYzt89M5w00C+HvWvRByjp9/nZ/ydheuHqW5Wq9kKfS9yv4lpf0KC92ckbXime7Bu6jUNB/SJ ViS9QsvxdVxcUxTPSSzHYCT3MuxzHXCRPdCOjye1aYJi3GfSntU94g8Vo2Zwefs7ggygTxozaf7 nUxy1BGQ5Q42VCRYZ1Tzex7z2vUOxmpjVHYvnsEx7+IG93kYSBEptfNXL4CiqgOzWs4kl+0PnD6 77telQY7bWAQrRYmjFaZZ8MxmuHaXKhHkwMMv7jdT6w/qhjonbnastBr02Tm7Vkzu4PvzmGXO4w xR6KIVoAv23VczA== X-Developer-Key: i=jlayton@kernel.org; a=openpgp; fpr=4BC0D7B24471B2A184EAF5D3000E684119568215 As Trond pointed out: "...provided that the presented stateid is actually valid, it is also sufficient to uniquely identify the file to which it is associated (see RFC8881 Section 8.2.4), so the filehandle should be considered mostly irrelevant for operations like DELEGRETURN." Don't ask fh_verify to filter on file type. Signed-off-by: Jeff Layton --- fs/nfsd/nfs4state.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c index a0e3fa2718c7ef331925e9ba8f2a66f331c76db5..5bf12abe4778ca0a16cd6896506= 2da25470c8a93 100644 --- a/fs/nfsd/nfs4state.c +++ b/fs/nfsd/nfs4state.c @@ -7758,7 +7758,8 @@ nfsd4_delegreturn(struct svc_rqst *rqstp, struct nfsd= 4_compound_state *cstate, __be32 status; struct nfsd_net *nn =3D net_generic(SVC_NET(rqstp), nfsd_net_id); =20 - if ((status =3D fh_verify(rqstp, &cstate->current_fh, S_IFREG, 0))) + status =3D fh_verify(rqstp, &cstate->current_fh, 0, 0); + if (status) return status; =20 status =3D nfsd4_lookup_stateid(cstate, stateid, SC_TYPE_DELEG, SC_STATUS= _REVOKED, &s, nn); --=20 2.49.0 From nobody Thu Dec 18 14:10:55 2025 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 9A428221F24; Mon, 2 Jun 2025 14:02:47 +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=1748872967; cv=none; b=MYwGITET4Kw44J77eySDOEOzHKMylREM3fxNPfTfvjAfCw4kSR5QdK76Xiz8xKt2308cQIhC34SMsx/bEgE0mDCy+r90/la+Jp8aRbLN762tLXJE9W2N1vfnjKDIIkH21qFxqIFgB1yKF3g+6+u78/yUWR9VF2q5AJg1dzGCyf8= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1748872967; c=relaxed/simple; bh=PXBLMUX1p1ivEi2SghQqejpVOASv6EpMNz942WPIY+Y=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=CuRXcSiUODd8xg2C0/vdCOaa4Nb6bxMJpLW3SEylMXsCnL4fbdnLxJkVCjo0KUANfTfEUzKIV6ACi9EYZt7CoRcsNxji92xauZvcoc/PvGTA3nNtazu892Jk2TWgJijfyqIaFjBPxsiK4K8TFtKei5E+bikxFlyUYQh9puJEg20= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=f8gcVocP; 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="f8gcVocP" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 938AEC4CEF2; Mon, 2 Jun 2025 14:02:45 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1748872967; bh=PXBLMUX1p1ivEi2SghQqejpVOASv6EpMNz942WPIY+Y=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=f8gcVocP2QNIDJ/gaynZuucaR+HgwQLwy82FloAU3WnGCVofkw0dRj1q2vAZG0NSb uHnRO8GQSzUD+aw5z6bHxZoaKApUmJ2oF5SaRAaFh7yUO5Si22vV+WVLKrXLQ/8kYN 9awGrp1Vl8yJNW2c/YpiOoC7bFNBDGjv/ZgH19URL4idVq1N8+PUuAx4Lb+KdxZcw6 mg/d5jAKp4Jn2hE7Vkaq6LmNksIILq2tpk2lzlnO5+Sx7VeLVpzdjGnq3kbd+YPdqm 1YuqYBy07P3LNvoQORme01L6wUCqibWGo0S09Jw31I/FynelAa/rgDIa+CWQjP74SU v+oyF4PcZ0LSw== From: Jeff Layton Date: Mon, 02 Jun 2025 10:01:55 -0400 Subject: [PATCH RFC v2 12/28] nfsd: check for delegation conflicts vs. the same client Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20250602-dir-deleg-v2-12-a7919700de86@kernel.org> References: <20250602-dir-deleg-v2-0-a7919700de86@kernel.org> In-Reply-To: <20250602-dir-deleg-v2-0-a7919700de86@kernel.org> To: Alexander Viro , Christian Brauner , Jan Kara , Chuck Lever , Alexander Aring , Trond Myklebust , Anna Schumaker , Steve French , Paulo Alcantara , Ronnie Sahlberg , Shyam Prasad N , Tom Talpey , Bharath SM , NeilBrown , Olga Kornievskaia , Dai Ngo , Jonathan Corbet , Amir Goldstein , Miklos Szeredi Cc: linux-fsdevel@vger.kernel.org, linux-kernel@vger.kernel.org, linux-nfs@vger.kernel.org, linux-cifs@vger.kernel.org, samba-technical@lists.samba.org, linux-doc@vger.kernel.org, Jeff Layton X-Mailer: b4 0.14.2 X-Developer-Signature: v=1; a=openpgp-sha256; l=2624; i=jlayton@kernel.org; h=from:subject:message-id; bh=PXBLMUX1p1ivEi2SghQqejpVOASv6EpMNz942WPIY+Y=; b=owEBbQKS/ZANAwAKAQAOaEEZVoIVAcsmYgBoPa7ms1aKe7zhc8MXHDKI3jra3rX582Xton3iw d5scL6lQOSJAjMEAAEKAB0WIQRLwNeyRHGyoYTq9dMADmhBGVaCFQUCaD2u5gAKCRAADmhBGVaC FcrAEAC4t2TYaUqLPw3qoHmgyPZz2urj8ypY4VH1R9ntDiFxdTTVDXpQ0TX0TmzFH84aGzUvh// 74vRhKcgUbBJzPYNk3ZndHIfmo+D+YUhx79nKZtpLwiAKsJ289LkfZB1jLcgwu4/rbHbpbaA6Pv zPEDrdy1xKZjyd2n4tnZHHNyOojHYhfUxoL5ILIcoY/WV0Epj3ZRqeZVSgcD3QMSinQ4FGCklnw O3WMXQZ88B5nmmna+aGZCjtUHNMO+gDkCp97R+IO83giTCzuf2WYw7gZ0iOiuPgmSyMjW2HOZYV Bb7bqlhcyvAM8Yn4/Yg+ShsJu6T1fVhs5HaeFjRp2YqlYfHqM8kuex7IZ4V4vHJP3Lh+AIkzDpC PW2kLRaZhgfOIiUvmo1Y4tZVkvTD9mUE+9RkzloWxhj8yrGUkjxjlUau8rcJD7DYHGCpegUw/rA gmdy1IbDUwU3KMfU/z6EbYZH/VLPg4iJIB6WdiIn9Hhaef9cam+hrtKReWixGn/2DfjTsdnGzRn 5w2gH/P+t+lMSZ779cbOGVUNEsfhwUpz2AmmmOWE0ZFyGiv4TY2hayO8LFJ7F+A59On9fg4H5gb 5tfu/KbtCO8dvM9cWKLsuyvvUoSm49LLkIqECy1PSS4bnDG0zcz09r++6YSS5MDoSl4E8lvM7gB oJbhyUqjnb6kwTg== X-Developer-Key: i=jlayton@kernel.org; a=openpgp; fpr=4BC0D7B24471B2A184EAF5D3000E684119568215 RFC 8881 requires that the server reply with GDD_UNAVAIL when the client requests a directory delegation that it already holds. When setting a directory delegation, check that the client associated with the stateid doesn't match an existing delegation. If it does, reject the setlease attempt. Signed-off-by: Jeff Layton --- fs/nfsd/nfs4state.c | 29 ++++++++++++++++++++++++++++- 1 file changed, 28 insertions(+), 1 deletion(-) diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c index 5bf12abe4778ca0a16cd68965062da25470c8a93..12f20e3c9c54b68cdd4c62aa290= 4c22c9ccfae0a 100644 --- a/fs/nfsd/nfs4state.c +++ b/fs/nfsd/nfs4state.c @@ -88,6 +88,7 @@ void nfsd4_end_grace(struct nfsd_net *nn); static void _free_cpntf_state_locked(struct nfsd_net *nn, struct nfs4_cpnt= f_state *cps); static void nfsd4_file_hash_remove(struct nfs4_file *fi); static void deleg_reaper(struct nfsd_net *nn); +static bool nfsd_dir_may_setlease(struct file_lease *new, struct file_leas= e *old); =20 /* Locking: */ =20 @@ -5503,6 +5504,31 @@ static const struct lease_manager_operations nfsd_le= ase_mng_ops =3D { .lm_change =3D nfsd_change_deleg_cb, }; =20 +static const struct lease_manager_operations nfsd_dir_lease_mng_ops =3D { + .lm_breaker_owns_lease =3D nfsd_breaker_owns_lease, + .lm_break =3D nfsd_break_deleg_cb, + .lm_change =3D nfsd_change_deleg_cb, + .lm_may_setlease =3D nfsd_dir_may_setlease, +}; + +static bool +nfsd_dir_may_setlease(struct file_lease *new, struct file_lease *old) +{ + struct nfs4_delegation *od, *nd; + + /* Only conflicts with other nfsd dir delegs */ + if (old->fl_lmops !=3D &nfsd_dir_lease_mng_ops) + return true; + + od =3D old->c.flc_owner; + nd =3D new->c.flc_owner; + + /* Are these for the same client? No bueno if so */ + if (od->dl_stid.sc_client =3D=3D nd->dl_stid.sc_client) + return false; + return true; +} + static __be32 nfsd4_check_seqid(struct nfsd4_compound_state *cstate, struc= t nfs4_stateowner *so, u32 seqid) { if (nfsd4_has_session(cstate)) @@ -5841,12 +5867,13 @@ static struct file_lease *nfs4_alloc_init_lease(str= uct nfs4_delegation *dp) fl =3D locks_alloc_lease(); if (!fl) return NULL; - fl->fl_lmops =3D &nfsd_lease_mng_ops; fl->c.flc_flags =3D FL_DELEG; fl->c.flc_type =3D deleg_is_read(dp->dl_type) ? F_RDLCK : F_WRLCK; fl->c.flc_owner =3D (fl_owner_t)dp; fl->c.flc_pid =3D current->tgid; fl->c.flc_file =3D dp->dl_stid.sc_file->fi_deleg_file->nf_file; + fl->fl_lmops =3D S_ISDIR(file_inode(fl->c.flc_file)->i_mode) ? + &nfsd_dir_lease_mng_ops : &nfsd_lease_mng_ops; return fl; } =20 --=20 2.49.0 From nobody Thu Dec 18 14:10:55 2025 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 D3D53230BC3; Mon, 2 Jun 2025 14:02:49 +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=1748872970; cv=none; b=gUZ2DLmnXGhEnxlSac2XluWB/EXXp5qTocMxFcI6cd8+ONAs3vcPKatVDytU1KSYoYqrLy/koSpULa76u4a64twVr6+PyX48VGs3mtZfQh8iwcZaBslr9FNo7yyoAJzrsV3y/MTe6yJWZW2JKUUuPHsFjD5O/wKhTIKog4jlE6k= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1748872970; c=relaxed/simple; bh=hYLRQ8v788ftgkpEhYsLTSyg0Nr10YJX5mZ5C9KFksk=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=LdgcSA/xAzdlICyOa3vrWy60OFnvz89w4hFF8aN5VWT2UQzJ0T2GMLPJA5sHVe6AvtI8SoxQ0GWmSAKFzdw8Omi00nMUNfqmF32/FSYDkAGOjnnUQK31816yPkWJCXO53bYp1Mhtp6DSWpte9IUcCwZYpHjZOFwhJt9DcbT7UB8= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=Sp3N8wjq; 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="Sp3N8wjq" Received: by smtp.kernel.org (Postfix) with ESMTPSA id B2677C4CEEB; Mon, 2 Jun 2025 14:02:47 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1748872969; bh=hYLRQ8v788ftgkpEhYsLTSyg0Nr10YJX5mZ5C9KFksk=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=Sp3N8wjqCEIq5C0H+crBQt+k+PkUxUZFqd1uW2JxFp1ERegi2SQzAlIhO1qCWsj/K 22eDdQp+0vJZy+s96O/8XGHoxz8zfHi6dhTkjNfhV+SpHqd9qPtddyZTyo1SCu2T0h Hsp/ldQ6CbmM05/UGYRXQM/ywIbizsyh+V76Ay5j0fs5IhBg+G85rEzRGGcvJJoaDP cQ9g4s5HRgrKJTszkABSjRwg3ubrNmMmXo/NZrvB6k8pxXx8fBT+ss6CpsuUjo+/u/ sphvYtx3SMa/h0b5+bqfgCI69hMcaCEYLvFlOjh2JGagv699vWkNC7wXI2Wy+5R8Wy PZje7bOcuSDRg== From: Jeff Layton Date: Mon, 02 Jun 2025 10:01:56 -0400 Subject: [PATCH RFC v2 13/28] nfsd: wire up GET_DIR_DELEGATION handling Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20250602-dir-deleg-v2-13-a7919700de86@kernel.org> References: <20250602-dir-deleg-v2-0-a7919700de86@kernel.org> In-Reply-To: <20250602-dir-deleg-v2-0-a7919700de86@kernel.org> To: Alexander Viro , Christian Brauner , Jan Kara , Chuck Lever , Alexander Aring , Trond Myklebust , Anna Schumaker , Steve French , Paulo Alcantara , Ronnie Sahlberg , Shyam Prasad N , Tom Talpey , Bharath SM , NeilBrown , Olga Kornievskaia , Dai Ngo , Jonathan Corbet , Amir Goldstein , Miklos Szeredi Cc: linux-fsdevel@vger.kernel.org, linux-kernel@vger.kernel.org, linux-nfs@vger.kernel.org, linux-cifs@vger.kernel.org, samba-technical@lists.samba.org, linux-doc@vger.kernel.org, Jeff Layton X-Mailer: b4 0.14.2 X-Developer-Signature: v=1; a=openpgp-sha256; l=4963; i=jlayton@kernel.org; h=from:subject:message-id; bh=hYLRQ8v788ftgkpEhYsLTSyg0Nr10YJX5mZ5C9KFksk=; b=owEBbQKS/ZANAwAKAQAOaEEZVoIVAcsmYgBoPa7n0atl1ii6zmc/TBC6kmriNVQJyCfmy9cb1 Jh0yDKgX0CJAjMEAAEKAB0WIQRLwNeyRHGyoYTq9dMADmhBGVaCFQUCaD2u5wAKCRAADmhBGVaC FS++D/9YV6d68qV5iRsui3V1GgS2bRY/r7U+0uqV1XtoqVqTPCkAtgr0rLSt59YcTK3YNR3RBfP J0oHNjl0wqhckZFOi80pM2VcPoEaEZQ49gaHTphp5BGuvai8xKL97O01wWdeBjVAe+1JWPhCEik Lf9UxGXl80dZhg1GcSMJnLHpdFO52sqms+NzSfrVd8gcuSf/XcclZSOftofzeih/jxN9D6aUXbS aAVoopMibvfHPHePnlONTNF8vRLMR+ll52JOrx+kS9yp2EOtHioPcpQiPLupbjLrr7ZgaF503Vz tfZKbyxam5804r34nSHDNNMN4AHc4HyidmRKacK0o8YMkuse/7dq4vH75CXFcq0uSjUVHwLf5PF pdxogVzaXvQ3irlZYVdOWJ9s8r7613457l/9AOlqGFm5oXuprRKvlhlT3SlI2CXNojKpr3EX1bP Pec0iDDDRylTRG5zAlaKYsW2VZAmXgbtWzGhXiGX2rtKwKII1t01uDvBCwpNWalspZt3D6ZmXIE rbnI9Gv/KM7QmPbhQ8BczYE4KgGXiePgYvUOXokNu0Vsf3XKUHG8tKViSXyb0YJaPQOoNSvqt2H 4o7Ycx3Tbfj7z0ir8BrDbrekIOjD6DS6RMRV26wSLDxBbLDUWY3R/PZPOA4Yt3ejduNdnw0Oz6G WyiCJiPXteElMPw== X-Developer-Key: i=jlayton@kernel.org; a=openpgp; fpr=4BC0D7B24471B2A184EAF5D3000E684119568215 Add a new routine for acquiring a read delegation on a directory. Since the same CB_RECALL/DELEGRETURN infrastrure is used for regular and directory delegations, we can just use a normal nfs4_delegation to represent it. Signed-off-by: Jeff Layton --- fs/nfsd/nfs4proc.c | 21 +++++++++++++- fs/nfsd/nfs4state.c | 82 +++++++++++++++++++++++++++++++++++++++++++++++++= ++++ fs/nfsd/state.h | 5 ++++ 3 files changed, 107 insertions(+), 1 deletion(-) diff --git a/fs/nfsd/nfs4proc.c b/fs/nfsd/nfs4proc.c index f13abbb13b388d223165b1168dc2c07eafb259cb..fa6f2980bcacd798c41387c71d5= 5a59fdbc8043c 100644 --- a/fs/nfsd/nfs4proc.c +++ b/fs/nfsd/nfs4proc.c @@ -2298,6 +2298,13 @@ nfsd4_get_dir_delegation(struct svc_rqst *rqstp, union nfsd4_op_u *u) { struct nfsd4_get_dir_delegation *gdd =3D &u->get_dir_delegation; + struct nfs4_delegation *dd; + struct nfsd_file *nf; + __be32 status; + + status =3D nfsd_file_acquire_dir(rqstp, &cstate->current_fh, &nf); + if (status !=3D nfs_ok) + return status; =20 /* * RFC 8881, section 18.39.3 says: @@ -2311,7 +2318,19 @@ nfsd4_get_dir_delegation(struct svc_rqst *rqstp, * return NFS4_OK with a non-fatal status of GDD4_UNAVAIL in this * situation. */ - gdd->gddrnf_status =3D GDD4_UNAVAIL; + dd =3D nfsd_get_dir_deleg(cstate, gdd, nf); + if (IS_ERR(dd)) { + int err =3D PTR_ERR(dd); + + if (err !=3D -EAGAIN) + return nfserrno(err); + gdd->gddrnf_status =3D GDD4_UNAVAIL; + return nfs_ok; + } + + gdd->gddrnf_status =3D GDD4_OK; + memcpy(&gdd->gddr_stateid, &dd->dl_stid.sc_stateid, sizeof(gdd->gddr_stat= eid)); + nfs4_put_stid(&dd->dl_stid); return nfs_ok; } =20 diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c index 12f20e3c9c54b68cdd4c62aa2904c22c9ccfae0a..ed5d6486d171ea0c886bd1f1ea1= 129bf4ccf429c 100644 --- a/fs/nfsd/nfs4state.c +++ b/fs/nfsd/nfs4state.c @@ -9307,3 +9307,85 @@ nfsd4_deleg_getattr_conflict(struct svc_rqst *rqstp,= struct dentry *dentry, nfs4_put_stid(&dp->dl_stid); return status; } + +/** + * nfsd_get_dir_deleg - attempt to get a directory delegation + * @cstate: compound state + * @gdd: GET_DIR_DELEGATION arg/resp structure + * @nf: nfsd_file opened on the directory + * + * Given a GET_DIR_DELEGATION request @gdd, attempt to acquire a delegation + * on the directory to which @nf refers. Note that this does not set up any + * sort of async notifications for the delegation. + */ +struct nfs4_delegation * +nfsd_get_dir_deleg(struct nfsd4_compound_state *cstate, + struct nfsd4_get_dir_delegation *gdd, + struct nfsd_file *nf) +{ + struct nfs4_client *clp =3D cstate->clp; + struct nfs4_delegation *dp; + struct file_lease *fl; + struct nfs4_file *fp; + int status =3D 0; + + fp =3D nfsd4_alloc_file(); + if (!fp) + return ERR_PTR(-ENOMEM); + + nfsd4_file_init(&cstate->current_fh, fp); + fp->fi_deleg_file =3D nf; + fp->fi_delegees =3D 1; + + /* if this client already has one, return that it's unavailable */ + spin_lock(&state_lock); + spin_lock(&fp->fi_lock); + if (nfs4_delegation_exists(clp, fp)) + status =3D -EAGAIN; + spin_unlock(&fp->fi_lock); + spin_unlock(&state_lock); + + if (status) + goto out_delegees; + + /* Try to set up the lease */ + status =3D -ENOMEM; + dp =3D alloc_init_deleg(clp, fp, NULL, NFS4_OPEN_DELEGATE_READ); + if (!dp) + goto out_delegees; + + fl =3D nfs4_alloc_init_lease(dp); + if (!fl) + goto out_put_stid; + + status =3D kernel_setlease(nf->nf_file, + fl->c.flc_type, &fl, NULL); + if (fl) + locks_free_lease(fl); + if (status) + goto out_put_stid; + + /* + * Now, try to hash it. This can fail if we race another nfsd task + * trying to set a delegation on the same file. If that happens, + * then just say UNAVAIL. + */ + spin_lock(&state_lock); + spin_lock(&clp->cl_lock); + spin_lock(&fp->fi_lock); + status =3D hash_delegation_locked(dp, fp); + spin_unlock(&fp->fi_lock); + spin_unlock(&clp->cl_lock); + spin_unlock(&state_lock); + + if (!status) + return dp; + + /* Something failed. Drop the lease and clean up the stid */ + kernel_setlease(fp->fi_deleg_file->nf_file, F_UNLCK, NULL, (void **)&dp); +out_put_stid: + nfs4_put_stid(&dp->dl_stid); +out_delegees: + put_deleg_file(fp); + return ERR_PTR(status); +} diff --git a/fs/nfsd/state.h b/fs/nfsd/state.h index 8adc2550129e67a4e6646395fa2811e1c2acb98e..0eeecd824770c4df8e1cc29fc73= 8e568d91d5e5f 100644 --- a/fs/nfsd/state.h +++ b/fs/nfsd/state.h @@ -855,4 +855,9 @@ static inline bool try_to_expire_client(struct nfs4_cli= ent *clp) =20 extern __be32 nfsd4_deleg_getattr_conflict(struct svc_rqst *rqstp, struct dentry *dentry, struct nfs4_delegation **pdp); + +struct nfsd4_get_dir_delegation; +struct nfs4_delegation *nfsd_get_dir_deleg(struct nfsd4_compound_state *cs= tate, + struct nfsd4_get_dir_delegation *gdd, + struct nfsd_file *nf); #endif /* NFSD4_STATE_H */ --=20 2.49.0 From nobody Thu Dec 18 14:10:55 2025 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 EEF92231849; Mon, 2 Jun 2025 14:02:51 +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=1748872972; cv=none; b=Ll/PDhLjj+b4TwWQfCNCEiJpW4vUrYmAKGKaOe+/RHdYLLca1uA0H+o2Z4A43dtul0rnWifzLJbvHH98DjV8z9XiY82kPUBnPzla/zWaEs9McVAH1UVzugUgLBFoirgYTQSq8hxnHls4ludUxTkgUgv+KGqcZ8JeYAOrMDkoPz4= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1748872972; c=relaxed/simple; bh=mSZ+Tq+Scvh8C9wum7JJA/yZBWRfnRsmhQedhLJ+MMs=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=mW70TKdYASiaj0nlYk+RGGa21d6/insb3g7LL1qU4g5xuz4pVWS1JIIPw15xYsq0NsOjKP9aLzkudv19IprMIdk0aPCgUhQSbE5FwjoUAgi5pB/Bwh5M7mbX02QjdXHH+eICgqcVz7sJ8niJ/Mpq2swzCJf+oD6xQsXTso8lC+0= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=K9ffYvv3; 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="K9ffYvv3" Received: by smtp.kernel.org (Postfix) with ESMTPSA id D1ABAC4CEF2; Mon, 2 Jun 2025 14:02:49 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1748872971; bh=mSZ+Tq+Scvh8C9wum7JJA/yZBWRfnRsmhQedhLJ+MMs=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=K9ffYvv3xQe4fdSRA0UFPMZm3dYPB26TXTOYHwDQ5GbGwrrEExeOgjrs8Fu4fEAlC Bu0ltIJkFtJgtZ70uLp3azfK4yHC+P/LGA5h9yv2S+UkEyaxMPMWt2oRDD8R3ithT6 Lzi4EMA4CDadXlzn67OY2vxAowL4n9BhzNJN8u/meKBDlOn3FVmdzAIRZqGG2+gVs2 ZL3L0x5zUB0QoDM8VV1tGqADiJTvvEq1qeBLyx/kKln3Df8LmOH81M7v+d36cFCVIr tfz01P5uURxRvzZPA3BlfKczhCfCOCBLkbTo5gMJmGB4VfNOd2UwrS7MUJIoxPNn1d PYsYexGrJOIcg== From: Jeff Layton Date: Mon, 02 Jun 2025 10:01:57 -0400 Subject: [PATCH RFC v2 14/28] filelock: rework the __break_lease API to use flags Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20250602-dir-deleg-v2-14-a7919700de86@kernel.org> References: <20250602-dir-deleg-v2-0-a7919700de86@kernel.org> In-Reply-To: <20250602-dir-deleg-v2-0-a7919700de86@kernel.org> To: Alexander Viro , Christian Brauner , Jan Kara , Chuck Lever , Alexander Aring , Trond Myklebust , Anna Schumaker , Steve French , Paulo Alcantara , Ronnie Sahlberg , Shyam Prasad N , Tom Talpey , Bharath SM , NeilBrown , Olga Kornievskaia , Dai Ngo , Jonathan Corbet , Amir Goldstein , Miklos Szeredi Cc: linux-fsdevel@vger.kernel.org, linux-kernel@vger.kernel.org, linux-nfs@vger.kernel.org, linux-cifs@vger.kernel.org, samba-technical@lists.samba.org, linux-doc@vger.kernel.org, Jeff Layton X-Mailer: b4 0.14.2 X-Developer-Signature: v=1; a=openpgp-sha256; l=7075; i=jlayton@kernel.org; h=from:subject:message-id; bh=mSZ+Tq+Scvh8C9wum7JJA/yZBWRfnRsmhQedhLJ+MMs=; b=owEBbQKS/ZANAwAKAQAOaEEZVoIVAcsmYgBoPa7ne7oHoBM+qhMZ3CaFsqLNTMCpC2dhUeaad JMhCmVDb1mJAjMEAAEKAB0WIQRLwNeyRHGyoYTq9dMADmhBGVaCFQUCaD2u5wAKCRAADmhBGVaC FetPEACOJPiOO1361MaUQCwy4nzClqOvT5QLoeMe/g1JBE5ZcO8uf6Fr9OZnsIEfDWR297Ef8Px gu+5BBdWCIOoDvPi9XmiQCBGWdlIXjV1uVr8KGIzHJ6sikPM17ePimWx/eWNtyyY2Laer2piKMW FjyoL3wNb+zxV8ZgvoXmiHT7DjlCHXeQQ3T6F4lEwYW8J2B/D2QMjIbz1IxccH/h4CljZ1FGwC+ pWsAEgdiDrc3lnj+QMIo+hVvZ5f97qCyplbN7U/WtqXvQ+sKUGZ87crY2cnsB+dVMYXS/iBoqyT Q7rwbBXhMXb7cTbi/720XvzcTdnBcb24joHv4+ZMcW0xu02oawvo57OHqPgEAb3tXyKeU0qBqtc UgSGsv41xZBKPhVIJ4DSgjSlrEYFSWOCRphNvxQBI+utalonG17PRF7BXDo2+OhteXhMrR8aYyn rDCnJ8rlZMjbX8chaW2lSM7BLgv76VzUhSIYPMZZpXEMhMAd6F0U8mn3tXIx9vyDsP24JwrbD0r tkqVBsmzke0zlX+Nqw6nYeaKmWgGrqiYj/EVthHLfwX4qnKiX4X9Jb6Ngz3/3YsD9ogK0JnUvAz 5r1k/AyfhyrPqKGHyzBKAbVRgD+HLBqddQ9CwAs9+MG4w8bhgjVz0y389HHRWYNGDzZJjaWR0co 8KvYn/51pVA04iA== X-Developer-Key: i=jlayton@kernel.org; a=openpgp; fpr=4BC0D7B24471B2A184EAF5D3000E684119568215 Declare a set of LEASE_BREAK_* flags that can be used to control how lease breaks work instead of requiring a type and an openmode. Signed-off-by: Jeff Layton --- fs/locks.c | 30 +++++++++++++++++----------- include/linux/filelock.h | 52 +++++++++++++++++++++++++++++++++++---------= ---- 2 files changed, 56 insertions(+), 26 deletions(-) diff --git a/fs/locks.c b/fs/locks.c index 82a1b528dc9dae8c1f3a81084072e649d481e8f1..6e46176d1e00962904f03c15150= 0e593f410e4c6 100644 --- a/fs/locks.c +++ b/fs/locks.c @@ -1529,29 +1529,35 @@ any_leases_conflict(struct inode *inode, struct fil= e_lease *breaker) /** * __break_lease - revoke all outstanding leases on file * @inode: the inode of the file to return - * @mode: O_RDONLY: break only write leases; O_WRONLY or O_RDWR: - * break all leases - * @type: FL_LEASE: break leases and delegations; FL_DELEG: break - * only delegations + * @flags: LEASE_BREAK_* flags * * break_lease (inlined for speed) has checked there already is at least * some kind of lock (maybe a lease) on this file. Leases are broken on - * a call to open() or truncate(). This function can sleep unless you - * specified %O_NONBLOCK to your open(). + * a call to open() or truncate(). This function can block waiting for the + * lease break unless you specify LEASE_BREAK_NONBLOCK. */ -int __break_lease(struct inode *inode, unsigned int mode, unsigned int typ= e) +int __break_lease(struct inode *inode, unsigned int flags) { - int error =3D 0; - struct file_lock_context *ctx; struct file_lease *new_fl, *fl, *tmp; + struct file_lock_context *ctx; unsigned long break_time; - int want_write =3D (mode & O_ACCMODE) !=3D O_RDONLY; LIST_HEAD(dispose); + bool want_write =3D !(flags & LEASE_BREAK_OPEN_RDONLY); + int error =3D 0; + =20 new_fl =3D lease_alloc(NULL, want_write ? F_WRLCK : F_RDLCK); if (IS_ERR(new_fl)) return PTR_ERR(new_fl); - new_fl->c.flc_flags =3D type; + + if (flags & LEASE_BREAK_LEASE) + new_fl->c.flc_flags =3D FL_LEASE; + else if (flags & LEASE_BREAK_DELEG) + new_fl->c.flc_flags =3D FL_DELEG; + else if (flags & LEASE_BREAK_LAYOUT) + new_fl->c.flc_flags =3D FL_LAYOUT; + else + return -EINVAL; =20 /* typically we will check that ctx is non-NULL before calling */ ctx =3D locks_inode_context(inode); @@ -1596,7 +1602,7 @@ int __break_lease(struct inode *inode, unsigned int m= ode, unsigned int type) if (list_empty(&ctx->flc_lease)) goto out; =20 - if (mode & O_NONBLOCK) { + if (flags & LEASE_BREAK_NONBLOCK) { trace_break_lease_noblock(inode, new_fl); error =3D -EWOULDBLOCK; goto out; diff --git a/include/linux/filelock.h b/include/linux/filelock.h index 60c76c8fb4dfdcaaa2cfa3f41f0f26ffcb3db29f..0fe368060781d0b22f735c2cfb8= d8c1a6a238290 100644 --- a/include/linux/filelock.h +++ b/include/linux/filelock.h @@ -221,7 +221,14 @@ int locks_lock_inode_wait(struct inode *inode, struct = file_lock *fl); void locks_init_lease(struct file_lease *); void locks_free_lease(struct file_lease *fl); struct file_lease *locks_alloc_lease(void); -int __break_lease(struct inode *inode, unsigned int flags, unsigned int ty= pe); + +#define LEASE_BREAK_LEASE BIT(0) // break leases and delegations +#define LEASE_BREAK_DELEG BIT(1) // break delegations only +#define LEASE_BREAK_LAYOUT BIT(2) // break layouts only +#define LEASE_BREAK_NONBLOCK BIT(3) // non-blocking break +#define LEASE_BREAK_OPEN_RDONLY BIT(4) // readonly open event + +int __break_lease(struct inode *inode, unsigned int flags); void lease_get_mtime(struct inode *, struct timespec64 *time); int generic_setlease(struct file *, int, struct file_lease **, void **priv= ); int kernel_setlease(struct file *, int, struct file_lease **, void **); @@ -376,7 +383,7 @@ static inline int locks_lock_inode_wait(struct inode *i= node, struct file_lock *f return -ENOLCK; } =20 -static inline int __break_lease(struct inode *inode, unsigned int mode, un= signed int type) +static inline int __break_lease(struct inode *inode, unsigned int flags) { return 0; } @@ -437,6 +444,17 @@ static inline int locks_lock_file_wait(struct file *fi= lp, struct file_lock *fl) } =20 #ifdef CONFIG_FILE_LOCKING +static inline unsigned int openmode_to_lease_flags(unsigned int mode) +{ + unsigned int flags =3D 0; + + if ((mode & O_ACCMODE) =3D=3D O_RDONLY) + flags |=3D LEASE_BREAK_OPEN_RDONLY; + if (mode & O_NONBLOCK) + flags |=3D LEASE_BREAK_NONBLOCK; + return flags; +} + static inline int break_lease(struct inode *inode, unsigned int mode) { struct file_lock_context *flctx; @@ -452,11 +470,11 @@ static inline int break_lease(struct inode *inode, un= signed int mode) return 0; smp_mb(); if (!list_empty_careful(&flctx->flc_lease)) - return __break_lease(inode, mode, FL_LEASE); + return __break_lease(inode, LEASE_BREAK_LEASE | openmode_to_lease_flags(= mode)); return 0; } =20 -static inline int break_deleg(struct inode *inode, unsigned int mode) +static inline int break_deleg(struct inode *inode, unsigned int flags) { struct file_lock_context *flctx; =20 @@ -470,8 +488,10 @@ static inline int break_deleg(struct inode *inode, uns= igned int mode) if (!flctx) return 0; smp_mb(); - if (!list_empty_careful(&flctx->flc_lease)) - return __break_lease(inode, mode, FL_DELEG); + if (!list_empty_careful(&flctx->flc_lease)) { + flags |=3D LEASE_BREAK_DELEG; + return __break_lease(inode, flags); + } return 0; } =20 @@ -479,7 +499,7 @@ static inline int try_break_deleg(struct inode *inode, = struct inode **delegated_ { int ret; =20 - ret =3D break_deleg(inode, O_WRONLY|O_NONBLOCK); + ret =3D break_deleg(inode, LEASE_BREAK_NONBLOCK); if (ret =3D=3D -EWOULDBLOCK && delegated_inode) { *delegated_inode =3D inode; ihold(inode); @@ -491,7 +511,7 @@ static inline int break_deleg_wait(struct inode **deleg= ated_inode) { int ret; =20 - ret =3D break_deleg(*delegated_inode, O_WRONLY); + ret =3D break_deleg(*delegated_inode, 0); iput(*delegated_inode); *delegated_inode =3D NULL; return ret; @@ -500,20 +520,24 @@ static inline int break_deleg_wait(struct inode **del= egated_inode) static inline int break_layout(struct inode *inode, bool wait) { smp_mb(); - if (inode->i_flctx && !list_empty_careful(&inode->i_flctx->flc_lease)) - return __break_lease(inode, - wait ? O_WRONLY : O_WRONLY | O_NONBLOCK, - FL_LAYOUT); + if (inode->i_flctx && !list_empty_careful(&inode->i_flctx->flc_lease)) { + unsigned int flags =3D LEASE_BREAK_LAYOUT; + + if (!wait) + flags |=3D LEASE_BREAK_NONBLOCK; + + return __break_lease(inode, flags); + } return 0; } =20 #else /* !CONFIG_FILE_LOCKING */ -static inline int break_lease(struct inode *inode, unsigned int mode) +static inline int break_lease(struct inode *inode, bool wait) { return 0; } =20 -static inline int break_deleg(struct inode *inode, unsigned int mode) +static inline int break_deleg(struct inode *inode, unsigned int flags) { return 0; } --=20 2.49.0 From nobody Thu Dec 18 14:10:55 2025 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 6FA81232376; Mon, 2 Jun 2025 14:02:54 +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=1748872974; cv=none; b=e/wKq498/GcUg2qQiQkTeUm4hK+bSsn3qNz1cKNEHt6CjimrKtic4JtQCMoWqutQs1g7qjTBcUAQlXXGJ8m+P2sV1ob7R6mhDIeHNj1/kCmgCt1zAL7syEuXpYO/mN9d0neafFsW3aiVpvcvk631+92fC1oW6xFp9hhkVhwdsaQ= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1748872974; c=relaxed/simple; bh=3k+VvTdjcwKXyNQVPi29EJW5NaPGU8wqkBuvNBLOJmg=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=LcwTfSlzE5Yqssf1nX/VDDvu1j10OyXr1qrQz48S/WYDRycn+whdcV5s5BGU10AjPzipDrQyEVurjpwjuzHPR/NTLXGHvR03YdaajXmxUz1m18L6rANSj64qs9nogpdzerA/nagTX4dKqfPnlOzLsBIv1k3N21B2oPmrD+k8dqw= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=ASI7Ygri; 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="ASI7Ygri" Received: by smtp.kernel.org (Postfix) with ESMTPSA id F061DC4CEF0; Mon, 2 Jun 2025 14:02:51 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1748872973; bh=3k+VvTdjcwKXyNQVPi29EJW5NaPGU8wqkBuvNBLOJmg=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=ASI7Ygrin0QZBCC9OLr1qAjHAafsCEB+4DQNF5jYwuZWDzu8cpdFhO7cWaX5eHXAo ZvVf5yzn/HW2Ob+sPseRyj28fNI4GBYrukFrrPpKqmmBjMsBBSREeKOyIMnQNg7LTJ eXwUEx7ybOb71Cmk6WWGYwPTJKnBxjvRYCxOvj1wmh1T/DxgQRceNi65j4jE+Y7lyR /ash4jGPgr5hsP0ocWhuAHUtVTjTmtqE4tYlP9asglfZqsKZvvYej+zk+pDIH622V1 y27SywSpznUnDDXUJE9P88opE2+uBVGLFSaf5gurfZiWsIONwDWdIpFnPEeiGAz+LU Sq2kG7PGoW0rw== From: Jeff Layton Date: Mon, 02 Jun 2025 10:01:58 -0400 Subject: [PATCH RFC v2 15/28] filelock: add struct delegated_inode Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20250602-dir-deleg-v2-15-a7919700de86@kernel.org> References: <20250602-dir-deleg-v2-0-a7919700de86@kernel.org> In-Reply-To: <20250602-dir-deleg-v2-0-a7919700de86@kernel.org> To: Alexander Viro , Christian Brauner , Jan Kara , Chuck Lever , Alexander Aring , Trond Myklebust , Anna Schumaker , Steve French , Paulo Alcantara , Ronnie Sahlberg , Shyam Prasad N , Tom Talpey , Bharath SM , NeilBrown , Olga Kornievskaia , Dai Ngo , Jonathan Corbet , Amir Goldstein , Miklos Szeredi Cc: linux-fsdevel@vger.kernel.org, linux-kernel@vger.kernel.org, linux-nfs@vger.kernel.org, linux-cifs@vger.kernel.org, samba-technical@lists.samba.org, linux-doc@vger.kernel.org, Jeff Layton X-Mailer: b4 0.14.2 X-Developer-Signature: v=1; a=openpgp-sha256; l=27085; i=jlayton@kernel.org; h=from:subject:message-id; bh=3k+VvTdjcwKXyNQVPi29EJW5NaPGU8wqkBuvNBLOJmg=; b=owEBbQKS/ZANAwAKAQAOaEEZVoIVAcsmYgBoPa7njTwbrGXHQ9ZwnJSIOTuo+UAlFRFzt4Bdv h3q2ghr+2KJAjMEAAEKAB0WIQRLwNeyRHGyoYTq9dMADmhBGVaCFQUCaD2u5wAKCRAADmhBGVaC FaWED/4z3+En3mW4KxYz5ZubB00WFVVY+fh+S1XPavUdzfpR1imob4bwvdbt8cFB7j5h1PIBxIv ZvMhLYyItXyWt9xNecdgqtFQ845vwpLC9DwbcV1DUZTdiV0Ji28FU9bqot/6lW1HStub+ZFQkyO qQM0Xy9H6XDoZGE4BgzOmi+M13Z+3GH9K/ZtmKVAV3RfzcgkT/TA5lc2TSAi21B8BUUdJElBpD3 4pssq9NMwFlaR2kSk2B9/d6G6+t9G8oYkQehpkge8PRuojJOlr0Axazqb1sT6pJBPi0MptmOLnC L047jCJSnXdr/yBIF+wmfOV4beRNU+CJHdQLHyzQJxUDusBG49AVmyVcgTGYhmoJSBikSZ327Xw mRHIfiMCDBplIgegwjyG1XX7G2yQdIfCjLqsj3fJxOSxMto/YIOtD0Cv2wmKc/XAPRAnJW7jQ6c gUsRcsLGgu73R5gh+qx0mc/+UUx3d9ZyOF5Jta+/SiTVi74FXMQla4RF4q+PhHGHvk3i6FuEYer xmsb8RYXRkEaqSKizZbSvBFPEmIZBJCTYiS3Z/KcnEwOjImyAqeq7CawXj2cDZrxJMgBYdlRu2L E9r4xDfwkVAreC5YivFXswsjjzT8amAcDzUcfDpjM/blV6l2uKQXXswvVUkTB9U6OVR5fGI8k1X rEIa9Pwqr3CuaDg== X-Developer-Key: i=jlayton@kernel.org; a=openpgp; fpr=4BC0D7B24471B2A184EAF5D3000E684119568215 Later patches will add support for ignoring certain events rather than breaking the delegation. To do this, the VFS must inform __break_lease() about why the delegation is being broken. Convert the delegated_inode double pointer in various VFS functions into a struct that has a inode and a reason for the delegation break. Also set the reason value in the appropriate places. Signed-off-by: Jeff Layton --- fs/attr.c | 4 +-- fs/namei.c | 75 +++++++++++++++++++++++++-------------------= ---- fs/open.c | 8 +++--- fs/posix_acl.c | 12 ++++---- fs/utimes.c | 4 +-- fs/xattr.c | 16 +++++------ include/linux/filelock.h | 63 +++++++++++++++++++++++++++++----------- include/linux/fs.h | 9 +++--- include/linux/xattr.h | 4 +-- 9 files changed, 115 insertions(+), 80 deletions(-) diff --git a/fs/attr.c b/fs/attr.c index 9caf63d20d03e86c535e9c8c91d49c2a34d34b7a..02f685a56729c2f8b3f6b6d636a= 9297a1e52062a 100644 --- a/fs/attr.c +++ b/fs/attr.c @@ -424,7 +424,7 @@ EXPORT_SYMBOL(may_setattr); * performed on the raw inode simply pass @nop_mnt_idmap. */ int notify_change(struct mnt_idmap *idmap, struct dentry *dentry, - struct iattr *attr, struct inode **delegated_inode) + struct iattr *attr, struct delegated_inode *delegated_inode) { struct inode *inode =3D dentry->d_inode; umode_t mode =3D inode->i_mode; @@ -543,7 +543,7 @@ int notify_change(struct mnt_idmap *idmap, struct dentr= y *dentry, * breaking the delegation in this case. */ if (!(ia_valid & ATTR_DELEG)) { - error =3D try_break_deleg(inode, delegated_inode); + error =3D try_break_deleg(inode, 0, delegated_inode); if (error) return error; } diff --git a/fs/namei.c b/fs/namei.c index 8f0517ade308134ed6566566d9b575c4e9fb0d4e..ba9cbdfb591d54cfe3315d8821c= e276a6f12700f 100644 --- a/fs/namei.c +++ b/fs/namei.c @@ -3372,7 +3372,7 @@ static inline umode_t vfs_prepare_mode(struct mnt_idm= ap *idmap, =20 static int __vfs_create(struct mnt_idmap *idmap, struct inode *dir, struct dentry *dentry, umode_t mode, bool want_excl, - struct inode **delegated_inode) + struct delegated_inode *delegated_inode) { int error; =20 @@ -3387,7 +3387,7 @@ static int __vfs_create(struct mnt_idmap *idmap, stru= ct inode *dir, error =3D security_inode_create(dir, dentry, mode); if (error) return error; - error =3D try_break_deleg(dir, delegated_inode); + error =3D try_break_deleg(dir, LEASE_BREAK_DIR_CREATE, delegated_inode); if (error) return error; error =3D dir->i_op->create(idmap, dir, dentry, mode, want_excl); @@ -3618,8 +3618,8 @@ static struct dentry *atomic_open(struct nameidata *n= d, struct dentry *dentry, * An error code is returned on failure. */ static struct dentry *lookup_open(struct nameidata *nd, struct file *file, - const struct open_flags *op, - bool got_write, struct inode **delegated_inode) + const struct open_flags *op, bool got_write, + struct delegated_inode *delegated_inode) { struct mnt_idmap *idmap; struct dentry *dir =3D nd->path.dentry; @@ -3709,7 +3709,7 @@ static struct dentry *lookup_open(struct nameidata *n= d, struct file *file, /* Negative dentry, just create the file */ if (!dentry->d_inode && (open_flag & O_CREAT)) { /* but break the directory lease first! */ - error =3D try_break_deleg(dir_inode, delegated_inode); + error =3D try_break_deleg(dir_inode, LEASE_BREAK_DIR_CREATE, delegated_i= node); if (error) goto out_dput; =20 @@ -3776,7 +3776,7 @@ static const char *open_last_lookups(struct nameidata= *nd, struct file *file, const struct open_flags *op) { struct dentry *dir =3D nd->path.dentry; - struct inode *delegated_inode =3D NULL; + struct delegated_inode delegated_inode =3D { }; int open_flag =3D op->open_flag; bool got_write =3D false; struct dentry *dentry; @@ -3836,7 +3836,7 @@ static const char *open_last_lookups(struct nameidata= *nd, mnt_drop_write(nd->path.mnt); =20 if (IS_ERR(dentry)) { - if (delegated_inode) { + if (deleg_inode(&delegated_inode)) { int error =3D break_deleg_wait(&delegated_inode); =20 if (!error) @@ -4217,7 +4217,7 @@ EXPORT_SYMBOL(user_path_create); =20 static int __vfs_mknod(struct mnt_idmap *idmap, struct inode *dir, struct dentry *dentry, umode_t mode, dev_t dev, - struct inode **delegated_inode) + struct delegated_inode *delegated_inode) { bool is_whiteout =3D S_ISCHR(mode) && dev =3D=3D WHITEOUT_DEV; int error =3D may_create(idmap, dir, dentry); @@ -4241,7 +4241,7 @@ static int __vfs_mknod(struct mnt_idmap *idmap, struc= t inode *dir, if (error) return error; =20 - error =3D try_break_deleg(dir, delegated_inode); + error =3D try_break_deleg(dir, LEASE_BREAK_DIR_CREATE, delegated_inode); if (error) return error; =20 @@ -4299,7 +4299,7 @@ static int do_mknodat(int dfd, struct filename *name,= umode_t mode, struct path path; int error; unsigned int lookup_flags =3D 0; - struct inode *delegated_inode =3D NULL; + struct delegated_inode delegated_inode =3D { }; =20 error =3D may_mknod(mode); if (error) @@ -4337,7 +4337,7 @@ static int do_mknodat(int dfd, struct filename *name,= umode_t mode, } out2: done_path_create(&path, dentry); - if (delegated_inode) { + if (deleg_inode(&delegated_inode)) { error =3D break_deleg_wait(&delegated_inode); if (!error) goto retry; @@ -4364,7 +4364,7 @@ SYSCALL_DEFINE3(mknod, const char __user *, filename,= umode_t, mode, unsigned, d =20 static struct dentry *__vfs_mkdir(struct mnt_idmap *idmap, struct inode *d= ir, struct dentry *dentry, umode_t mode, - struct inode **delegated_inode) + struct delegated_inode *delegated_inode) { int error; unsigned max_links =3D dir->i_sb->s_max_links; @@ -4387,7 +4387,7 @@ static struct dentry *__vfs_mkdir(struct mnt_idmap *i= dmap, struct inode *dir, if (max_links && dir->i_nlink >=3D max_links) goto err; =20 - error =3D try_break_deleg(dir, delegated_inode); + error =3D try_break_deleg(dir, LEASE_BREAK_DIR_CREATE, delegated_inode); if (error) goto err; =20 @@ -4441,7 +4441,7 @@ int do_mkdirat(int dfd, struct filename *name, umode_= t mode) struct path path; int error; unsigned int lookup_flags =3D LOOKUP_DIRECTORY; - struct inode *delegated_inode =3D NULL; + struct delegated_inode delegated_inode =3D { }; =20 retry: dentry =3D filename_create(dfd, name, &path, lookup_flags); @@ -4458,7 +4458,7 @@ int do_mkdirat(int dfd, struct filename *name, umode_= t mode) error =3D PTR_ERR(dentry); } done_path_create(&path, dentry); - if (delegated_inode) { + if (deleg_inode(&delegated_inode)) { error =3D break_deleg_wait(&delegated_inode); if (!error) goto retry; @@ -4483,7 +4483,7 @@ SYSCALL_DEFINE2(mkdir, const char __user *, pathname,= umode_t, mode) } =20 static int __vfs_rmdir(struct mnt_idmap *idmap, struct inode *dir, - struct dentry *dentry, struct inode **delegated_inode) + struct dentry *dentry, struct delegated_inode *delegated_inode) { int error =3D may_delete(idmap, dir, dentry, 1); =20 @@ -4505,7 +4505,7 @@ static int __vfs_rmdir(struct mnt_idmap *idmap, struc= t inode *dir, if (error) goto out; =20 - error =3D try_break_deleg(dir, delegated_inode); + error =3D try_break_deleg(dir, LEASE_BREAK_DIR_DELETE, delegated_inode); if (error) goto out; =20 @@ -4555,7 +4555,7 @@ int do_rmdir(int dfd, struct filename *name) struct qstr last; int type; unsigned int lookup_flags =3D 0; - struct inode *delegated_inode =3D NULL; + struct delegated_inode delegated_inode =3D { }; retry: error =3D filename_parentat(dfd, name, lookup_flags, &path, &last, &type); if (error) @@ -4594,7 +4594,7 @@ int do_rmdir(int dfd, struct filename *name) mnt_drop_write(path.mnt); exit2: path_put(&path); - if (delegated_inode) { + if (deleg_inode(&delegated_inode)) { error =3D break_deleg_wait(&delegated_inode); if (!error) goto retry; @@ -4639,7 +4639,7 @@ SYSCALL_DEFINE1(rmdir, const char __user *, pathname) * raw inode simply pass @nop_mnt_idmap. */ int vfs_unlink(struct mnt_idmap *idmap, struct inode *dir, - struct dentry *dentry, struct inode **delegated_inode) + struct dentry *dentry, struct delegated_inode *delegated_inode) { struct inode *target =3D dentry->d_inode; int error =3D may_delete(idmap, dir, dentry, 0); @@ -4658,10 +4658,10 @@ int vfs_unlink(struct mnt_idmap *idmap, struct inod= e *dir, else { error =3D security_inode_unlink(dir, dentry); if (!error) { - error =3D try_break_deleg(dir, delegated_inode); + error =3D try_break_deleg(dir, LEASE_BREAK_DIR_DELETE, delegated_inode); if (error) goto out; - error =3D try_break_deleg(target, delegated_inode); + error =3D try_break_deleg(target, 0, delegated_inode); if (error) goto out; error =3D dir->i_op->unlink(dir, dentry); @@ -4700,7 +4700,7 @@ int do_unlinkat(int dfd, struct filename *name) struct qstr last; int type; struct inode *inode =3D NULL; - struct inode *delegated_inode =3D NULL; + struct delegated_inode delegated_inode =3D { }; unsigned int lookup_flags =3D 0; retry: error =3D filename_parentat(dfd, name, lookup_flags, &path, &last, &type); @@ -4737,7 +4737,7 @@ int do_unlinkat(int dfd, struct filename *name) if (inode) iput(inode); /* truncate the inode here */ inode =3D NULL; - if (delegated_inode) { + if (deleg_inode(&delegated_inode)) { error =3D break_deleg_wait(&delegated_inode); if (!error) goto retry_deleg; @@ -4886,7 +4886,7 @@ SYSCALL_DEFINE2(symlink, const char __user *, oldname= , const char __user *, newn */ int vfs_link(struct dentry *old_dentry, struct mnt_idmap *idmap, struct inode *dir, struct dentry *new_dentry, - struct inode **delegated_inode) + struct delegated_inode *delegated_inode) { struct inode *inode =3D old_dentry->d_inode; unsigned max_links =3D dir->i_sb->s_max_links; @@ -4930,9 +4930,9 @@ int vfs_link(struct dentry *old_dentry, struct mnt_id= map *idmap, else if (max_links && inode->i_nlink >=3D max_links) error =3D -EMLINK; else { - error =3D try_break_deleg(dir, delegated_inode); + error =3D try_break_deleg(dir, LEASE_BREAK_DIR_CREATE, delegated_inode); if (!error) - error =3D try_break_deleg(inode, delegated_inode); + error =3D try_break_deleg(inode, 0, delegated_inode); if (!error) error =3D dir->i_op->link(old_dentry, dir, new_dentry); } @@ -4964,7 +4964,7 @@ int do_linkat(int olddfd, struct filename *old, int n= ewdfd, struct mnt_idmap *idmap; struct dentry *new_dentry; struct path old_path, new_path; - struct inode *delegated_inode =3D NULL; + struct delegated_inode delegated_inode =3D { }; int how =3D 0; int error; =20 @@ -5008,7 +5008,7 @@ int do_linkat(int olddfd, struct filename *old, int n= ewdfd, new_dentry, &delegated_inode); out_dput: done_path_create(&new_path, new_dentry); - if (delegated_inode) { + if (deleg_inode(&delegated_inode)) { error =3D break_deleg_wait(&delegated_inode); if (!error) { path_put(&old_path); @@ -5093,7 +5093,7 @@ int vfs_rename(struct renamedata *rd) struct inode *old_dir =3D rd->old_dir, *new_dir =3D rd->new_dir; struct dentry *old_dentry =3D rd->old_dentry; struct dentry *new_dentry =3D rd->new_dentry; - struct inode **delegated_inode =3D rd->delegated_inode; + struct delegated_inode *delegated_inode =3D rd->delegated_inode; unsigned int flags =3D rd->flags; bool is_dir =3D d_is_dir(old_dentry); struct inode *source =3D old_dentry->d_inode; @@ -5198,21 +5198,24 @@ int vfs_rename(struct renamedata *rd) old_dir->i_nlink >=3D max_links) goto out; } - error =3D try_break_deleg(old_dir, delegated_inode); + error =3D try_break_deleg(old_dir, + old_dir =3D=3D new_dir ? LEASE_BREAK_DIR_RENAME : + LEASE_BREAK_DIR_DELETE, + delegated_inode); if (error) goto out; if (new_dir !=3D old_dir) { - error =3D try_break_deleg(new_dir, delegated_inode); + error =3D try_break_deleg(new_dir, LEASE_BREAK_DIR_CREATE, delegated_ino= de); if (error) goto out; } if (!is_dir) { - error =3D try_break_deleg(source, delegated_inode); + error =3D try_break_deleg(source, 0, delegated_inode); if (error) goto out; } if (target && !new_is_dir) { - error =3D try_break_deleg(target, delegated_inode); + error =3D try_break_deleg(target, 0, delegated_inode); if (error) goto out; } @@ -5264,7 +5267,7 @@ int do_renameat2(int olddfd, struct filename *from, i= nt newdfd, struct path old_path, new_path; struct qstr old_last, new_last; int old_type, new_type; - struct inode *delegated_inode =3D NULL; + struct delegated_inode delegated_inode =3D { }; unsigned int lookup_flags =3D 0, target_flags =3D LOOKUP_RENAME_TARGET | LOOKUP_CREATE; bool should_retry =3D false; @@ -5373,7 +5376,7 @@ int do_renameat2(int olddfd, struct filename *from, i= nt newdfd, exit3: unlock_rename(new_path.dentry, old_path.dentry); exit_lock_rename: - if (delegated_inode) { + if (deleg_inode(&delegated_inode)) { error =3D break_deleg_wait(&delegated_inode); if (!error) goto retry_deleg; diff --git a/fs/open.c b/fs/open.c index 7828234a7caa40c83e69683bd1ecfe69a90e2b49..529f9d4ee73453a9e3da818ebd4= ba0eb17245521 100644 --- a/fs/open.c +++ b/fs/open.c @@ -630,7 +630,7 @@ SYSCALL_DEFINE1(chroot, const char __user *, filename) int chmod_common(const struct path *path, umode_t mode) { struct inode *inode =3D path->dentry->d_inode; - struct inode *delegated_inode =3D NULL; + struct delegated_inode delegated_inode =3D { }; struct iattr newattrs; int error; =20 @@ -650,7 +650,7 @@ int chmod_common(const struct path *path, umode_t mode) &newattrs, &delegated_inode); out_unlock: inode_unlock(inode); - if (delegated_inode) { + if (deleg_inode(&delegated_inode)) { error =3D break_deleg_wait(&delegated_inode); if (!error) goto retry_deleg; @@ -755,7 +755,7 @@ int chown_common(const struct path *path, uid_t user, g= id_t group) struct mnt_idmap *idmap; struct user_namespace *fs_userns; struct inode *inode =3D path->dentry->d_inode; - struct inode *delegated_inode =3D NULL; + struct delegated_inode delegated_inode =3D { }; int error; struct iattr newattrs; kuid_t uid; @@ -790,7 +790,7 @@ int chown_common(const struct path *path, uid_t user, g= id_t group) error =3D notify_change(idmap, path->dentry, &newattrs, &delegated_inode); inode_unlock(inode); - if (delegated_inode) { + if (deleg_inode(&delegated_inode)) { error =3D break_deleg_wait(&delegated_inode); if (!error) goto retry_deleg; diff --git a/fs/posix_acl.c b/fs/posix_acl.c index 4050942ab52f95741da2df13d191ade5c5ca12a2..19a45fc8e413d0fb2e2d906488c= 3ce648bb318a4 100644 --- a/fs/posix_acl.c +++ b/fs/posix_acl.c @@ -1091,7 +1091,7 @@ int vfs_set_acl(struct mnt_idmap *idmap, struct dentr= y *dentry, int acl_type; int error; struct inode *inode =3D d_inode(dentry); - struct inode *delegated_inode =3D NULL; + struct delegated_inode delegated_inode =3D { }; =20 acl_type =3D posix_acl_type(acl_name); if (acl_type < 0) @@ -1125,7 +1125,7 @@ int vfs_set_acl(struct mnt_idmap *idmap, struct dentr= y *dentry, if (error) goto out_inode_unlock; =20 - error =3D try_break_deleg(inode, &delegated_inode); + error =3D try_break_deleg(inode, 0, &delegated_inode); if (error) goto out_inode_unlock; =20 @@ -1141,7 +1141,7 @@ int vfs_set_acl(struct mnt_idmap *idmap, struct dentr= y *dentry, out_inode_unlock: inode_unlock(inode); =20 - if (delegated_inode) { + if (deleg_inode(&delegated_inode)) { error =3D break_deleg_wait(&delegated_inode); if (!error) goto retry_deleg; @@ -1212,7 +1212,7 @@ int vfs_remove_acl(struct mnt_idmap *idmap, struct de= ntry *dentry, int acl_type; int error; struct inode *inode =3D d_inode(dentry); - struct inode *delegated_inode =3D NULL; + struct delegated_inode delegated_inode =3D { }; =20 acl_type =3D posix_acl_type(acl_name); if (acl_type < 0) @@ -1233,7 +1233,7 @@ int vfs_remove_acl(struct mnt_idmap *idmap, struct de= ntry *dentry, if (error) goto out_inode_unlock; =20 - error =3D try_break_deleg(inode, &delegated_inode); + error =3D try_break_deleg(inode, 0, &delegated_inode); if (error) goto out_inode_unlock; =20 @@ -1249,7 +1249,7 @@ int vfs_remove_acl(struct mnt_idmap *idmap, struct de= ntry *dentry, out_inode_unlock: inode_unlock(inode); =20 - if (delegated_inode) { + if (deleg_inode(&delegated_inode)) { error =3D break_deleg_wait(&delegated_inode); if (!error) goto retry_deleg; diff --git a/fs/utimes.c b/fs/utimes.c index c7c7958e57b22f91646ca9f76d18781b64d371a3..4145cbbc190ffb5990fef248300= c853ec32d643f 100644 --- a/fs/utimes.c +++ b/fs/utimes.c @@ -22,7 +22,7 @@ int vfs_utimes(const struct path *path, struct timespec64= *times) int error; struct iattr newattrs; struct inode *inode =3D path->dentry->d_inode; - struct inode *delegated_inode =3D NULL; + struct delegated_inode delegated_inode =3D { }; =20 if (times) { if (!nsec_valid(times[0].tv_nsec) || @@ -66,7 +66,7 @@ int vfs_utimes(const struct path *path, struct timespec64= *times) error =3D notify_change(mnt_idmap(path->mnt), path->dentry, &newattrs, &delegated_inode); inode_unlock(inode); - if (delegated_inode) { + if (deleg_inode(&delegated_inode)) { error =3D break_deleg_wait(&delegated_inode); if (!error) goto retry_deleg; diff --git a/fs/xattr.c b/fs/xattr.c index 8ec5b0204bfdc587e7875893e3b1a1e1479d7d1b..1de49ba91b8e6ff9c45c461fe99= 63f587420cc5f 100644 --- a/fs/xattr.c +++ b/fs/xattr.c @@ -274,7 +274,7 @@ int __vfs_setxattr_noperm(struct mnt_idmap *idmap, int __vfs_setxattr_locked(struct mnt_idmap *idmap, struct dentry *dentry, const char *name, const void *value, size_t size, - int flags, struct inode **delegated_inode) + int flags, struct delegated_inode *delegated_inode) { struct inode *inode =3D dentry->d_inode; int error; @@ -288,7 +288,7 @@ __vfs_setxattr_locked(struct mnt_idmap *idmap, struct d= entry *dentry, if (error) goto out; =20 - error =3D try_break_deleg(inode, delegated_inode); + error =3D try_break_deleg(inode, 0, delegated_inode); if (error) goto out; =20 @@ -305,7 +305,7 @@ vfs_setxattr(struct mnt_idmap *idmap, struct dentry *de= ntry, const char *name, const void *value, size_t size, int flags) { struct inode *inode =3D dentry->d_inode; - struct inode *delegated_inode =3D NULL; + struct delegated_inode delegated_inode =3D { }; const void *orig_value =3D value; int error; =20 @@ -322,7 +322,7 @@ vfs_setxattr(struct mnt_idmap *idmap, struct dentry *de= ntry, flags, &delegated_inode); inode_unlock(inode); =20 - if (delegated_inode) { + if (deleg_inode(&delegated_inode)) { error =3D break_deleg_wait(&delegated_inode); if (!error) goto retry_deleg; @@ -533,7 +533,7 @@ EXPORT_SYMBOL(__vfs_removexattr); int __vfs_removexattr_locked(struct mnt_idmap *idmap, struct dentry *dentry, const char *name, - struct inode **delegated_inode) + struct delegated_inode *delegated_inode) { struct inode *inode =3D dentry->d_inode; int error; @@ -546,7 +546,7 @@ __vfs_removexattr_locked(struct mnt_idmap *idmap, if (error) goto out; =20 - error =3D try_break_deleg(inode, delegated_inode); + error =3D try_break_deleg(inode, 0, delegated_inode); if (error) goto out; =20 @@ -567,7 +567,7 @@ vfs_removexattr(struct mnt_idmap *idmap, struct dentry = *dentry, const char *name) { struct inode *inode =3D dentry->d_inode; - struct inode *delegated_inode =3D NULL; + struct delegated_inode delegated_inode =3D { }; int error; =20 retry_deleg: @@ -576,7 +576,7 @@ vfs_removexattr(struct mnt_idmap *idmap, struct dentry = *dentry, name, &delegated_inode); inode_unlock(inode); =20 - if (delegated_inode) { + if (deleg_inode(&delegated_inode)) { error =3D break_deleg_wait(&delegated_inode); if (!error) goto retry_deleg; diff --git a/include/linux/filelock.h b/include/linux/filelock.h index 0fe368060781d0b22f735c2cfb8d8c1a6a238290..f2b2d1e1d1ab08671895c3bfe39= 8e5bba02353d8 100644 --- a/include/linux/filelock.h +++ b/include/linux/filelock.h @@ -160,6 +160,19 @@ struct file_lock_context { struct list_head flc_lease; }; =20 +#define LEASE_BREAK_LEASE BIT(0) // break leases and delegations +#define LEASE_BREAK_DELEG BIT(1) // break delegations only +#define LEASE_BREAK_LAYOUT BIT(2) // break layouts only +#define LEASE_BREAK_NONBLOCK BIT(3) // non-blocking break +#define LEASE_BREAK_OPEN_RDONLY BIT(4) // readonly open event +#define LEASE_BREAK_DIR_CREATE BIT(6) // dir deleg create event +#define LEASE_BREAK_DIR_DELETE BIT(7) // dir deleg delete event +#define LEASE_BREAK_DIR_RENAME BIT(8) // dir deleg rename event + +#define LEASE_BREAK_DIR_REASON_MASK (LEASE_BREAK_DIR_CREATE | \ + LEASE_BREAK_DIR_DELETE | \ + LEASE_BREAK_DIR_RENAME) + #ifdef CONFIG_FILE_LOCKING int fcntl_getlk(struct file *, unsigned int, struct flock *); int fcntl_setlk(unsigned int, struct file *, unsigned int, @@ -222,12 +235,6 @@ void locks_init_lease(struct file_lease *); void locks_free_lease(struct file_lease *fl); struct file_lease *locks_alloc_lease(void); =20 -#define LEASE_BREAK_LEASE BIT(0) // break leases and delegations -#define LEASE_BREAK_DELEG BIT(1) // break delegations only -#define LEASE_BREAK_LAYOUT BIT(2) // break layouts only -#define LEASE_BREAK_NONBLOCK BIT(3) // non-blocking break -#define LEASE_BREAK_OPEN_RDONLY BIT(4) // readonly open event - int __break_lease(struct inode *inode, unsigned int flags); void lease_get_mtime(struct inode *, struct timespec64 *time); int generic_setlease(struct file *, int, struct file_lease **, void **priv= ); @@ -495,25 +502,41 @@ static inline int break_deleg(struct inode *inode, un= signed int flags) return 0; } =20 -static inline int try_break_deleg(struct inode *inode, struct inode **dele= gated_inode) +struct delegated_inode { + struct inode *di_inode; + unsigned int di_reason; // LEASE_BREAK_* flags +}; + +static inline struct inode *deleg_inode(struct delegated_inode *di) +{ + return di->di_inode; +} + +static inline int try_break_deleg(struct inode *inode, unsigned int reason, + struct delegated_inode *di) { int ret; =20 - ret =3D break_deleg(inode, LEASE_BREAK_NONBLOCK); - if (ret =3D=3D -EWOULDBLOCK && delegated_inode) { - *delegated_inode =3D inode; + /* Clear any extraneous reason bits, after warning if any are set */ + WARN_ON_ONCE(reason & ~LEASE_BREAK_DIR_REASON_MASK); + reason &=3D LEASE_BREAK_DIR_REASON_MASK; + + ret =3D break_deleg(inode, reason | LEASE_BREAK_NONBLOCK); + if (ret =3D=3D -EWOULDBLOCK && di) { + di->di_inode =3D inode; + di->di_reason =3D reason; ihold(inode); } return ret; } =20 -static inline int break_deleg_wait(struct inode **delegated_inode) +static inline int break_deleg_wait(struct delegated_inode *di) { int ret; =20 - ret =3D break_deleg(*delegated_inode, 0); - iput(*delegated_inode); - *delegated_inode =3D NULL; + ret =3D break_deleg(di->di_inode, di->di_reason); + iput(di->di_inode); + di->di_inode =3D NULL; return ret; } =20 @@ -532,6 +555,13 @@ static inline int break_layout(struct inode *inode, bo= ol wait) } =20 #else /* !CONFIG_FILE_LOCKING */ +struct delegated_inode { }; + +static inline struct inode *deleg_inode(struct delegated_inode *di) +{ + return NULL; +} + static inline int break_lease(struct inode *inode, bool wait) { return 0; @@ -542,12 +572,13 @@ static inline int break_deleg(struct inode *inode, un= signed int flags) return 0; } =20 -static inline int try_break_deleg(struct inode *inode, struct inode **dele= gated_inode) +static inline int try_break_deleg(struct inode *inode, unsigned int reason, + struct delegated_inode *delegated_inode) { return 0; } =20 -static inline int break_deleg_wait(struct inode **delegated_inode) +static inline int break_deleg_wait(struct delegated_inode *delegated_inode) { BUG(); return 0; diff --git a/include/linux/fs.h b/include/linux/fs.h index 0db87f8e676cc8d022b28042bf6fd1af5f8928e3..172094c88165f909ee3cd53c8b0= 2ff6d69f04e5a 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h @@ -82,6 +82,7 @@ struct fs_context; struct fs_parameter_spec; struct fileattr; struct iomap_ops; +struct delegated_inode; =20 extern void __init inode_init(void); extern void __init inode_init_early(void); @@ -1997,10 +1998,10 @@ int vfs_mknod(struct mnt_idmap *, struct inode *, s= truct dentry *, int vfs_symlink(struct mnt_idmap *, struct inode *, struct dentry *, const char *); int vfs_link(struct dentry *, struct mnt_idmap *, struct inode *, - struct dentry *, struct inode **); + struct dentry *, struct delegated_inode *); int vfs_rmdir(struct mnt_idmap *, struct inode *, struct dentry *); int vfs_unlink(struct mnt_idmap *, struct inode *, struct dentry *, - struct inode **); + struct delegated_inode *); =20 /** * struct renamedata - contains all information required for renaming @@ -2020,7 +2021,7 @@ struct renamedata { struct mnt_idmap *new_mnt_idmap; struct inode *new_dir; struct dentry *new_dentry; - struct inode **delegated_inode; + struct delegated_inode *delegated_inode; unsigned int flags; } __randomize_layout; =20 @@ -3028,7 +3029,7 @@ static inline int bmap(struct inode *inode, sector_t= *block) #endif =20 int notify_change(struct mnt_idmap *, struct dentry *, - struct iattr *, struct inode **); + struct iattr *, struct delegated_inode *); int inode_permission(struct mnt_idmap *, struct inode *, int); int generic_permission(struct mnt_idmap *, struct inode *, int); static inline int file_permission(struct file *file, int mask) diff --git a/include/linux/xattr.h b/include/linux/xattr.h index 86b0d47984a16d935dd1c45ca80a3b8bb5b7295b..64e9afe7d647dc38f686a4b5c6f= 765e061cde54c 100644 --- a/include/linux/xattr.h +++ b/include/linux/xattr.h @@ -85,12 +85,12 @@ int __vfs_setxattr_noperm(struct mnt_idmap *, struct de= ntry *, const char *, const void *, size_t, int); int __vfs_setxattr_locked(struct mnt_idmap *, struct dentry *, const char *, const void *, size_t, int, - struct inode **); + struct delegated_inode *); int vfs_setxattr(struct mnt_idmap *, struct dentry *, const char *, const void *, size_t, int); int __vfs_removexattr(struct mnt_idmap *, struct dentry *, const char *); int __vfs_removexattr_locked(struct mnt_idmap *, struct dentry *, - const char *, struct inode **); + const char *, struct delegated_inode *); int vfs_removexattr(struct mnt_idmap *, struct dentry *, const char *); =20 ssize_t generic_listxattr(struct dentry *dentry, char *buffer, size_t buff= er_size); --=20 2.49.0 From nobody Thu Dec 18 14:10:55 2025 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 4B183233710; Mon, 2 Jun 2025 14:02:56 +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=1748872976; cv=none; b=fQT2KD/melh4wsFRjEHXhK/RcE/6zp2ZOUPSFQyPKinAyT13c+7copugD1Hr28rfcvbv49r0RZOi4FBvz/Kj7tzCbixz+gLNOv+Ebxgp54p2hnh2nSNJsbR+wT2LKPlVXEelUjqwDcsczLBiA4znvl2MMA4Q3buNlFG6hxWH+cA= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1748872976; c=relaxed/simple; bh=l1z9iLUkJ0KvsPge0I8LFG6jb0PtwW40TMKjx9uD3Ls=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=sk4XAuY6QGUyvNLLeOYjGTzr8Y+gu08SJsXJNFAcpHlUksOr9eNd4i1zS5k2Z+yTDkBM0wmPtnm1zz0HIujs7DSfS+vsjQFc/xa0T/+3vBc3lTEdcVw7loNpuYL4LLRlqQ1Db60j6Cxcoyf9UsFHcgU3wMK+cMW1OiYTdBlSAwQ= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=Xc/dEgij; 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="Xc/dEgij" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 2C752C4CEEB; Mon, 2 Jun 2025 14:02:54 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1748872976; bh=l1z9iLUkJ0KvsPge0I8LFG6jb0PtwW40TMKjx9uD3Ls=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=Xc/dEgijwM+KWINT6xRSiuECZeDVQa0/hGg9S2z7Lavf06L2SOITTHzCRWLUYtXW5 p1Vw9s5OeYlBmJNQwaiY/biiyl/RaVNGllgCoCgZsLv+V893IpaFu1ux63LdWlXf3R 2YLf589SghXRJ53zrZy0kOUe6dRoMuo4T3X6+50KoLM2hKPaaOWZo9M6Kme1+LVpNg ewDy2ZEBzw9dc8OLtdIu8cix3iaRC6D2uSX7xXVva+6zk2sOf7bfP0FE1PLFnfzsnl iEnTuGhsBDqMLkk/lRWi4EDYjKosyY8pQZMg6amiZk5efmz8gsCQiy54I5FXUQphwu o+C4eoWzvdKNQ== From: Jeff Layton Date: Mon, 02 Jun 2025 10:01:59 -0400 Subject: [PATCH RFC v2 16/28] filelock: add support for ignoring deleg breaks for dir change events Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20250602-dir-deleg-v2-16-a7919700de86@kernel.org> References: <20250602-dir-deleg-v2-0-a7919700de86@kernel.org> In-Reply-To: <20250602-dir-deleg-v2-0-a7919700de86@kernel.org> To: Alexander Viro , Christian Brauner , Jan Kara , Chuck Lever , Alexander Aring , Trond Myklebust , Anna Schumaker , Steve French , Paulo Alcantara , Ronnie Sahlberg , Shyam Prasad N , Tom Talpey , Bharath SM , NeilBrown , Olga Kornievskaia , Dai Ngo , Jonathan Corbet , Amir Goldstein , Miklos Szeredi Cc: linux-fsdevel@vger.kernel.org, linux-kernel@vger.kernel.org, linux-nfs@vger.kernel.org, linux-cifs@vger.kernel.org, samba-technical@lists.samba.org, linux-doc@vger.kernel.org, Jeff Layton X-Mailer: b4 0.14.2 X-Developer-Signature: v=1; a=openpgp-sha256; l=5743; i=jlayton@kernel.org; h=from:subject:message-id; bh=l1z9iLUkJ0KvsPge0I8LFG6jb0PtwW40TMKjx9uD3Ls=; b=owEBbQKS/ZANAwAKAQAOaEEZVoIVAcsmYgBoPa7n5joJeAiGMTeYtl2VHuJMTpkez3iSh3Rzg ovZBrIcu4qJAjMEAAEKAB0WIQRLwNeyRHGyoYTq9dMADmhBGVaCFQUCaD2u5wAKCRAADmhBGVaC Fbu/EADE42Xwa7/1tThWNVhEe1pk7DYQS7gD89WSuvz+X9VFYW3asu8vEwNYZtDIaAKLZuOXpe5 AIhsDQjYIyktimSQdiSNF7K7AAjqSXxlSMSxbhHqRXBTw5CjDXfvKFYfIwQTOaRR7RdVwnptDvH ym+9xf3SWSjfJQ4PdvJ+DG6QRwcdKWGUg0lInh0jKU8Vkoc6sq2zYYaAaGTFei+CWctQtDkVaa5 mAMmoeBbTcIwkcvzeLAoM/2+qaXhj9bxe0pu9MObJsCBRcdjsqpdGURzmd4SFfdGyfwqLf43dkR IEpr8W0FtOIvz0/7LwB/xgk5hMvsJ+YM6wOY1kXByQK/6FKoMlDDEzI+U5k8Rnl0nvDgBvvb6Wm k0lK+Hg3LIrbPSJzv03sN9s7vtmsXcVAWs7C01j6xsBgES8bHjGwBbvOlDodu+3u3sxCPJyWB6J Oci+B5ZNXrDxXLL1lK5xjh19Kp6sdnYHrJxco1hrzHqzHHopS8GoGaSVliuVPUF/ak6Ogoj9SZP WnbuOFu3LtVwbX3yAGEXsLoDhGplKSA0IQeVTVlOcm0YbabD2VogWHR0uC+QsEhGGoakJNRgdFa TXoeulGoY3NzuFiS2bTDNw9xBucW13BK+KBvbBLsrQjtGJ/GZGUTSRZgOi75PAb6KOyQ9sI6ebY 1PxaHINBn5WSMvQ== X-Developer-Key: i=jlayton@kernel.org; a=openpgp; fpr=4BC0D7B24471B2A184EAF5D3000E684119568215 If a NFS client requests a directory delegation with a notification bitmask covering directory change events, the server shouldn't recall the delegation. Instead the client will be notified of the change after the fact. Add a support for ignoring lease breaks on directory changes. Signed-off-by: Jeff Layton --- fs/locks.c | 56 ++++++++++++++++++++++++++++++++++++++++----= ---- include/linux/filelock.h | 29 ++++++++++++++----------- 2 files changed, 63 insertions(+), 22 deletions(-) diff --git a/fs/locks.c b/fs/locks.c index 6e46176d1e00962904f03c151500e593f410e4c6..95270a1fab4a1792a6fcad738cc= 9d937d99ad2af 100644 --- a/fs/locks.c +++ b/fs/locks.c @@ -1526,15 +1526,52 @@ any_leases_conflict(struct inode *inode, struct fil= e_lease *breaker) return false; } =20 +static bool +ignore_dir_deleg_break(struct file_lease *fl, unsigned int flags) +{ + if ((flags & LEASE_BREAK_DIR_CREATE) && (fl->c.flc_flags & FL_IGN_DIR_CRE= ATE)) + return true; + if ((flags & LEASE_BREAK_DIR_DELETE) && (fl->c.flc_flags & FL_IGN_DIR_DEL= ETE)) + return true; + if ((flags & LEASE_BREAK_DIR_RENAME) && (fl->c.flc_flags & FL_IGN_DIR_REN= AME)) + return true; + + return false; +} + +static bool +visible_leases_remaining(struct inode *inode, unsigned int flags) +{ + struct file_lock_context *ctx =3D locks_inode_context(inode); + struct file_lease *fl; + + lockdep_assert_held(&ctx->flc_lock); + + if (list_empty(&ctx->flc_lease)) + return false; + + if (!S_ISDIR(inode->i_mode)) + return true; + + list_for_each_entry(fl, &ctx->flc_lease, c.flc_list) { + if (!ignore_dir_deleg_break(fl, flags)) + return true; + } + return false; +} + /** - * __break_lease - revoke all outstanding leases on file - * @inode: the inode of the file to return - * @flags: LEASE_BREAK_* flags + * __break_lease - revoke all outstanding leases on file + * @inode: the inode of the file to return + * @flags: LEASE_BREAK_* flags * - * break_lease (inlined for speed) has checked there already is at least - * some kind of lock (maybe a lease) on this file. Leases are broken on - * a call to open() or truncate(). This function can block waiting for the - * lease break unless you specify LEASE_BREAK_NONBLOCK. + * break_lease (inlined for speed) has checked there already is at least + * some kind of lock (maybe a lease) on this file. Leases and Delegations + * are broken on a call to open() or truncate(). Delegations are also + * broken on any event that would change the ctime. Directory delegations + * are broken whenever the directory changes (unless the delegation is set + * up to ignore the event). This function can block waiting for the lease + * break unless you specify LEASE_BREAK_NONBLOCK. */ int __break_lease(struct inode *inode, unsigned int flags) { @@ -1545,7 +1582,6 @@ int __break_lease(struct inode *inode, unsigned int f= lags) bool want_write =3D !(flags & LEASE_BREAK_OPEN_RDONLY); int error =3D 0; =20 - new_fl =3D lease_alloc(NULL, want_write ? F_WRLCK : F_RDLCK); if (IS_ERR(new_fl)) return PTR_ERR(new_fl); @@ -1584,6 +1620,8 @@ int __break_lease(struct inode *inode, unsigned int f= lags) list_for_each_entry_safe(fl, tmp, &ctx->flc_lease, c.flc_list) { if (!leases_conflict(&fl->c, &new_fl->c)) continue; + if (S_ISDIR(inode->i_mode) && ignore_dir_deleg_break(fl, flags)) + continue; if (want_write) { if (fl->c.flc_flags & FL_UNLOCK_PENDING) continue; @@ -1599,7 +1637,7 @@ int __break_lease(struct inode *inode, unsigned int f= lags) locks_delete_lock_ctx(&fl->c, &dispose); } =20 - if (list_empty(&ctx->flc_lease)) + if (!visible_leases_remaining(inode, flags)) goto out; =20 if (flags & LEASE_BREAK_NONBLOCK) { diff --git a/include/linux/filelock.h b/include/linux/filelock.h index f2b2d1e1d1ab08671895c3bfe398e5bba02353d8..32b30c14f5fd52727b1a18957e9= dbc930c922941 100644 --- a/include/linux/filelock.h +++ b/include/linux/filelock.h @@ -4,19 +4,22 @@ =20 #include =20 -#define FL_POSIX 1 -#define FL_FLOCK 2 -#define FL_DELEG 4 /* NFSv4 delegation */ -#define FL_ACCESS 8 /* not trying to lock, just looking */ -#define FL_EXISTS 16 /* when unlocking, test for existence */ -#define FL_LEASE 32 /* lease held on this file */ -#define FL_CLOSE 64 /* unlock on close */ -#define FL_SLEEP 128 /* A blocking lock */ -#define FL_DOWNGRADE_PENDING 256 /* Lease is being downgraded */ -#define FL_UNLOCK_PENDING 512 /* Lease is being broken */ -#define FL_OFDLCK 1024 /* lock is "owned" by struct file */ -#define FL_LAYOUT 2048 /* outstanding pNFS layout */ -#define FL_RECLAIM 4096 /* reclaiming from a reboot server */ +#define FL_POSIX BIT(0) /* POSIX lock */ +#define FL_FLOCK BIT(1) /* BSD lock */ +#define FL_LEASE BIT(2) /* file lease */ +#define FL_DELEG BIT(3) /* NFSv4 delegation */ +#define FL_LAYOUT BIT(4) /* outstanding pNFS layout */ +#define FL_ACCESS BIT(5) /* not trying to lock, just looking */ +#define FL_EXISTS BIT(6) /* when unlocking, test for existence */ +#define FL_CLOSE BIT(7) /* unlock on close */ +#define FL_SLEEP BIT(8) /* A blocking lock */ +#define FL_DOWNGRADE_PENDING BIT(9) /* Lease is being downgraded */ +#define FL_UNLOCK_PENDING BIT(10) /* Lease is being broken */ +#define FL_OFDLCK BIT(11) /* POSIX lock "owned" by struct file */ +#define FL_RECLAIM BIT(12) /* reclaiming from a reboot server */ +#define FL_IGN_DIR_CREATE BIT(13) /* ignore DIR_CREATE events */ +#define FL_IGN_DIR_DELETE BIT(14) /* ignore DIR_DELETE events */ +#define FL_IGN_DIR_RENAME BIT(15) /* ignore DIR_RENAME events */ =20 #define FL_CLOSE_POSIX (FL_POSIX | FL_CLOSE) =20 --=20 2.49.0 From nobody Thu Dec 18 14:10:55 2025 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 ACBBC2343D4; Mon, 2 Jun 2025 14:02:58 +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=1748872978; cv=none; b=sBImL0f7eytc0T/rFTYCKPmTdo7r8zOBZYEDkKyy0XaUys99GdiF+j5cYVou86m+/OG4uUQ2dnPdIPM1ZbeuNQ53VQ1ybtZFqKdjnrShRwMxcwhzLKHoUZf2UIHSOv8ZbABQwk87j6z66bEkkosFqY4J7YAVCAUMaXmZhb8byV8= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1748872978; c=relaxed/simple; bh=seErxpiSRxkH2bkmFkFAfk0mHe9vn7gtVplOYiMIB5M=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=Hx2eqVxyX76pVkwmei45WQgC4OdhI6t80mxwXeP+a/TQIP0m182dwAuVD125/hOmboxIZWGrtL4LinusE0HdDyi6joCQ3zWCAUbR0dXQgcz4sobwBoDvqrR1xc97WrPcUzuMJ5ktbl87WMaojcLGsWuLZRnKzIMljwNZL5gK0M4= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=RQcsXKdX; 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="RQcsXKdX" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 4A82DC4CEF2; Mon, 2 Jun 2025 14:02:56 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1748872978; bh=seErxpiSRxkH2bkmFkFAfk0mHe9vn7gtVplOYiMIB5M=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=RQcsXKdX+GVmH4x3RT3xIArc8bw+bjQyTn77Fjj9Pl18oGbh/3R9rSZNzZF7SSIqe gbZdROVqOqYD9S2Hyw7Hwvd9XQXeya8bzti5ZJP+F4GSn+ehMTOYxwZH81A4ygEn/P NnLkSJMtj2p6vC0b8QR1eNtF2WaQIKVNE4clxPyzybRk9bTWwV2yZiX23nXNLWy+RF LkD792DC2bmn7hb7Z2+kVn9R/nhWlwnf+dN+l/7FOsjSDRdd4lBH6fQhizDxlPWy6A eKtfNHkhOPJHB7Fhybn55POBzdNobLR1++97dKmy7GXpWGpFgFNY/Kn4DbkNzeo7zn y/OnDMSu7W3PA== From: Jeff Layton Date: Mon, 02 Jun 2025 10:02:00 -0400 Subject: [PATCH RFC v2 17/28] filelock: add an inode_lease_ignore_mask helper Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20250602-dir-deleg-v2-17-a7919700de86@kernel.org> References: <20250602-dir-deleg-v2-0-a7919700de86@kernel.org> In-Reply-To: <20250602-dir-deleg-v2-0-a7919700de86@kernel.org> To: Alexander Viro , Christian Brauner , Jan Kara , Chuck Lever , Alexander Aring , Trond Myklebust , Anna Schumaker , Steve French , Paulo Alcantara , Ronnie Sahlberg , Shyam Prasad N , Tom Talpey , Bharath SM , NeilBrown , Olga Kornievskaia , Dai Ngo , Jonathan Corbet , Amir Goldstein , Miklos Szeredi Cc: linux-fsdevel@vger.kernel.org, linux-kernel@vger.kernel.org, linux-nfs@vger.kernel.org, linux-cifs@vger.kernel.org, samba-technical@lists.samba.org, linux-doc@vger.kernel.org, Jeff Layton X-Mailer: b4 0.14.2 X-Developer-Signature: v=1; a=openpgp-sha256; l=2316; i=jlayton@kernel.org; h=from:subject:message-id; bh=seErxpiSRxkH2bkmFkFAfk0mHe9vn7gtVplOYiMIB5M=; b=owEBbQKS/ZANAwAKAQAOaEEZVoIVAcsmYgBoPa7nrG4viER6ob/N0NfNizE5cMqkHwJ1oGwl+ 3TbdrPv4VuJAjMEAAEKAB0WIQRLwNeyRHGyoYTq9dMADmhBGVaCFQUCaD2u5wAKCRAADmhBGVaC FellEACFyFCST+vidRNBnhdQbYswOvu6ZZl3xx/7Z93cUUk1jRfcAUebmiajMBY7ZIkI24lhwBC 9DTZ0JXmeOJxE+WvmijpCVUAZuH50CKBxbrgwl/KzmG2zqJqp+yo8G88a/Z2iw0dcDBw8Jw+c8G MK/95LSJHAqWt7dYgZLGemW+8E9YY71+7t01L6BSuTe2dJQX4mzHlEKQgrOUhuGUj9m5YRcH1Cb f4C6uoIpU3qX1iuUU8k9MfcBz0hZiv4oSdvvGRWK7e6FVmHEIJnfen9ZRiy9XAjUhaNEo9Sqkgk mOcL7u8cKzDbGfOAzimLVfh5GFjJ0d4d3QbnnObmxp1MjuF8BKuPpbQXDLG56iqUy9dYVxjoKSh p4qSKOFRsDDCakNyqFOPSilopZvzid84LZCwTpwTaOReBuq51YXjwZt/AgqEuryjtQQ+pesmubx mI24dHo1AC89fp143inbdl383kxPJKeaPZLxz7dK4NXxwHgnO8GPEZAFYVNoEwHvY79v7lUBgey AhTEklQ/L8Sr120pUufQBIyHWQfSLPfbQOQqcAROadhxxv8EMzs+Ae8XXs7wNDSOcBx0StXJOz0 buk2/I8AHQTiH3oT13ANxElPvd+xMeR0MZM0zdJiWIeEKNjC1zMYfDAU/3GDZV7CkJxI+NO05V8 0sEKNT5TqCT+8ng== X-Developer-Key: i=jlayton@kernel.org; a=openpgp; fpr=4BC0D7B24471B2A184EAF5D3000E684119568215 Add a new routine that returns a mask of all dir change events that are currently ignored by any leases. nfsd will use this to determine how to configure the fsnotify_mark mask. Signed-off-by: Jeff Layton --- fs/locks.c | 32 ++++++++++++++++++++++++++++++++ include/linux/filelock.h | 1 + 2 files changed, 33 insertions(+) diff --git a/fs/locks.c b/fs/locks.c index 95270a1fab4a1792a6fcad738cc9d937d99ad2af..522455196353f64d3150c45c9d1= cd260751bd7b9 100644 --- a/fs/locks.c +++ b/fs/locks.c @@ -1526,6 +1526,38 @@ any_leases_conflict(struct inode *inode, struct file= _lease *breaker) return false; } =20 +#define IGNORE_MASK (FL_IGN_DIR_CREATE | FL_IGN_DIR_DELETE | FL_IGN_DIR_RE= NAME) + +/** + * inode_lease_ignore_mask - return union of all ignored inode events for = this inode + * @inode: inode of which to get ignore mask + * + * Walk the list of leases, and return the result of all of + * their FL_IGN_DIR_* bits or'ed together. + */ +u32 +inode_lease_ignore_mask(struct inode *inode) +{ + struct file_lock_context *ctx; + struct file_lock_core *flc; + u32 mask =3D 0; + + ctx =3D locks_inode_context(inode); + if (!ctx) + return 0; + + spin_lock(&ctx->flc_lock); + list_for_each_entry(flc, &ctx->flc_lease, flc_list) { + mask |=3D flc->flc_flags & IGNORE_MASK; + /* If we already have everything, we can stop */ + if (mask =3D=3D IGNORE_MASK) + break; + } + spin_unlock(&ctx->flc_lock); + return mask; +} +EXPORT_SYMBOL_GPL(inode_lease_ignore_mask); + static bool ignore_dir_deleg_break(struct file_lease *fl, unsigned int flags) { diff --git a/include/linux/filelock.h b/include/linux/filelock.h index 32b30c14f5fd52727b1a18957e9dbc930c922941..4513a8dad3974bf5fb08e0df4f0= 85d71155e04f5 100644 --- a/include/linux/filelock.h +++ b/include/linux/filelock.h @@ -244,6 +244,7 @@ int generic_setlease(struct file *, int, struct file_le= ase **, void **priv); int kernel_setlease(struct file *, int, struct file_lease **, void **); int vfs_setlease(struct file *, int, struct file_lease **, void **); int lease_modify(struct file_lease *, int, struct list_head *); +u32 inode_lease_ignore_mask(struct inode *inode); =20 struct notifier_block; int lease_register_notifier(struct notifier_block *); --=20 2.49.0 From nobody Thu Dec 18 14:10:55 2025 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 D1AD02356C0; Mon, 2 Jun 2025 14:03:00 +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=1748872980; cv=none; b=jGmBIDYJCsXcQt1LAD+qwllExNPKwZ2ehcE8HGN8MpCxv4pzuN4oETUhw32LDsSk+gIGd3/pmL0CrzmmqHltfFOzaXzW08fshwPS1IAKzcl99TJ9dGagmpaTzO/hAKG+J0plZ99OFE98uGGfVFvvSFedV08PSp8eQT3WixxBu7o= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1748872980; c=relaxed/simple; bh=2lqSkS/6jX0OeCPE0CFNjM3jkEwY+uEDS/XqwDkEqFA=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=cU3un4ImqQn6Ij3zlz9IT8YI+83lW9IeFS8HfFjbgR56XcHTBPX/ZOc4A0J0jqGu0OID8u2Iz0LRiVaQ+PAgU2pV0bFn7C/zrvPbJTUCdaD07sgVsQgNSWfRf4n7H79CXy9rr/DjSqAKvS0uQtep3SZQPv3CLs10o/Xg7St507I= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=R2UrPF2S; 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="R2UrPF2S" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 69EB6C4CEEB; Mon, 2 Jun 2025 14:02:58 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1748872980; bh=2lqSkS/6jX0OeCPE0CFNjM3jkEwY+uEDS/XqwDkEqFA=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=R2UrPF2SyTTg2X+O7XONwrIb0Aa+1BZ2eyFzgoJ/8IGxlTvAcKguZrbT6fmwe9T5B /e0zNl1t28I+wZZbiSLiyOWOq+zCHOh+4Xk/vbCXR7/8sVWKMEXF01JTi1NkFd6DZt wXoNPXNIf70tc/Q31ImJN+Amene/lRN3M3aJiY40VWTK+R/K9gCcpykYFjpBDxazmC VY10G9D2Qu28/8VDrs6V8ZLCZA+XwossvnGxHC0aeTUkKHMS4HyhR+sRhTb6QZlw7W mewIJdD1Rpdf/JsZeSXYJnen4C8uqvc3IcjIje/rnF1I+a4S9RkqJTu+QmdsQNkdvy SV8cc6jzRDkQw== From: Jeff Layton Date: Mon, 02 Jun 2025 10:02:01 -0400 Subject: [PATCH RFC v2 18/28] nfsd: add protocol support for CB_NOTIFY Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20250602-dir-deleg-v2-18-a7919700de86@kernel.org> References: <20250602-dir-deleg-v2-0-a7919700de86@kernel.org> In-Reply-To: <20250602-dir-deleg-v2-0-a7919700de86@kernel.org> To: Alexander Viro , Christian Brauner , Jan Kara , Chuck Lever , Alexander Aring , Trond Myklebust , Anna Schumaker , Steve French , Paulo Alcantara , Ronnie Sahlberg , Shyam Prasad N , Tom Talpey , Bharath SM , NeilBrown , Olga Kornievskaia , Dai Ngo , Jonathan Corbet , Amir Goldstein , Miklos Szeredi Cc: linux-fsdevel@vger.kernel.org, linux-kernel@vger.kernel.org, linux-nfs@vger.kernel.org, linux-cifs@vger.kernel.org, samba-technical@lists.samba.org, linux-doc@vger.kernel.org, Jeff Layton X-Mailer: b4 0.14.2 X-Developer-Signature: v=1; a=openpgp-sha256; l=46762; i=jlayton@kernel.org; h=from:subject:message-id; bh=2lqSkS/6jX0OeCPE0CFNjM3jkEwY+uEDS/XqwDkEqFA=; b=owEBbQKS/ZANAwAKAQAOaEEZVoIVAcsmYgBoPa7oAfgB45aC3bkZK6ccGxGaF4GyDxCQgBluc 2um7zTu1VOJAjMEAAEKAB0WIQRLwNeyRHGyoYTq9dMADmhBGVaCFQUCaD2u6AAKCRAADmhBGVaC FWd1D/9Ge95X8Ij8VARilJZ4MDlHqF58K4ymIRG21DGsra8pQqHkdKs4Vlu71YLVz2+9f20WmG1 v0L34wx6q81gU2+am37pF6vOu8nmgyN++gNzgXqo1YvGtMFKRmtrNtNm1vwqpSFkUOsL/ROXhtY 3KO+Jq2NLqDV0LaIPAU5YM0Gphdli9+F5WzvMrBzcmXIjv/NZVXrPxvTYYItZt9AKvM9snssG/W rjHJXg+SJQhNZXVLI8BZcK80vC9w1sJ+ggr9ffd8NQ1usQ/7z7JKPAZTHSxM07MTXswIaGK7bCY 3NXsFEmPDv0XsmX2sfX01BEQ4ahtxKG6fn6mGuRg/rEYxIbfFzEl5GKzzhtXnK8+k4p9l58Huoy 7jqmXONS4zsCAFXl6Rx4hMcgyrt2D7vPlYXBS2iPzvmoRPPaQCkrScJmsNSE+V/nGobhoHbgH5f xvbNw3oEZ/fHfxxjYGq8ftt+tfcGWbX0lPnbhwM3RAOSEFUsco6w6JnawK2ySRqTx4gsvntPUVF wLQGPLhuJLX0btjsE8cSKGJ5K9/Tz4zjOqo1QCUJAxYOj4OvLKyZ8XT1Jyg7LDGNEXFgzENTYkR zyaf19ZxblNEQ8uA9iDepmeg+OAsHgiUjQ/YQNCaulGdLhyOwo3C/LFYqD1xT9yLxIH7TJHMnsg ctKIUkG6DxYmLOA== X-Developer-Key: i=jlayton@kernel.org; a=openpgp; fpr=4BC0D7B24471B2A184EAF5D3000E684119568215 Add the necessary bits to nfs4_1.x and remove the duplicate definitions from nfs4.h and the uapi nfs4 header. Regenerate the xdr files. Signed-off-by: Jeff Layton --- Documentation/sunrpc/xdr/nfs4_1.x | 252 ++++++++++++++++- fs/nfsd/nfs4xdr_gen.c | 506 +++++++++++++++++++++++++++++++= +++- fs/nfsd/nfs4xdr_gen.h | 17 +- fs/nfsd/trace.h | 1 + include/linux/nfs4.h | 127 --------- include/linux/sunrpc/xdrgen/nfs4_1.h | 293 +++++++++++++++++++- include/uapi/linux/nfs4.h | 2 - 7 files changed, 1057 insertions(+), 141 deletions(-) diff --git a/Documentation/sunrpc/xdr/nfs4_1.x b/Documentation/sunrpc/xdr/n= fs4_1.x index ca95150a3a29fc5418991bf2395326bd73645ea8..2de9ba6426edd053d4c8274e079= f3570244af8d4 100644 --- a/Documentation/sunrpc/xdr/nfs4_1.x +++ b/Documentation/sunrpc/xdr/nfs4_1.x @@ -45,13 +45,162 @@ pragma header nfs4; /* * Basic typedefs for RFC 1832 data type definitions */ -typedef hyper int64_t; -typedef unsigned int uint32_t; +typedef int int32_t; +typedef unsigned int uint32_t; +typedef hyper int64_t; +typedef unsigned hyper uint64_t; + +const NFS4_VERIFIER_SIZE =3D 8; +const NFS4_FHSIZE =3D 128; + +enum nfsstat4 { + NFS4_OK =3D 0, /* everything is okay */ + NFS4ERR_PERM =3D 1, /* caller not privileged */ + NFS4ERR_NOENT =3D 2, /* no such file/directory */ + NFS4ERR_IO =3D 5, /* hard I/O error */ + NFS4ERR_NXIO =3D 6, /* no such device */ + NFS4ERR_ACCESS =3D 13, /* access denied */ + NFS4ERR_EXIST =3D 17, /* file already exists */ + NFS4ERR_XDEV =3D 18, /* different filesystems */ + + /* + * Please do not allocate value 19; it was used in NFSv3 + * and we do not want a value in NFSv3 to have a different + * meaning in NFSv4.x. + */ + + NFS4ERR_NOTDIR =3D 20, /* should be a directory */ + NFS4ERR_ISDIR =3D 21, /* should not be directory */ + NFS4ERR_INVAL =3D 22, /* invalid argument */ + NFS4ERR_FBIG =3D 27, /* file exceeds server max */ + NFS4ERR_NOSPC =3D 28, /* no space on filesystem */ + NFS4ERR_ROFS =3D 30, /* read-only filesystem */ + NFS4ERR_MLINK =3D 31, /* too many hard links */ + NFS4ERR_NAMETOOLONG =3D 63, /* name exceeds server max */ + NFS4ERR_NOTEMPTY =3D 66, /* directory not empty */ + NFS4ERR_DQUOT =3D 69, /* hard quota limit reached*/ + NFS4ERR_STALE =3D 70, /* file no longer exists */ + NFS4ERR_BADHANDLE =3D 10001,/* Illegal filehandle */ + NFS4ERR_BAD_COOKIE =3D 10003,/* READDIR cookie is stale */ + NFS4ERR_NOTSUPP =3D 10004,/* operation not supported */ + NFS4ERR_TOOSMALL =3D 10005,/* response limit exceeded */ + NFS4ERR_SERVERFAULT =3D 10006,/* undefined server error */ + NFS4ERR_BADTYPE =3D 10007,/* type invalid for CREATE */ + NFS4ERR_DELAY =3D 10008,/* file "busy" - retry */ + NFS4ERR_SAME =3D 10009,/* nverify says attrs same */ + NFS4ERR_DENIED =3D 10010,/* lock unavailable */ + NFS4ERR_EXPIRED =3D 10011,/* lock lease expired */ + NFS4ERR_LOCKED =3D 10012,/* I/O failed due to lock */ + NFS4ERR_GRACE =3D 10013,/* in grace period */ + NFS4ERR_FHEXPIRED =3D 10014,/* filehandle expired */ + NFS4ERR_SHARE_DENIED =3D 10015,/* share reserve denied */ + NFS4ERR_WRONGSEC =3D 10016,/* wrong security flavor */ + NFS4ERR_CLID_INUSE =3D 10017,/* clientid in use */ + + /* NFS4ERR_RESOURCE is not a valid error in NFSv4.1 */ + NFS4ERR_RESOURCE =3D 10018,/* resource exhaustion */ + + NFS4ERR_MOVED =3D 10019,/* filesystem relocated */ + NFS4ERR_NOFILEHANDLE =3D 10020,/* current FH is not set */ + NFS4ERR_MINOR_VERS_MISMATCH=3D 10021,/* minor vers not supp */ + NFS4ERR_STALE_CLIENTID =3D 10022,/* server has rebooted */ + NFS4ERR_STALE_STATEID =3D 10023,/* server has rebooted */ + NFS4ERR_OLD_STATEID =3D 10024,/* state is out of sync */ + NFS4ERR_BAD_STATEID =3D 10025,/* incorrect stateid */ + NFS4ERR_BAD_SEQID =3D 10026,/* request is out of seq. */ + NFS4ERR_NOT_SAME =3D 10027,/* verify - attrs not same */ + NFS4ERR_LOCK_RANGE =3D 10028,/* overlapping lock range */ + NFS4ERR_SYMLINK =3D 10029,/* should be file/directory*/ + NFS4ERR_RESTOREFH =3D 10030,/* no saved filehandle */ + NFS4ERR_LEASE_MOVED =3D 10031,/* some filesystem moved */ + NFS4ERR_ATTRNOTSUPP =3D 10032,/* recommended attr not sup*/ + NFS4ERR_NO_GRACE =3D 10033,/* reclaim outside of grace*/ + NFS4ERR_RECLAIM_BAD =3D 10034,/* reclaim error at server */ + NFS4ERR_RECLAIM_CONFLICT=3D 10035,/* conflict on reclaim */ + NFS4ERR_BADXDR =3D 10036,/* XDR decode failed */ + NFS4ERR_LOCKS_HELD =3D 10037,/* file locks held at CLOSE*/ + NFS4ERR_OPENMODE =3D 10038,/* conflict in OPEN and I/O*/ + NFS4ERR_BADOWNER =3D 10039,/* owner translation bad */ + NFS4ERR_BADCHAR =3D 10040,/* utf-8 char not supported*/ + NFS4ERR_BADNAME =3D 10041,/* name not supported */ + NFS4ERR_BAD_RANGE =3D 10042,/* lock range not supported*/ + NFS4ERR_LOCK_NOTSUPP =3D 10043,/* no atomic up/downgrade */ + NFS4ERR_OP_ILLEGAL =3D 10044,/* undefined operation */ + NFS4ERR_DEADLOCK =3D 10045,/* file locking deadlock */ + NFS4ERR_FILE_OPEN =3D 10046,/* open file blocks op. */ + NFS4ERR_ADMIN_REVOKED =3D 10047,/* lockowner state revoked */ + NFS4ERR_CB_PATH_DOWN =3D 10048,/* callback path down */ + + /* NFSv4.1 errors start here. */ + + NFS4ERR_BADIOMODE =3D 10049, + NFS4ERR_BADLAYOUT =3D 10050, + NFS4ERR_BAD_SESSION_DIGEST =3D 10051, + NFS4ERR_BADSESSION =3D 10052, + NFS4ERR_BADSLOT =3D 10053, + NFS4ERR_COMPLETE_ALREADY =3D 10054, + NFS4ERR_CONN_NOT_BOUND_TO_SESSION =3D 10055, + NFS4ERR_DELEG_ALREADY_WANTED =3D 10056, + NFS4ERR_BACK_CHAN_BUSY =3D 10057,/*backchan reqs outstanding*/ + NFS4ERR_LAYOUTTRYLATER =3D 10058, + NFS4ERR_LAYOUTUNAVAILABLE =3D 10059, + NFS4ERR_NOMATCHING_LAYOUT =3D 10060, + NFS4ERR_RECALLCONFLICT =3D 10061, + NFS4ERR_UNKNOWN_LAYOUTTYPE =3D 10062, + NFS4ERR_SEQ_MISORDERED =3D 10063,/* unexpected seq.ID in req*/ + NFS4ERR_SEQUENCE_POS =3D 10064,/* [CB_]SEQ. op not 1st op */ + NFS4ERR_REQ_TOO_BIG =3D 10065,/* request too big */ + NFS4ERR_REP_TOO_BIG =3D 10066,/* reply too big */ + NFS4ERR_REP_TOO_BIG_TO_CACHE =3D10067,/* rep. not all cached*/ + NFS4ERR_RETRY_UNCACHED_REP =3D10068,/* retry & rep. uncached*/ + NFS4ERR_UNSAFE_COMPOUND =3D10069,/* retry/recovery too hard */ + NFS4ERR_TOO_MANY_OPS =3D 10070,/*too many ops in [CB_]COMP*/ + NFS4ERR_OP_NOT_IN_SESSION =3D10071,/* op needs [CB_]SEQ. op */ + NFS4ERR_HASH_ALG_UNSUPP =3D 10072, /* hash alg. not supp. */ + /* Error 10073 is unused. */ + NFS4ERR_CLIENTID_BUSY =3D 10074,/* clientid has state */ + NFS4ERR_PNFS_IO_HOLE =3D 10075,/* IO to _SPARSE file hole */ + NFS4ERR_SEQ_FALSE_RETRY=3D 10076,/* Retry !=3D original req. */ + NFS4ERR_BAD_HIGH_SLOT =3D 10077,/* req has bad highest_slot*/ + NFS4ERR_DEADSESSION =3D 10078,/*new req sent to dead sess*/ + NFS4ERR_ENCR_ALG_UNSUPP=3D 10079,/* encr alg. not supp. */ + NFS4ERR_PNFS_NO_LAYOUT =3D 10080,/* I/O without a layout */ + NFS4ERR_NOT_ONLY_OP =3D 10081,/* addl ops not allowed */ + NFS4ERR_WRONG_CRED =3D 10082,/* op done by wrong cred */ + NFS4ERR_WRONG_TYPE =3D 10083,/* op on wrong type object */ + NFS4ERR_DIRDELEG_UNAVAIL=3D10084,/* delegation not avail. */ + NFS4ERR_REJECT_DELEG =3D 10085,/* cb rejected delegation */ + NFS4ERR_RETURNCONFLICT =3D 10086,/* layout get before return*/ + NFS4ERR_DELEG_REVOKED =3D 10087, /* deleg./layout revoked */ + NFS4ERR_PARTNER_NOTSUPP =3D 10088, + NFS4ERR_PARTNER_NO_AUTH =3D 10089, + NFS4ERR_UNION_NOTSUPP =3D 10090, + NFS4ERR_OFFLOAD_DENIED =3D 10091, + NFS4ERR_WRONG_LFS =3D 10092, + NFS4ERR_BADLABEL =3D 10093, + NFS4ERR_OFFLOAD_NO_REQS =3D 10094, + NFS4ERR_NOXATTR =3D 10095, + NFS4ERR_XATTR2BIG =3D 10096, + + /* always set this to one more than the last one in the enum */ + NFS4ERR_FIRST_FREE =3D 10097 +}; =20 /* * Basic data types */ +typedef opaque attrlist4<>; typedef uint32_t bitmap4<>; +typedef uint64_t nfs_cookie4; +typedef opaque nfs_fh4; +typedef opaque utf8string<>; +typedef utf8string utf8str_cis; +typedef utf8string utf8str_cs; +typedef utf8string utf8str_mixed; +typedef utf8str_cs component4; +typedef utf8str_cs linktext4; +typedef component4 pathname4<>; +typedef opaque verifier4[NFS4_VERIFIER_SIZE]; =20 /* * Timeval @@ -61,6 +210,21 @@ struct nfstime4 { uint32_t nseconds; }; =20 +/* + * File attribute container + */ +struct fattr4 { + bitmap4 attrmask; + attrlist4 attr_vals; +}; + +/* + * Stateid + */ +struct stateid4 { + uint32_t seqid; + opaque other[12]; +}; =20 /* * The following content was extracted from draft-ietf-nfsv4-delstid @@ -184,3 +348,87 @@ enum open_delegation_type4 { OPEN_DELEGATE_READ_ATTRS_DELEG =3D 4, OPEN_DELEGATE_WRITE_ATTRS_DELEG =3D 5 }; + +/* + * Directory notification types. + */ +enum notify_type4 { + NOTIFY4_CHANGE_CHILD_ATTRS =3D 0, + NOTIFY4_CHANGE_DIR_ATTRS =3D 1, + NOTIFY4_REMOVE_ENTRY =3D 2, + NOTIFY4_ADD_ENTRY =3D 3, + NOTIFY4_RENAME_ENTRY =3D 4, + NOTIFY4_CHANGE_COOKIE_VERIFIER =3D 5 +}; + +/* Changed entry information. */ +struct notify_entry4 { + component4 ne_file; + fattr4 ne_attrs; +}; + +/* Previous entry information */ +struct prev_entry4 { + notify_entry4 pe_prev_entry; + /* what READDIR returned for this entry */ + nfs_cookie4 pe_prev_entry_cookie; +}; + +struct notify_remove4 { + notify_entry4 nrm_old_entry; + nfs_cookie4 nrm_old_entry_cookie; +}; +pragma public notify_remove4; + +struct notify_add4 { + /* + * Information on object + * possibly renamed over. + */ + notify_remove4 nad_old_entry<1>; + notify_entry4 nad_new_entry; + /* what READDIR would have returned for this entry */ + nfs_cookie4 nad_new_entry_cookie<1>; + prev_entry4 nad_prev_entry<1>; + bool nad_last_entry; +}; +pragma public notify_add4; + +struct notify_attr4 { + notify_entry4 na_changed_entry; +}; + +struct notify_rename4 { + notify_remove4 nrn_old_entry; + notify_add4 nrn_new_entry; +}; +pragma public notify_rename4; + +struct notify_verifier4 { + verifier4 nv_old_cookieverf; + verifier4 nv_new_cookieverf; +}; + +/* + * Objects of type notify_<>4 and + * notify_device_<>4 are encoded in this. + */ +typedef opaque notifylist4<>; + +struct notify4 { + /* composed from notify_type4 or notify_deviceid_type4 */ + bitmap4 notify_mask; + notifylist4 notify_vals; +}; + +struct CB_NOTIFY4args { + stateid4 cna_stateid; + nfs_fh4 cna_fh; + notify4 cna_changes<>; +}; +pragma public CB_NOTIFY4args; + +struct CB_NOTIFY4res { + nfsstat4 cnr_status; +}; +pragma public CB_NOTIFY4res; diff --git a/fs/nfsd/nfs4xdr_gen.c b/fs/nfsd/nfs4xdr_gen.c index a17b5d8e60b3579caa2e2a8b40ed757070e1a622..14e7c4aa9b07168d98fb48a54e6= 952bfb71d29a7 100644 --- a/fs/nfsd/nfs4xdr_gen.c +++ b/fs/nfsd/nfs4xdr_gen.c @@ -1,16 +1,16 @@ // SPDX-License-Identifier: GPL-2.0 // Generated by xdrgen. Manual edits will be lost. // XDR specification file: ../../Documentation/sunrpc/xdr/nfs4_1.x -// XDR specification modification time: Mon Oct 14 09:10:13 2024 +// XDR specification modification time: Fri May 16 10:52:35 2025 =20 #include =20 #include "nfs4xdr_gen.h" =20 static bool __maybe_unused -xdrgen_decode_int64_t(struct xdr_stream *xdr, int64_t *ptr) +xdrgen_decode_int32_t(struct xdr_stream *xdr, int32_t *ptr) { - return xdrgen_decode_hyper(xdr, ptr); + return xdrgen_decode_int(xdr, ptr); }; =20 static bool __maybe_unused @@ -19,6 +19,35 @@ xdrgen_decode_uint32_t(struct xdr_stream *xdr, uint32_t = *ptr) return xdrgen_decode_unsigned_int(xdr, ptr); }; =20 +static bool __maybe_unused +xdrgen_decode_int64_t(struct xdr_stream *xdr, int64_t *ptr) +{ + return xdrgen_decode_hyper(xdr, ptr); +}; + +static bool __maybe_unused +xdrgen_decode_uint64_t(struct xdr_stream *xdr, uint64_t *ptr) +{ + return xdrgen_decode_unsigned_hyper(xdr, ptr); +}; + +static bool __maybe_unused +xdrgen_decode_nfsstat4(struct xdr_stream *xdr, nfsstat4 *ptr) +{ + u32 val; + + if (xdr_stream_decode_u32(xdr, &val) < 0) + return false; + *ptr =3D val; + return true; +} + +static bool __maybe_unused +xdrgen_decode_attrlist4(struct xdr_stream *xdr, attrlist4 *ptr) +{ + return xdrgen_decode_opaque(xdr, ptr, 0); +}; + static bool __maybe_unused xdrgen_decode_bitmap4(struct xdr_stream *xdr, bitmap4 *ptr) { @@ -30,6 +59,71 @@ xdrgen_decode_bitmap4(struct xdr_stream *xdr, bitmap4 *p= tr) return true; }; =20 +static bool __maybe_unused +xdrgen_decode_nfs_cookie4(struct xdr_stream *xdr, nfs_cookie4 *ptr) +{ + return xdrgen_decode_uint64_t(xdr, ptr); +}; + +static bool __maybe_unused +xdrgen_decode_nfs_fh4(struct xdr_stream *xdr, nfs_fh4 *ptr) +{ + return xdrgen_decode_opaque(xdr, ptr, NFS4_FHSIZE); +}; + +static bool __maybe_unused +xdrgen_decode_utf8string(struct xdr_stream *xdr, utf8string *ptr) +{ + return xdrgen_decode_opaque(xdr, ptr, 0); +}; + +static bool __maybe_unused +xdrgen_decode_utf8str_cis(struct xdr_stream *xdr, utf8str_cis *ptr) +{ + return xdrgen_decode_utf8string(xdr, ptr); +}; + +static bool __maybe_unused +xdrgen_decode_utf8str_cs(struct xdr_stream *xdr, utf8str_cs *ptr) +{ + return xdrgen_decode_utf8string(xdr, ptr); +}; + +static bool __maybe_unused +xdrgen_decode_utf8str_mixed(struct xdr_stream *xdr, utf8str_mixed *ptr) +{ + return xdrgen_decode_utf8string(xdr, ptr); +}; + +static bool __maybe_unused +xdrgen_decode_component4(struct xdr_stream *xdr, component4 *ptr) +{ + return xdrgen_decode_utf8str_cs(xdr, ptr); +}; + +static bool __maybe_unused +xdrgen_decode_linktext4(struct xdr_stream *xdr, linktext4 *ptr) +{ + return xdrgen_decode_utf8str_cs(xdr, ptr); +}; + +static bool __maybe_unused +xdrgen_decode_pathname4(struct xdr_stream *xdr, pathname4 *ptr) +{ + if (xdr_stream_decode_u32(xdr, &ptr->count) < 0) + return false; + for (u32 i =3D 0; i < ptr->count; i++) + if (!xdrgen_decode_component4(xdr, &ptr->element[i])) + return false; + return true; +}; + +static bool __maybe_unused +xdrgen_decode_verifier4(struct xdr_stream *xdr, verifier4 *ptr) +{ + return xdr_stream_decode_opaque_fixed(xdr, ptr, NFS4_VERIFIER_SIZE) >=3D = 0; +}; + static bool __maybe_unused xdrgen_decode_nfstime4(struct xdr_stream *xdr, struct nfstime4 *ptr) { @@ -40,6 +134,26 @@ xdrgen_decode_nfstime4(struct xdr_stream *xdr, struct n= fstime4 *ptr) return true; }; =20 +static bool __maybe_unused +xdrgen_decode_fattr4(struct xdr_stream *xdr, struct fattr4 *ptr) +{ + if (!xdrgen_decode_bitmap4(xdr, &ptr->attrmask)) + return false; + if (!xdrgen_decode_attrlist4(xdr, &ptr->attr_vals)) + return false; + return true; +}; + +static bool __maybe_unused +xdrgen_decode_stateid4(struct xdr_stream *xdr, struct stateid4 *ptr) +{ + if (!xdrgen_decode_uint32_t(xdr, &ptr->seqid)) + return false; + if (xdr_stream_decode_opaque_fixed(xdr, ptr->other, 12) < 0) + return false; + return true; +}; + static bool __maybe_unused xdrgen_decode_fattr4_offline(struct xdr_stream *xdr, fattr4_offline *ptr) { @@ -147,9 +261,148 @@ xdrgen_decode_open_delegation_type4(struct xdr_stream= *xdr, open_delegation_type } =20 static bool __maybe_unused -xdrgen_encode_int64_t(struct xdr_stream *xdr, const int64_t value) +xdrgen_decode_notify_type4(struct xdr_stream *xdr, notify_type4 *ptr) { - return xdrgen_encode_hyper(xdr, value); + u32 val; + + if (xdr_stream_decode_u32(xdr, &val) < 0) + return false; + *ptr =3D val; + return true; +} + +static bool __maybe_unused +xdrgen_decode_notify_entry4(struct xdr_stream *xdr, struct notify_entry4 *= ptr) +{ + if (!xdrgen_decode_component4(xdr, &ptr->ne_file)) + return false; + if (!xdrgen_decode_fattr4(xdr, &ptr->ne_attrs)) + return false; + return true; +}; + +static bool __maybe_unused +xdrgen_decode_prev_entry4(struct xdr_stream *xdr, struct prev_entry4 *ptr) +{ + if (!xdrgen_decode_notify_entry4(xdr, &ptr->pe_prev_entry)) + return false; + if (!xdrgen_decode_nfs_cookie4(xdr, &ptr->pe_prev_entry_cookie)) + return false; + return true; +}; + +bool +xdrgen_decode_notify_remove4(struct xdr_stream *xdr, struct notify_remove4= *ptr) +{ + if (!xdrgen_decode_notify_entry4(xdr, &ptr->nrm_old_entry)) + return false; + if (!xdrgen_decode_nfs_cookie4(xdr, &ptr->nrm_old_entry_cookie)) + return false; + return true; +}; + +bool +xdrgen_decode_notify_add4(struct xdr_stream *xdr, struct notify_add4 *ptr) +{ + if (xdr_stream_decode_u32(xdr, &ptr->nad_old_entry.count) < 0) + return false; + if (ptr->nad_old_entry.count > 1) + return false; + for (u32 i =3D 0; i < ptr->nad_old_entry.count; i++) + if (!xdrgen_decode_notify_remove4(xdr, &ptr->nad_old_entry.element[i])) + return false; + if (!xdrgen_decode_notify_entry4(xdr, &ptr->nad_new_entry)) + return false; + if (xdr_stream_decode_u32(xdr, &ptr->nad_new_entry_cookie.count) < 0) + return false; + if (ptr->nad_new_entry_cookie.count > 1) + return false; + for (u32 i =3D 0; i < ptr->nad_new_entry_cookie.count; i++) + if (!xdrgen_decode_nfs_cookie4(xdr, &ptr->nad_new_entry_cookie.element[i= ])) + return false; + if (xdr_stream_decode_u32(xdr, &ptr->nad_prev_entry.count) < 0) + return false; + if (ptr->nad_prev_entry.count > 1) + return false; + for (u32 i =3D 0; i < ptr->nad_prev_entry.count; i++) + if (!xdrgen_decode_prev_entry4(xdr, &ptr->nad_prev_entry.element[i])) + return false; + if (!xdrgen_decode_bool(xdr, &ptr->nad_last_entry)) + return false; + return true; +}; + +static bool __maybe_unused +xdrgen_decode_notify_attr4(struct xdr_stream *xdr, struct notify_attr4 *pt= r) +{ + if (!xdrgen_decode_notify_entry4(xdr, &ptr->na_changed_entry)) + return false; + return true; +}; + +bool +xdrgen_decode_notify_rename4(struct xdr_stream *xdr, struct notify_rename4= *ptr) +{ + if (!xdrgen_decode_notify_remove4(xdr, &ptr->nrn_old_entry)) + return false; + if (!xdrgen_decode_notify_add4(xdr, &ptr->nrn_new_entry)) + return false; + return true; +}; + +static bool __maybe_unused +xdrgen_decode_notify_verifier4(struct xdr_stream *xdr, struct notify_verif= ier4 *ptr) +{ + if (!xdrgen_decode_verifier4(xdr, &ptr->nv_old_cookieverf)) + return false; + if (!xdrgen_decode_verifier4(xdr, &ptr->nv_new_cookieverf)) + return false; + return true; +}; + +static bool __maybe_unused +xdrgen_decode_notifylist4(struct xdr_stream *xdr, notifylist4 *ptr) +{ + return xdrgen_decode_opaque(xdr, ptr, 0); +}; + +static bool __maybe_unused +xdrgen_decode_notify4(struct xdr_stream *xdr, struct notify4 *ptr) +{ + if (!xdrgen_decode_bitmap4(xdr, &ptr->notify_mask)) + return false; + if (!xdrgen_decode_notifylist4(xdr, &ptr->notify_vals)) + return false; + return true; +}; + +bool +xdrgen_decode_CB_NOTIFY4args(struct xdr_stream *xdr, struct CB_NOTIFY4args= *ptr) +{ + if (!xdrgen_decode_stateid4(xdr, &ptr->cna_stateid)) + return false; + if (!xdrgen_decode_nfs_fh4(xdr, &ptr->cna_fh)) + return false; + if (xdr_stream_decode_u32(xdr, &ptr->cna_changes.count) < 0) + return false; + for (u32 i =3D 0; i < ptr->cna_changes.count; i++) + if (!xdrgen_decode_notify4(xdr, &ptr->cna_changes.element[i])) + return false; + return true; +}; + +bool +xdrgen_decode_CB_NOTIFY4res(struct xdr_stream *xdr, struct CB_NOTIFY4res *= ptr) +{ + if (!xdrgen_decode_nfsstat4(xdr, &ptr->cnr_status)) + return false; + return true; +}; + +static bool __maybe_unused +xdrgen_encode_int32_t(struct xdr_stream *xdr, const int32_t value) +{ + return xdrgen_encode_int(xdr, value); }; =20 static bool __maybe_unused @@ -158,6 +411,30 @@ xdrgen_encode_uint32_t(struct xdr_stream *xdr, const u= int32_t value) return xdrgen_encode_unsigned_int(xdr, value); }; =20 +static bool __maybe_unused +xdrgen_encode_int64_t(struct xdr_stream *xdr, const int64_t value) +{ + return xdrgen_encode_hyper(xdr, value); +}; + +static bool __maybe_unused +xdrgen_encode_uint64_t(struct xdr_stream *xdr, const uint64_t value) +{ + return xdrgen_encode_unsigned_hyper(xdr, value); +}; + +static bool __maybe_unused +xdrgen_encode_nfsstat4(struct xdr_stream *xdr, nfsstat4 value) +{ + return xdr_stream_encode_u32(xdr, value) =3D=3D XDR_UNIT; +} + +static bool __maybe_unused +xdrgen_encode_attrlist4(struct xdr_stream *xdr, const attrlist4 value) +{ + return xdr_stream_encode_opaque(xdr, value.data, value.len) >=3D 0; +}; + static bool __maybe_unused xdrgen_encode_bitmap4(struct xdr_stream *xdr, const bitmap4 value) { @@ -169,6 +446,71 @@ xdrgen_encode_bitmap4(struct xdr_stream *xdr, const bi= tmap4 value) return true; }; =20 +static bool __maybe_unused +xdrgen_encode_nfs_cookie4(struct xdr_stream *xdr, const nfs_cookie4 value) +{ + return xdrgen_encode_uint64_t(xdr, value); +}; + +static bool __maybe_unused +xdrgen_encode_nfs_fh4(struct xdr_stream *xdr, const nfs_fh4 value) +{ + return xdr_stream_encode_opaque(xdr, value.data, value.len) >=3D 0; +}; + +static bool __maybe_unused +xdrgen_encode_utf8string(struct xdr_stream *xdr, const utf8string value) +{ + return xdr_stream_encode_opaque(xdr, value.data, value.len) >=3D 0; +}; + +static bool __maybe_unused +xdrgen_encode_utf8str_cis(struct xdr_stream *xdr, const utf8str_cis value) +{ + return xdrgen_encode_utf8string(xdr, value); +}; + +static bool __maybe_unused +xdrgen_encode_utf8str_cs(struct xdr_stream *xdr, const utf8str_cs value) +{ + return xdrgen_encode_utf8string(xdr, value); +}; + +static bool __maybe_unused +xdrgen_encode_utf8str_mixed(struct xdr_stream *xdr, const utf8str_mixed va= lue) +{ + return xdrgen_encode_utf8string(xdr, value); +}; + +static bool __maybe_unused +xdrgen_encode_component4(struct xdr_stream *xdr, const component4 value) +{ + return xdrgen_encode_utf8str_cs(xdr, value); +}; + +static bool __maybe_unused +xdrgen_encode_linktext4(struct xdr_stream *xdr, const linktext4 value) +{ + return xdrgen_encode_utf8str_cs(xdr, value); +}; + +static bool __maybe_unused +xdrgen_encode_pathname4(struct xdr_stream *xdr, const pathname4 value) +{ + if (xdr_stream_encode_u32(xdr, value.count) !=3D XDR_UNIT) + return false; + for (u32 i =3D 0; i < value.count; i++) + if (!xdrgen_encode_component4(xdr, value.element[i])) + return false; + return true; +}; + +static bool __maybe_unused +xdrgen_encode_verifier4(struct xdr_stream *xdr, const verifier4 value) +{ + return xdr_stream_encode_opaque_fixed(xdr, value, NFS4_VERIFIER_SIZE) >= =3D 0; +}; + static bool __maybe_unused xdrgen_encode_nfstime4(struct xdr_stream *xdr, const struct nfstime4 *valu= e) { @@ -179,6 +521,26 @@ xdrgen_encode_nfstime4(struct xdr_stream *xdr, const s= truct nfstime4 *value) return true; }; =20 +static bool __maybe_unused +xdrgen_encode_fattr4(struct xdr_stream *xdr, const struct fattr4 *value) +{ + if (!xdrgen_encode_bitmap4(xdr, value->attrmask)) + return false; + if (!xdrgen_encode_attrlist4(xdr, value->attr_vals)) + return false; + return true; +}; + +static bool __maybe_unused +xdrgen_encode_stateid4(struct xdr_stream *xdr, const struct stateid4 *valu= e) +{ + if (!xdrgen_encode_uint32_t(xdr, value->seqid)) + return false; + if (xdr_stream_encode_opaque_fixed(xdr, value->other, 12) < 0) + return false; + return true; +}; + static bool __maybe_unused xdrgen_encode_fattr4_offline(struct xdr_stream *xdr, const fattr4_offline = value) { @@ -254,3 +616,137 @@ xdrgen_encode_open_delegation_type4(struct xdr_stream= *xdr, open_delegation_type { return xdr_stream_encode_u32(xdr, value) =3D=3D XDR_UNIT; } + +static bool __maybe_unused +xdrgen_encode_notify_type4(struct xdr_stream *xdr, notify_type4 value) +{ + return xdr_stream_encode_u32(xdr, value) =3D=3D XDR_UNIT; +} + +static bool __maybe_unused +xdrgen_encode_notify_entry4(struct xdr_stream *xdr, const struct notify_en= try4 *value) +{ + if (!xdrgen_encode_component4(xdr, value->ne_file)) + return false; + if (!xdrgen_encode_fattr4(xdr, &value->ne_attrs)) + return false; + return true; +}; + +static bool __maybe_unused +xdrgen_encode_prev_entry4(struct xdr_stream *xdr, const struct prev_entry4= *value) +{ + if (!xdrgen_encode_notify_entry4(xdr, &value->pe_prev_entry)) + return false; + if (!xdrgen_encode_nfs_cookie4(xdr, value->pe_prev_entry_cookie)) + return false; + return true; +}; + +bool +xdrgen_encode_notify_remove4(struct xdr_stream *xdr, const struct notify_r= emove4 *value) +{ + if (!xdrgen_encode_notify_entry4(xdr, &value->nrm_old_entry)) + return false; + if (!xdrgen_encode_nfs_cookie4(xdr, value->nrm_old_entry_cookie)) + return false; + return true; +}; + +bool +xdrgen_encode_notify_add4(struct xdr_stream *xdr, const struct notify_add4= *value) +{ + if (value->nad_old_entry.count > 1) + return false; + if (xdr_stream_encode_u32(xdr, value->nad_old_entry.count) !=3D XDR_UNIT) + return false; + for (u32 i =3D 0; i < value->nad_old_entry.count; i++) + if (!xdrgen_encode_notify_remove4(xdr, &value->nad_old_entry.element[i])) + return false; + if (!xdrgen_encode_notify_entry4(xdr, &value->nad_new_entry)) + return false; + if (value->nad_new_entry_cookie.count > 1) + return false; + if (xdr_stream_encode_u32(xdr, value->nad_new_entry_cookie.count) !=3D XD= R_UNIT) + return false; + for (u32 i =3D 0; i < value->nad_new_entry_cookie.count; i++) + if (!xdrgen_encode_nfs_cookie4(xdr, value->nad_new_entry_cookie.element[= i])) + return false; + if (value->nad_prev_entry.count > 1) + return false; + if (xdr_stream_encode_u32(xdr, value->nad_prev_entry.count) !=3D XDR_UNIT) + return false; + for (u32 i =3D 0; i < value->nad_prev_entry.count; i++) + if (!xdrgen_encode_prev_entry4(xdr, &value->nad_prev_entry.element[i])) + return false; + if (!xdrgen_encode_bool(xdr, value->nad_last_entry)) + return false; + return true; +}; + +static bool __maybe_unused +xdrgen_encode_notify_attr4(struct xdr_stream *xdr, const struct notify_att= r4 *value) +{ + if (!xdrgen_encode_notify_entry4(xdr, &value->na_changed_entry)) + return false; + return true; +}; + +bool +xdrgen_encode_notify_rename4(struct xdr_stream *xdr, const struct notify_r= ename4 *value) +{ + if (!xdrgen_encode_notify_remove4(xdr, &value->nrn_old_entry)) + return false; + if (!xdrgen_encode_notify_add4(xdr, &value->nrn_new_entry)) + return false; + return true; +}; + +static bool __maybe_unused +xdrgen_encode_notify_verifier4(struct xdr_stream *xdr, const struct notify= _verifier4 *value) +{ + if (!xdrgen_encode_verifier4(xdr, value->nv_old_cookieverf)) + return false; + if (!xdrgen_encode_verifier4(xdr, value->nv_new_cookieverf)) + return false; + return true; +}; + +static bool __maybe_unused +xdrgen_encode_notifylist4(struct xdr_stream *xdr, const notifylist4 value) +{ + return xdr_stream_encode_opaque(xdr, value.data, value.len) >=3D 0; +}; + +static bool __maybe_unused +xdrgen_encode_notify4(struct xdr_stream *xdr, const struct notify4 *value) +{ + if (!xdrgen_encode_bitmap4(xdr, value->notify_mask)) + return false; + if (!xdrgen_encode_notifylist4(xdr, value->notify_vals)) + return false; + return true; +}; + +bool +xdrgen_encode_CB_NOTIFY4args(struct xdr_stream *xdr, const struct CB_NOTIF= Y4args *value) +{ + if (!xdrgen_encode_stateid4(xdr, &value->cna_stateid)) + return false; + if (!xdrgen_encode_nfs_fh4(xdr, value->cna_fh)) + return false; + if (xdr_stream_encode_u32(xdr, value->cna_changes.count) !=3D XDR_UNIT) + return false; + for (u32 i =3D 0; i < value->cna_changes.count; i++) + if (!xdrgen_encode_notify4(xdr, &value->cna_changes.element[i])) + return false; + return true; +}; + +bool +xdrgen_encode_CB_NOTIFY4res(struct xdr_stream *xdr, const struct CB_NOTIFY= 4res *value) +{ + if (!xdrgen_encode_nfsstat4(xdr, value->cnr_status)) + return false; + return true; +}; diff --git a/fs/nfsd/nfs4xdr_gen.h b/fs/nfsd/nfs4xdr_gen.h index 41a0033b72562ee3c1fcdcd4a887ce635385b22b..c2936e1188007a5c6a6a4f3f373= a69728bf7459c 100644 --- a/fs/nfsd/nfs4xdr_gen.h +++ b/fs/nfsd/nfs4xdr_gen.h @@ -1,7 +1,7 @@ /* SPDX-License-Identifier: GPL-2.0 */ /* Generated by xdrgen. Manual edits will be lost. */ /* XDR specification file: ../../Documentation/sunrpc/xdr/nfs4_1.x */ -/* XDR specification modification time: Mon Oct 14 09:10:13 2024 */ +/* XDR specification modification time: Fri May 16 10:52:35 2025 */ =20 #ifndef _LINUX_XDRGEN_NFS4_1_DECL_H #define _LINUX_XDRGEN_NFS4_1_DECL_H @@ -22,4 +22,19 @@ bool xdrgen_encode_fattr4_time_deleg_access(struct xdr_s= tream *xdr, const fattr4 bool xdrgen_decode_fattr4_time_deleg_modify(struct xdr_stream *xdr, fattr4= _time_deleg_modify *ptr); bool xdrgen_encode_fattr4_time_deleg_modify(struct xdr_stream *xdr, const = fattr4_time_deleg_modify *value); =20 +bool xdrgen_decode_notify_remove4(struct xdr_stream *xdr, struct notify_re= move4 *ptr); +bool xdrgen_encode_notify_remove4(struct xdr_stream *xdr, const struct not= ify_remove4 *value); + +bool xdrgen_decode_notify_add4(struct xdr_stream *xdr, struct notify_add4 = *ptr); +bool xdrgen_encode_notify_add4(struct xdr_stream *xdr, const struct notify= _add4 *value); + +bool xdrgen_decode_notify_rename4(struct xdr_stream *xdr, struct notify_re= name4 *ptr); +bool xdrgen_encode_notify_rename4(struct xdr_stream *xdr, const struct not= ify_rename4 *value); + +bool xdrgen_decode_CB_NOTIFY4args(struct xdr_stream *xdr, struct CB_NOTIFY= 4args *ptr); +bool xdrgen_encode_CB_NOTIFY4args(struct xdr_stream *xdr, const struct CB_= NOTIFY4args *value); + +bool xdrgen_decode_CB_NOTIFY4res(struct xdr_stream *xdr, struct CB_NOTIFY4= res *ptr); +bool xdrgen_encode_CB_NOTIFY4res(struct xdr_stream *xdr, const struct CB_N= OTIFY4res *value); + #endif /* _LINUX_XDRGEN_NFS4_1_DECL_H */ diff --git a/fs/nfsd/trace.h b/fs/nfsd/trace.h index 3c5505ef5e3a38d805a48ea4e190063b5341684d..0c68df50eae248c7c9afe0437df= cf29837e09275 100644 --- a/fs/nfsd/trace.h +++ b/fs/nfsd/trace.h @@ -1615,6 +1615,7 @@ TRACE_EVENT(nfsd_cb_setup_err, { OP_CB_RECALL, "CB_RECALL" }, \ { OP_CB_LAYOUTRECALL, "CB_LAYOUTRECALL" }, \ { OP_CB_RECALL_ANY, "CB_RECALL_ANY" }, \ + { OP_CB_NOTIFY, "CB_NOTIFY" }, \ { OP_CB_NOTIFY_LOCK, "CB_NOTIFY_LOCK" }, \ { OP_CB_OFFLOAD, "CB_OFFLOAD" }) =20 diff --git a/include/linux/nfs4.h b/include/linux/nfs4.h index d8cad844870aa74ce1e0cc78c499fb001d898c93..5e86622259ae75dc199cd54bcdd= c669d3cda1a99 100644 --- a/include/linux/nfs4.h +++ b/include/linux/nfs4.h @@ -170,133 +170,6 @@ Needs to be updated if more operations are defined in= future.*/ #define LAST_NFS42_OP OP_REMOVEXATTR #define LAST_NFS4_OP LAST_NFS42_OP =20 -enum nfsstat4 { - NFS4_OK =3D 0, - NFS4ERR_PERM =3D 1, - NFS4ERR_NOENT =3D 2, - NFS4ERR_IO =3D 5, - NFS4ERR_NXIO =3D 6, - NFS4ERR_ACCESS =3D 13, - NFS4ERR_EXIST =3D 17, - NFS4ERR_XDEV =3D 18, - /* Unused/reserved 19 */ - NFS4ERR_NOTDIR =3D 20, - NFS4ERR_ISDIR =3D 21, - NFS4ERR_INVAL =3D 22, - NFS4ERR_FBIG =3D 27, - NFS4ERR_NOSPC =3D 28, - NFS4ERR_ROFS =3D 30, - NFS4ERR_MLINK =3D 31, - NFS4ERR_NAMETOOLONG =3D 63, - NFS4ERR_NOTEMPTY =3D 66, - NFS4ERR_DQUOT =3D 69, - NFS4ERR_STALE =3D 70, - NFS4ERR_BADHANDLE =3D 10001, - NFS4ERR_BAD_COOKIE =3D 10003, - NFS4ERR_NOTSUPP =3D 10004, - NFS4ERR_TOOSMALL =3D 10005, - NFS4ERR_SERVERFAULT =3D 10006, - NFS4ERR_BADTYPE =3D 10007, - NFS4ERR_DELAY =3D 10008, - NFS4ERR_SAME =3D 10009, - NFS4ERR_DENIED =3D 10010, - NFS4ERR_EXPIRED =3D 10011, - NFS4ERR_LOCKED =3D 10012, - NFS4ERR_GRACE =3D 10013, - NFS4ERR_FHEXPIRED =3D 10014, - NFS4ERR_SHARE_DENIED =3D 10015, - NFS4ERR_WRONGSEC =3D 10016, - NFS4ERR_CLID_INUSE =3D 10017, - NFS4ERR_RESOURCE =3D 10018, - NFS4ERR_MOVED =3D 10019, - NFS4ERR_NOFILEHANDLE =3D 10020, - NFS4ERR_MINOR_VERS_MISMATCH =3D 10021, - NFS4ERR_STALE_CLIENTID =3D 10022, - NFS4ERR_STALE_STATEID =3D 10023, - NFS4ERR_OLD_STATEID =3D 10024, - NFS4ERR_BAD_STATEID =3D 10025, - NFS4ERR_BAD_SEQID =3D 10026, - NFS4ERR_NOT_SAME =3D 10027, - NFS4ERR_LOCK_RANGE =3D 10028, - NFS4ERR_SYMLINK =3D 10029, - NFS4ERR_RESTOREFH =3D 10030, - NFS4ERR_LEASE_MOVED =3D 10031, - NFS4ERR_ATTRNOTSUPP =3D 10032, - NFS4ERR_NO_GRACE =3D 10033, - NFS4ERR_RECLAIM_BAD =3D 10034, - NFS4ERR_RECLAIM_CONFLICT =3D 10035, - NFS4ERR_BADXDR =3D 10036, - NFS4ERR_LOCKS_HELD =3D 10037, - NFS4ERR_OPENMODE =3D 10038, - NFS4ERR_BADOWNER =3D 10039, - NFS4ERR_BADCHAR =3D 10040, - NFS4ERR_BADNAME =3D 10041, - NFS4ERR_BAD_RANGE =3D 10042, - NFS4ERR_LOCK_NOTSUPP =3D 10043, - NFS4ERR_OP_ILLEGAL =3D 10044, - NFS4ERR_DEADLOCK =3D 10045, - NFS4ERR_FILE_OPEN =3D 10046, - NFS4ERR_ADMIN_REVOKED =3D 10047, - NFS4ERR_CB_PATH_DOWN =3D 10048, - - /* nfs41 */ - NFS4ERR_BADIOMODE =3D 10049, - NFS4ERR_BADLAYOUT =3D 10050, - NFS4ERR_BAD_SESSION_DIGEST =3D 10051, - NFS4ERR_BADSESSION =3D 10052, - NFS4ERR_BADSLOT =3D 10053, - NFS4ERR_COMPLETE_ALREADY =3D 10054, - NFS4ERR_CONN_NOT_BOUND_TO_SESSION =3D 10055, - NFS4ERR_DELEG_ALREADY_WANTED =3D 10056, - NFS4ERR_BACK_CHAN_BUSY =3D 10057, /* backchan reqs outstanding */ - NFS4ERR_LAYOUTTRYLATER =3D 10058, - NFS4ERR_LAYOUTUNAVAILABLE =3D 10059, - NFS4ERR_NOMATCHING_LAYOUT =3D 10060, - NFS4ERR_RECALLCONFLICT =3D 10061, - NFS4ERR_UNKNOWN_LAYOUTTYPE =3D 10062, - NFS4ERR_SEQ_MISORDERED =3D 10063, /* unexpected seq.id in req */ - NFS4ERR_SEQUENCE_POS =3D 10064, /* [CB_]SEQ. op not 1st op */ - NFS4ERR_REQ_TOO_BIG =3D 10065, /* request too big */ - NFS4ERR_REP_TOO_BIG =3D 10066, /* reply too big */ - NFS4ERR_REP_TOO_BIG_TO_CACHE =3D 10067, /* rep. not all cached */ - NFS4ERR_RETRY_UNCACHED_REP =3D 10068, /* retry & rep. uncached */ - NFS4ERR_UNSAFE_COMPOUND =3D 10069, /* retry/recovery too hard */ - NFS4ERR_TOO_MANY_OPS =3D 10070, /* too many ops in [CB_]COMP */ - NFS4ERR_OP_NOT_IN_SESSION =3D 10071, /* op needs [CB_]SEQ. op */ - NFS4ERR_HASH_ALG_UNSUPP =3D 10072, /* hash alg. not supp. */ - /* Error 10073 is unused. */ - NFS4ERR_CLIENTID_BUSY =3D 10074, /* clientid has state */ - NFS4ERR_PNFS_IO_HOLE =3D 10075, /* IO to _SPARSE file hole */ - NFS4ERR_SEQ_FALSE_RETRY =3D 10076, /* retry not original */ - NFS4ERR_BAD_HIGH_SLOT =3D 10077, /* sequence arg bad */ - NFS4ERR_DEADSESSION =3D 10078, /* persistent session dead */ - NFS4ERR_ENCR_ALG_UNSUPP =3D 10079, /* SSV alg mismatch */ - NFS4ERR_PNFS_NO_LAYOUT =3D 10080, /* direct I/O with no layout */ - NFS4ERR_NOT_ONLY_OP =3D 10081, /* bad compound */ - NFS4ERR_WRONG_CRED =3D 10082, /* permissions:state change */ - NFS4ERR_WRONG_TYPE =3D 10083, /* current operation mismatch */ - NFS4ERR_DIRDELEG_UNAVAIL =3D 10084, /* no directory delegation */ - NFS4ERR_REJECT_DELEG =3D 10085, /* on callback */ - NFS4ERR_RETURNCONFLICT =3D 10086, /* outstanding layoutreturn */ - NFS4ERR_DELEG_REVOKED =3D 10087, /* deleg./layout revoked */ - - /* nfs42 */ - NFS4ERR_PARTNER_NOTSUPP =3D 10088, - NFS4ERR_PARTNER_NO_AUTH =3D 10089, - NFS4ERR_UNION_NOTSUPP =3D 10090, - NFS4ERR_OFFLOAD_DENIED =3D 10091, - NFS4ERR_WRONG_LFS =3D 10092, - NFS4ERR_BADLABEL =3D 10093, - NFS4ERR_OFFLOAD_NO_REQS =3D 10094, - - /* xattr (RFC8276) */ - NFS4ERR_NOXATTR =3D 10095, - NFS4ERR_XATTR2BIG =3D 10096, - - /* can be used for internal errors */ - NFS4ERR_FIRST_FREE -}; - /* error codes for internal client use */ #define NFS4ERR_RESET_TO_MDS 12001 #define NFS4ERR_RESET_TO_PNFS 12002 diff --git a/include/linux/sunrpc/xdrgen/nfs4_1.h b/include/linux/sunrpc/xd= rgen/nfs4_1.h index cf21a14aa8850f4b21cd365cb7bc22a02c6097ce..e7bd95e3e19c8b4b8c69119457e= ac9abc486b0bd 100644 --- a/include/linux/sunrpc/xdrgen/nfs4_1.h +++ b/include/linux/sunrpc/xdrgen/nfs4_1.h @@ -1,7 +1,7 @@ /* SPDX-License-Identifier: GPL-2.0 */ /* Generated by xdrgen. Manual edits will be lost. */ /* XDR specification file: ../../Documentation/sunrpc/xdr/nfs4_1.x */ -/* XDR specification modification time: Mon Oct 14 09:10:13 2024 */ +/* XDR specification modification time: Fri Nov 1 12:17:17 2024 */ =20 #ifndef _LINUX_XDRGEN_NFS4_1_DEF_H #define _LINUX_XDRGEN_NFS4_1_DEF_H @@ -9,20 +9,181 @@ #include #include =20 -typedef s64 int64_t; +typedef s32 int32_t; =20 typedef u32 uint32_t; =20 +typedef s64 int64_t; + +typedef u64 uint64_t; + +enum { NFS4_VERIFIER_SIZE =3D 8 }; + +enum { NFS4_FHSIZE =3D 128 }; + +enum nfsstat4 { + NFS4_OK =3D 0, + NFS4ERR_PERM =3D 1, + NFS4ERR_NOENT =3D 2, + NFS4ERR_IO =3D 5, + NFS4ERR_NXIO =3D 6, + NFS4ERR_ACCESS =3D 13, + NFS4ERR_EXIST =3D 17, + NFS4ERR_XDEV =3D 18, + NFS4ERR_NOTDIR =3D 20, + NFS4ERR_ISDIR =3D 21, + NFS4ERR_INVAL =3D 22, + NFS4ERR_FBIG =3D 27, + NFS4ERR_NOSPC =3D 28, + NFS4ERR_ROFS =3D 30, + NFS4ERR_MLINK =3D 31, + NFS4ERR_NAMETOOLONG =3D 63, + NFS4ERR_NOTEMPTY =3D 66, + NFS4ERR_DQUOT =3D 69, + NFS4ERR_STALE =3D 70, + NFS4ERR_BADHANDLE =3D 10001, + NFS4ERR_BAD_COOKIE =3D 10003, + NFS4ERR_NOTSUPP =3D 10004, + NFS4ERR_TOOSMALL =3D 10005, + NFS4ERR_SERVERFAULT =3D 10006, + NFS4ERR_BADTYPE =3D 10007, + NFS4ERR_DELAY =3D 10008, + NFS4ERR_SAME =3D 10009, + NFS4ERR_DENIED =3D 10010, + NFS4ERR_EXPIRED =3D 10011, + NFS4ERR_LOCKED =3D 10012, + NFS4ERR_GRACE =3D 10013, + NFS4ERR_FHEXPIRED =3D 10014, + NFS4ERR_SHARE_DENIED =3D 10015, + NFS4ERR_WRONGSEC =3D 10016, + NFS4ERR_CLID_INUSE =3D 10017, + NFS4ERR_RESOURCE =3D 10018, + NFS4ERR_MOVED =3D 10019, + NFS4ERR_NOFILEHANDLE =3D 10020, + NFS4ERR_MINOR_VERS_MISMATCH =3D 10021, + NFS4ERR_STALE_CLIENTID =3D 10022, + NFS4ERR_STALE_STATEID =3D 10023, + NFS4ERR_OLD_STATEID =3D 10024, + NFS4ERR_BAD_STATEID =3D 10025, + NFS4ERR_BAD_SEQID =3D 10026, + NFS4ERR_NOT_SAME =3D 10027, + NFS4ERR_LOCK_RANGE =3D 10028, + NFS4ERR_SYMLINK =3D 10029, + NFS4ERR_RESTOREFH =3D 10030, + NFS4ERR_LEASE_MOVED =3D 10031, + NFS4ERR_ATTRNOTSUPP =3D 10032, + NFS4ERR_NO_GRACE =3D 10033, + NFS4ERR_RECLAIM_BAD =3D 10034, + NFS4ERR_RECLAIM_CONFLICT =3D 10035, + NFS4ERR_BADXDR =3D 10036, + NFS4ERR_LOCKS_HELD =3D 10037, + NFS4ERR_OPENMODE =3D 10038, + NFS4ERR_BADOWNER =3D 10039, + NFS4ERR_BADCHAR =3D 10040, + NFS4ERR_BADNAME =3D 10041, + NFS4ERR_BAD_RANGE =3D 10042, + NFS4ERR_LOCK_NOTSUPP =3D 10043, + NFS4ERR_OP_ILLEGAL =3D 10044, + NFS4ERR_DEADLOCK =3D 10045, + NFS4ERR_FILE_OPEN =3D 10046, + NFS4ERR_ADMIN_REVOKED =3D 10047, + NFS4ERR_CB_PATH_DOWN =3D 10048, + NFS4ERR_BADIOMODE =3D 10049, + NFS4ERR_BADLAYOUT =3D 10050, + NFS4ERR_BAD_SESSION_DIGEST =3D 10051, + NFS4ERR_BADSESSION =3D 10052, + NFS4ERR_BADSLOT =3D 10053, + NFS4ERR_COMPLETE_ALREADY =3D 10054, + NFS4ERR_CONN_NOT_BOUND_TO_SESSION =3D 10055, + NFS4ERR_DELEG_ALREADY_WANTED =3D 10056, + NFS4ERR_BACK_CHAN_BUSY =3D 10057, + NFS4ERR_LAYOUTTRYLATER =3D 10058, + NFS4ERR_LAYOUTUNAVAILABLE =3D 10059, + NFS4ERR_NOMATCHING_LAYOUT =3D 10060, + NFS4ERR_RECALLCONFLICT =3D 10061, + NFS4ERR_UNKNOWN_LAYOUTTYPE =3D 10062, + NFS4ERR_SEQ_MISORDERED =3D 10063, + NFS4ERR_SEQUENCE_POS =3D 10064, + NFS4ERR_REQ_TOO_BIG =3D 10065, + NFS4ERR_REP_TOO_BIG =3D 10066, + NFS4ERR_REP_TOO_BIG_TO_CACHE =3D 10067, + NFS4ERR_RETRY_UNCACHED_REP =3D 10068, + NFS4ERR_UNSAFE_COMPOUND =3D 10069, + NFS4ERR_TOO_MANY_OPS =3D 10070, + NFS4ERR_OP_NOT_IN_SESSION =3D 10071, + NFS4ERR_HASH_ALG_UNSUPP =3D 10072, + NFS4ERR_CLIENTID_BUSY =3D 10074, + NFS4ERR_PNFS_IO_HOLE =3D 10075, + NFS4ERR_SEQ_FALSE_RETRY =3D 10076, + NFS4ERR_BAD_HIGH_SLOT =3D 10077, + NFS4ERR_DEADSESSION =3D 10078, + NFS4ERR_ENCR_ALG_UNSUPP =3D 10079, + NFS4ERR_PNFS_NO_LAYOUT =3D 10080, + NFS4ERR_NOT_ONLY_OP =3D 10081, + NFS4ERR_WRONG_CRED =3D 10082, + NFS4ERR_WRONG_TYPE =3D 10083, + NFS4ERR_DIRDELEG_UNAVAIL =3D 10084, + NFS4ERR_REJECT_DELEG =3D 10085, + NFS4ERR_RETURNCONFLICT =3D 10086, + NFS4ERR_DELEG_REVOKED =3D 10087, + NFS4ERR_PARTNER_NOTSUPP =3D 10088, + NFS4ERR_PARTNER_NO_AUTH =3D 10089, + NFS4ERR_UNION_NOTSUPP =3D 10090, + NFS4ERR_OFFLOAD_DENIED =3D 10091, + NFS4ERR_WRONG_LFS =3D 10092, + NFS4ERR_BADLABEL =3D 10093, + NFS4ERR_OFFLOAD_NO_REQS =3D 10094, + NFS4ERR_NOXATTR =3D 10095, + NFS4ERR_XATTR2BIG =3D 10096, + NFS4ERR_FIRST_FREE =3D 10097, +}; +typedef enum nfsstat4 nfsstat4; + +typedef opaque attrlist4; + typedef struct { u32 count; uint32_t *element; } bitmap4; =20 +typedef uint64_t nfs_cookie4; + +typedef opaque nfs_fh4; + +typedef opaque utf8string; + +typedef utf8string utf8str_cis; + +typedef utf8string utf8str_cs; + +typedef utf8string utf8str_mixed; + +typedef utf8str_cs component4; + +typedef utf8str_cs linktext4; + +typedef struct { + u32 count; + component4 *element; +} pathname4; + +typedef u8 verifier4[NFS4_VERIFIER_SIZE]; + struct nfstime4 { int64_t seconds; uint32_t nseconds; }; =20 +struct fattr4 { + bitmap4 attrmask; + attrlist4 attr_vals; +}; + +struct stateid4 { + uint32_t seqid; + u8 other[12]; +}; + typedef bool fattr4_offline; =20 enum { FATTR4_OFFLINE =3D 83 }; @@ -126,13 +287,115 @@ enum open_delegation_type4 { }; typedef enum open_delegation_type4 open_delegation_type4; =20 -#define NFS4_int64_t_sz \ - (XDR_hyper) +enum notify_type4 { + NOTIFY4_CHANGE_CHILD_ATTRS =3D 0, + NOTIFY4_CHANGE_DIR_ATTRS =3D 1, + NOTIFY4_REMOVE_ENTRY =3D 2, + NOTIFY4_ADD_ENTRY =3D 3, + NOTIFY4_RENAME_ENTRY =3D 4, + NOTIFY4_CHANGE_COOKIE_VERIFIER =3D 5, +}; +typedef enum notify_type4 notify_type4; + +struct notify_entry4 { + component4 ne_file; + struct fattr4 ne_attrs; +}; + +struct prev_entry4 { + struct notify_entry4 pe_prev_entry; + nfs_cookie4 pe_prev_entry_cookie; +}; + +struct notify_remove4 { + struct notify_entry4 nrm_old_entry; + nfs_cookie4 nrm_old_entry_cookie; +}; + +struct notify_add4 { + struct { + u32 count; + struct notify_remove4 *element; + } nad_old_entry; + struct notify_entry4 nad_new_entry; + struct { + u32 count; + nfs_cookie4 *element; + } nad_new_entry_cookie; + struct { + u32 count; + struct prev_entry4 *element; + } nad_prev_entry; + bool nad_last_entry; +}; + +struct notify_attr4 { + struct notify_entry4 na_changed_entry; +}; + +struct notify_rename4 { + struct notify_remove4 nrn_old_entry; + struct notify_add4 nrn_new_entry; +}; + +struct notify_verifier4 { + verifier4 nv_old_cookieverf; + verifier4 nv_new_cookieverf; +}; + +typedef opaque notifylist4; + +struct notify4 { + bitmap4 notify_mask; + notifylist4 notify_vals; +}; + +struct CB_NOTIFY4args { + struct stateid4 cna_stateid; + nfs_fh4 cna_fh; + struct { + u32 count; + struct notify4 *element; + } cna_changes; +}; + +struct CB_NOTIFY4res { + nfsstat4 cnr_status; +}; + +#define NFS4_int32_t_sz \ + (XDR_int) #define NFS4_uint32_t_sz \ (XDR_unsigned_int) +#define NFS4_int64_t_sz \ + (XDR_hyper) +#define NFS4_uint64_t_sz \ + (XDR_unsigned_hyper) +#define NFS4_nfsstat4_sz (XDR_int) +#define NFS4_attrlist4_sz (XDR_unsigned_int) #define NFS4_bitmap4_sz (XDR_unsigned_int) +#define NFS4_nfs_cookie4_sz \ + (NFS4_uint64_t_sz) +#define NFS4_nfs_fh4_sz (XDR_unsigned_int + XDR_QUADLEN(NF= S4_FHSIZE)) +#define NFS4_utf8string_sz (XDR_unsigned_int) +#define NFS4_utf8str_cis_sz \ + (NFS4_utf8string_sz) +#define NFS4_utf8str_cs_sz \ + (NFS4_utf8string_sz) +#define NFS4_utf8str_mixed_sz \ + (NFS4_utf8string_sz) +#define NFS4_component4_sz \ + (NFS4_utf8str_cs_sz) +#define NFS4_linktext4_sz \ + (NFS4_utf8str_cs_sz) +#define NFS4_pathname4_sz (XDR_unsigned_int) +#define NFS4_verifier4_sz (XDR_QUADLEN(NFS4_VERIFIER_SIZE)) #define NFS4_nfstime4_sz \ (NFS4_int64_t_sz + NFS4_uint32_t_sz) +#define NFS4_fattr4_sz \ + (NFS4_bitmap4_sz + NFS4_attrlist4_sz) +#define NFS4_stateid4_sz \ + (NFS4_uint32_t_sz + XDR_QUADLEN(12)) #define NFS4_fattr4_offline_sz \ (XDR_bool) #define NFS4_open_arguments4_sz \ @@ -149,5 +412,27 @@ typedef enum open_delegation_type4 open_delegation_typ= e4; #define NFS4_fattr4_time_deleg_modify_sz \ (NFS4_nfstime4_sz) #define NFS4_open_delegation_type4_sz (XDR_int) +#define NFS4_notify_type4_sz (XDR_int) +#define NFS4_notify_entry4_sz \ + (NFS4_component4_sz + NFS4_fattr4_sz) +#define NFS4_prev_entry4_sz \ + (NFS4_notify_entry4_sz + NFS4_nfs_cookie4_sz) +#define NFS4_notify_remove4_sz \ + (NFS4_notify_entry4_sz + NFS4_nfs_cookie4_sz) +#define NFS4_notify_add4_sz \ + (XDR_unsigned_int + (1 * (NFS4_notify_remove4_sz)) + NFS4_notify_entry4_s= z + XDR_unsigned_int + (1 * (NFS4_nfs_cookie4_sz)) + XDR_unsigned_int + (1 = * (NFS4_prev_entry4_sz)) + XDR_bool) +#define NFS4_notify_attr4_sz \ + (NFS4_notify_entry4_sz) +#define NFS4_notify_rename4_sz \ + (NFS4_notify_remove4_sz + NFS4_notify_add4_sz) +#define NFS4_notify_verifier4_sz \ + (NFS4_verifier4_sz + NFS4_verifier4_sz) +#define NFS4_notifylist4_sz (XDR_unsigned_int) +#define NFS4_notify4_sz \ + (NFS4_bitmap4_sz + NFS4_notifylist4_sz) +#define NFS4_CB_NOTIFY4args_sz \ + (NFS4_stateid4_sz + NFS4_nfs_fh4_sz + XDR_unsigned_int) +#define NFS4_CB_NOTIFY4res_sz \ + (NFS4_nfsstat4_sz) =20 #endif /* _LINUX_XDRGEN_NFS4_1_DEF_H */ diff --git a/include/uapi/linux/nfs4.h b/include/uapi/linux/nfs4.h index 4273e0249fcbb54996f5642f9920826b9d68b7b9..289205b53a0858e589380c69ad1= ba0cfd5f825fd 100644 --- a/include/uapi/linux/nfs4.h +++ b/include/uapi/linux/nfs4.h @@ -17,11 +17,9 @@ #include =20 #define NFS4_BITMAP_SIZE 3 -#define NFS4_VERIFIER_SIZE 8 #define NFS4_STATEID_SEQID_SIZE 4 #define NFS4_STATEID_OTHER_SIZE 12 #define NFS4_STATEID_SIZE (NFS4_STATEID_SEQID_SIZE + NFS4_STATEID_OTHER_SI= ZE) -#define NFS4_FHSIZE 128 #define NFS4_MAXPATHLEN PATH_MAX #define NFS4_MAXNAMLEN NAME_MAX #define NFS4_OPAQUE_LIMIT 1024 --=20 2.49.0 From nobody Thu Dec 18 14:10:55 2025 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 E5C712367B5; Mon, 2 Jun 2025 14:03:02 +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=1748872983; cv=none; b=GFWl6g7CbdjfnGYuB0h0CIFpmliWzCziVnkXptvGYX+SE6c8Y/o9MzPUke7iNFXlTdyIYIUOPK3oDpxw/LAMJM4gTDtGf6AgoVIL3Uw/Vjp4zECTyG9m2dsherFDSSYOm3YSid/Xfuyo0LFcNLCRfKB8DbWnIsfoXG/BOxRKkw0= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1748872983; c=relaxed/simple; bh=IAW2Swc9Ux+I09E48UJb8JVeRwV4qhwM+6f680yjtME=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=HU1mdlwQaHSd3rDjSPM5YVZV2c1TUbby+CG0ef0ZJWVIDgcEw9JNox2TCwCK8Nm0f02H7KAKlze6zvTUsKBE3x9TScW8iqkxyudx+y9LfoqJDmr+qswdBfhA2g83BUZVvcTN43Gj4RGiRhkTjeWav5F9b7VekrqT3dsAy95ylxM= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=BryyJgNZ; 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="BryyJgNZ" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 8A468C4CEF2; Mon, 2 Jun 2025 14:03:00 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1748872982; bh=IAW2Swc9Ux+I09E48UJb8JVeRwV4qhwM+6f680yjtME=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=BryyJgNZ1UZbsSntnRWoUVEnXvdMmr8uY7iftCpCO/kSTVlr0CwCZe3EHCfILhtjC 8VPkNmul+UxQ3E9vckSFkmMUxkKBJ00puZr/Fe5ABj9whwVysJN9cUQysDWQ7qHGIM NA4/ci/4UZ+rb2l9sXDTwwlkQz8fsyonOzUj+oW074/bpf5eSOycy/lXsOXCCpMSkH ktRNrmqz93cLE1GyYuvKfKxFbTeA8ZrXlFJ4VXzCgVldZL69gRX7YCeoY7P7P06X9z OsLpKWLrQc+B//GANsA+sx+NYbnIBPTkj+4dO4cj+hQrRQs4vKdZkHZ3HmZw2AURQ1 OCi/FbaHSBQkA== From: Jeff Layton Date: Mon, 02 Jun 2025 10:02:02 -0400 Subject: [PATCH RFC v2 19/28] nfsd: add callback encoding and decoding linkages for CB_NOTIFY Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20250602-dir-deleg-v2-19-a7919700de86@kernel.org> References: <20250602-dir-deleg-v2-0-a7919700de86@kernel.org> In-Reply-To: <20250602-dir-deleg-v2-0-a7919700de86@kernel.org> To: Alexander Viro , Christian Brauner , Jan Kara , Chuck Lever , Alexander Aring , Trond Myklebust , Anna Schumaker , Steve French , Paulo Alcantara , Ronnie Sahlberg , Shyam Prasad N , Tom Talpey , Bharath SM , NeilBrown , Olga Kornievskaia , Dai Ngo , Jonathan Corbet , Amir Goldstein , Miklos Szeredi Cc: linux-fsdevel@vger.kernel.org, linux-kernel@vger.kernel.org, linux-nfs@vger.kernel.org, linux-cifs@vger.kernel.org, samba-technical@lists.samba.org, linux-doc@vger.kernel.org, Jeff Layton X-Mailer: b4 0.14.2 X-Developer-Signature: v=1; a=openpgp-sha256; l=3669; i=jlayton@kernel.org; h=from:subject:message-id; bh=IAW2Swc9Ux+I09E48UJb8JVeRwV4qhwM+6f680yjtME=; b=owEBbQKS/ZANAwAKAQAOaEEZVoIVAcsmYgBoPa7o/C4u2CzxSt45gwy2PBAYNdBgyeACaOv0y IHMrgVKNbGJAjMEAAEKAB0WIQRLwNeyRHGyoYTq9dMADmhBGVaCFQUCaD2u6AAKCRAADmhBGVaC FQxTEACkJl9eXB8VhcZVobO4W5PtDfxBWSV3CmwRjCiCIQQO4640dXqNIkwMCZdfuUsRP602Gtu Tl8tF/N50AcDrGQTUORowh02HnTal+NEmD2ZJwtaSdBlNdF6C8ZMSprQM6mXSlfJHgvIpJ8sB7B ar1yKdvZH1ktD5mxH7u1oMHZr0gRYPl7Mj7US0zqerNa8xZHPZ80wOKeQGquDAT7oKMRMIBMNxA kQL3cM/QF3/Hse2g2VuJLb7CzvRPnLa8gIPma1q2Ysm7uXn06dSalm/hbwm94X/wI7EXJxq7Nqi GdEEC6gzkHAlAhEbQlia0USmOUSQVXsvblja8ueejmlWPLuM7BiW9wXBubRKzwj8fQGv6tP7GOR g02rGndFtFvyfds+PFw8/oPrnOc+IG0h8Xe9nNFVSTpaQk2X9yDANVL7JDM/tcctDKcD7HA4l0l jP0gxDZaXjmklxtsGqi7otJPKmP18PyMyF6tSuu3OqXI4mxrNN4MibKvJoagECmOlB5L+jCZaRP xLbvlLCqM8THZts+B7NA12XuD9NBncmutbNhozwPIfWtLUQaZtSsWlZYr0Tfl0wNzjYX3LqJex7 8y5rvALskO5xUdsgC44qAawTCK6j4+zlZI8BgmoBf7ITdIkB7l13oXVHH6/JItNyOApMiWAxmsu eWXI20xi5FJ2JLg== X-Developer-Key: i=jlayton@kernel.org; a=openpgp; fpr=4BC0D7B24471B2A184EAF5D3000E684119568215 Add routines for encoding and decoding CB_NOTIFY messages. These call into the code generated by xdrgen to do the actual encoding and decoding. Signed-off-by: Jeff Layton --- fs/nfsd/nfs4callback.c | 46 ++++++++++++++++++++++++++++++++++++++++++++++ fs/nfsd/state.h | 1 + fs/nfsd/xdr4cb.h | 11 +++++++++++ 3 files changed, 58 insertions(+) diff --git a/fs/nfsd/nfs4callback.c b/fs/nfsd/nfs4callback.c index e00b2aea8da2b93f366d88888f404734953f1942..2dca686d67fc0f0fcf7997a252b= 4f5988b9de6c7 100644 --- a/fs/nfsd/nfs4callback.c +++ b/fs/nfsd/nfs4callback.c @@ -865,6 +865,51 @@ static void encode_stateowner(struct xdr_stream *xdr, = struct nfs4_stateowner *so xdr_encode_opaque(p, so->so_owner.data, so->so_owner.len); } =20 +static void nfs4_xdr_enc_cb_notify(struct rpc_rqst *req, + struct xdr_stream *xdr, + const void *data) +{ + const struct nfsd4_callback *cb =3D data; + struct nfs4_cb_compound_hdr hdr =3D { + .ident =3D 0, + .minorversion =3D cb->cb_clp->cl_minorversion, + }; + struct CB_NOTIFY4args args =3D { }; + + WARN_ON_ONCE(hdr.minorversion =3D=3D 0); + + encode_cb_compound4args(xdr, &hdr); + encode_cb_sequence4args(xdr, cb, &hdr); + + /* + * FIXME: get stateid and fh from delegation. Inline the cna_changes + * buffer, and zero it. + */ + WARN_ON_ONCE(!xdrgen_encode_CB_NOTIFY4args(xdr, &args)); + + hdr.nops++; + encode_cb_nops(&hdr); +} + +static int nfs4_xdr_dec_cb_notify(struct rpc_rqst *rqstp, + struct xdr_stream *xdr, + void *data) +{ + struct nfsd4_callback *cb =3D data; + struct nfs4_cb_compound_hdr hdr; + int status; + + status =3D decode_cb_compound4res(xdr, &hdr); + if (unlikely(status)) + return status; + + status =3D decode_cb_sequence4res(xdr, cb); + if (unlikely(status || cb->cb_seq_status)) + return status; + + return decode_cb_op_status(xdr, OP_CB_NOTIFY, &cb->cb_status); +} + static void nfs4_xdr_enc_cb_notify_lock(struct rpc_rqst *req, struct xdr_stream *xdr, const void *data) @@ -1026,6 +1071,7 @@ static const struct rpc_procinfo nfs4_cb_procedures[]= =3D { #ifdef CONFIG_NFSD_PNFS PROC(CB_LAYOUT, COMPOUND, cb_layout, cb_layout), #endif + PROC(CB_NOTIFY, COMPOUND, cb_notify, cb_notify), PROC(CB_NOTIFY_LOCK, COMPOUND, cb_notify_lock, cb_notify_lock), PROC(CB_OFFLOAD, COMPOUND, cb_offload, cb_offload), PROC(CB_RECALL_ANY, COMPOUND, cb_recall_any, cb_recall_any), diff --git a/fs/nfsd/state.h b/fs/nfsd/state.h index 0eeecd824770c4df8e1cc29fc738e568d91d5e5f..5f21c79be032cc1334a301aad73= e6bbcc8da5eb0 100644 --- a/fs/nfsd/state.h +++ b/fs/nfsd/state.h @@ -743,6 +743,7 @@ enum nfsd4_cb_op { NFSPROC4_CLNT_CB_NOTIFY_LOCK, NFSPROC4_CLNT_CB_RECALL_ANY, NFSPROC4_CLNT_CB_GETATTR, + NFSPROC4_CLNT_CB_NOTIFY, }; =20 /* Returns true iff a is later than b: */ diff --git a/fs/nfsd/xdr4cb.h b/fs/nfsd/xdr4cb.h index f4e29c0c701c9b04c44dadc752e847dc4da163d6..100f726ed92730ba953ae217b47= be0bd7aefd4e5 100644 --- a/fs/nfsd/xdr4cb.h +++ b/fs/nfsd/xdr4cb.h @@ -33,6 +33,17 @@ cb_sequence_dec_sz + \ op_dec_sz) =20 +#define NFS4_enc_cb_notify_sz (cb_compound_enc_hdr_sz + \ + cb_sequence_enc_sz + \ + 1 + enc_stateid_sz + \ + enc_nfs4_fh_sz + \ + 1) + /* followed by an array of notify4's in pages */ + +#define NFS4_dec_cb_notify_sz (cb_compound_dec_hdr_sz + \ + cb_sequence_dec_sz + \ + op_dec_sz) + #define NFS4_enc_cb_notify_lock_sz (cb_compound_enc_hdr_sz + \ cb_sequence_enc_sz + \ 2 + 1 + \ --=20 2.49.0 From nobody Thu Dec 18 14:10:55 2025 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 0A50B237717; Mon, 2 Jun 2025 14:03:04 +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=1748872986; cv=none; b=jU30tVfzNooZp2aLrRqQolR7mPpJpCo4em7/qVMN7CjdY11U+IA0Chrn9ZhlcVE6pBMIHzN+hmC2JU4jnfjkc4f52zx8kKviwp2nhVI8RoJ5KSJZxmYdylp3BQN6cmAKDt5WhobR/oUlJrLLGScWSZ4JL94xV6oC1DGyhck2dQM= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1748872986; c=relaxed/simple; bh=cgNaQOGbQUuNTbDBhZE4Xhl8ZE+uZe9DaW6C0He81Zs=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=jEi7igU5YrDUQTpgX/l/15eqnCvJ+jtFggvBsj8M5+jEBSQmhGc8Z6IjY2sOGKscVd7f8KzkXrsUBxmojDllLknb8wXAhw7OyhQcivk9Pyp8y9OwszRGX/uYG/1AiSrK/etopQ4MIY0Gbktw+HGj/6T35rKJMrZZWIW3X/c+Qgw= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=Eb9f9a9r; 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="Eb9f9a9r" Received: by smtp.kernel.org (Postfix) with ESMTPSA id A8F16C4CEF3; Mon, 2 Jun 2025 14:03:02 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1748872984; bh=cgNaQOGbQUuNTbDBhZE4Xhl8ZE+uZe9DaW6C0He81Zs=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=Eb9f9a9robfK75PtoOQpFCkn82rlKRabrkNZFeDaPWA0LYRrui4JKCo8CbRZkLCk6 zBPUMerp/giGE4g7ta0BNUGuLnp1atMKlFh+WFSDR7el0ZeuSFKAMY6R6h41sV/ux1 PnOY/GDZW5Momms2CG/QwdbIjQEo6AyKUjsNBIeCJHSUKQI8kBQMyOrwWlKo8ZZs50 FZFviFfpAFz9c1euHwI/hI1KTiHm6h8T2xbbKXhlZ9m1SvlwfmSAS1BK1aGrWz1qpS +n5sGs0dpASAUe6KcOjzIHpyLUUw0pcu+qaAf2HT0fcQp//8uJTirtGLXK9rp+znoz hkQPrOz4+JsAg== From: Jeff Layton Date: Mon, 02 Jun 2025 10:02:03 -0400 Subject: [PATCH RFC v2 20/28] nfsd: add data structures for handling CB_NOTIFY to directory delegation Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20250602-dir-deleg-v2-20-a7919700de86@kernel.org> References: <20250602-dir-deleg-v2-0-a7919700de86@kernel.org> In-Reply-To: <20250602-dir-deleg-v2-0-a7919700de86@kernel.org> To: Alexander Viro , Christian Brauner , Jan Kara , Chuck Lever , Alexander Aring , Trond Myklebust , Anna Schumaker , Steve French , Paulo Alcantara , Ronnie Sahlberg , Shyam Prasad N , Tom Talpey , Bharath SM , NeilBrown , Olga Kornievskaia , Dai Ngo , Jonathan Corbet , Amir Goldstein , Miklos Szeredi Cc: linux-fsdevel@vger.kernel.org, linux-kernel@vger.kernel.org, linux-nfs@vger.kernel.org, linux-cifs@vger.kernel.org, samba-technical@lists.samba.org, linux-doc@vger.kernel.org, Jeff Layton X-Mailer: b4 0.14.2 X-Developer-Signature: v=1; a=openpgp-sha256; l=8261; i=jlayton@kernel.org; h=from:subject:message-id; bh=cgNaQOGbQUuNTbDBhZE4Xhl8ZE+uZe9DaW6C0He81Zs=; b=owEBbQKS/ZANAwAKAQAOaEEZVoIVAcsmYgBoPa7oXfZDf9eb2xiJM9kokQlrmhspGllCmzveP zX2IvU0BnGJAjMEAAEKAB0WIQRLwNeyRHGyoYTq9dMADmhBGVaCFQUCaD2u6AAKCRAADmhBGVaC FcarD/491grrAfE+Ggf+lUZ/apYA+svEJW6WklIyT5c1q72Czmsnk5OsJwbjZKtRbQpDO2dMISc RjbATljjOvPqWEdL+PQEnnyTZ2thGWXtSVQMy8bo+TQfgFdpRMVKH9uB5I1f9hl/J/VC5IlMkMk FbN52OrUM2KKzgizODGwTr8nCozqII77zfRjXZIeZp62zD38Odb2kzKYhW4bN5FDQRrwHm6jy8a nKLGXDTrP/urE168xkWuIFGmUtsUvsEigHezfOkrzXcaEk6cTgkoDLWddnUBqNiNu5QJzqkriLC ZLsHqS/RBJYxNl048h2w6EKlC2qcO3KP0f0tC/BDbruH+XvVzvnfr4qTC+Ng6LLTp+A1NCYlBus hzeyu4+zyf3h3oIDDzGoZpxEFQQzyjnuqCHTW6iZJiKf0KO4VdrFHZcsKR1r0w3/taZMTffD3dZ dVqX5hP2Xi/7CV7pbUEK8HE/QJ5Gu4LaLC+WflUBklCfLq2mFmzeHG+GkTHfSWk1nPHDh51BI7d Cu481fix+HfCvbQv2mGQbOB0ysiFPJaNkQ5IPOo6Gzvc7z9eBqBWAx1+Uy+JMF9Nzi9cobwUN/0 haidfId2wovFXI4zx/Kh4rdSCFem7yCMAUp3osdBEJPXRrIbDBbp7v8ozCi3KgcihYtIi6WfAaR Zu4szjZ67nVrkYw== X-Developer-Key: i=jlayton@kernel.org; a=openpgp; fpr=4BC0D7B24471B2A184EAF5D3000E684119568215 When a directory delegation is created, have it allocate the necessary data structures to collect events and run a CB_NOTIFY callback. Signed-off-by: Jeff Layton --- fs/nfsd/nfs4state.c | 143 +++++++++++++++++++++++++++++++++++++++++++++---= ---- fs/nfsd/state.h | 33 +++++++++++- 2 files changed, 157 insertions(+), 19 deletions(-) diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c index ed5d6486d171ea0c886bd1f1ea1129bf4ccf429c..ebebfd6d304627d6c82bae5b84e= a6c599d9e9474 100644 --- a/fs/nfsd/nfs4state.c +++ b/fs/nfsd/nfs4state.c @@ -130,6 +130,7 @@ static void free_session(struct nfsd4_session *); static const struct nfsd4_callback_ops nfsd4_cb_recall_ops; static const struct nfsd4_callback_ops nfsd4_cb_notify_lock_ops; static const struct nfsd4_callback_ops nfsd4_cb_getattr_ops; +static const struct nfsd4_callback_ops nfsd4_cb_notify_ops; =20 static struct workqueue_struct *laundry_wq; =20 @@ -1048,6 +1049,45 @@ static void nfs4_free_deleg(struct nfs4_stid *stid) atomic_long_dec(&num_delegations); } =20 +static struct nfsd4_notify_spool *alloc_notify_spool(void) +{ + struct nfsd4_notify_spool *spool; + + spool =3D kmalloc(sizeof(*spool), GFP_KERNEL); + if (!spool) + return NULL; + + spool->nns_page =3D alloc_page(GFP_KERNEL); + if (!spool->nns_page) { + kfree(spool); + return NULL; + } + + spool->nns_idx =3D 0; + spool->nns_xdr.buflen =3D PAGE_SIZE; + spool->nns_xdr.pages =3D &spool->nns_page; + + xdr_init_encode_pages(&spool->nns_stream, &spool->nns_xdr); + return spool; +} + +static void free_notify_spool(struct nfsd4_notify_spool *spool) +{ + if (spool) { + put_page(spool->nns_page); + kfree(spool); + } +} + +static void nfs4_free_dir_deleg(struct nfs4_stid *stid) +{ + struct nfs4_delegation *dp =3D delegstateid(stid); + + free_notify_spool(dp->dl_cb_notify.ncn_gather); + free_notify_spool(dp->dl_cb_notify.ncn_send); + nfs4_free_deleg(stid); +} + /* * When we recall a delegation, we should be careful not to hand it * out again straight away. @@ -1126,29 +1166,22 @@ static void block_delegations(struct knfsd_fh *fh) } =20 static struct nfs4_delegation * -alloc_init_deleg(struct nfs4_client *clp, struct nfs4_file *fp, - struct nfs4_clnt_odstate *odstate, u32 dl_type) +__alloc_init_deleg(struct nfs4_client *clp, struct nfs4_file *fp, + struct nfs4_clnt_odstate *odstate, u32 dl_type, + void (*sc_free)(struct nfs4_stid *)) { + struct nfs4_stid *stid =3D nfs4_alloc_stid(clp, deleg_slab, sc_free); struct nfs4_delegation *dp; - struct nfs4_stid *stid; - long n; =20 - dprintk("NFSD alloc_init_deleg\n"); - n =3D atomic_long_inc_return(&num_delegations); - if (n < 0 || n > max_delegations) - goto out_dec; - if (delegation_blocked(&fp->fi_fhandle)) - goto out_dec; - stid =3D nfs4_alloc_stid(clp, deleg_slab, nfs4_free_deleg); if (stid =3D=3D NULL) - goto out_dec; - dp =3D delegstateid(stid); + return NULL; =20 /* * delegation seqid's are never incremented. The 4.1 special * meaning of seqid 0 isn't meaningful, really, but let's avoid - * 0 anyway just for consistency and use 1: + * 0 anyway just for consistency and use 1. */ + dp =3D delegstateid(stid); dp->dl_stid.sc_stateid.si_generation =3D 1; INIT_LIST_HEAD(&dp->dl_perfile); INIT_LIST_HEAD(&dp->dl_perclnt); @@ -1158,19 +1191,65 @@ alloc_init_deleg(struct nfs4_client *clp, struct nf= s4_file *fp, dp->dl_type =3D dl_type; dp->dl_retries =3D 1; dp->dl_recalled =3D false; + get_nfs4_file(fp); + dp->dl_stid.sc_file =3D fp; nfsd4_init_cb(&dp->dl_recall, dp->dl_stid.sc_client, &nfsd4_cb_recall_ops, NFSPROC4_CLNT_CB_RECALL); + return dp; +} + +static struct nfs4_delegation * +alloc_init_deleg(struct nfs4_client *clp, struct nfs4_file *fp, + struct nfs4_clnt_odstate *odstate, u32 dl_type) +{ + struct nfs4_delegation *dp; + long n; + + dprintk("NFSD alloc_init_deleg\n"); + n =3D atomic_long_inc_return(&num_delegations); + if (n < 0 || n > max_delegations) + goto out_dec; + if (delegation_blocked(&fp->fi_fhandle)) + goto out_dec; + + dp =3D __alloc_init_deleg(clp, fp, odstate, dl_type, nfs4_free_deleg); + if (!dp) + goto out_dec; + nfsd4_init_cb(&dp->dl_cb_fattr.ncf_getattr, dp->dl_stid.sc_client, &nfsd4_cb_getattr_ops, NFSPROC4_CLNT_CB_GETATTR); dp->dl_cb_fattr.ncf_file_modified =3D false; - get_nfs4_file(fp); - dp->dl_stid.sc_file =3D fp; return dp; out_dec: atomic_long_dec(&num_delegations); return NULL; } =20 +static struct nfs4_delegation * +alloc_init_dir_deleg(struct nfs4_client *clp, struct nfs4_file *fp) +{ + struct nfs4_delegation *dp; + struct nfsd4_cb_notify *cbn; + struct nfsd4_notify_spool *ncn; + + ncn =3D alloc_notify_spool(); + if (!ncn) + return NULL; + + dp =3D __alloc_init_deleg(clp, fp, NULL, NFS4_OPEN_DELEGATE_READ, + nfs4_free_dir_deleg); + if (!dp) { + free_notify_spool(ncn); + return NULL; + } + + cbn =3D &dp->dl_cb_notify; + cbn->ncn_gather =3D ncn; + nfsd4_init_cb(&cbn->ncn_cb, dp->dl_stid.sc_client, + &nfsd4_cb_notify_ops, NFSPROC4_CLNT_CB_NOTIFY); + return dp; +} + void nfs4_put_stid(struct nfs4_stid *s) { @@ -3197,6 +3276,30 @@ nfsd4_cb_getattr_release(struct nfsd4_callback *cb) nfs4_put_stid(&dp->dl_stid); } =20 +static int +nfsd4_cb_notify_done(struct nfsd4_callback *cb, + struct rpc_task *task) +{ + switch (task->tk_status) { + case -NFS4ERR_DELAY: + rpc_delay(task, 2 * HZ); + return 0; + default: + return 1; + } +} + +static void +nfsd4_cb_notify_release(struct nfsd4_callback *cb) +{ + struct nfsd4_cb_notify *ncn =3D + container_of(cb, struct nfsd4_cb_notify, ncn_cb); + struct nfs4_delegation *dp =3D + container_of(ncn, struct nfs4_delegation, dl_cb_notify); + + nfs4_put_stid(&dp->dl_stid); +} + static const struct nfsd4_callback_ops nfsd4_cb_recall_any_ops =3D { .done =3D nfsd4_cb_recall_any_done, .release =3D nfsd4_cb_recall_any_release, @@ -3209,6 +3312,12 @@ static const struct nfsd4_callback_ops nfsd4_cb_geta= ttr_ops =3D { .opcode =3D OP_CB_GETATTR, }; =20 +static const struct nfsd4_callback_ops nfsd4_cb_notify_ops =3D { + .done =3D nfsd4_cb_notify_done, + .release =3D nfsd4_cb_notify_release, + .opcode =3D OP_CB_NOTIFY, +}; + static void nfs4_cb_getattr(struct nfs4_cb_fattr *ncf) { struct nfs4_delegation *dp =3D @@ -9350,7 +9459,7 @@ nfsd_get_dir_deleg(struct nfsd4_compound_state *cstat= e, =20 /* Try to set up the lease */ status =3D -ENOMEM; - dp =3D alloc_init_deleg(clp, fp, NULL, NFS4_OPEN_DELEGATE_READ); + dp =3D alloc_init_dir_deleg(clp, fp); if (!dp) goto out_delegees; =20 diff --git a/fs/nfsd/state.h b/fs/nfsd/state.h index 5f21c79be032cc1334a301aad73e6bbcc8da5eb0..706bbc7076a4f1d0be3ea7067d1= 93683821d74eb 100644 --- a/fs/nfsd/state.h +++ b/fs/nfsd/state.h @@ -188,6 +188,31 @@ struct nfs4_cb_fattr { u64 ncf_cur_fsize; }; =20 +#define NFSD4_NOTIFY_SPOOL_SZ 16 + +/* A place to collect notifications */ +struct nfsd4_notify_spool { + struct xdr_stream nns_stream; + struct xdr_buf nns_xdr; + struct page *nns_page; + struct notify4 nns_ent[NFSD4_NOTIFY_SPOOL_SZ]; + u32 nns_idx; +}; + +/* + * Represents a directory delegation. The callback is for handling CB_NOTI= FYs. + * As notifications from fsnotify come in, encode the relevant notify_*4 i= n the + * ncn_stream, and append a new ncn_notify_array value. + * + * Periodically, fire off a CB_NOTIFY request to the server. Replace the w= ith + * new ones and send the request. + */ +struct nfsd4_cb_notify { + struct nfsd4_callback ncn_cb; + struct nfsd4_notify_spool *ncn_gather; + struct nfsd4_notify_spool *ncn_send; +}; + /* * Represents a delegation stateid. The nfs4_client holds references to th= ese * and they are put when it is being destroyed or when the delegation is @@ -222,8 +247,12 @@ struct nfs4_delegation { struct nfsd4_callback dl_recall; bool dl_recalled; =20 - /* for CB_GETATTR */ - struct nfs4_cb_fattr dl_cb_fattr; + union { + /* for CB_GETATTR */ + struct nfs4_cb_fattr dl_cb_fattr; + /* for CB_NOTIFY */ + struct nfsd4_cb_notify dl_cb_notify; + }; }; =20 static inline bool deleg_is_read(u32 dl_type) --=20 2.49.0 From nobody Thu Dec 18 14:10:55 2025 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 D449F239567; Mon, 2 Jun 2025 14:03: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=1748872986; cv=none; b=fpXfjwbGQeavwBUjtQLHTaWrbUutsnLceGCyZ7Cz7U6hVFrDT5KdGf49pXsNO41docPFB4vvTwi6Yh+Fgf3XO/04d65Xy6Ku48TGdBxSiL0+EUcD7s3M/zG/c2lO9a5MQvLcBaJbYh233JPpmOt2x6ZtbdOKUtsagXB4nDI3bMQ= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1748872986; c=relaxed/simple; bh=x1o0Ihmm4BVt5ZC6hQAevJ2br6+2hL/MI5r9KqN/NNw=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=lZBZ/n62ibmrov/oYy0agCE+cdgicbo2bmZHAvVLpAbc0NBeFQXa+YktbdivCa3NjrO+ruz5ba8uzQ8/tqEMs/N91hd96QY66+gsk93Deir9mQEWROTEdcCmSb4MWCrWvUItyCI/yrOmt2ILyfUpFHTuuvrzry9VD15NPQynXZY= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=YsLYoqQW; 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="YsLYoqQW" Received: by smtp.kernel.org (Postfix) with ESMTPSA id C6F21C4CEEB; Mon, 2 Jun 2025 14:03:04 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1748872986; bh=x1o0Ihmm4BVt5ZC6hQAevJ2br6+2hL/MI5r9KqN/NNw=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=YsLYoqQW5Hhlb2D2ckZkD6c/4IyvIKoYrf27/Yq57Kcoa2bi1S6Iz+6lNWKqPwkha UuwJt/f/3+P7VHseotyV8M0fCmrJOZZYZMREZdBwr9hnIB62nDJVvdwJNb5bqZ10Q2 3+cxc6aDE0lJf7LBx5QqrRVMjOnz5R3wbc0mv2G/646TJZoLoSkUJbPNHMEgUCdhoo q4UVtOSArgpNApBT3TkqaD6zWte/ci3JogL8GF5bbLFCJdZ1+D8SEUe4NmkUSSIiOt RGf6gntioX3oRbO6HjX8SEN9BgydRmJK/x2McPFUrn5kZ28rit1peJrpIffJiQphf3 51T28tXpuzdPg== From: Jeff Layton Date: Mon, 02 Jun 2025 10:02:04 -0400 Subject: [PATCH RFC v2 21/28] fsnotify: export fsnotify_recalc_mask() Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20250602-dir-deleg-v2-21-a7919700de86@kernel.org> References: <20250602-dir-deleg-v2-0-a7919700de86@kernel.org> In-Reply-To: <20250602-dir-deleg-v2-0-a7919700de86@kernel.org> To: Alexander Viro , Christian Brauner , Jan Kara , Chuck Lever , Alexander Aring , Trond Myklebust , Anna Schumaker , Steve French , Paulo Alcantara , Ronnie Sahlberg , Shyam Prasad N , Tom Talpey , Bharath SM , NeilBrown , Olga Kornievskaia , Dai Ngo , Jonathan Corbet , Amir Goldstein , Miklos Szeredi Cc: linux-fsdevel@vger.kernel.org, linux-kernel@vger.kernel.org, linux-nfs@vger.kernel.org, linux-cifs@vger.kernel.org, samba-technical@lists.samba.org, linux-doc@vger.kernel.org, Jeff Layton X-Mailer: b4 0.14.2 X-Developer-Signature: v=1; a=openpgp-sha256; l=753; i=jlayton@kernel.org; h=from:subject:message-id; bh=x1o0Ihmm4BVt5ZC6hQAevJ2br6+2hL/MI5r9KqN/NNw=; b=owEBbQKS/ZANAwAKAQAOaEEZVoIVAcsmYgBoPa7pfOaDl5D8IUu3Zh9z/dAF7GZkLHCc/cGwt tkaZ2PJF5aJAjMEAAEKAB0WIQRLwNeyRHGyoYTq9dMADmhBGVaCFQUCaD2u6QAKCRAADmhBGVaC FbhgEACWbSTkaxvAegVDzQuZYFsLQb8pnSrkPTuqXzRpePBGVdykoJdXrH6HntRb9iUx1PJuaVj PKp4IsKLlg5SebxTEeYQPuEOC4q5aaDObvFQJg+mXt5vpQ6pFiVd8R6Rpgpujb3AlI/qQ9Ye70J JXdL5NzcdBlxk8f+sxK29NGNJ4ISvnlQBFIDHXrB2IDl/H6NkKpNWt/hx+vXk4fEj8XAoJ7LU7Y K5BLzc/GHENujpMuZhDAw416cLBIrVY44a9qXoTNCgpqB9vKSev0EInZjPJzKFuwVa9uAVkOdnp gz4Y69ZjSFrF/i/5GQLyJDE805cq2H+tOD+eil5QkMBFkfRvuaNMHUtiBKN3LeUbANyQtkMTVYM zi6akgLPnib5fQ6Fgc15gBf5SyUvsTlMPJovAwbLBd/G/GbczFoEOwYN3Ocu5pEXDb2TL6ifBlf 4tdTuFBozBlQ/hISmeKTJqgDhzdVo/LGk19NtD9JPAUGlhTwRBL0tEdDjbSJiP8QhBmzzAsdp3x JhEd1t3J9V27WEqw46/2J+pgsnyZS0Emn6JB3e576fUDOQuGnLqTwm9RBULMZYCmTE4V/5H4Q2S Flpr95jfb2MBhrD6bQivvFwfC3R4nxrma0JMd0Lp5LtZZdWJ2crVQ0hrjQLsVhuooUOG41YQrq7 SZ2rN5pPtEaR7Uw== X-Developer-Key: i=jlayton@kernel.org; a=openpgp; fpr=4BC0D7B24471B2A184EAF5D3000E684119568215 nfsd needs to call this when new directory delegations are set or unset. Signed-off-by: Jeff Layton --- fs/notify/mark.c | 1 + 1 file changed, 1 insertion(+) diff --git a/fs/notify/mark.c b/fs/notify/mark.c index 798340db69d761dd05c1b361c251818dee89b9cf..ff21409c3ca3ad948557225afc5= 86da3728f7cbe 100644 --- a/fs/notify/mark.c +++ b/fs/notify/mark.c @@ -308,6 +308,7 @@ void fsnotify_recalc_mask(struct fsnotify_mark_connecto= r *conn) if (update_children) fsnotify_conn_set_children_dentry_flags(conn); } +EXPORT_SYMBOL_GPL(fsnotify_recalc_mask); =20 /* Free all connectors queued for freeing once SRCU period ends */ static void fsnotify_connector_destroy_workfn(struct work_struct *work) --=20 2.49.0 From nobody Thu Dec 18 14:10:55 2025 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 5161323A993; Mon, 2 Jun 2025 14:03: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=1748872989; cv=none; b=lF3RmgPp/MP7O3SMljkdBXT94vGvaBzml6z3dKOQa2qRYHUf04DEeGpjTbOYhwB6nGTHU3YC+hJ4ORFrKFC9WI0ZuzH+vM9KyBwZCEM5Eb6FaY9fXBiw8bbdJDjSHRZzqVA5tDn8JdEIdgKHCGgIkV+1xAqLgT1mSh2rRIEUDTg= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1748872989; c=relaxed/simple; bh=Pz55JuEEdLCPilzrHKqDX5mWZdXe/U4sVTUky1eCFX4=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=moHhATYa5qmdiq5DkFoLPlgcOcmJhYPt8z6Jb5YAgG6oFSf3IgxiN0tDFg9HYzMccqRPoH90cIr8fsEaCTwh9Wgz0ib8mFeBMWGB+GqF52bEQBXNAeHEdntt3XXLwv1qSJt26OHkhuDbsCoEp0mmcMfLmIGtpoiASv1wT2VPYl4= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=Sz1dfezB; 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="Sz1dfezB" Received: by smtp.kernel.org (Postfix) with ESMTPSA id E47F8C4CEF0; Mon, 2 Jun 2025 14:03:06 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1748872988; bh=Pz55JuEEdLCPilzrHKqDX5mWZdXe/U4sVTUky1eCFX4=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=Sz1dfezBREnI0gVUCr8j87GmlF19pB6tuAMbiS/ED6wCiq/k7Nt3r9IIKRcEhasZi L5bJnXcdn2VI9Dpvt9PSBwxqd6p5rQ5Kv5mX0k7bIJkfpBFYiQpat3MqAivPa1YfJm tvwR8+HX6ko8hEPnnS17Z89HnF/QCZXIbLUkq07k/kTM9JIxZbkUW45QNKB8XDt0sk hvbTyInUPH/Ddctyd7TjFn0EnUBcx1B4S1c8Zk0bzdaQzL5mbGWEbf5knz7wqMyhz3 KFOVwZ2+paaXHa4b/BhUe2+8grcgF62jtmywhKmgHo6Gq2a3IG6movNNlyj4DPOFNE Fb+ojMiyO3SPA== From: Jeff Layton Date: Mon, 02 Jun 2025 10:02:05 -0400 Subject: [PATCH RFC v2 22/28] nfsd: update the fsnotify mark when setting or removing a dir delegation Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20250602-dir-deleg-v2-22-a7919700de86@kernel.org> References: <20250602-dir-deleg-v2-0-a7919700de86@kernel.org> In-Reply-To: <20250602-dir-deleg-v2-0-a7919700de86@kernel.org> To: Alexander Viro , Christian Brauner , Jan Kara , Chuck Lever , Alexander Aring , Trond Myklebust , Anna Schumaker , Steve French , Paulo Alcantara , Ronnie Sahlberg , Shyam Prasad N , Tom Talpey , Bharath SM , NeilBrown , Olga Kornievskaia , Dai Ngo , Jonathan Corbet , Amir Goldstein , Miklos Szeredi Cc: linux-fsdevel@vger.kernel.org, linux-kernel@vger.kernel.org, linux-nfs@vger.kernel.org, linux-cifs@vger.kernel.org, samba-technical@lists.samba.org, linux-doc@vger.kernel.org, Jeff Layton X-Mailer: b4 0.14.2 X-Developer-Signature: v=1; a=openpgp-sha256; l=2347; i=jlayton@kernel.org; h=from:subject:message-id; bh=Pz55JuEEdLCPilzrHKqDX5mWZdXe/U4sVTUky1eCFX4=; b=owEBbQKS/ZANAwAKAQAOaEEZVoIVAcsmYgBoPa7pF2+xZkaJPqdnmOahnyjGwgiTAqmYC2EuT 41/q3TC7nWJAjMEAAEKAB0WIQRLwNeyRHGyoYTq9dMADmhBGVaCFQUCaD2u6QAKCRAADmhBGVaC FfBcD/4stoDSJG2Rrvar396rOzV8JxwBy1maDQ9VHvj5tI58Ahj8l9ESUK7WJxZIzePPymVwCFi yLuuE9kVoTKvkrj8ps5dRr4F66yGl5oS6yFQazHQ2cM66fhgJO/jNHhK+fdZY6UT+i/hSAW7fLE kZCEkfEe588gXZYHqJIHHQ/1WwCt24HG7gXvmCZ5D07Z1Z2b/pNM4HHs7gGKGSd11OLdRXvszjm H6CcFJgFNhx1nJ5C3XRCy0HxNJeWlRltL8U8rUmTTx1CaHx4xsU9ceqf3QaioKMY+T9JnODZDDx e0NeAu3Yd9hiFFbIaRSHTziHiIUJYoqIKltS77jFk5iJCg7IqyCwqA4Rc5wCfWWCsWJs47CZ05o HswxHPCgcrnXzt2JgWWd0hS2D9PuT8BJyS3fYAfBKA5sRQZJS1W34PtAbu1p8bJBKJczef93jwf tXSAp2XL39xNJ2E2P+A+PXhQQBq+JLkiZLnkS63mrH9MeNwI3zYR1mzw8VQjS1y9xqQtBCIiTRy P3deIlugpW3FBVzrF18zDhwpevvM/1sYockg11sAyaWqbGIyOUqyfl9wksI782nHYh5bht7g881 bV58IoalhgmSkiGlItD9CgCsjTpIDujToLsmAes36Uxwo3me0IXXYmO9k07nhvUYHq4GkrRfx31 uqb1qulwFavBKnw== X-Developer-Key: i=jlayton@kernel.org; a=openpgp; fpr=4BC0D7B24471B2A184EAF5D3000E684119568215 Add a new helper function that will update the mask on the nfsd_file's fsnotify_mark to be a union of all current directory delegations on an inode. Call that when directory delegations are added or removed. Signed-off-by: Jeff Layton --- fs/nfsd/nfs4state.c | 36 +++++++++++++++++++++++++++++++++++- 1 file changed, 35 insertions(+), 1 deletion(-) diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c index ebebfd6d304627d6c82bae5b84ea6c599d9e9474..164020a01b737f76d2780b30274= e75dcc3def819 100644 --- a/fs/nfsd/nfs4state.c +++ b/fs/nfsd/nfs4state.c @@ -1302,6 +1302,37 @@ static void put_deleg_file(struct nfs4_file *fp) nfs4_file_put_access(fp, NFS4_SHARE_ACCESS_READ); } =20 +static void nfsd_fsnotify_recalc_mask(struct nfsd_file *nf) +{ + struct fsnotify_mark *fsn_mark =3D &nf->nf_mark->nfm_mark; + struct inode *inode =3D file_inode(nf->nf_file); + u32 lease_mask, mask =3D 0; + bool recalc =3D false; + + /* This is only needed when adding or removing dir delegs */ + if (!S_ISDIR(inode->i_mode)) + return; + + /* Set up notifications for any ignored delegation events */ + lease_mask =3D inode_lease_ignore_mask(inode); + if (lease_mask & FL_IGN_DIR_CREATE) + mask |=3D FS_CREATE; + if (lease_mask & FL_IGN_DIR_DELETE) + mask |=3D FS_DELETE; + if (lease_mask & FL_IGN_DIR_RENAME) + mask |=3D FS_RENAME; + + spin_lock(&fsn_mark->lock); + if (fsn_mark->mask !=3D mask) { + fsn_mark->mask =3D mask; + recalc =3D true; + } + spin_unlock(&fsn_mark->lock); + + if (recalc) + fsnotify_recalc_mask(fsn_mark->connector); +} + static void nfs4_unlock_deleg_lease(struct nfs4_delegation *dp) { struct nfs4_file *fp =3D dp->dl_stid.sc_file; @@ -1309,6 +1340,7 @@ static void nfs4_unlock_deleg_lease(struct nfs4_deleg= ation *dp) =20 WARN_ON_ONCE(!fp->fi_delegees); =20 + nfsd_fsnotify_recalc_mask(nf); kernel_setlease(nf->nf_file, F_UNLCK, NULL, (void **)&dp); put_deleg_file(fp); } @@ -9487,8 +9519,10 @@ nfsd_get_dir_deleg(struct nfsd4_compound_state *csta= te, spin_unlock(&clp->cl_lock); spin_unlock(&state_lock); =20 - if (!status) + if (!status) { + nfsd_fsnotify_recalc_mask(nf); return dp; + } =20 /* Something failed. Drop the lease and clean up the stid */ kernel_setlease(fp->fi_deleg_file->nf_file, F_UNLCK, NULL, (void **)&dp); --=20 2.49.0 From nobody Thu Dec 18 14:10:55 2025 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 30BB0237717; Mon, 2 Jun 2025 14:03: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=1748872991; cv=none; b=M8z0bpemRzloi0a+cxMlSxC/ubEJYwr3EX5Gz7SwJkzCITQqz8HHyfEoSsmTfQb0hIyZNR17dC32pBgVaZv65jHbXcd255px3x5lJgT3f7WrLpnNzQA+5AybBe5mR2QGoKtlv4cP1fkf7OCneTfc0XlXctEbK9nFkCikIEm2dYA= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1748872991; c=relaxed/simple; bh=cybvGGUeAdvyfxQog3LULK6UI3fwBr3sT2axjjTf/Yw=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=P+OiOblQOI0v1lq0TmN6OWYz0ene+f4bKatHFh2s/WtV5ZX9HhOz+uPYgWdLCOdQI5+k6861zDgLD1Kzu462SX4mQDdB2zcnC8/6J2KeTi0ouZLcT65cJ+C7TUbpCCWezvaph5fNnOwSc5fqeJcYRcEzlCh/bAu9/vW2xrNBonA= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=B6klgPwR; 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="B6klgPwR" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 0EE0EC4CEF7; Mon, 2 Jun 2025 14:03:08 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1748872990; bh=cybvGGUeAdvyfxQog3LULK6UI3fwBr3sT2axjjTf/Yw=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=B6klgPwRCov7N1ZUxaPpVh18TRGWAL8UqrTq+i999/NzSFRz0ih1cjMiyIJMjRrrm W3ZzvokpSl0ADAgjMaI1EBunveBlAl+ui00hcm4SCHBXPqy9DVzMoiXmWc2RWrN12y sPcuG1I3AVOR2gunrPtSBU65FngU4ZOrRHfrIZRQvggaoEHClsg2u3ToZePU98WrcV DfX+lm3nQp0SQYIxsYDsCChmRpeNeia/Z7RRLhs7fHMwVLNoTGW8YZuuuoZ2Aa5EJA 9ZatQMXrPwJTSPsmLIt715w2IMMR1Ip78Clg7BlLH0BZzVERHJ3x2INcTAgxvCsq00 zLbtYFQcTVsVQ== From: Jeff Layton Date: Mon, 02 Jun 2025 10:02:06 -0400 Subject: [PATCH RFC v2 23/28] nfsd: make nfsd4_callback_ops->prepare operation bool return Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20250602-dir-deleg-v2-23-a7919700de86@kernel.org> References: <20250602-dir-deleg-v2-0-a7919700de86@kernel.org> In-Reply-To: <20250602-dir-deleg-v2-0-a7919700de86@kernel.org> To: Alexander Viro , Christian Brauner , Jan Kara , Chuck Lever , Alexander Aring , Trond Myklebust , Anna Schumaker , Steve French , Paulo Alcantara , Ronnie Sahlberg , Shyam Prasad N , Tom Talpey , Bharath SM , NeilBrown , Olga Kornievskaia , Dai Ngo , Jonathan Corbet , Amir Goldstein , Miklos Szeredi Cc: linux-fsdevel@vger.kernel.org, linux-kernel@vger.kernel.org, linux-nfs@vger.kernel.org, linux-cifs@vger.kernel.org, samba-technical@lists.samba.org, linux-doc@vger.kernel.org, Jeff Layton X-Mailer: b4 0.14.2 X-Developer-Signature: v=1; a=openpgp-sha256; l=3521; i=jlayton@kernel.org; h=from:subject:message-id; bh=cybvGGUeAdvyfxQog3LULK6UI3fwBr3sT2axjjTf/Yw=; b=kA0DAAoBAA5oQRlWghUByyZiAGg9rumjMKHFOs+0Usc+IR8lmqecPTHS+/WoxEzzFmFfP83Jk 4kCMwQAAQoAHRYhBEvA17JEcbKhhOr10wAOaEEZVoIVBQJoPa7pAAoJEAAOaEEZVoIVl00QAIlR xab8NbOD+LeXrDxrvbcM/SDRvKMW+B+d7Z+Hwf3PkExUF5YxozRo/aFSVn7Oj7Gd2spUdPiN1vG 9G1VKUl0nZhY17+HEjPeYSYjq/NojNXvwaAn/pdnRCnL1tu00fVxDLzZyJz3w5WUJwbrC52yrFb iHx8I4hmYzXvdbOx5IHI5uaK+1XEmFw7WujAS+Re2HadlzuNdLUrQKLBC5k9reTxVWDi4MvT/Pe SAAp56U2XE7ow3+QHsrMrfEbv6SnvyHGAlQHIFfHoi/F4qR7pDPGExctJFSm3GrCKUlWFXZw9NP sB25ETYry/+tdV741x4HR6fNnAT3kyR9dUTu4humtftfinJErg+Gf5gQtMDW3ZT5k0DJpDBXbmy NlmPMLDuwqD2LR8j+usj7hz0cxJruRgCTALImPu9Q3GgflPPvj5Iwh2YeqdU7xLcKEIKEFQbBje Iy7A09DBy2r85vPUoIa5+BbOwTuQFgaVBJQadA1vHXUhmED0jY2wyJi64afraUhajHlkDGMx0pI ySHLIXXhhEU19zS0QRP1GAJW/vyVMmeGoQMV8SU5l98gBVNNdB85UW4mcrRWsnlXDGFITtbyTcQ 9yTopdjvl+lye7CFFHXIAsXcNCpFm6d6U36aFwELSvLSsfHOv7hY81BKg9jGKyTDo3R1B1tdhue tQYAz X-Developer-Key: i=jlayton@kernel.org; a=openpgp; fpr=4BC0D7B24471B2A184EAF5D3000E684119568215 For a CB_NOTIFY operation, we need to stop processing the callback if an allocation fails. Change the ->prepare callback operation to return true if processing should continue, and false otherwise. Signed-off-by: Jeff Layton --- fs/nfsd/nfs4callback.c | 5 ++++- fs/nfsd/nfs4layouts.c | 3 ++- fs/nfsd/nfs4state.c | 6 ++++-- fs/nfsd/state.h | 6 +++--- 4 files changed, 13 insertions(+), 7 deletions(-) diff --git a/fs/nfsd/nfs4callback.c b/fs/nfsd/nfs4callback.c index 2dca686d67fc0f0fcf7997a252b4f5988b9de6c7..fe7b20b94d76efd309e27c1a3ef= 359e7101dac80 100644 --- a/fs/nfsd/nfs4callback.c +++ b/fs/nfsd/nfs4callback.c @@ -1785,7 +1785,10 @@ nfsd4_run_cb_work(struct work_struct *work) =20 if (!test_and_clear_bit(NFSD4_CALLBACK_REQUEUE, &cb->cb_flags)) { if (cb->cb_ops && cb->cb_ops->prepare) - cb->cb_ops->prepare(cb); + if (!cb->cb_ops->prepare(cb)) { + nfsd41_destroy_cb(cb); + return; + } } =20 cb->cb_msg.rpc_cred =3D clp->cl_cb_cred; diff --git a/fs/nfsd/nfs4layouts.c b/fs/nfsd/nfs4layouts.c index 290271ac424540e4405a5fd0eacc8db9f47603cd..f23699998e4c978b4af0c87cc0a= 959851ef5ac4b 100644 --- a/fs/nfsd/nfs4layouts.c +++ b/fs/nfsd/nfs4layouts.c @@ -653,7 +653,7 @@ nfsd4_cb_layout_fail(struct nfs4_layout_stateid *ls, st= ruct nfsd_file *file) } } =20 -static void +static bool nfsd4_cb_layout_prepare(struct nfsd4_callback *cb) { struct nfs4_layout_stateid *ls =3D @@ -662,6 +662,7 @@ nfsd4_cb_layout_prepare(struct nfsd4_callback *cb) mutex_lock(&ls->ls_mutex); nfs4_inc_and_copy_stateid(&ls->ls_recall_sid, &ls->ls_stid); mutex_unlock(&ls->ls_mutex); + return true; } =20 static int diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c index 164020a01b737f76d2780b30274e75dcc3def819..5860d44fea0a4f854d65c87bcac= b8eea19ce82e4 100644 --- a/fs/nfsd/nfs4state.c +++ b/fs/nfsd/nfs4state.c @@ -362,12 +362,13 @@ remove_blocked_locks(struct nfs4_lockowner *lo) } } =20 -static void +static bool nfsd4_cb_notify_lock_prepare(struct nfsd4_callback *cb) { struct nfsd4_blocked_lock *nbl =3D container_of(cb, struct nfsd4_blocked_lock, nbl_cb); locks_delete_block(&nbl->nbl_lock); + return true; } =20 static int @@ -5482,7 +5483,7 @@ bool nfsd_wait_for_delegreturn(struct svc_rqst *rqstp= , struct inode *inode) return timeo > 0; } =20 -static void nfsd4_cb_recall_prepare(struct nfsd4_callback *cb) +static bool nfsd4_cb_recall_prepare(struct nfsd4_callback *cb) { struct nfs4_delegation *dp =3D cb_to_delegation(cb); struct nfsd_net *nn =3D net_generic(dp->dl_stid.sc_client->net, @@ -5503,6 +5504,7 @@ static void nfsd4_cb_recall_prepare(struct nfsd4_call= back *cb) list_add_tail(&dp->dl_recall_lru, &nn->del_recall_lru); } spin_unlock(&state_lock); + return true; } =20 static int nfsd4_cb_recall_done(struct nfsd4_callback *cb, diff --git a/fs/nfsd/state.h b/fs/nfsd/state.h index 706bbc7076a4f1d0be3ea7067d193683821d74eb..98f87fa724ee242f3a855faa205= 223b0e09a16ed 100644 --- a/fs/nfsd/state.h +++ b/fs/nfsd/state.h @@ -97,9 +97,9 @@ struct nfsd4_callback { }; =20 struct nfsd4_callback_ops { - void (*prepare)(struct nfsd4_callback *); - int (*done)(struct nfsd4_callback *, struct rpc_task *); - void (*release)(struct nfsd4_callback *); + bool (*prepare)(struct nfsd4_callback *cb); + int (*done)(struct nfsd4_callback *cb, struct rpc_task *task); + void (*release)(struct nfsd4_callback *cb); uint32_t opcode; }; =20 --=20 2.49.0 From nobody Thu Dec 18 14:10:55 2025 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 35BBD23C51A; Mon, 2 Jun 2025 14:03: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=1748872993; cv=none; b=ofpM07Eno1GlTqMh7NXVgT59TbyQxn3C8T7nZ7MWa3H6YG3VqjkJ1sIUSm5QByfVWbS3wB4H81sKCPqFQyvypDRQHRoYJe1MQzzwWs9r3GRWVciaNzD6Az+C0zJo3RV2OzzuS4SHaK2lL3io3yRw52chkxbOAepEanzQikuIx58= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1748872993; c=relaxed/simple; bh=RR9zI2aKCWvdTRzyv49hk1nm82KMFUT0MxbaFrGaC7s=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=HuHXXZ0OsDZyKPS/+7n67YT2Zg9QWRRjNqNNi12ejkR4F6tQe6c3h56GFrs4XXUZZ9c7tdfMfXLSxzhv8Ve2p1uMKijV5FTU6t12gE0NtI0Ecbzj8F0HVfwEWPDKUaeCufVDH8R8bPqyLckc9+Gj9X3jILmMM9rw3LC1nZ6s4DU= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=uqZglaU7; 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="uqZglaU7" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 2D067C4CEEB; Mon, 2 Jun 2025 14:03:11 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1748872993; bh=RR9zI2aKCWvdTRzyv49hk1nm82KMFUT0MxbaFrGaC7s=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=uqZglaU7i+pa7/ltiNi0iAW7f7L88LLztwn/SJN/TPTMhS0fxQzUofnOkZZ921Vdy FYNEW29oIDIQonZux3bhtHb+usPJqAaZDEcGc16Rn/hl3JVpN0vyN3503MbUj4wwWe hHsSfNl8knRbYy5AKGF0jLemA9ApCCfRveypXxwFWnQWdbTYGmiqHz1Jx/jBIPkhm3 yYjkCOhGsYCEDFvtnYVRylajTo0PUAYqAIl+Bw6txajgVgWQET5zITThvbarqVR7w4 M7LgIWHKT3aql31SkVe0dNOC6RI0VGXuIdUHDAj8bkA45SjtKS+u8MRNwfLvGp855s nM339wKIrnPfw== From: Jeff Layton Date: Mon, 02 Jun 2025 10:02:07 -0400 Subject: [PATCH RFC v2 24/28] nfsd: add notification handlers for dir events Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20250602-dir-deleg-v2-24-a7919700de86@kernel.org> References: <20250602-dir-deleg-v2-0-a7919700de86@kernel.org> In-Reply-To: <20250602-dir-deleg-v2-0-a7919700de86@kernel.org> To: Alexander Viro , Christian Brauner , Jan Kara , Chuck Lever , Alexander Aring , Trond Myklebust , Anna Schumaker , Steve French , Paulo Alcantara , Ronnie Sahlberg , Shyam Prasad N , Tom Talpey , Bharath SM , NeilBrown , Olga Kornievskaia , Dai Ngo , Jonathan Corbet , Amir Goldstein , Miklos Szeredi Cc: linux-fsdevel@vger.kernel.org, linux-kernel@vger.kernel.org, linux-nfs@vger.kernel.org, linux-cifs@vger.kernel.org, samba-technical@lists.samba.org, linux-doc@vger.kernel.org, Jeff Layton X-Mailer: b4 0.14.2 X-Developer-Signature: v=1; a=openpgp-sha256; l=13567; i=jlayton@kernel.org; h=from:subject:message-id; bh=RR9zI2aKCWvdTRzyv49hk1nm82KMFUT0MxbaFrGaC7s=; b=owEBbQKS/ZANAwAKAQAOaEEZVoIVAcsmYgBoPa7qcPCqcsBPSmvzCGaFGjXtQ3U0Kf+qcgXnu 87smOOmAnOJAjMEAAEKAB0WIQRLwNeyRHGyoYTq9dMADmhBGVaCFQUCaD2u6gAKCRAADmhBGVaC FdhqEACFCXjVn02rVy92FGCGl/1gBFVLCUeZTzVkA6cnfV6N9X4JUXXXQp+u/YmbjuXiG7tXnhE jme2L7KFkyhXNJb8LvIziG201uuf2C4JR+b3tEtt5BtpIE9/cdkdTxX46isCssyD2ZL+pzxeySb /Akted2YjPggnbh7sFL7WSdZ8SN6W5lUMi1aUBQA14/pxuRu4A/jMEZPIF8wSKnZCU5OaV46H1n MvWFdESVu+H9gv1MT7l86KlxOA+WTGEWfvXg9Farzg/+hUKe7J5iM5Jomn+3j0cgYHa7Kc+XtyC m2YVVbgzskAaOaZ+olwDQRpmWIfdxLQPIzOS/8OsHQx0ksaWgBVMeNTlqYlQNbo+4uSn8NKlkPp QPQtogWMpimES5mjs1RyupcWPFhndPgubMdU7YoCdq4fVVdVYabqYPiNSqw5rVHaBZ9hFpk2+2l jT9SnFcx3w12Yp8vZgHcECuB1/qis6mL3xK/Q+oLlxWt1iSf8HJGyakKRPstcKAObD5kIS0VY7Z xD+OpDSJyGi/qG2YY3tTDD6NG/3ehLqkaUgvlo6xhzHp13KZ05gAPXU9Q0NSNRv4wYr+hRh1kE6 dnz9GmbbfPJ7K7RPLDZ7ezZXpCpp7T7DmJnntBBn2quTOqaGJRt7cKurorUz85ekum8ZLBSpali 83RmLB5cw4aAWAg== X-Developer-Key: i=jlayton@kernel.org; a=openpgp; fpr=4BC0D7B24471B2A184EAF5D3000E684119568215 Add the necessary parts to accept a fsnotify callback for directory change event and create a CB_NOTIFY request for it. When a dir nfsd_file is created set a handle_event callback to handle the notification. Use that to marshal the event into the notifylist4 buffer, and kick off the callback workqueue job to handle the send. Signed-off-by: Jeff Layton --- fs/nfsd/filecache.c | 51 +++++++++++++---- fs/nfsd/nfs4callback.c | 19 +++++-- fs/nfsd/nfs4state.c | 152 +++++++++++++++++++++++++++++++++++++++++++++= ++++ fs/nfsd/state.h | 2 + 4 files changed, 207 insertions(+), 17 deletions(-) diff --git a/fs/nfsd/filecache.c b/fs/nfsd/filecache.c index 3468883146afc080d2b4862e6002b2c6ff7315b9..6cd4cfa0b46bf33c4134987a12e= 42c8455fc4879 100644 --- a/fs/nfsd/filecache.c +++ b/fs/nfsd/filecache.c @@ -72,6 +72,7 @@ static struct kmem_cache *nfsd_file_mark_slab; static struct list_lru nfsd_file_lru; static unsigned long nfsd_file_flags; static struct fsnotify_group *nfsd_file_fsnotify_group; +static struct fsnotify_group *nfsd_dir_fsnotify_group; static struct delayed_work nfsd_filecache_laundrette; static struct rhltable nfsd_file_rhltable ____cacheline_aligned_in_smp; @@ -147,7 +148,7 @@ static void nfsd_file_mark_put(struct nfsd_file_mark *nfm) { if (refcount_dec_and_test(&nfm->nfm_ref)) { - fsnotify_destroy_mark(&nfm->nfm_mark, nfsd_file_fsnotify_group); + fsnotify_destroy_mark(&nfm->nfm_mark, nfm->nfm_mark.group); fsnotify_put_mark(&nfm->nfm_mark); } } @@ -155,35 +156,37 @@ nfsd_file_mark_put(struct nfsd_file_mark *nfm) static struct nfsd_file_mark * nfsd_file_mark_find_or_create(struct inode *inode) { - int err; - struct fsnotify_mark *mark; struct nfsd_file_mark *nfm =3D NULL, *new; + struct fsnotify_group *group; + struct fsnotify_mark *mark; + int err; + + group =3D S_ISDIR(inode->i_mode) ? nfsd_dir_fsnotify_group : nfsd_file_fs= notify_group; =20 do { - fsnotify_group_lock(nfsd_file_fsnotify_group); - mark =3D fsnotify_find_inode_mark(inode, - nfsd_file_fsnotify_group); + fsnotify_group_lock(group); + mark =3D fsnotify_find_inode_mark(inode, group); if (mark) { nfm =3D nfsd_file_mark_get(container_of(mark, struct nfsd_file_mark, nfm_mark)); - fsnotify_group_unlock(nfsd_file_fsnotify_group); + fsnotify_group_unlock(group); if (nfm) { fsnotify_put_mark(mark); break; } /* Avoid soft lockup race with nfsd_file_mark_put() */ - fsnotify_destroy_mark(mark, nfsd_file_fsnotify_group); + fsnotify_destroy_mark(mark, group); fsnotify_put_mark(mark); } else { - fsnotify_group_unlock(nfsd_file_fsnotify_group); + fsnotify_group_unlock(group); } =20 /* allocate a new nfm */ new =3D kmem_cache_alloc(nfsd_file_mark_slab, GFP_KERNEL); if (!new) return NULL; - fsnotify_init_mark(&new->nfm_mark, nfsd_file_fsnotify_group); + fsnotify_init_mark(&new->nfm_mark, group); new->nfm_mark.mask =3D FS_ATTRIB|FS_DELETE_SELF; refcount_set(&new->nfm_ref, 1); =20 @@ -758,12 +761,25 @@ nfsd_file_fsnotify_handle_event(struct fsnotify_mark = *mark, u32 mask, return 0; } =20 +static int +nfsd_dir_fsnotify_handle_event(struct fsnotify_group *group, u32 mask, + const void *data, int data_type, struct inode *dir, + const struct qstr *name, u32 cookie, + struct fsnotify_iter_info *iter_info) +{ + return nfsd_handle_dir_event(mask, dir, data, data_type, name); +} =20 static const struct fsnotify_ops nfsd_file_fsnotify_ops =3D { .handle_inode_event =3D nfsd_file_fsnotify_handle_event, .free_mark =3D nfsd_file_mark_free, }; =20 +static const struct fsnotify_ops nfsd_dir_fsnotify_ops =3D { + .handle_event =3D nfsd_dir_fsnotify_handle_event, + .free_mark =3D nfsd_file_mark_free, +}; + int nfsd_file_cache_init(void) { @@ -815,8 +831,7 @@ nfsd_file_cache_init(void) goto out_shrinker; } =20 - nfsd_file_fsnotify_group =3D fsnotify_alloc_group(&nfsd_file_fsnotify_ops, - 0); + nfsd_file_fsnotify_group =3D fsnotify_alloc_group(&nfsd_file_fsnotify_ops= , 0); if (IS_ERR(nfsd_file_fsnotify_group)) { pr_err("nfsd: unable to create fsnotify group: %ld\n", PTR_ERR(nfsd_file_fsnotify_group)); @@ -825,11 +840,23 @@ nfsd_file_cache_init(void) goto out_notifier; } =20 + nfsd_dir_fsnotify_group =3D fsnotify_alloc_group(&nfsd_dir_fsnotify_ops, = 0); + if (IS_ERR(nfsd_dir_fsnotify_group)) { + pr_err("nfsd: unable to create fsnotify group: %ld\n", + PTR_ERR(nfsd_dir_fsnotify_group)); + ret =3D PTR_ERR(nfsd_dir_fsnotify_group); + nfsd_dir_fsnotify_group =3D NULL; + goto out_notify_group; + } + INIT_DELAYED_WORK(&nfsd_filecache_laundrette, nfsd_file_gc_worker); out: if (ret) clear_bit(NFSD_FILE_CACHE_UP, &nfsd_file_flags); return ret; +out_notify_group: + fsnotify_put_group(nfsd_file_fsnotify_group); + nfsd_file_fsnotify_group =3D NULL; out_notifier: lease_unregister_notifier(&nfsd_file_lease_notifier); out_shrinker: diff --git a/fs/nfsd/nfs4callback.c b/fs/nfsd/nfs4callback.c index fe7b20b94d76efd309e27c1a3ef359e7101dac80..69cea84eceabe15b4e1e1aa31db= 601ad763b00ac 100644 --- a/fs/nfsd/nfs4callback.c +++ b/fs/nfsd/nfs4callback.c @@ -870,21 +870,30 @@ static void nfs4_xdr_enc_cb_notify(struct rpc_rqst *r= eq, const void *data) { const struct nfsd4_callback *cb =3D data; + struct nfsd4_cb_notify *ncn =3D container_of(cb, struct nfsd4_cb_notify, = ncn_cb); + struct nfs4_delegation *dp =3D container_of(ncn, struct nfs4_delegation, = dl_cb_notify); struct nfs4_cb_compound_hdr hdr =3D { .ident =3D 0, .minorversion =3D cb->cb_clp->cl_minorversion, }; - struct CB_NOTIFY4args args =3D { }; + struct CB_NOTIFY4args args; + __be32 *p; =20 WARN_ON_ONCE(hdr.minorversion =3D=3D 0); =20 encode_cb_compound4args(xdr, &hdr); encode_cb_sequence4args(xdr, cb, &hdr); =20 - /* - * FIXME: get stateid and fh from delegation. Inline the cna_changes - * buffer, and zero it. - */ + p =3D xdr_reserve_space(xdr, 4); + *p =3D cpu_to_be32(OP_CB_NOTIFY); + + args.cna_stateid.seqid =3D dp->dl_stid.sc_stateid.si_generation; + memcpy(&args.cna_stateid.other, &dp->dl_stid.sc_stateid.si_opaque, + ARRAY_SIZE(args.cna_stateid.other)); + args.cna_fh.len =3D dp->dl_stid.sc_file->fi_fhandle.fh_size; + args.cna_fh.data =3D dp->dl_stid.sc_file->fi_fhandle.fh_raw; + args.cna_changes.count =3D ncn->ncn_send->nns_idx; + args.cna_changes.element =3D ncn->ncn_send->nns_ent; WARN_ON_ONCE(!xdrgen_encode_CB_NOTIFY4args(xdr, &args)); =20 hdr.nops++; diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c index 5860d44fea0a4f854d65c87bcacb8eea19ce82e4..35b9e35f8b507cc9b3924fead30= 37433cd8f9371 100644 --- a/fs/nfsd/nfs4state.c +++ b/fs/nfsd/nfs4state.c @@ -55,6 +55,7 @@ #include "netns.h" #include "pnfs.h" #include "filecache.h" +#include "nfs4xdr_gen.h" #include "trace.h" =20 #define NFSDDBG_FACILITY NFSDDBG_PROC @@ -3309,15 +3310,83 @@ nfsd4_cb_getattr_release(struct nfsd4_callback *cb) nfs4_put_stid(&dp->dl_stid); } =20 +static bool +nfsd4_cb_notify_prepare(struct nfsd4_callback *cb) +{ + struct nfsd4_cb_notify *ncn =3D + container_of(cb, struct nfsd4_cb_notify, ncn_cb); + struct nfs4_delegation *dp =3D + container_of(ncn, struct nfs4_delegation, dl_cb_notify); + struct nfs4_file *fp =3D dp->dl_stid.sc_file; + struct nfsd_file *nf =3D fp->fi_deleg_file; + struct inode *inode =3D file_inode(nf->nf_file); + struct file_lock_context *flc =3D locks_inode_context(inode); + struct nfsd4_notify_spool *spool; + + if (WARN_ON_ONCE(!flc)) + return false; + + if (WARN_ON_ONCE(ncn->ncn_send)) + return false; + + spool =3D alloc_notify_spool(); + if (!spool) { + nfsd4_run_cb(&dp->dl_recall); + return false; + } + + spin_lock(&flc->flc_lock); + ncn->ncn_send =3D ncn->ncn_gather; + ncn->ncn_gather =3D spool; + spin_unlock(&flc->flc_lock); + return true; +} + +/* Returns true if more notifications are waiting to be sent */ +static bool +nfsd4_cb_notify_release_send_spool(struct nfsd4_callback *cb) +{ + struct nfsd4_cb_notify *ncn =3D container_of(cb, struct nfsd4_cb_notify, = ncn_cb); + struct nfs4_delegation *dp =3D container_of(ncn, struct nfs4_delegation, = dl_cb_notify); + struct nfs4_file *fp =3D dp->dl_stid.sc_file; + struct nfsd_file *nf =3D fp->fi_deleg_file; + struct inode *inode =3D file_inode(nf->nf_file); + struct file_lock_context *flc =3D locks_inode_context(inode); + struct nfsd4_notify_spool *spool; + bool more; + + spin_lock(&flc->flc_lock); + spool =3D ncn->ncn_send; + ncn->ncn_send =3D NULL; + more =3D ncn->ncn_gather && ncn->ncn_gather->nns_idx; + spin_unlock(&flc->flc_lock); + + free_notify_spool(spool); + return more; +} + static int nfsd4_cb_notify_done(struct nfsd4_callback *cb, struct rpc_task *task) { + struct nfsd4_cb_notify *ncn =3D container_of(cb, struct nfsd4_cb_notify, = ncn_cb); + struct nfs4_delegation *dp =3D container_of(ncn, struct nfs4_delegation, = dl_cb_notify); + switch (task->tk_status) { case -NFS4ERR_DELAY: rpc_delay(task, 2 * HZ); return 0; + case 0: + /* If successful, release the send spool and maybe requeue the cb */ + if (nfsd4_cb_notify_release_send_spool(cb)) { + refcount_inc(&dp->dl_stid.sc_count); + nfsd4_run_cb(cb); + } + return 1; default: + /* For any other hard error, recall the deleg */ + nfsd4_run_cb(&dp->dl_recall); + nfsd4_cb_notify_release_send_spool(cb); return 1; } } @@ -3331,6 +3400,8 @@ nfsd4_cb_notify_release(struct nfsd4_callback *cb) container_of(ncn, struct nfs4_delegation, dl_cb_notify); =20 nfs4_put_stid(&dp->dl_stid); + if (nfsd4_cb_notify_release_send_spool(cb)) + nfsd4_run_cb(cb); } =20 static const struct nfsd4_callback_ops nfsd4_cb_recall_any_ops =3D { @@ -3346,6 +3417,7 @@ static const struct nfsd4_callback_ops nfsd4_cb_getat= tr_ops =3D { }; =20 static const struct nfsd4_callback_ops nfsd4_cb_notify_ops =3D { + .prepare =3D nfsd4_cb_notify_prepare, .done =3D nfsd4_cb_notify_done, .release =3D nfsd4_cb_notify_release, .opcode =3D OP_CB_NOTIFY, @@ -9534,3 +9606,83 @@ nfsd_get_dir_deleg(struct nfsd4_compound_state *csta= te, put_deleg_file(fp); return ERR_PTR(status); } + +static void +nfsd4_run_cb_notify(struct nfsd4_cb_notify *ncn) +{ + struct nfs4_delegation *dp =3D container_of(ncn, struct nfs4_delegation, = dl_cb_notify); + + if (test_and_set_bit(NFSD4_CALLBACK_RUNNING, &ncn->ncn_cb.cb_flags)) + return; + + if (!refcount_inc_not_zero(&dp->dl_stid.sc_count)) + clear_bit(NFSD4_CALLBACK_RUNNING, &ncn->ncn_cb.cb_flags); + else + nfsd4_run_cb(&ncn->ncn_cb); +} + +int +nfsd_handle_dir_event(u32 mask, const struct inode *dir, const void *data, + int data_type, const struct qstr *name) +{ + struct file_lock_context *ctx; + struct file_lock_core *flc; + + ctx =3D locks_inode_context(dir); + if (!ctx || list_empty(&ctx->flc_lease)) + return 0; + + /* + * FIXME: Do getattr against @inode, and then generate an fattr4. Use tha= t as the + * ne_attrs in the notify_entry4's. + */ + spin_lock(&ctx->flc_lock); + list_for_each_entry(flc, &ctx->flc_lease, flc_list) { + struct file_lease *fl =3D container_of(flc, struct file_lease, c); + struct nfs4_delegation *dp =3D flc->flc_owner; + struct nfsd4_cb_notify *ncn =3D &dp->dl_cb_notify; + struct nfsd4_notify_spool *nns =3D ncn->ncn_gather; + struct xdr_stream *stream =3D &nns->nns_stream; + static uint32_t zerobm; + + if (fl->fl_lmops !=3D &nfsd_dir_lease_mng_ops) + continue; + + /* If no buffer or slots are available, give up and break the deleg */ + if (!nns || nns->nns_idx >=3D NFSD4_NOTIFY_SPOOL_SZ) { + nfsd_break_deleg_cb(fl); + continue; + } + + if (mask & FS_DELETE) { + static uint32_t notify_remove_bitmap =3D BIT(NOTIFY4_REMOVE_ENTRY); + struct notify4 *ent =3D &nns->nns_ent[nns->nns_idx]; + struct notify_remove4 nr =3D { }; + u8 *p =3D (u8 *)(stream->p); + + if (!(flc->flc_flags & FL_IGN_DIR_DELETE)) + continue; + + nr.nrm_old_entry.ne_file.len =3D name->len; + nr.nrm_old_entry.ne_file.data =3D (char *)name->name; + nr.nrm_old_entry.ne_attrs.attrmask.count =3D 1; + nr.nrm_old_entry.ne_attrs.attrmask.element =3D &zerobm; + if (!xdrgen_encode_notify_remove4(stream, &nr)) { + pr_warn("nfsd: unable to marshal notify_remove4 to xdr stream\n"); + continue; + } + + /* grab a notify4 in the buffer and set it up */ + ent->notify_mask.count =3D 1; + ent->notify_mask.element =3D ¬ify_remove_bitmap; + ent->notify_vals.len =3D (u8 *)stream->p - p; + ent->notify_vals.data =3D p; + ++nns->nns_idx; + } + + if (nns->nns_idx) + nfsd4_run_cb_notify(ncn); + } + spin_unlock(&ctx->flc_lock); + return 0; +} diff --git a/fs/nfsd/state.h b/fs/nfsd/state.h index 98f87fa724ee242f3a855faa205223b0e09a16ed..345fa6325fde0435f8110506254= 57a0d3cc29f3b 100644 --- a/fs/nfsd/state.h +++ b/fs/nfsd/state.h @@ -845,6 +845,8 @@ bool nfsd4_has_active_async_copies(struct nfs4_client *= clp); extern struct nfs4_client_reclaim *nfs4_client_to_reclaim(struct xdr_netob= j name, struct xdr_netobj princhash, struct nfsd_net *nn); extern bool nfs4_has_reclaimed_state(struct xdr_netobj name, struct nfsd_n= et *nn); +int nfsd_handle_dir_event(u32 mask, const struct inode *dir, const void *d= ata, + int data_type, const struct qstr *name); =20 void put_nfs4_file(struct nfs4_file *fi); extern void nfs4_put_cpntf_state(struct nfsd_net *nn, --=20 2.49.0 From nobody Thu Dec 18 14:10:55 2025 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 BFCC42236FC; Mon, 2 Jun 2025 14:03: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=1748872997; cv=none; b=vBf7BKq1xr6WV70kE2NuXPdRkM67yoa9W88nFqIm+fpq5SLyFQsrfhTNTB0sNJY2rBzYeJciN/ULQe5Pj0kc6JlDur/IymBSQ2MIyQuX/uNYpA04h30TjGKzSr/5Vdk10n0UUXr562GWHYxnrnhtLZI6YJM25r9jrq+gSa9qbrc= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1748872997; c=relaxed/simple; bh=H0xMoRMbO/wWa3vUx7i5LYdj5QyZv1EQ/6dovruf8N4=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=E/DrFRkpKOL+uQYuoU1SC94o4m2cnN+VzzjEdnMUhtG52sJqyeJsKnNAPYEH8jSR7h2U8JP12qkCrGFhArXD0ozvjrYmGgok7/49Hs/YmMtmAiYi7oOShXqK1Tc0azTzItzfEVVIixYTPF79KDpTSlxseCBSURrvsEsWq19ElJY= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=IhT+uzN6; 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="IhT+uzN6" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 4C288C4CEEE; Mon, 2 Jun 2025 14:03:13 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1748872995; bh=H0xMoRMbO/wWa3vUx7i5LYdj5QyZv1EQ/6dovruf8N4=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=IhT+uzN60w/TcRihzKBQtQLrmCisCge/93iB3Xx1+s/EgrcpNAFVVpb6aMKiLc6WW Mmp/II6Z/Dhvp9Mv6vZOP+wRgpjsyp9c9XueDh8k1pcgOKvv2CeYBWD3RoNRnRW1On zoHUCwFlBcZFZii68EOZGwkxYRHEqa4Ds0m+mOl67kMufocblSoSBVPWWS62Rt8fyG PLX6Hl50lXeEfTvDAWOPRYvpZPcfwQ2AFAStYw5OIU68L6q5++HYOV4UhmNY0BCel3 k2BLiTEBQnD1WQpEAI5pjOHl361yWu3teGJqz45HIkcsD+nRB/P0JvvCEj1rJ6Nr9i HdWRSQk03koRw== From: Jeff Layton Date: Mon, 02 Jun 2025 10:02:08 -0400 Subject: [PATCH RFC v2 25/28] nfsd: allow nfsd to get a dir lease with an ignore mask Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20250602-dir-deleg-v2-25-a7919700de86@kernel.org> References: <20250602-dir-deleg-v2-0-a7919700de86@kernel.org> In-Reply-To: <20250602-dir-deleg-v2-0-a7919700de86@kernel.org> To: Alexander Viro , Christian Brauner , Jan Kara , Chuck Lever , Alexander Aring , Trond Myklebust , Anna Schumaker , Steve French , Paulo Alcantara , Ronnie Sahlberg , Shyam Prasad N , Tom Talpey , Bharath SM , NeilBrown , Olga Kornievskaia , Dai Ngo , Jonathan Corbet , Amir Goldstein , Miklos Szeredi Cc: linux-fsdevel@vger.kernel.org, linux-kernel@vger.kernel.org, linux-nfs@vger.kernel.org, linux-cifs@vger.kernel.org, samba-technical@lists.samba.org, linux-doc@vger.kernel.org, Jeff Layton X-Mailer: b4 0.14.2 X-Developer-Signature: v=1; a=openpgp-sha256; l=3345; i=jlayton@kernel.org; h=from:subject:message-id; bh=H0xMoRMbO/wWa3vUx7i5LYdj5QyZv1EQ/6dovruf8N4=; b=owEBbQKS/ZANAwAKAQAOaEEZVoIVAcsmYgBoPa7qLjDR+iYEt5LHIKN3FETfC8LjOi06SmIUb my5kUQQOuaJAjMEAAEKAB0WIQRLwNeyRHGyoYTq9dMADmhBGVaCFQUCaD2u6gAKCRAADmhBGVaC Fa0ZEAC/ilcsSqLGWNmLU0y+pByHH5TpRYO/30ZWZ+qDc0DIUIJqksYup/D+5jJ1x37YYV3HPFQ oIrmcbg/NZSsyIzs9bPcG90KJfasq+/0WS85gKI6MXOlIdedi3Bxr2pkcoEeBfsxeCfHNJyn+qP zYNbkmYPacav2ixJi1RMLxnCznFvcWdbHvyPr+WibN5Sz815fCFRk+IDVtKJrhBYyCyWuSar0pB 2+wGeg4E6jONHtkF54K26mmxFQr3NiZ3qtUIKpORPMlflGDhK+/5kgx+SYDn4xZ/t1i3SVEPGVL NVlzPxgHd6veMD6jmdQpxlBEwFQPw5r7w++hUfTwvoqUxya2usD3DyKDE/njbKk+hXIuJPnl9P6 zInERqZ/6dQyONZRJ9cHs97nJ1IHsF6mSi7aI1hB0N/SK9UI+gW9n4ckYg0NSsBK4qxVX30MWRn 8V5sWUiAkxIdX1lmA1dMQxPkfmgbnFGQjyGvhc17ZlRG33pLtyYKcopeLzEyCSHV/x9a72efSum vx1x8U6NPcdtYyKBeM0gKb7c7ieuwDPhlw8urmNnh/Iq8xDldzwF/GYZlYfphjD/zf0vsfFDEHM g8ePJnyVAGx7TR1WQz7b5zboyBucwi8+A/lnUQkS8kOEVTMflH0eR/C9U0knrkDNdAKMFMyR20N Xq+36HfUokGbCwQ== X-Developer-Key: i=jlayton@kernel.org; a=openpgp; fpr=4BC0D7B24471B2A184EAF5D3000E684119568215 When requesting a directory lease, enable the FL_IGN_DIR_* bits that correspond to the requested notification types. Signed-off-by: Jeff Layton --- fs/nfsd/nfs4proc.c | 3 +++ fs/nfsd/nfs4state.c | 27 +++++++++++++++++++++------ 2 files changed, 24 insertions(+), 6 deletions(-) diff --git a/fs/nfsd/nfs4proc.c b/fs/nfsd/nfs4proc.c index fa6f2980bcacd798c41387c71d55a59fdbc8043c..77b6d0363b9f4cfea96f3f1abd3= e462fd2a77754 100644 --- a/fs/nfsd/nfs4proc.c +++ b/fs/nfsd/nfs4proc.c @@ -2292,6 +2292,8 @@ nfsd4_verify(struct svc_rqst *rqstp, struct nfsd4_com= pound_state *cstate, return status =3D=3D nfserr_same ? nfs_ok : status; } =20 +#define SUPPORTED_NOTIFY_MASK BIT(NOTIFY4_REMOVE_ENTRY) + static __be32 nfsd4_get_dir_delegation(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, @@ -2330,6 +2332,7 @@ nfsd4_get_dir_delegation(struct svc_rqst *rqstp, =20 gdd->gddrnf_status =3D GDD4_OK; memcpy(&gdd->gddr_stateid, &dd->dl_stid.sc_stateid, sizeof(gdd->gddr_stat= eid)); + gdd->gddr_notification[0] =3D gdd->gdda_notification_types[0] & SUPPORTED= _NOTIFY_MASK; nfs4_put_stid(&dd->dl_stid); return nfs_ok; } diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c index 35b9e35f8b507cc9b3924fead3037433cd8f9371..a75179ffa6006868bae39312638= 30d7b7e1a8882 100644 --- a/fs/nfsd/nfs4state.c +++ b/fs/nfsd/nfs4state.c @@ -6075,14 +6075,14 @@ static bool nfsd4_cb_channel_good(struct nfs4_clien= t *clp) return clp->cl_minorversion && clp->cl_cb_state =3D=3D NFSD4_CB_UNKNOWN; } =20 -static struct file_lease *nfs4_alloc_init_lease(struct nfs4_delegation *dp) +static struct file_lease *nfs4_alloc_init_lease(struct nfs4_delegation *dp= , unsigned int ignore) { struct file_lease *fl; =20 fl =3D locks_alloc_lease(); if (!fl) return NULL; - fl->c.flc_flags =3D FL_DELEG; + fl->c.flc_flags =3D FL_DELEG | ignore; fl->c.flc_type =3D deleg_is_read(dp->dl_type) ? F_RDLCK : F_WRLCK; fl->c.flc_owner =3D (fl_owner_t)dp; fl->c.flc_pid =3D current->tgid; @@ -6299,7 +6299,7 @@ nfs4_set_delegation(struct nfsd4_open *open, struct n= fs4_ol_stateid *stp, if (!dp) goto out_delegees; =20 - fl =3D nfs4_alloc_init_lease(dp); + fl =3D nfs4_alloc_init_lease(dp, 0); if (!fl) goto out_clnt_odstate; =20 @@ -9523,6 +9523,21 @@ nfsd4_deleg_getattr_conflict(struct svc_rqst *rqstp,= struct dentry *dentry, return status; } =20 +static unsigned int +nfsd_notify_to_ignore_mask(u32 notify) +{ + unsigned int mask =3D 0; + + if (notify & BIT(NOTIFY4_REMOVE_ENTRY)) + mask |=3D FL_IGN_DIR_DELETE; + if (notify & BIT(NOTIFY4_ADD_ENTRY)) + mask |=3D FL_IGN_DIR_CREATE; + if (notify & BIT(NOTIFY4_RENAME_ENTRY)) + mask |=3D FL_IGN_DIR_RENAME; + + return mask; +} + /** * nfsd_get_dir_deleg - attempt to get a directory delegation * @cstate: compound state @@ -9569,12 +9584,12 @@ nfsd_get_dir_deleg(struct nfsd4_compound_state *cst= ate, if (!dp) goto out_delegees; =20 - fl =3D nfs4_alloc_init_lease(dp); + fl =3D nfs4_alloc_init_lease(dp, + nfsd_notify_to_ignore_mask(gdd->gdda_notification_types[0])); if (!fl) goto out_put_stid; =20 - status =3D kernel_setlease(nf->nf_file, - fl->c.flc_type, &fl, NULL); + status =3D kernel_setlease(nf->nf_file, fl->c.flc_type, &fl, NULL); if (fl) locks_free_lease(fl); if (status) --=20 2.49.0 From nobody Thu Dec 18 14:10:55 2025 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 CEC3F23F271; Mon, 2 Jun 2025 14:03: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=1748873000; cv=none; b=hm4LbCoHFdtbxEFxGYadZZRK+9BblLTeEUfOAZm1Wdy25XxrO/sGg08XlyTnwAxHXOpGvFnw9fN3qWLS+WXGYQaboC0gR2fDX3A3gIKS/51ZIzP8haQwY28Lw8O+/dJCnNcrVAzARaw04e/m0KuVQjUgVvzXyrW/rw41nGdnAj4= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1748873000; c=relaxed/simple; bh=9e+P0L/QsD4juhtFT+7NMVrWkPdeOAQ/vSzBn2kNXLM=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=CFC8HFwn6874wtUQ7ZVJGhcA9Zl0BeQwDy/TAahaia0W3LaAei5vmwW78LWH6VnfrkUIvkmNFd2S8J2KcFzSG5ke7lDQ/WOZB6d1y4AgMGH3aLG/PKg6wBAplVIx8ykHi+h3hnOXk5RBa+dWo0xykM8CT8k4EhaU5lKqpYM7lco= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=LRL8vvk2; 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="LRL8vvk2" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 6946CC4CEF0; Mon, 2 Jun 2025 14:03:15 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1748872997; bh=9e+P0L/QsD4juhtFT+7NMVrWkPdeOAQ/vSzBn2kNXLM=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=LRL8vvk2DQjer13Ucxib56Lne1A87J4uDDdrOMGl/0mZoqlGrxQL8JRi0AhloJKrU lrim3qTrlgdyPxvErVvl2k43i2TkC6BID+FEappT9SJyU7NFChl79yxJKb0xZfGpm1 IyFmSMCjSMTMDb/SP5HXPNu8/bPbD0fSOKRZ6lh0xc2SwOaOCphi+VJFQf49m9z2IK TgsNTIPGk7Fe+tg6xSogGI8n+sgI93OV5Ti1F+mqm08nVLgjwjnzhQZyJ+vaeR9/Ej EQuzVGEep1XZ0TpdBvJWuFEvEv2tDm81SVXC3adJxfdXuWkAXTNv0ucETRhhFwRG+1 YMTwQ5bwcdMYA== From: Jeff Layton Date: Mon, 02 Jun 2025 10:02:09 -0400 Subject: [PATCH RFC v2 26/28] nfsd: add a tracepoint for nfsd_file_fsnotify_handle_dir_event() Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20250602-dir-deleg-v2-26-a7919700de86@kernel.org> References: <20250602-dir-deleg-v2-0-a7919700de86@kernel.org> In-Reply-To: <20250602-dir-deleg-v2-0-a7919700de86@kernel.org> To: Alexander Viro , Christian Brauner , Jan Kara , Chuck Lever , Alexander Aring , Trond Myklebust , Anna Schumaker , Steve French , Paulo Alcantara , Ronnie Sahlberg , Shyam Prasad N , Tom Talpey , Bharath SM , NeilBrown , Olga Kornievskaia , Dai Ngo , Jonathan Corbet , Amir Goldstein , Miklos Szeredi Cc: linux-fsdevel@vger.kernel.org, linux-kernel@vger.kernel.org, linux-nfs@vger.kernel.org, linux-cifs@vger.kernel.org, samba-technical@lists.samba.org, linux-doc@vger.kernel.org, Jeff Layton X-Mailer: b4 0.14.2 X-Developer-Signature: v=1; a=openpgp-sha256; l=3304; i=jlayton@kernel.org; h=from:subject:message-id; bh=9e+P0L/QsD4juhtFT+7NMVrWkPdeOAQ/vSzBn2kNXLM=; b=owEBbQKS/ZANAwAKAQAOaEEZVoIVAcsmYgBoPa7qGCN/tyFSnu4EEdOIYj4brEKvdCzRvMcHJ /gm023Cew+JAjMEAAEKAB0WIQRLwNeyRHGyoYTq9dMADmhBGVaCFQUCaD2u6gAKCRAADmhBGVaC FUt3D/4gPw1XPr/4jvmQgwN2G714b3xAZZh9r/Ysn8hIVq66LlW1U5l5tKa9lpUiIMscuC54Tn0 ctxBK9a15TQaJANvZ/fo6swDSRwj37PYN/2SByvWWWnD8Mj8zqIxW3gBnIQxOyt1P+Yvh7UpvAS n5T2ARMVtzOJ+9PiAw1cPaeXsvUTDpfARqUt2iYcwxc2XCpO9c1/tWneLqLvHH01fJGhP8ObMGB IN5MPejhq5qhrQc9L87/B2tO10mRC0AXozfcgXJkAI0Iljcpcwa9cxokSuSqgBkNleoW+fLr9P+ vanhIqH/0QRxp4ZRnA46V4uMyQbIiGaCYxDWr6DzefTvme2Cs60KEkCWUfZwzifyc/wDe9FGJ9k RFnvVhB2WICiu3/7EAC0S2Uo1SpM0idc+zAG91lw9kRAdGoyYw5yVwpw04MjxrcR0QdmCgOmlNH UUtXgu9yfoEtx//3bphe6ntaIlVl8ofmnsIl2w/5HJzYP8YdxWiXS3kM2/b7dOSoexq0bUJ09/O dn73a+i1X2w6b7HxwsCBCL7v7kIVjp/2qEZgBSiH6lcbE5y3A89b3epF1/IewkbK+vz1Okvt1wI xIDej8HsUsDDKuHIymkWQnQ7+XLhdF87M1uucjyaqiSaSMrpdpGriqb1f+/AICNYlFxFv4RYbSc fuQsIoH0DJF2N0A== X-Developer-Key: i=jlayton@kernel.org; a=openpgp; fpr=4BC0D7B24471B2A184EAF5D3000E684119568215 Repurpose the existing nfsd_file_fsnotify_handle_event tracepoint() as a class and call it from the dir notificaiton codepath. Add info about the dir to it. Signed-off-by: Jeff Layton --- fs/nfsd/filecache.c | 2 +- fs/nfsd/nfs4state.c | 3 +++ fs/nfsd/trace.h | 25 ++++++++++++++++++------- 3 files changed, 22 insertions(+), 8 deletions(-) diff --git a/fs/nfsd/filecache.c b/fs/nfsd/filecache.c index 6cd4cfa0b46bf33c4134987a12e42c8455fc4879..ba72470b870cd0e266ba7fac817= 4a1a249a840e8 100644 --- a/fs/nfsd/filecache.c +++ b/fs/nfsd/filecache.c @@ -743,7 +743,7 @@ nfsd_file_fsnotify_handle_event(struct fsnotify_mark *m= ark, u32 mask, if (WARN_ON_ONCE(!inode)) return 0; =20 - trace_nfsd_file_fsnotify_handle_event(inode, mask); + trace_nfsd_file_fsnotify_handle_event(inode, dir, mask); =20 /* Should be no marks on non-regular files */ if (!S_ISREG(inode->i_mode)) { diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c index a75179ffa6006868bae3931263830d7b7e1a8882..a610a90d119a771771cdb60ce3e= e4ab3604cb8a3 100644 --- a/fs/nfsd/nfs4state.c +++ b/fs/nfsd/nfs4state.c @@ -9640,9 +9640,12 @@ int nfsd_handle_dir_event(u32 mask, const struct inode *dir, const void *data, int data_type, const struct qstr *name) { + struct inode *inode =3D fsnotify_data_inode(data, data_type); struct file_lock_context *ctx; struct file_lock_core *flc; =20 + trace_nfsd_file_fsnotify_handle_dir_event(inode, dir, mask); + ctx =3D locks_inode_context(dir); if (!ctx || list_empty(&ctx->flc_lease)) return 0; diff --git a/fs/nfsd/trace.h b/fs/nfsd/trace.h index 0c68df50eae248c7c9afe0437dfcf29837e09275..968e13a721942c051448f21af2f= 13849511b7c6a 100644 --- a/fs/nfsd/trace.h +++ b/fs/nfsd/trace.h @@ -1293,25 +1293,36 @@ TRACE_EVENT(nfsd_file_is_cached, ) ); =20 -TRACE_EVENT(nfsd_file_fsnotify_handle_event, - TP_PROTO(struct inode *inode, u32 mask), - TP_ARGS(inode, mask), +DECLARE_EVENT_CLASS(nfsd_file_fsnotify_handle_event_class, + TP_PROTO(const struct inode *inode, const struct inode *dir, u32 mask), + TP_ARGS(inode, dir, mask), TP_STRUCT__entry( - __field(struct inode *, inode) + __field(ino_t, ino) + __field(ino_t, dir) __field(unsigned int, nlink) __field(umode_t, mode) __field(u32, mask) ), TP_fast_assign( - __entry->inode =3D inode; + __entry->ino =3D inode->i_ino; + __entry->dir =3D dir ? dir->i_ino : 0; __entry->nlink =3D inode->i_nlink; __entry->mode =3D inode->i_mode; __entry->mask =3D mask; ), - TP_printk("inode=3D%p nlink=3D%u mode=3D0%ho mask=3D0x%x", __entry->inode, - __entry->nlink, __entry->mode, __entry->mask) + TP_printk("dir=3D%lu inode=3D%lu nlink=3D%u mode=3D0%ho mask=3D0x%x", + __entry->dir, __entry->ino, __entry->nlink, + __entry->mode, __entry->mask) ); =20 +#define DEFINE_NFSD_FSNOTIFY_HANDLE_EVENT(name) \ +DEFINE_EVENT(nfsd_file_fsnotify_handle_event_class, name, \ + TP_PROTO(const struct inode *inode, const struct inode *dir, u32 mask), \ + TP_ARGS(inode, dir, mask)) + +DEFINE_NFSD_FSNOTIFY_HANDLE_EVENT(nfsd_file_fsnotify_handle_event); +DEFINE_NFSD_FSNOTIFY_HANDLE_EVENT(nfsd_file_fsnotify_handle_dir_event); + DECLARE_EVENT_CLASS(nfsd_file_gc_class, TP_PROTO( const struct nfsd_file *nf --=20 2.49.0 From nobody Thu Dec 18 14:10:55 2025 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 A741723E329; Mon, 2 Jun 2025 14:03: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=1748872999; cv=none; b=X8NugnmHjdAypIa4Ksxuc24NbVGrnZ6WZewWhdTgT1A4+tDvkOpViJKI+HOmInsTfpKqJjqKXdV4jGsk1EcEWTvPyQnyLehAgQkr0xO8HXYCnofUVLs4HeJwfRDQfvhe0dXT7WcDrtBXh/ntbcyOFB3Cgiqq5cKMzjAqPVvtwwA= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1748872999; c=relaxed/simple; bh=59lO1H0HFaeJYRaOFknHPnKwbcMhKqcR1RcYJk3zJp8=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=e161TTreukv3rEN1LPT9iw8YYKShjmxiSsiA5TAGmS59uKG6DniclODbnfLWOtWuSUDe6Cy6H3lO/8iZbYtionWYeMFPgohRmS+zskOJXBc/DPJLyDQ/WbRmUuQwhpoWWQt23+zpIPCQV9T/Nkk0VDaMV4h67ef6QqpRDpA9c7U= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=E7sY1J7U; 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="E7sY1J7U" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 86FDEC4CEF3; Mon, 2 Jun 2025 14:03:17 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1748872999; bh=59lO1H0HFaeJYRaOFknHPnKwbcMhKqcR1RcYJk3zJp8=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=E7sY1J7U36lAQIjOSujstSEN9p95d/5eGbViNZHlF7bmw4ugPeuLDAbyHwM99WPRw AaCbTiGvz0rDx8VtndbetUPgJttSJsiGec0QCqzr/XhdHpVciZCv/oo6BDiDbLObwF hU7Ud5Cff89h8Ys4ay/jCzEX1o87MzxbNv88OkXHycg220Clyjzn0BBSNKvmd2Ygrq J4Tzxn/zxeVBfvX/CcfA9yXGqxdxcNjrXIH4yPhxqI35/zSfBIJTBtCrPb0EEsmHh+ SpxrkdwsKxUYrHV4u6siQz/bnlGzcZBgEHuG//3a9XKY1IGrVQWzZAALcHEH/Rn4O6 +6qBnypRG0z9g== From: Jeff Layton Date: Mon, 02 Jun 2025 10:02:10 -0400 Subject: [PATCH RFC v2 27/28] nfsd: add support for NOTIFY4_ADD_ENTRY events Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20250602-dir-deleg-v2-27-a7919700de86@kernel.org> References: <20250602-dir-deleg-v2-0-a7919700de86@kernel.org> In-Reply-To: <20250602-dir-deleg-v2-0-a7919700de86@kernel.org> To: Alexander Viro , Christian Brauner , Jan Kara , Chuck Lever , Alexander Aring , Trond Myklebust , Anna Schumaker , Steve French , Paulo Alcantara , Ronnie Sahlberg , Shyam Prasad N , Tom Talpey , Bharath SM , NeilBrown , Olga Kornievskaia , Dai Ngo , Jonathan Corbet , Amir Goldstein , Miklos Szeredi Cc: linux-fsdevel@vger.kernel.org, linux-kernel@vger.kernel.org, linux-nfs@vger.kernel.org, linux-cifs@vger.kernel.org, samba-technical@lists.samba.org, linux-doc@vger.kernel.org, Jeff Layton X-Mailer: b4 0.14.2 X-Developer-Signature: v=1; a=openpgp-sha256; l=2234; i=jlayton@kernel.org; h=from:subject:message-id; bh=59lO1H0HFaeJYRaOFknHPnKwbcMhKqcR1RcYJk3zJp8=; b=owEBbQKS/ZANAwAKAQAOaEEZVoIVAcsmYgBoPa7rIM5QBqdRTXsqVsis2QI9j4EVcJx+ejfPm Xe+c+6GkPqJAjMEAAEKAB0WIQRLwNeyRHGyoYTq9dMADmhBGVaCFQUCaD2u6wAKCRAADmhBGVaC Fel8EACuokS+qrJPqj8zBdVTDNgwG58ld1ZrqJbTMNMco5yHuFKVS5rQW/v0EkbXUkqcFd64fp3 uq5ZMYMAzQTuC6bgdYLrK3aG3ugKSueTgHk3zEwH6xDuU8oFr4PnMqQMnmaowXbH3Wz0e3rah5w KkR8ogpK63qTrDooocrBySPFMGjdcUU4tPeiACQNEWOhRVh8X67oLTD/yV5N7GCOApF8FkdyXxI bw9Whr9pXzHaVK8Ee1YprvC5J/4m32/93f0bVcW7RNlbcckdi3PoB7oI9J0yfFuQ2X7nVFeQ9IP G8Ak9okfpKptMfiXGcecWZimnB2bz4uxIEX4NWMHXEyG7u5gEnwxd/Z5LIFvEvWuyVrwLd8NiS+ RMiFXFD8T8JguzgmVMf4Ifssh57bIgXin9G4fSaUGQWQyTRMCZlCNqze79XBhpIDNQq4SrBe/gF WHlW1amr1/+2FRlJKs1Iv1dB1BkJEVl5PF4Pb9BTZR8xzU7EYvPNVN0MbWaTa+gpDv2xVwLE1NV 5xLhejbXvczNk8Fnllw2eSjMELJUvtMbcm6LY4RWSqB6vNWUfp7YRxvml/mO4DoG9Yd8AACOY59 R7aQ9QJ6mxpKqWV14vrkYJO2avqaBua2CwilDh5r20zqdSYV4FA+U0AYDbSnqSsorlIAOlrpff7 qmh3/nYBPtqG+EA== X-Developer-Key: i=jlayton@kernel.org; a=openpgp; fpr=4BC0D7B24471B2A184EAF5D3000E684119568215 Add support for handling NOTIFY4_ADD_ENTRY events. When a notification comes in, marshall the event to the notify_spool and kick off the callback. Signed-off-by: Jeff Layton --- fs/nfsd/nfs4proc.c | 2 +- fs/nfsd/nfs4state.c | 25 +++++++++++++++++++++++++ 2 files changed, 26 insertions(+), 1 deletion(-) diff --git a/fs/nfsd/nfs4proc.c b/fs/nfsd/nfs4proc.c index 77b6d0363b9f4cfea96f3f1abd3e462fd2a77754..a2996343fa0db33e014731f62aa= a4e7c72506a76 100644 --- a/fs/nfsd/nfs4proc.c +++ b/fs/nfsd/nfs4proc.c @@ -2292,7 +2292,7 @@ nfsd4_verify(struct svc_rqst *rqstp, struct nfsd4_com= pound_state *cstate, return status =3D=3D nfserr_same ? nfs_ok : status; } =20 -#define SUPPORTED_NOTIFY_MASK BIT(NOTIFY4_REMOVE_ENTRY) +#define SUPPORTED_NOTIFY_MASK BIT(NOTIFY4_REMOVE_ENTRY|NOTIFY4_ADD_ENTRY) =20 static __be32 nfsd4_get_dir_delegation(struct svc_rqst *rqstp, diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c index a610a90d119a771771cdb60ce3ee4ab3604cb8a3..9dc607e355d5839d80946d49832= 05c15ece6a71e 100644 --- a/fs/nfsd/nfs4state.c +++ b/fs/nfsd/nfs4state.c @@ -9697,6 +9697,31 @@ nfsd_handle_dir_event(u32 mask, const struct inode *= dir, const void *data, ent->notify_vals.data =3D p; ++nns->nns_idx; } + if (mask & FS_CREATE) { + static uint32_t notify_add_bitmap =3D BIT(NOTIFY4_ADD_ENTRY); + struct notify4 *ent =3D &nns->nns_ent[nns->nns_idx]; + struct notify_add4 na =3D { }; + u8 *p =3D (u8 *)(stream->p); + + if (!(flc->flc_flags & FL_IGN_DIR_CREATE)) + continue; + + na.nad_new_entry.ne_file.len =3D name->len; + na.nad_new_entry.ne_file.data =3D (char *)name->name; + na.nad_new_entry.ne_attrs.attrmask.count =3D 1; + na.nad_new_entry.ne_attrs.attrmask.element =3D &zerobm; + if (!xdrgen_encode_notify_add4(stream, &na)) { + pr_warn("nfsd: unable to marshal notify_add4 to xdr stream\n"); + continue; + } + + /* grab a notify4 in the buffer and set it up */ + ent->notify_mask.count =3D 1; + ent->notify_mask.element =3D ¬ify_add_bitmap; + ent->notify_vals.len =3D (u8 *)stream->p - p; + ent->notify_vals.data =3D p; + ++nns->nns_idx; + } =20 if (nns->nns_idx) nfsd4_run_cb_notify(ncn); --=20 2.49.0 From nobody Thu Dec 18 14:10:55 2025 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 19FDF2405FD; Mon, 2 Jun 2025 14:03: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=1748873002; cv=none; b=TIoc6I/ZzqkYEKwje6n3Cz1wbi7ayECZmVejbztFer6fZFwy4cJJIcevudxMdr248sGx6bj9gH16sXsXJavgTOA7uQMbtkI70oTwJEf8LJZK3GPTKarBRbXyzlb45s5XsSQeUoWqRlRo11Cn8/xghapa0smATkGgNkvHMOvEer4= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1748873002; c=relaxed/simple; bh=WRTUFe5zAa4ehyUDpuZU2A396vCsORsejbqIXvfw4eM=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=Nb4VGUEJAOHQsg0VsNjeVJzcSPxpOMThnFWWyHJPBYLXv0wejvSm86t9Qig5FEpSPbY0i2Ddx2eYsMUPzS9h61h+o+TV04cVaV8MUVcz+wlIj1ZGvExfvk8A5auFY3hl9bmHLtdG0uyr+DsxbinAAHR9BtfEGn7t8TedRlu/Rns= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=d4O0muln; 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="d4O0muln" Received: by smtp.kernel.org (Postfix) with ESMTPSA id A54F5C4CEF6; Mon, 2 Jun 2025 14:03:19 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1748873001; bh=WRTUFe5zAa4ehyUDpuZU2A396vCsORsejbqIXvfw4eM=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=d4O0mulna5zpsC6abaqW7ZzC6op2McHxHnBQVPqnQwhFOlxMsWRGVVWKLUXcf8a9c ohFTvdxrxc7Mw85ldB9a5qQBhmlJxwyhnI3A2zQS2IwOxh1AqxlItPsdXlfHF9ulzu yZjj/k8bPLr0m9dlKgzUOFoIHWUg7nPX5mPdQam6R5qUbEsyJjbdzRH7Kd5fCmDO1g ImOxd8OSI1VJKt5JelTrmpxO82lN+wO7Ddskf308gJgCtkZWMUf40TMHO5LBvSdWXa n88yEb3aCDXEDuEH26sbPdu8rmrtCoVVIHmhmaMURopXs2VOEuq283oc1xJH5V32Yj 8ardsieZOx80w== From: Jeff Layton Date: Mon, 02 Jun 2025 10:02:11 -0400 Subject: [PATCH RFC v2 28/28] nfsd: add support for NOTIFY4_RENAME_ENTRY events Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20250602-dir-deleg-v2-28-a7919700de86@kernel.org> References: <20250602-dir-deleg-v2-0-a7919700de86@kernel.org> In-Reply-To: <20250602-dir-deleg-v2-0-a7919700de86@kernel.org> To: Alexander Viro , Christian Brauner , Jan Kara , Chuck Lever , Alexander Aring , Trond Myklebust , Anna Schumaker , Steve French , Paulo Alcantara , Ronnie Sahlberg , Shyam Prasad N , Tom Talpey , Bharath SM , NeilBrown , Olga Kornievskaia , Dai Ngo , Jonathan Corbet , Amir Goldstein , Miklos Szeredi Cc: linux-fsdevel@vger.kernel.org, linux-kernel@vger.kernel.org, linux-nfs@vger.kernel.org, linux-cifs@vger.kernel.org, samba-technical@lists.samba.org, linux-doc@vger.kernel.org, Jeff Layton X-Mailer: b4 0.14.2 X-Developer-Signature: v=1; a=openpgp-sha256; l=2877; i=jlayton@kernel.org; h=from:subject:message-id; bh=WRTUFe5zAa4ehyUDpuZU2A396vCsORsejbqIXvfw4eM=; b=owEBbQKS/ZANAwAKAQAOaEEZVoIVAcsmYgBoPa7rYWh5WPyBqmd/mpYouoAaeCmO7iYpghNrL 2FZXSv49syJAjMEAAEKAB0WIQRLwNeyRHGyoYTq9dMADmhBGVaCFQUCaD2u6wAKCRAADmhBGVaC FRLAD/9Nrz7K/6BZh3J7GzB7TSD3Iu8DHCsSAkiig2bJ4KYuyJdr/v9vr7B1pSdCR+UN7OFPToX Cm6Lbv3HaVp1569JJ5aYfDQoaZhxDg0IQIajjWvorce9w+r9GbvoOvWAAe5BWBJugD1asZSxQqI wiB9z2fvE0r2MQwvvooV7GfDANY0anAIEkbYzEWIN4fecGqDWn9Frk/3sichSwRgrrOQuYz+o5d zVb+QPivMvVfFmkfe9v8NbGkSFuB40v84Ab3uWvui0QTRbag79oAdWGoo+EYsACgW8fPGxMiPad byakNt0nXAuGnwBKf8zV3emFCUt/PcIcK7soVpY1b5UAXn7lJ2Rn3TKIORKcLJEtIZwXmRxG78a WzbYtyBOGJie63ytKV43ixhN0S8UghXP0Spi7OB2nn7NxwqjT3E52Cb23yNABtf4fbkVKqd0aMm GEnYGTeTvDnC6gzAOYqd0lBVRwPURcrqbWe1kKqJ8fqTjRjJNTJQYtpEyKGWwGrsdpYMtG0AaFj QxE+AnC27WCcQlSJ6dk00isFmg8Sl9aFtZ/anoVk75oIoztNAr+3gbhRNzEs/XNEQV5iIfwWD07 P4nOoepshUDmBrvKd/rsdpJLAH/J8sdZqByh/vnJfaGnhpB5RhXUSakmBErmo95bsnfmRExVT1j IS0rm0gaUtKGXmA== X-Developer-Key: i=jlayton@kernel.org; a=openpgp; fpr=4BC0D7B24471B2A184EAF5D3000E684119568215 Add support for RENAME events. Marshal the event into the notifylist4 buffer and kick the callback handler. Signed-off-by: Jeff Layton --- fs/nfsd/nfs4proc.c | 2 +- fs/nfsd/nfs4state.c | 39 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 40 insertions(+), 1 deletion(-) diff --git a/fs/nfsd/nfs4proc.c b/fs/nfsd/nfs4proc.c index a2996343fa0db33e014731f62aaa4e7c72506a76..4573c0651aa49df6089bcc4e5d4= 0f45d46b1c499 100644 --- a/fs/nfsd/nfs4proc.c +++ b/fs/nfsd/nfs4proc.c @@ -2292,7 +2292,7 @@ nfsd4_verify(struct svc_rqst *rqstp, struct nfsd4_com= pound_state *cstate, return status =3D=3D nfserr_same ? nfs_ok : status; } =20 -#define SUPPORTED_NOTIFY_MASK BIT(NOTIFY4_REMOVE_ENTRY|NOTIFY4_ADD_ENTRY) +#define SUPPORTED_NOTIFY_MASK BIT(NOTIFY4_REMOVE_ENTRY|NOTIFY4_ADD_ENTRY|N= OTIFY4_RENAME_ENTRY) =20 static __be32 nfsd4_get_dir_delegation(struct svc_rqst *rqstp, diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c index 9dc607e355d5839d80946d4983205c15ece6a71e..6333e95c075259af0c160eb1301= 49c776e55f5a8 100644 --- a/fs/nfsd/nfs4state.c +++ b/fs/nfsd/nfs4state.c @@ -9722,6 +9722,45 @@ nfsd_handle_dir_event(u32 mask, const struct inode *= dir, const void *data, ent->notify_vals.data =3D p; ++nns->nns_idx; } + if (mask & FS_RENAME) { + struct dentry *new_dentry =3D fsnotify_data_dentry(data, data_type); + static uint32_t notify_rename_bitmap =3D BIT(NOTIFY4_RENAME_ENTRY); + struct notify4 *ent =3D &nns->nns_ent[nns->nns_idx]; + struct notify_rename4 nr =3D { }; + u8 *p =3D (u8 *)(stream->p); + struct name_snapshot n; + bool ret; + + if (!(flc->flc_flags & FL_IGN_DIR_RENAME)) + continue; + + /* FIXME: warn? */ + if (!new_dentry) + continue; + + nr.nrn_old_entry.nrm_old_entry.ne_file.len =3D name->len; + nr.nrn_old_entry.nrm_old_entry.ne_file.data =3D (char *)name->name; + nr.nrn_old_entry.nrm_old_entry.ne_attrs.attrmask.count =3D 1; + nr.nrn_old_entry.nrm_old_entry.ne_attrs.attrmask.element =3D &zerobm; + take_dentry_name_snapshot(&n, new_dentry); + nr.nrn_new_entry.nad_new_entry.ne_file.len =3D n.name.len; + nr.nrn_new_entry.nad_new_entry.ne_file.data =3D (char *)n.name.name; + nr.nrn_new_entry.nad_new_entry.ne_attrs.attrmask.count =3D 1; + nr.nrn_new_entry.nad_new_entry.ne_attrs.attrmask.element =3D &zerobm; + ret =3D xdrgen_encode_notify_rename4(stream, &nr); + release_dentry_name_snapshot(&n); + if (!ret) { + pr_warn("nfsd: unable to marshal notify_rename4 to xdr stream\n"); + continue; + } + + /* grab a notify4 in the buffer and set it up */ + ent->notify_mask.count =3D 1; + ent->notify_mask.element =3D ¬ify_rename_bitmap; + ent->notify_vals.len =3D (u8 *)stream->p - p; + ent->notify_vals.data =3D p; + ++nns->nns_idx; + } =20 if (nns->nns_idx) nfsd4_run_cb_notify(ncn); --=20 2.49.0