From nobody Sun Feb 8 06:55:58 2026 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 24A0733F8BD; Tue, 21 Oct 2025 15:26:05 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1761060367; cv=none; b=g03I9bW6BrqtqdCMzfWL9sHRGa8Tp3Fbuyp5/Ja8aCzU50QMcjG9in7NBGcqfySJFcsV3Ux6961q7TYqDEmY+5wGI6e9hgg3HGszwRFhNvnHWgjKb1g7JHE+vPsRLqBZncffFO69xtd3t1Ka7zM1RGqrDb2yzhBZ6Sqa6kWTrJ8= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1761060367; c=relaxed/simple; bh=dxvpC5CTwlaM82NIyMQ70G3zBp6uBnMFProuC2fkia0=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=p8IJv+vlEhH9DNRBRxTh1P3q1RoBIFtPFMWZWbymruImHGSRsIZ9c4kDayQ/y8MaRo5L7RgoYj6xwKeSJiOIfX+6wUT+cwcBcy+DSUqpRS3pY8JG02bA8ne8m30BXt4vG/f5pjJjqNdP3dgSynM7JQOT1sLBhKoI8PFbpkM97/k= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=cgd6jLI9; 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="cgd6jLI9" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 7000DC4CEF1; Tue, 21 Oct 2025 15:26:02 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1761060365; bh=dxvpC5CTwlaM82NIyMQ70G3zBp6uBnMFProuC2fkia0=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=cgd6jLI9KhRmkTrcC91F3FAzaNa22cpBHHtb/iHHqslEn4zxhJNvly48bNPs9ucfK 6aF4gw2e3vBB2Ns1dOOKWYdjjwYJxVgLOaqfq8xSxCwyZeJRgsYvmH9xzm2EdlM41G JEJKGP6i+F1qIxSrAozELSdqOWGvax7S4LqyOctQwx0eGqTwbGu0AHKRxZl5jofamp iTkpSgZFBZ4owLDY3sec8abljxPtZ0fEW6y9wOhEkmmwriQ0ekA9AidJllJ8bMH1DA YjDhopKBEowwz4YHPEyUM5KKSDAgW3uf7AMBKswsR6A5hC07JdezA81NlqOxlKEoCZ oiM8W+RuRrgVQ== From: Jeff Layton Date: Tue, 21 Oct 2025 11:25:36 -0400 Subject: [PATCH v3 01/13] 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: <20251021-dir-deleg-ro-v3-1-a08b1cde9f4c@kernel.org> References: <20251021-dir-deleg-ro-v3-0-a08b1cde9f4c@kernel.org> In-Reply-To: <20251021-dir-deleg-ro-v3-0-a08b1cde9f4c@kernel.org> To: Miklos Szeredi , 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 , Greg Kroah-Hartman , "Rafael J. Wysocki" , Danilo Krummrich , David Howells , Tyler Hicks , NeilBrown , Olga Kornievskaia , Dai Ngo , Amir Goldstein , Namjae Jeon , Steve French , Sergey Senozhatsky , Carlos Maiolino , Kuniyuki Iwashima , "David S. Miller" , Eric Dumazet , Jakub Kicinski , Paolo Abeni , Simon Horman 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, netfs@lists.linux.dev, ecryptfs@vger.kernel.org, linux-unionfs@vger.kernel.org, linux-xfs@vger.kernel.org, netdev@vger.kernel.org, Jeff Layton X-Mailer: b4 0.14.2 X-Developer-Signature: v=1; a=openpgp-sha256; l=3451; i=jlayton@kernel.org; h=from:subject:message-id; bh=dxvpC5CTwlaM82NIyMQ70G3zBp6uBnMFProuC2fkia0=; b=owEBbQKS/ZANAwAKAQAOaEEZVoIVAcsmYgBo96YEVYLznz73RG2SG2lZYGviOe6oYp7vdP463 dBJqnqKDm+JAjMEAAEKAB0WIQRLwNeyRHGyoYTq9dMADmhBGVaCFQUCaPemBAAKCRAADmhBGVaC FbNuD/9rHiRNhZ4IMbW65OW8jit0py4NylV+LNDh5XD1QLhkZtGe5K89UxF7Bm37UL9Xrgf/zzk JUWRS5hfZfnJsAWCDKiUIGBT3eNOAn1ET5tMB1DjXZoODfNxl0Huis1dbyq2nVfkq5jN5DajtEQ qnZosPPdiIgP22s/4jcILFMY14Axa7/1nRFcLMpB2sQXwL2OVQtYJD4Hv50U/dQ0i4jRdhYkmPM dVR+WRKMCJcmAc4IaOhGWBKiol43Pyy0RqrqdITgOC4P9DZoBm1EMwgBRSFPdRSqioB13w+o1to LWbyOYCEP+uaf1kKxAiFSBvUBQb0IDcgBsyUyYd1AR128p0CvqjIaYbJ6SRfZi/FsV0DmsVE+Ir yvJwjG1ANo/Zsv6Lrzmxu3xNzyZFRa2ABikyi90SJKXoi7z7nNAndVwpkK4L7h3ZCKFs1sEs0O7 jXVjapzr3UmVwg4bvtDGLRTMWbXYOtyPa64rI9T0hial9saTZZ5LwwWUTPQc447CwB1gIeGwJyp nfMjMouvNOTFHGYuwXU14uHMhHKZCpIF9VFLmylMPZQc4Hhp7gFBKdv4hsXBDGnhg8X6OpCTKLe hHA8v5f6B2D49NiiGlB/NuO+CvmDl3RzgJVT2TFnoLGXV6H9AGRd7rFrklCSPtmDp1djAoiEMci DH1XyNEa4/PsP/Q== 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 special: It's the only filesystem that supports atomic_open and allows kernel-internal leases. atomic_open is issued when the VFS doesn't know the state of the dentry being opened. If the file doesn't exist, it may be created, in which case the dir lease should be broken. The existing kernel-internal lease implementation has no provision for this. Ensure that we don't allow directory leases by default going forward by explicitly disabling them there. Reviewed-by: NeilBrown Signed-off-by: Jeff Layton Reviewed-by: Jan Kara --- 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 ecaec0fea3a132e7cbb88121e7db7fb504d57d3c..667774cc72a1d49796f531fcb34= 2d2e4878beb85 100644 --- a/fs/fuse/dir.c +++ b/fs/fuse/dir.c @@ -2230,6 +2230,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 04a3f0e2072461b6e2d3d1cd12f2b089d69a7db3..0b16921fb52e602ea2e0c3de39d= 9d772af98ba7d 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 7f43e890d3564a000dab9365048a3e17dc96395c..7317f26892c5782a39660cae87e= c1afea24e36c0 100644 --- a/fs/nfs/nfs4file.c +++ b/fs/nfs/nfs4file.c @@ -431,6 +431,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 4f959f1e08d235071a151c1438c753fcd05099e5..1522c6b61b48c05c93f2bedeab0= d35b6d85378e2 100644 --- a/fs/smb/client/cifsfs.c +++ b/fs/smb/client/cifsfs.c @@ -1149,6 +1149,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.51.0 From nobody Sun Feb 8 06:55:58 2026 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 326BF3446B5; Tue, 21 Oct 2025 15:26:09 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1761060369; cv=none; b=JOqqgZ4Eya1C/d4PJ55pU9UdN/pdJ+SsOKgHKZ3Zl2mV1q16EXG1FN+eXDrNzODIQJ58zIVb4AZ1j/WJhJUPnJ4u1myfDl+9KShhpJcsnXMZsQfF/mIZQ8pxvHNiiOadaQljmw0/K5lgO1s5FwCLMNLrJkCuBjF1UP1YwauZxLM= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1761060369; c=relaxed/simple; bh=i348Ph7fxJZlvNatYcFVNpQ/4JzywLWgI/chglRS2Bk=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=nMKQu0FSIX89EqgN2m6z425thO4r9KKewmxBT0ru1FlS13+ERV0NbMA/oz0IDH95Dflfu/mUO658/WeiQUH7kXFf0xqdwt3FzdCL3xJzVV0HPzIaU6Kj2rw/lTLNXT3qopCrmhaRqnvItXhYA52U1xkZaw2BNB6Pc7W1DJ1MuVE= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=KZNAWojH; 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="KZNAWojH" Received: by smtp.kernel.org (Postfix) with ESMTPSA id D2DEEC4CEF5; Tue, 21 Oct 2025 15:26:05 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1761060369; bh=i348Ph7fxJZlvNatYcFVNpQ/4JzywLWgI/chglRS2Bk=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=KZNAWojHSy0zMPLG2xp6wivs9G8aFPa8C8r9uP2a5IrVN9y3NVaZDv1JkpXCBpCIM ST8OgKfLxXMQtxryT95GKpqKO4weyBNYPg8pqN9A3U6hzu7ykXlR885dKzYqV9AxNs 9anObsKA1PNJbqB/8jKpma6b5mVCbDq0mzR6R/GXkxNOnzLnhH/ldXwM6VXxUsLJ1Y qG0eUmnQKR89yTyCNvOSPNT8Zsy3YwuzmttQevfeBew5EEjs2jGeJNBBSjJsI8pPue MGWlweEjr2nvfNI946p3qn4dM5oTvWRWUFd8dVdMi3oQBI+oj9cVW+sbI2E6Z55/m2 hhgm3k6IIfyww== From: Jeff Layton Date: Tue, 21 Oct 2025 11:25:37 -0400 Subject: [PATCH v3 02/13] 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: <20251021-dir-deleg-ro-v3-2-a08b1cde9f4c@kernel.org> References: <20251021-dir-deleg-ro-v3-0-a08b1cde9f4c@kernel.org> In-Reply-To: <20251021-dir-deleg-ro-v3-0-a08b1cde9f4c@kernel.org> To: Miklos Szeredi , 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 , Greg Kroah-Hartman , "Rafael J. Wysocki" , Danilo Krummrich , David Howells , Tyler Hicks , NeilBrown , Olga Kornievskaia , Dai Ngo , Amir Goldstein , Namjae Jeon , Steve French , Sergey Senozhatsky , Carlos Maiolino , Kuniyuki Iwashima , "David S. Miller" , Eric Dumazet , Jakub Kicinski , Paolo Abeni , Simon Horman 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, netfs@lists.linux.dev, ecryptfs@vger.kernel.org, linux-unionfs@vger.kernel.org, linux-xfs@vger.kernel.org, netdev@vger.kernel.org, Jeff Layton X-Mailer: b4 0.14.2 X-Developer-Signature: v=1; a=openpgp-sha256; l=1915; i=jlayton@kernel.org; h=from:subject:message-id; bh=i348Ph7fxJZlvNatYcFVNpQ/4JzywLWgI/chglRS2Bk=; b=owEBbQKS/ZANAwAKAQAOaEEZVoIVAcsmYgBo96YESrzIdn0YyHqW0yDMTvi1tTcZpTcDxDe55 NNB2EfxRnWJAjMEAAEKAB0WIQRLwNeyRHGyoYTq9dMADmhBGVaCFQUCaPemBAAKCRAADmhBGVaC FaShEAC7Aq23NlSZeHJDisQkXnXppDvQlgXgqlrBkyprAdVBYTB02zjmLMSisSrLjw/8Ubt5xAf LAoSAe3cc0bPVW1H7nersMBONx3k6M2AhV7Tk8/Txj6oyuEh02z4uaAhXZ1O/ahqK9QGFhvxw3w iHkHLluu1KqjHXfm1b1luACSjxYuh9MSJRrOLHXZQorM9ad70ncsp/pzgq6JJWXGB3k4hOK0AQi 3NzKtsSC9kzcMfNrQUxqshhp4OjEGqhIs80EqzhIL9fw301TztNF/6nEELVrSZHrM66hsqMUpgC 0EhRPdK8pCFAxV2jclcIlwlytSWdzdV3ujYs4mjMP0erP5cQPl2vu+ZGVLpXOwQyK6tAKlJGmEy LKEV1e5IdIlkcB/hbqPuDgvmrKAkUlIiB4nxzCgNxfkQYHnQXUbV7oeZB/SRZ3fqt+93za8PyHD CeE0A46aD2MEBBz+oSg8wOpw1UbQuoBNoWJ1Bwki1T98lb98ga4cWkML2J+QTggqgbymSXHJgXB vplUt0C2yMvxLRFKi/3kUsgCBuJnz39uBEaAI35RQ9EuTJHjM4RRH02CHfggoFNbITfPpdQQWOB Q+7hFHWvRRawbvuWkpGfB9qH8I2ZLYDdK/9WCEMK4/u+nQXJ79uqRs9H/746M/3AIAehNnfqQ47 N/rtmRAkAxlIV+Q== 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. Reviewed-by: Jan Kara Reviewed-by: NeilBrown 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 7377020a2cba02501483020e0fc93c279fb38d3e..6e61e0215b34134b1690f864e27= 19e3f82cf71a8 100644 --- a/fs/namei.c +++ b/fs/namei.c @@ -4667,6 +4667,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; @@ -4936,7 +4939,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); } @@ -5203,6 +5208,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.51.0 From nobody Sun Feb 8 06:55:58 2026 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 EE603343218; Tue, 21 Oct 2025 15:26:12 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1761060373; cv=none; b=BmQo476v+4xBLzaq+V8rh8sgK8GcQHdRvLQnOdGnH7Mm11tY7H3fVb/d/1k/Ovzi3Oqz9w3ss4bCmmR3gFoR89ilNBe5wjbzYbygD1Y+0RqGta8aQqtasNfMDAWeOTiAwW7XFdnaGMgb2BNiEEz/hhDpB6UyPw6l8qMnVtbXqvw= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1761060373; c=relaxed/simple; bh=fquIbNNyhedSINPdZZrOQAlr1sZhilSlFO2OBS1kyRE=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=ZXrVMeLixcg7FVkBFIFgr/OlurFaHTfaJhh7M1htfNR5xk7pXVhbBLc462nSHX5vij5eGayZ+FZeUMdlXmEjS0STqg3acZBaWDqERxGGSNi6KuJRFxn+7y9N1yPUAoIKR8ITjWyr1kVLHNHVLnAoR8NocyHQem5iwomkAYtdiMk= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=QNUrwMoF; 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="QNUrwMoF" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 3FA94C4CEFF; Tue, 21 Oct 2025 15:26:09 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1761060372; bh=fquIbNNyhedSINPdZZrOQAlr1sZhilSlFO2OBS1kyRE=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=QNUrwMoFfsN8arTX9+A9dfCjce3GPfmD+AsKqx7ZgwL2/L7kgr7w8a+0KFNK2BG32 uz9BuyeJlCVjQxWPsfZJY2cNeitCAuXwZXSR20v0kexFSj7Ugy2Z1Eg60ekXOlwEzx sb4Zvtvc4z1M4X5G1rXwjK41QQT2gGm7RIbyJKuaxKhSV+1QJurZXN8WJ/dPzWCz5p Uehbo/rfQ9Wp4+gWhvw0wQm0cDncjR43Ncm748VrIzHnQYpBXzlB9dzqjvQ+QKrSP7 ykLkgxI47uqDvQ+UoWvhx6w5jKQXCQcvo/kmXFl9N5Ip+sY7LjQZuvL63S9m5tQ3JM mwOWt/HB/gbHQ== From: Jeff Layton Date: Tue, 21 Oct 2025 11:25:38 -0400 Subject: [PATCH v3 03/13] 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: <20251021-dir-deleg-ro-v3-3-a08b1cde9f4c@kernel.org> References: <20251021-dir-deleg-ro-v3-0-a08b1cde9f4c@kernel.org> In-Reply-To: <20251021-dir-deleg-ro-v3-0-a08b1cde9f4c@kernel.org> To: Miklos Szeredi , 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 , Greg Kroah-Hartman , "Rafael J. Wysocki" , Danilo Krummrich , David Howells , Tyler Hicks , NeilBrown , Olga Kornievskaia , Dai Ngo , Amir Goldstein , Namjae Jeon , Steve French , Sergey Senozhatsky , Carlos Maiolino , Kuniyuki Iwashima , "David S. Miller" , Eric Dumazet , Jakub Kicinski , Paolo Abeni , Simon Horman 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, netfs@lists.linux.dev, ecryptfs@vger.kernel.org, linux-unionfs@vger.kernel.org, linux-xfs@vger.kernel.org, netdev@vger.kernel.org, Jeff Layton X-Mailer: b4 0.14.2 X-Developer-Signature: v=1; a=openpgp-sha256; l=9206; i=jlayton@kernel.org; h=from:subject:message-id; bh=fquIbNNyhedSINPdZZrOQAlr1sZhilSlFO2OBS1kyRE=; b=owEBbQKS/ZANAwAKAQAOaEEZVoIVAcsmYgBo96YEQvzAe/BY5zs5Xj08cgX+PpuzZVP7N42Kz DMthrI7EzqJAjMEAAEKAB0WIQRLwNeyRHGyoYTq9dMADmhBGVaCFQUCaPemBAAKCRAADmhBGVaC FbGFD/9p1bzJRPPUavhf7yyhGVO/rQ/tQUSKEbYiThgW85u8P08BgCNbqm3Utd4VWqR9Ljd/o6u iplhVvFGa+cjrvu8Fg93oKwZGENyXeHwOlLJnXR3J91OzDCnOFDrvJ1NpoE4MHWAVH7imUlYxaf bpCNiPoEPznhGu1V7oFFoHRXF3p34WHd2JedfwOXL/xt+hY2LA3H8cx6Wop0FYPt3rjNngS4HNn qXgXya459zjx9k3XKGQ2aaJAqyrLaL51H/xLeMDnDr5wCSWTK+QbOfahxuRk4gH2LmZpw9q+kIh GpuEKwoZFxnVUG29eHlnGVyINE2Ke5nnwxfYhQR3VF5MGY8w9NRRlIWP4dJzqUHt+dm9w0z0gXw LZcsKXBM4WuDjMzCz/nEddhZW9sJH45KqCCdELTnxPdBtx0qGcYgOz7OciBgCtxSibdqaBU2qE0 FWFlFScIZzhoep2bkHtbJSJMcox0OG/+hN5h8EbxAbeS4ahARaM9bxeNmg6516vVCoRomRqYwsx 75LWjWquhOPPTiYPpyhRlv2gAQBsjG0ZjFrQ3FbdRjWb4UF0QzAJIZO/U8WIr1RPgyLEt9iRVGe h7PppVVvmuIKnBkF7SGYXr6L0mTDM2mF7MkEl7N3Y9jWvIp9zjIjA9fHXtQ6ekqtgtJl2eLLkzk 2n0/P6kabXZlOIA== 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 new delegated_inode parameter to vfs_mkdir. All of the existing callers set that to NULL for now, except for do_mkdirat which will properly block until the lease is gone. Reviewed-by: Jan Kara Reviewed-by: NeilBrown Signed-off-by: Jeff Layton --- drivers/base/devtmpfs.c | 2 +- fs/cachefiles/namei.c | 2 +- fs/ecryptfs/inode.c | 2 +- fs/init.c | 2 +- fs/namei.c | 24 ++++++++++++++++++------ fs/nfsd/nfs4recover.c | 2 +- fs/nfsd/vfs.c | 2 +- fs/overlayfs/overlayfs.h | 2 +- fs/smb/server/vfs.c | 2 +- fs/xfs/scrub/orphanage.c | 2 +- include/linux/fs.h | 2 +- 11 files changed, 28 insertions(+), 16 deletions(-) diff --git a/drivers/base/devtmpfs.c b/drivers/base/devtmpfs.c index 9d4e46ad8352257a6a65d85526ebdbf9bf2d4b19..0e79621cb0f79870003b867ca38= 4199171ded4e0 100644 --- a/drivers/base/devtmpfs.c +++ b/drivers/base/devtmpfs.c @@ -180,7 +180,7 @@ static int dev_mkdir(const char *name, umode_t mode) if (IS_ERR(dentry)) return PTR_ERR(dentry); =20 - dentry =3D vfs_mkdir(&nop_mnt_idmap, d_inode(path.dentry), dentry, mode); + dentry =3D vfs_mkdir(&nop_mnt_idmap, d_inode(path.dentry), dentry, mode, = NULL); if (!IS_ERR(dentry)) /* mark as kernel-created inode */ d_inode(dentry)->i_private =3D &thread; diff --git a/fs/cachefiles/namei.c b/fs/cachefiles/namei.c index d1edb2ac38376c4f9d2a18026450bb3c774f7824..50c0f9c76d1fd4c05db90d7d0d1= bad574523ead0 100644 --- a/fs/cachefiles/namei.c +++ b/fs/cachefiles/namei.c @@ -130,7 +130,7 @@ struct dentry *cachefiles_get_directory(struct cachefil= es_cache *cache, goto mkdir_error; ret =3D cachefiles_inject_write_error(); if (ret =3D=3D 0) - subdir =3D vfs_mkdir(&nop_mnt_idmap, d_inode(dir), subdir, 0700); + subdir =3D vfs_mkdir(&nop_mnt_idmap, d_inode(dir), subdir, 0700, NULL); else subdir =3D ERR_PTR(ret); if (IS_ERR(subdir)) { diff --git a/fs/ecryptfs/inode.c b/fs/ecryptfs/inode.c index ed1394da8d6bd7065f2a074378331f13fcda17f9..35830b3144f8f71374a78b3e746= 3b864f4fc216e 100644 --- a/fs/ecryptfs/inode.c +++ b/fs/ecryptfs/inode.c @@ -508,7 +508,7 @@ static struct dentry *ecryptfs_mkdir(struct mnt_idmap *= idmap, struct inode *dir, goto out; =20 lower_dentry =3D vfs_mkdir(&nop_mnt_idmap, lower_dir, - lower_dentry, mode); + lower_dentry, mode, NULL); rc =3D PTR_ERR(lower_dentry); if (IS_ERR(lower_dentry)) goto out; diff --git a/fs/init.c b/fs/init.c index 07f592ccdba868509d0f3aaf9936d8d890fdbec5..895f8a09a71acfd03e11164e3b4= 41a7d4e2de146 100644 --- a/fs/init.c +++ b/fs/init.c @@ -233,7 +233,7 @@ int __init init_mkdir(const char *pathname, umode_t mod= e) error =3D security_path_mkdir(&path, dentry, mode); if (!error) { dentry =3D vfs_mkdir(mnt_idmap(path.mnt), path.dentry->d_inode, - dentry, mode); + dentry, mode, NULL); if (IS_ERR(dentry)) error =3D PTR_ERR(dentry); } diff --git a/fs/namei.c b/fs/namei.c index 6e61e0215b34134b1690f864e2719e3f82cf71a8..86cf6eca1f485361c6732974e41= 03cf5ea721539 100644 --- a/fs/namei.c +++ b/fs/namei.c @@ -4407,10 +4407,11 @@ SYSCALL_DEFINE3(mknod, const char __user *, filenam= e, umode_t, mode, unsigned, d =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 + * @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 + * @delegated_inode: returns parent inode, if the inode is delegated. * * Create a directory. * @@ -4427,7 +4428,8 @@ SYSCALL_DEFINE3(mknod, const char __user *, filename,= umode_t, mode, unsigned, d * 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) + struct dentry *dentry, umode_t mode, + struct inode **delegated_inode) { int error; unsigned max_links =3D dir->i_sb->s_max_links; @@ -4450,6 +4452,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)) @@ -4473,6 +4479,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); @@ -4484,11 +4491,16 @@ int do_mkdirat(int dfd, struct filename *name, umod= e_t mode) 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, mode, &delegated_inode); if (IS_ERR(dentry)) error =3D PTR_ERR(dentry); } end_creating_path(&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; diff --git a/fs/nfsd/nfs4recover.c b/fs/nfsd/nfs4recover.c index b1005abcb9035b2cf743200808a251b00af7e3f4..423dd102b51198ea7c447be2b9a= 0a5020c950dba 100644 --- a/fs/nfsd/nfs4recover.c +++ b/fs/nfsd/nfs4recover.c @@ -202,7 +202,7 @@ nfsd4_create_clid_dir(struct nfs4_client *clp) * as well be forgiving and just succeed silently. */ goto out_put; - dentry =3D vfs_mkdir(&nop_mnt_idmap, d_inode(dir), dentry, S_IRWXU); + dentry =3D vfs_mkdir(&nop_mnt_idmap, d_inode(dir), dentry, 0700, NULL); if (IS_ERR(dentry)) status =3D PTR_ERR(dentry); out_put: diff --git a/fs/nfsd/vfs.c b/fs/nfsd/vfs.c index 8b2dc7a88aab015d1e39da0dd4e6daf7e276aabe..5f24af289d509bea54a324b8851= fa06de6050353 100644 --- a/fs/nfsd/vfs.c +++ b/fs/nfsd/vfs.c @@ -1645,7 +1645,7 @@ nfsd_create_locked(struct svc_rqst *rqstp, struct svc= _fh *fhp, nfsd_check_ignore_resizing(iap); break; case S_IFDIR: - dchild =3D vfs_mkdir(&nop_mnt_idmap, dirp, dchild, iap->ia_mode); + dchild =3D vfs_mkdir(&nop_mnt_idmap, dirp, dchild, iap->ia_mode, NULL); if (IS_ERR(dchild)) { host_err =3D PTR_ERR(dchild); } else if (d_is_negative(dchild)) { diff --git a/fs/overlayfs/overlayfs.h b/fs/overlayfs/overlayfs.h index c8fd5951fc5ece1ae6b3e2a0801ca15f9faf7d72..0f65f9a5d54d4786b39e4f4f30f= 416d5b9016e70 100644 --- a/fs/overlayfs/overlayfs.h +++ b/fs/overlayfs/overlayfs.h @@ -248,7 +248,7 @@ static inline struct dentry *ovl_do_mkdir(struct ovl_fs= *ofs, { struct dentry *ret; =20 - ret =3D vfs_mkdir(ovl_upper_mnt_idmap(ofs), dir, dentry, mode); + ret =3D vfs_mkdir(ovl_upper_mnt_idmap(ofs), dir, dentry, mode, NULL); pr_debug("mkdir(%pd2, 0%o) =3D %i\n", dentry, mode, PTR_ERR_OR_ZERO(ret)); return ret; } diff --git a/fs/smb/server/vfs.c b/fs/smb/server/vfs.c index 891ed2dc2b7351a5cb14a2241d71095ffdd03f08..3d2190f26623b23ea79c6341090= 5a3c3ad684048 100644 --- a/fs/smb/server/vfs.c +++ b/fs/smb/server/vfs.c @@ -230,7 +230,7 @@ int ksmbd_vfs_mkdir(struct ksmbd_work *work, const char= *name, umode_t mode) idmap =3D mnt_idmap(path.mnt); mode |=3D S_IFDIR; d =3D dentry; - dentry =3D vfs_mkdir(idmap, d_inode(path.dentry), dentry, mode); + dentry =3D vfs_mkdir(idmap, d_inode(path.dentry), dentry, mode, NULL); if (IS_ERR(dentry)) err =3D PTR_ERR(dentry); else if (d_is_negative(dentry)) diff --git a/fs/xfs/scrub/orphanage.c b/fs/xfs/scrub/orphanage.c index 9c12cb8442311ca26b169e4d1567939ae44a5be0..91c9d07b97f306f57aebb9b69ba= 564b0c2cb8c17 100644 --- a/fs/xfs/scrub/orphanage.c +++ b/fs/xfs/scrub/orphanage.c @@ -167,7 +167,7 @@ xrep_orphanage_create( */ if (d_really_is_negative(orphanage_dentry)) { orphanage_dentry =3D vfs_mkdir(&nop_mnt_idmap, root_inode, - orphanage_dentry, 0750); + orphanage_dentry, 0750, NULL); error =3D PTR_ERR(orphanage_dentry); if (IS_ERR(orphanage_dentry)) goto out_unlock_root; diff --git a/include/linux/fs.h b/include/linux/fs.h index c895146c1444be36e0a779df55622cc38c9419ff..1040df3792794cd353b86558b41= 618294e25b8a6 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h @@ -2113,7 +2113,7 @@ bool inode_owner_or_capable(struct mnt_idmap *idmap, int vfs_create(struct mnt_idmap *, struct inode *, struct dentry *, umode_t, bool); struct dentry *vfs_mkdir(struct mnt_idmap *, struct inode *, - struct dentry *, umode_t); + struct dentry *, umode_t, struct inode **); int vfs_mknod(struct mnt_idmap *, struct inode *, struct dentry *, umode_t, dev_t); int vfs_symlink(struct mnt_idmap *, struct inode *, --=20 2.51.0 From nobody Sun Feb 8 06:55:58 2026 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 52DE6345CD7; Tue, 21 Oct 2025 15:26: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=1761060376; cv=none; b=RRKwjdnKsWaLWxdhExNcoX1fKrwCehPmZHXos2+E7Ki13bAwY57W4XhDvUZjaqZe/Tsh3NDN4uSNYEXUMz9thT3dc4n+eh1fNbreZFdmezRbsy55fePgMwGlwJoWsrV5didcp23+FFWTGLvcRU1ViBVz60rW2sI+0UsuYFxUqAM= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1761060376; c=relaxed/simple; bh=BNQJaBr9mlUE++piDiBq8FCyr25mMT9XYhs2EJPR/Xs=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=u8Q2JD/pQuPwA14AGO8fduSOo8QVylsNeToGQJAbiYNDqSYuvOhGPATnG2/WZFT27EfiQTRncnpPtkzhhNxmLTTcj+i3HV3Vc0WR3oFz0PPme0cWwz+XpQZ0eg70n6H+QyJVUfGauQpjv9aT5UCqwnGU9utfu85WKXtF/Lz+TcI= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=j8slyY9/; 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="j8slyY9/" Received: by smtp.kernel.org (Postfix) with ESMTPSA id A18C7C4CEF5; Tue, 21 Oct 2025 15:26:12 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1761060375; bh=BNQJaBr9mlUE++piDiBq8FCyr25mMT9XYhs2EJPR/Xs=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=j8slyY9/EzfWqT9d1gOhJXKTREgF/3ZqzuKT9hzAUesJgbxDH2NPwE0N04vDJtmis WMKLq2VOwCbvVRotHdq+i4au61qzx1IqqnmftqHbEZxH8eu1qvQ7e8HAFxnKOTQy+b SDFACXk2nLA4cc2OG3TSvyCEwCL8BMTunHog3NnwOBFohN1rvwusKA/WEp22i9o9Ze 9ykO6vuelpX2c/uPpi+G75Qscj7+Wwrhpbpo/vbOcxcIqRGCv2hXBh6t6g0rG3dqDW JCSTmYpKFBw9J0p700sDpwm1UtIpvHj9rPKXAspaEd38EePDL5aBMbJQItMQltLsgv GZL8f53EmU4Sg== From: Jeff Layton Date: Tue, 21 Oct 2025 11:25:39 -0400 Subject: [PATCH v3 04/13] 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: <20251021-dir-deleg-ro-v3-4-a08b1cde9f4c@kernel.org> References: <20251021-dir-deleg-ro-v3-0-a08b1cde9f4c@kernel.org> In-Reply-To: <20251021-dir-deleg-ro-v3-0-a08b1cde9f4c@kernel.org> To: Miklos Szeredi , 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 , Greg Kroah-Hartman , "Rafael J. Wysocki" , Danilo Krummrich , David Howells , Tyler Hicks , NeilBrown , Olga Kornievskaia , Dai Ngo , Amir Goldstein , Namjae Jeon , Steve French , Sergey Senozhatsky , Carlos Maiolino , Kuniyuki Iwashima , "David S. Miller" , Eric Dumazet , Jakub Kicinski , Paolo Abeni , Simon Horman 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, netfs@lists.linux.dev, ecryptfs@vger.kernel.org, linux-unionfs@vger.kernel.org, linux-xfs@vger.kernel.org, netdev@vger.kernel.org, Jeff Layton X-Mailer: b4 0.14.2 X-Developer-Signature: v=1; a=openpgp-sha256; l=7805; i=jlayton@kernel.org; h=from:subject:message-id; bh=BNQJaBr9mlUE++piDiBq8FCyr25mMT9XYhs2EJPR/Xs=; b=owEBbQKS/ZANAwAKAQAOaEEZVoIVAcsmYgBo96YEc0WpYvNNJg2vjpK158r69HFb+eiOu0/nV zrWk03ddqGJAjMEAAEKAB0WIQRLwNeyRHGyoYTq9dMADmhBGVaCFQUCaPemBAAKCRAADmhBGVaC FXzID/97EQQYYEK2GhVBQftEuPS9kZL/rJY7+/9hYTzhhbQBLXBFiB1NvDUffXBlE2s4m+eXTVP CptsZs8gEfKf/he0IveDANnHo8yIS0Ti4f+6JijQvMZtThvglqppnf6msbeXnIsRzneltlJoAFm wDeRFX9JORLGCpa+fzUfiiG6FBVK8JWo00teMMQL0pLUjCvtvN8JfWKUgHQQi1+TISX2pH9h+SY FttEiY4IFGdqOrwxwHp7o38Fbq1QMPHYWdkQcQn3HH4qpUdPjUP7BshV6/dpDhV2plCfDaQ0Wpg Sk5ijtheKtO0JWVAYjJcPu9riF9iBqvjZ603KN0Mn3k1jIu1g5dg0FrGjVVgNaojAd9ldINEkOC UnVpHy+zppEVeGHOZMz2CGCyRbbNFBYt2oukQZZf00Mt06745kb/3RhN26u2Qyh4ex9TjRjaMTe 2KHkzeQdYs007w4xufoWUtC1P2z2jdFhNEjen9tKe+UCqJlCPA61lwCgxOEN7CUzufyJCsCM1K3 GuSLU9AYJgzR92yLJFcvqf6FlvIB68M4s3J5toFGj1kBBnf5uHP/MZSiteG/cP0zuOm5iOytbPZ v9GRpY5LevETXKxZeV33LMuF+lgmsjLq55Vi2eLJHFARBvwG+Gh1L9aL5Nx2nyWLYX/KkpGNdQQ WPde2lgy4peh9XA== 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" return pointer to vfs_rmdir() and populate that pointer with the parent inode if it's non-NULL. Most existing in-kernel callers pass in a NULL pointer. Reviewed-by: Jan Kara Reviewed-by: NeilBrown Signed-off-by: Jeff Layton --- drivers/base/devtmpfs.c | 2 +- fs/ecryptfs/inode.c | 2 +- fs/namei.c | 22 +++++++++++++++++----- fs/nfsd/nfs4recover.c | 4 ++-- fs/nfsd/vfs.c | 2 +- fs/overlayfs/overlayfs.h | 2 +- fs/smb/server/vfs.c | 4 ++-- include/linux/fs.h | 3 ++- 8 files changed, 27 insertions(+), 14 deletions(-) diff --git a/drivers/base/devtmpfs.c b/drivers/base/devtmpfs.c index 0e79621cb0f79870003b867ca384199171ded4e0..104025104ef75381984fd94dfbd= 50feeaa8cdd22 100644 --- a/drivers/base/devtmpfs.c +++ b/drivers/base/devtmpfs.c @@ -261,7 +261,7 @@ static int dev_rmdir(const char *name) return PTR_ERR(dentry); if (d_inode(dentry)->i_private =3D=3D &thread) err =3D vfs_rmdir(&nop_mnt_idmap, d_inode(parent.dentry), - dentry); + dentry, NULL); else err =3D -EPERM; =20 diff --git a/fs/ecryptfs/inode.c b/fs/ecryptfs/inode.c index 35830b3144f8f71374a78b3e7463b864f4fc216e..88631291b32535f623a3fbe4ea9= b6ed48a306ca0 100644 --- a/fs/ecryptfs/inode.c +++ b/fs/ecryptfs/inode.c @@ -540,7 +540,7 @@ static int ecryptfs_rmdir(struct inode *dir, struct den= try *dentry) if (d_unhashed(lower_dentry)) rc =3D -EINVAL; else - rc =3D vfs_rmdir(&nop_mnt_idmap, lower_dir, lower_dentry); + rc =3D vfs_rmdir(&nop_mnt_idmap, lower_dir, lower_dentry, NULL); } if (!rc) { clear_nlink(d_inode(dentry)); diff --git a/fs/namei.c b/fs/namei.c index 86cf6eca1f485361c6732974e4103cf5ea721539..4b5a99653c558397e592715d9d4= 663cd4a63ef86 100644 --- a/fs/namei.c +++ b/fs/namei.c @@ -4522,9 +4522,10 @@ SYSCALL_DEFINE2(mkdir, const char __user *, pathname= , umode_t, 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 + * @idmap: idmap of the mount the inode was found from + * @dir: inode of the parent directory + * @dentry: dentry of the child directory + * @delegated_inode: returns parent inode, if it's delegated. * * Remove a directory. * @@ -4535,7 +4536,7 @@ SYSCALL_DEFINE2(mkdir, const char __user *, pathname,= umode_t, mode) * raw inode simply pass @nop_mnt_idmap. */ int vfs_rmdir(struct mnt_idmap *idmap, struct inode *dir, - struct dentry *dentry) + struct dentry *dentry, struct inode **delegated_inode) { int error =3D may_delete(idmap, dir, dentry, 1); =20 @@ -4557,6 +4558,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; @@ -4583,6 +4588,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) @@ -4612,7 +4618,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: @@ -4620,6 +4627,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; diff --git a/fs/nfsd/nfs4recover.c b/fs/nfsd/nfs4recover.c index 423dd102b51198ea7c447be2b9a0a5020c950dba..71f8bf25d209937e13c9ae56310= 1b7d8bf55f4ce 100644 --- a/fs/nfsd/nfs4recover.c +++ b/fs/nfsd/nfs4recover.c @@ -315,7 +315,7 @@ nfsd4_unlink_clid_dir(char *name, struct nfsd_net *nn) status =3D -ENOENT; if (d_really_is_negative(dentry)) goto out; - status =3D vfs_rmdir(&nop_mnt_idmap, d_inode(dir), dentry); + status =3D vfs_rmdir(&nop_mnt_idmap, d_inode(dir), dentry, NULL); out: dput(dentry); out_unlock: @@ -409,7 +409,7 @@ purge_old(struct dentry *parent, char *cname, struct nf= sd_net *nn) inode_lock_nested(d_inode(parent), I_MUTEX_PARENT); child =3D lookup_one(&nop_mnt_idmap, &QSTR(cname), parent); if (!IS_ERR(child)) { - status =3D vfs_rmdir(&nop_mnt_idmap, d_inode(parent), child); + status =3D vfs_rmdir(&nop_mnt_idmap, d_inode(parent), child, NULL); if (status) printk("failed to remove client recovery directory %pd\n", child); diff --git a/fs/nfsd/vfs.c b/fs/nfsd/vfs.c index 5f24af289d509bea54a324b8851fa06de6050353..85afd2fad7e08b66b1a9ce372af= dea1df52086be 100644 --- a/fs/nfsd/vfs.c +++ b/fs/nfsd/vfs.c @@ -2195,7 +2195,7 @@ nfsd_unlink(struct svc_rqst *rqstp, struct svc_fh *fh= p, int type, break; } } else { - host_err =3D vfs_rmdir(&nop_mnt_idmap, dirp, rdentry); + host_err =3D vfs_rmdir(&nop_mnt_idmap, dirp, rdentry, NULL); } fh_fill_post_attrs(fhp); =20 diff --git a/fs/overlayfs/overlayfs.h b/fs/overlayfs/overlayfs.h index 0f65f9a5d54d4786b39e4f4f30f416d5b9016e70..d215d7349489686b66bb66e939b= 27046f7d836f6 100644 --- a/fs/overlayfs/overlayfs.h +++ b/fs/overlayfs/overlayfs.h @@ -206,7 +206,7 @@ static inline int ovl_do_notify_change(struct ovl_fs *o= fs, static inline int ovl_do_rmdir(struct ovl_fs *ofs, struct inode *dir, struct dentry *dentry) { - int err =3D vfs_rmdir(ovl_upper_mnt_idmap(ofs), dir, dentry); + int err =3D vfs_rmdir(ovl_upper_mnt_idmap(ofs), dir, dentry, NULL); =20 pr_debug("rmdir(%pd2) =3D %i\n", dentry, err); return err; diff --git a/fs/smb/server/vfs.c b/fs/smb/server/vfs.c index 3d2190f26623b23ea79c63410905a3c3ad684048..c5f0f3170d586cb2dc4d416b809= 48c642797fb82 100644 --- a/fs/smb/server/vfs.c +++ b/fs/smb/server/vfs.c @@ -609,7 +609,7 @@ int ksmbd_vfs_remove_file(struct ksmbd_work *work, cons= t struct path *path) =20 idmap =3D mnt_idmap(path->mnt); if (S_ISDIR(d_inode(path->dentry)->i_mode)) { - err =3D vfs_rmdir(idmap, d_inode(parent), path->dentry); + err =3D vfs_rmdir(idmap, d_inode(parent), path->dentry, NULL); if (err && err !=3D -ENOTEMPTY) ksmbd_debug(VFS, "rmdir failed, err %d\n", err); } else { @@ -1090,7 +1090,7 @@ int ksmbd_vfs_unlink(struct file *filp) dget(dentry); =20 if (S_ISDIR(d_inode(dentry)->i_mode)) - err =3D vfs_rmdir(idmap, d_inode(dir), dentry); + err =3D vfs_rmdir(idmap, d_inode(dir), dentry, NULL); else err =3D vfs_unlink(idmap, d_inode(dir), dentry, NULL); =20 diff --git a/include/linux/fs.h b/include/linux/fs.h index 1040df3792794cd353b86558b41618294e25b8a6..d8bdaf7c87502ff17775602f539= 1d375738b4ed8 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h @@ -2120,7 +2120,8 @@ 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 **); -int vfs_rmdir(struct mnt_idmap *, struct inode *, struct dentry *); +int vfs_rmdir(struct mnt_idmap *, struct inode *, struct dentry *, + struct inode **); int vfs_unlink(struct mnt_idmap *, struct inode *, struct dentry *, struct inode **); =20 --=20 2.51.0 From nobody Sun Feb 8 06:55:58 2026 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 BB72C34678B; Tue, 21 Oct 2025 15:26: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=1761060379; cv=none; b=lhKhGAuW/HpHlhLBgFsJQneEVAE4815IeL0nhZvoybhRW61bkrS3jN+gcytcdUhxs9SLs1u2wOcVOIEJPCX+hgKBrmojpzBtpn86gYrzWsxua0S/Wdog7aeroBGHS7tojdeQTf0XYTyY2+H1QUASw/u4qomB24u9ISnO8tshvhQ= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1761060379; c=relaxed/simple; bh=HyqRgBw91WhqZtzTenMCR+3dGk9xVGJz9VhQTZtIs78=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=jaOkFIvEzMBzFLuZ3mLt0A7WzZLeedVaYTryQlzNBG/mxzYVhf7D8TA9nukWXNDXv7rTlElv60fwnUz4wfvj5wwI8+GYCi7/hMkeRfbcXIoBuH8WKQF8Yj5rVLXr3sD5gXxMx3uF//H7e4WS1CWs6ZbFyQzFPDaFxJuqJSnfLHE= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=qvFM4CMP; 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="qvFM4CMP" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 0F646C116B1; Tue, 21 Oct 2025 15:26:15 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1761060379; bh=HyqRgBw91WhqZtzTenMCR+3dGk9xVGJz9VhQTZtIs78=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=qvFM4CMPLeb6PTxJsg94dwm8fHqO3C7L4dPUo4vcp2qkkAHgsBG2D5j3+7wPNxzf8 uVBjFFih4UbTc6ykQcMOiW5bfmfxzaLW6CXw7cqGH13DtDMr9Z/Mbu+5G60X/RvICf gde0uyN7z4FL2VZ492HS/uZIQW07iaaq7y2Sghl6TPa3YX2Lm/WN9F/SZ95ZZ4QoTw m6y3oxVcFLnfyho4qpxf0U1krrR3mVWYbpuOMgwudZoBOgX6ZEzn6ksF+FRb0mT3sU sPLQHbFRdH4MGdMdq7Aw+IKKWctD4oHTlxTJSX2p915jHmwWJCaH736BnaKmnDAyXF 4BwiFuHwtyAOA== From: Jeff Layton Date: Tue, 21 Oct 2025 11:25:40 -0400 Subject: [PATCH v3 05/13] 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: <20251021-dir-deleg-ro-v3-5-a08b1cde9f4c@kernel.org> References: <20251021-dir-deleg-ro-v3-0-a08b1cde9f4c@kernel.org> In-Reply-To: <20251021-dir-deleg-ro-v3-0-a08b1cde9f4c@kernel.org> To: Miklos Szeredi , 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 , Greg Kroah-Hartman , "Rafael J. Wysocki" , Danilo Krummrich , David Howells , Tyler Hicks , NeilBrown , Olga Kornievskaia , Dai Ngo , Amir Goldstein , Namjae Jeon , Steve French , Sergey Senozhatsky , Carlos Maiolino , Kuniyuki Iwashima , "David S. Miller" , Eric Dumazet , Jakub Kicinski , Paolo Abeni , Simon Horman 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, netfs@lists.linux.dev, ecryptfs@vger.kernel.org, linux-unionfs@vger.kernel.org, linux-xfs@vger.kernel.org, netdev@vger.kernel.org, Jeff Layton X-Mailer: b4 0.14.2 X-Developer-Signature: v=1; a=openpgp-sha256; l=3018; i=jlayton@kernel.org; h=from:subject:message-id; bh=HyqRgBw91WhqZtzTenMCR+3dGk9xVGJz9VhQTZtIs78=; b=owEBbQKS/ZANAwAKAQAOaEEZVoIVAcsmYgBo96YEEfoW9eozdR9KGWdnmBcYOlqeBlMd7he64 LC8Ey2eB8eJAjMEAAEKAB0WIQRLwNeyRHGyoYTq9dMADmhBGVaCFQUCaPemBAAKCRAADmhBGVaC FcdkD/9+C+fUrYqbky0LjtjE9purC4C6aTs51o32EHqnaGafX+7RETjcbJpdejBnmJSOLQSjid7 3/7STizAiD9JhkYCrDQg8CfD7dSLaiCz2jtf/5jGQN3b6fCNvyKQLHmYFYEMySZjUWsboh+D8Ye iewgJDKWzudnJ34AwOS7eoYlm4OwvxrYj6JVYvmH1h94tpSQEp41zE90Vddwrl01s2d8zo3eXlG GBMDuov1arvrdK4afgIOYo8lVPzrFiJ+QQ7e+9cGyYXC2/AamwrCWnoQj+Jgj/a1fhDPTWOUVmJ DJCe3xAmzIW4MHaNAgX7jJD7Q6mqwUwietEK2Qqxu7L2aW7/K0o091HurZyQuZpoawzErq36GAh ei5iuMie+TG21eh/joB5/KDAgwaoM96RLEX17lRjZkpkZ9CKA8oIV50fL0BhgXKerHwfBRkZtNP jxidwAvRkX+YAvPt52Of0Y4RygYvUDy0BIPkAO9uE09NEjpe5BPM84yEoEFlN9FlN+dXCRQ0Ucz MVKoh2ymU3pzIoSt0hysMdxxZsyXkl01vxvzPSxJfsbwhidUPCWK1QmrkYZKpvhkhL79cHB1fA+ SpooeFFmFkQeCpB6JmHKGeettb5wtLPmm//dT6SG/bgY1A5ovehZ0U9Oe9UgDLqP13FXrl01682 u6cHD7i387v2U4g== 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. Reviewed-by: Jan Kara Reviewed-by: NeilBrown 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 4b5a99653c558397e592715d9d4663cd4a63ef86..786f42bd184b5dbf6d754fa1fb6= c94c0f75429f2 100644 --- a/fs/namei.c +++ b/fs/namei.c @@ -3697,7 +3697,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; @@ -3786,6 +3786,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) { @@ -3849,6 +3854,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; @@ -3879,7 +3885,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); /* @@ -3892,7 +3898,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); @@ -3907,8 +3913,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.51.0 From nobody Sun Feb 8 06:55:58 2026 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 BADDB347FC1; Tue, 21 Oct 2025 15:26:22 +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=1761060382; cv=none; b=rHJH83vs4fBZTX/Whi7bk9FjTMu/2WhPeL4UKY/1w2pNCuGLsMwSgVMDzEEu/Q5LkZrJxqiK2bkzR2ViYPzTo/0SD7+8VtLGPDgZRWZ0pkfpRlHztXd+lSBPkEGE9QnsDO1yd9hCcffpp9qX/bDx0VgzMyDK+9+b9azsnfrttQ8= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1761060382; c=relaxed/simple; bh=1if+7pIcycx8q41cWWMlMqA3QfQkY2owvRZn4v6lKC8=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=QyHfZGiuq6jbPGmjEYdkTNq0TiVZAeL30Tw37aBjaL0RMl1W0wIPd5Mx2UYjNHBrgcqEE/1caowushb3sqkAPnQWz9C3jkUldSOXuRjzgIW++EzFPP2L4+q5AXK0XrxLGpyJ9rphd1mNY5yBr51n0LCr/wpJ8lPAhI8wzxe+Rno= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=HBQG02Eb; 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="HBQG02Eb" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 700EFC19421; Tue, 21 Oct 2025 15:26:19 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1761060382; bh=1if+7pIcycx8q41cWWMlMqA3QfQkY2owvRZn4v6lKC8=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=HBQG02EbwsAw3KkIwEEybgzGqDgYbEUd8viqGcfF9a/mMqT0//aZRQGwsBx8qFqSP Tpoz7UW8trCDkYt/NMtE7AM9h3L7LqocH4xhxXJVdMJO3XfiTIxFZ9/QczFiIV1Gfy zJqEGy2HV5ssPCJwuZXbshTNPmN74JbsuZntIi+7xVNmAF8FwFslghavATo5L9nEPP x6J48BL5cCHfdErMyjzCbAbS7aOxI6XncB2y8h1oJZz8TyBAi8LmAHX+5bpMahCIGH Aw5xrgnfyFxBVUO7bTb2W89y39/ghwkVMaX74+wSuKh3Hxz9lJU72sa9CIF3PrpM8Q QnqsDIOGkd4zA== From: Jeff Layton Date: Tue, 21 Oct 2025 11:25:41 -0400 Subject: [PATCH v3 06/13] 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: <20251021-dir-deleg-ro-v3-6-a08b1cde9f4c@kernel.org> References: <20251021-dir-deleg-ro-v3-0-a08b1cde9f4c@kernel.org> In-Reply-To: <20251021-dir-deleg-ro-v3-0-a08b1cde9f4c@kernel.org> To: Miklos Szeredi , 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 , Greg Kroah-Hartman , "Rafael J. Wysocki" , Danilo Krummrich , David Howells , Tyler Hicks , NeilBrown , Olga Kornievskaia , Dai Ngo , Amir Goldstein , Namjae Jeon , Steve French , Sergey Senozhatsky , Carlos Maiolino , Kuniyuki Iwashima , "David S. Miller" , Eric Dumazet , Jakub Kicinski , Paolo Abeni , Simon Horman 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, netfs@lists.linux.dev, ecryptfs@vger.kernel.org, linux-unionfs@vger.kernel.org, linux-xfs@vger.kernel.org, netdev@vger.kernel.org, Jeff Layton X-Mailer: b4 0.14.2 X-Developer-Signature: v=1; a=openpgp-sha256; l=7451; i=jlayton@kernel.org; h=from:subject:message-id; bh=1if+7pIcycx8q41cWWMlMqA3QfQkY2owvRZn4v6lKC8=; b=owEBbQKS/ZANAwAKAQAOaEEZVoIVAcsmYgBo96YFKWV6I0Px7WL6VsPpL9jFbX+1T+qvjmzr2 8wvSHv0cteJAjMEAAEKAB0WIQRLwNeyRHGyoYTq9dMADmhBGVaCFQUCaPemBQAKCRAADmhBGVaC FaqnEACa0vhuueepIFqyIn+koGRzeI1c9QE2xXVQZmuS9YRNKktNcdk2B8aU873Iekpl8Oh4EPl g/Axm2ZeOHuHEjybkyxs1uNAdn/JgI3y/be3vEXxgzu5xKnag0hwbBvCPJPxuRseIbGWsMJ4UxO zFmGCfEaJU4uRi4Z2/PA658oqAIYuCpHjoc20+YE6mGJudRtaXzdtJePuTAV/ayIOFUMHki4QPl tCZJiQVumIXNnS54I1ABc35gdb/ay0cDics+aYiXbsINNCwy1x8X+hxh9B6a0ThX/NoAsLngV75 TL4huPIYtYrrB4HvG6l91EoSFPWHdl1gPd+R4Np+dXRp0K7Q6s7TXNaJzd2ia+wO5lazc+GUJdO 9Ns1W0X4I8zmDUe77vRsnioPEG31RH3qE8vlwcwhmOKQyCPkMvji+eLi/mhovy09d4G7PNYa6V4 EvJL6QJ0ijIKSU3zsgS2veB6bP4eGYEeiR89Fq0WaonREYCswxVpbP+guP4XCT8PK5vUAkSZ41E MVES+E0IFXYpEnG4RWCN+iSkOOZTgmY+Yt/ghPgfLE0UawzPz5qFZnKz6ZdWu9DTzXqr63dR2mp tz6WpLw9qhniUAN/fyKfyT1q3illcgVtaQBTFnmtIG92jtGVn8tEVTlzVo03sim6puwxlmsGJD2 i6XtuMeZIW+gEYg== 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 vfs_create. Most callers are converted to pass in NULL, but do_mknodat() is changed to wait for a delegation break if there is one. Reviewed-by: Jan Kara Reviewed-by: NeilBrown Signed-off-by: Jeff Layton --- fs/ecryptfs/inode.c | 2 +- fs/namei.c | 26 +++++++++++++++++++------- fs/nfsd/nfs3proc.c | 2 +- fs/nfsd/vfs.c | 3 +-- fs/open.c | 2 +- fs/overlayfs/overlayfs.h | 2 +- fs/smb/server/vfs.c | 2 +- include/linux/fs.h | 2 +- 8 files changed, 26 insertions(+), 15 deletions(-) diff --git a/fs/ecryptfs/inode.c b/fs/ecryptfs/inode.c index 88631291b32535f623a3fbe4ea9b6ed48a306ca0..661709b157ce854c3bfdfdb13f7= c10435fad9756 100644 --- a/fs/ecryptfs/inode.c +++ b/fs/ecryptfs/inode.c @@ -189,7 +189,7 @@ ecryptfs_do_create(struct inode *directory_inode, rc =3D lock_parent(ecryptfs_dentry, &lower_dentry, &lower_dir); if (!rc) rc =3D vfs_create(&nop_mnt_idmap, lower_dir, - lower_dentry, mode, true); + lower_dentry, mode, true, NULL); if (rc) { printk(KERN_ERR "%s: Failure to create dentry in lower fs; " "rc =3D [%d]\n", __func__, rc); diff --git a/fs/namei.c b/fs/namei.c index 786f42bd184b5dbf6d754fa1fb6c94c0f75429f2..7510942e0249de19df4363b92f8= 13b3acdfc2254 100644 --- a/fs/namei.c +++ b/fs/namei.c @@ -3460,11 +3460,12 @@ static inline umode_t vfs_prepare_mode(struct mnt_i= dmap *idmap, =20 /** * vfs_create - create new file - * @idmap: idmap of the mount the inode was found from - * @dir: inode of the parent directory - * @dentry: dentry of the child file - * @mode: mode of the child file - * @want_excl: whether the file must not yet exist + * @idmap: idmap of the mount the inode was found from + * @dir: inode of the parent directory + * @dentry: dentry of the child file + * @mode: mode of the child file + * @want_excl: whether the file must not yet exist + * @delegated_inode: returns parent inode, if the inode is delegated. * * Create a new file. * @@ -3475,7 +3476,8 @@ static inline umode_t vfs_prepare_mode(struct mnt_idm= ap *idmap, * raw inode simply pass @nop_mnt_idmap. */ int vfs_create(struct mnt_idmap *idmap, struct inode *dir, - struct dentry *dentry, umode_t mode, bool want_excl) + struct dentry *dentry, umode_t mode, bool want_excl, + struct inode **delegated_inode) { int error; =20 @@ -3488,6 +3490,9 @@ int vfs_create(struct mnt_idmap *idmap, struct inode = *dir, =20 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); @@ -4365,6 +4370,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) @@ -4384,7 +4390,8 @@ static int do_mknodat(int dfd, struct filename *name,= umode_t mode, switch (mode & S_IFMT) { case 0: case S_IFREG: error =3D vfs_create(idmap, path.dentry->d_inode, - dentry, mode, true); + dentry, mode, true, + &delegated_inode); if (!error) security_path_post_mknod(idmap, dentry); break; @@ -4399,6 +4406,11 @@ static int do_mknodat(int dfd, struct filename *name= , umode_t mode, } out2: end_creating_path(&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; diff --git a/fs/nfsd/nfs3proc.c b/fs/nfsd/nfs3proc.c index ad14b34583bb9fd7cd1e29f5f8676fa3442dd661..dbf70d184c0276d198599a22eb0= 953a2a1dde2c8 100644 --- a/fs/nfsd/nfs3proc.c +++ b/fs/nfsd/nfs3proc.c @@ -344,7 +344,7 @@ nfsd3_create_file(struct svc_rqst *rqstp, struct svc_fh= *fhp, status =3D fh_fill_pre_attrs(fhp); if (status !=3D nfs_ok) goto out; - host_err =3D vfs_create(&nop_mnt_idmap, inode, child, iap->ia_mode, true); + host_err =3D vfs_create(&nop_mnt_idmap, inode, child, iap->ia_mode, true,= NULL); if (host_err < 0) { status =3D nfserrno(host_err); goto out; diff --git a/fs/nfsd/vfs.c b/fs/nfsd/vfs.c index 85afd2fad7e08b66b1a9ce372afdea1df52086be..7eaae44467188fab0909fabec98= 6e103bcd52457 100644 --- a/fs/nfsd/vfs.c +++ b/fs/nfsd/vfs.c @@ -1639,8 +1639,7 @@ nfsd_create_locked(struct svc_rqst *rqstp, struct svc= _fh *fhp, err =3D 0; switch (type) { case S_IFREG: - host_err =3D vfs_create(&nop_mnt_idmap, dirp, dchild, - iap->ia_mode, true); + host_err =3D vfs_create(&nop_mnt_idmap, dirp, dchild, iap->ia_mode, true= , NULL); if (!host_err) nfsd_check_ignore_resizing(iap); break; diff --git a/fs/open.c b/fs/open.c index 3d64372ecc675e4795eb0a0deda10f8f67b95640..4d98f8b52b98bc95e52cb247d14= 871ff6e4a1b5c 100644 --- a/fs/open.c +++ b/fs/open.c @@ -1173,7 +1173,7 @@ struct file *dentry_create(const struct path *path, i= nt flags, umode_t mode, =20 error =3D vfs_create(mnt_idmap(path->mnt), d_inode(path->dentry->d_parent), - path->dentry, mode, true); + path->dentry, mode, true, NULL); if (!error) error =3D vfs_open(path, f); =20 diff --git a/fs/overlayfs/overlayfs.h b/fs/overlayfs/overlayfs.h index d215d7349489686b66bb66e939b27046f7d836f6..d3123f5d97e86b58e4c9608cf6e= f2abd1fcddbcd 100644 --- a/fs/overlayfs/overlayfs.h +++ b/fs/overlayfs/overlayfs.h @@ -235,7 +235,7 @@ static inline int ovl_do_create(struct ovl_fs *ofs, struct inode *dir, struct dentry *dentry, umode_t mode) { - int err =3D vfs_create(ovl_upper_mnt_idmap(ofs), dir, dentry, mode, true); + int err =3D vfs_create(ovl_upper_mnt_idmap(ofs), dir, dentry, mode, true,= NULL); =20 pr_debug("create(%pd2, 0%o) =3D %i\n", dentry, mode, err); return err; diff --git a/fs/smb/server/vfs.c b/fs/smb/server/vfs.c index c5f0f3170d586cb2dc4d416b80948c642797fb82..be278bb6b71bab8aa41aed06a88= 06e7bc2de4cd3 100644 --- a/fs/smb/server/vfs.c +++ b/fs/smb/server/vfs.c @@ -189,7 +189,7 @@ int ksmbd_vfs_create(struct ksmbd_work *work, const cha= r *name, umode_t mode) =20 mode |=3D S_IFREG; err =3D vfs_create(mnt_idmap(path.mnt), d_inode(path.dentry), - dentry, mode, true); + dentry, mode, true, NULL); if (!err) { ksmbd_vfs_inherit_owner(work, d_inode(path.dentry), d_inode(dentry)); diff --git a/include/linux/fs.h b/include/linux/fs.h index d8bdaf7c87502ff17775602f5391d375738b4ed8..5fcf64d9cf42ce135c0fbcbf6df= bf8816ae0bcb1 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h @@ -2111,7 +2111,7 @@ bool inode_owner_or_capable(struct mnt_idmap *idmap, * VFS helper functions.. */ int vfs_create(struct mnt_idmap *, struct inode *, - struct dentry *, umode_t, bool); + struct dentry *, umode_t, bool, struct inode **); struct dentry *vfs_mkdir(struct mnt_idmap *, struct inode *, struct dentry *, umode_t, struct inode **); int vfs_mknod(struct mnt_idmap *, struct inode *, struct dentry *, --=20 2.51.0 From nobody Sun Feb 8 06:55:58 2026 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 7F9243491C5; Tue, 21 Oct 2025 15:26: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=1761060386; cv=none; b=umBYxKInIwMuMkLnWMphDrMjvrPNCCKST78/zVJxcN6lcyxa6JjZ0rHk7dyeY03nzZlF72nP+8bkTjqee7SQe+xc7FgK1pW3sdAwnV8VOC7W4cK/SDxSEpxNfJVbsEIP+4mV959ZrhrnWpnY4QETG5Q1ovHe3Ri27YxVr0gfbAE= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1761060386; c=relaxed/simple; bh=yTgOStwUbcuSXR0JicjTG44hgRhCgvUguUODuPzyJCs=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=daflsns4ki+RXqTGt66QyoILjBK6JBSSvquuH2fDyMAS8qJNua0JyBZYNH/kZ4VT1i+mrfrvNMxsJXkD6H1YhbcJ27AixotUh8Cv2+YeEN4H5oIXRWmxKaHYrbFkJcjVlC332j+nFtS4KhZRNf1EF96vy8Tpz+iQuArXBhuvy7U= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=pYh2M77J; 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="pYh2M77J" Received: by smtp.kernel.org (Postfix) with ESMTPSA id D427EC116C6; Tue, 21 Oct 2025 15:26:22 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1761060386; bh=yTgOStwUbcuSXR0JicjTG44hgRhCgvUguUODuPzyJCs=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=pYh2M77Jjbnc2s1mAU2dIv8Nudl10TuxUjc2JAti1QOwQ05bynxKrqzZQ60f29eIv UnA7n1TNv3u8AC6xbEL7pRZxfdJo0tr108Ew3kaoa9n28KQK5+oxyy3EQFOQy0l4oz 8PcBvvztrsZka4guq9xcgco7DX4+5L8DvXuRBuxBUeKSI0ZlOMHDh/6bDwQAmWkN7v jaR58hz3c2X1Ck074XBD67gDYyUpC03MB2y++1Sbx4s/pceAAQlWh1Z1ozx3uZ+BWk MgNbNA8Ma9T3NKAVB5lGKPH+5rRmz2A3SIEjfhFpSE8DH85YOWBrPjGA8GvCj/gupi JPbb8emYZlX6A== From: Jeff Layton Date: Tue, 21 Oct 2025 11:25:42 -0400 Subject: [PATCH v3 07/13] 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: <20251021-dir-deleg-ro-v3-7-a08b1cde9f4c@kernel.org> References: <20251021-dir-deleg-ro-v3-0-a08b1cde9f4c@kernel.org> In-Reply-To: <20251021-dir-deleg-ro-v3-0-a08b1cde9f4c@kernel.org> To: Miklos Szeredi , 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 , Greg Kroah-Hartman , "Rafael J. Wysocki" , Danilo Krummrich , David Howells , Tyler Hicks , NeilBrown , Olga Kornievskaia , Dai Ngo , Amir Goldstein , Namjae Jeon , Steve French , Sergey Senozhatsky , Carlos Maiolino , Kuniyuki Iwashima , "David S. Miller" , Eric Dumazet , Jakub Kicinski , Paolo Abeni , Simon Horman 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, netfs@lists.linux.dev, ecryptfs@vger.kernel.org, linux-unionfs@vger.kernel.org, linux-xfs@vger.kernel.org, netdev@vger.kernel.org, Jeff Layton X-Mailer: b4 0.14.2 X-Developer-Signature: v=1; a=openpgp-sha256; l=7491; i=jlayton@kernel.org; h=from:subject:message-id; bh=yTgOStwUbcuSXR0JicjTG44hgRhCgvUguUODuPzyJCs=; b=owEBbQKS/ZANAwAKAQAOaEEZVoIVAcsmYgBo96YFAnlIJo/MYWe+AjYeieNWpSrK5vYSrf8gc L/7l9jJA9eJAjMEAAEKAB0WIQRLwNeyRHGyoYTq9dMADmhBGVaCFQUCaPemBQAKCRAADmhBGVaC FZ1sD/sE+YFbP/tRPvSHthcvwkoRmY3I1Z/bgs1aPEYJS3iP7coQDSlUsvE1zDwSzRD0+nEXnC3 pcrRClpBKv74Z4sNPkfcuzl/x9v70N6TbDCPF2aBAmQYjeMbY4v4qFRX9tZno6oUHwhYpEkZNsG 9ZsI4O5QOtt+l9HGXXyQ0OGZqh0gtXgnME2KdilXFEJ38M6i0vFO4wwjpQKzcWxKIs+r1NRuHwW TPp4BU5I2a5iApTZa6aVMNV+wiDeDkBq3wdTCVrp1kyGmI89Z6DN9qvC4qIoe+qvZYa4SLJBiJg 4iuIdFfQgTSlMZAk3nQEpoRa5wXgjoLF+4VwFEbIVEvCbbX7qyiL/hVvmL2WNVo9IZmWYCCfn98 pT446X7BCtPkjsX/B6RrTuilCH5n8dkfBS8yKk5v7pN8H5D/yE+VBy+GiazuhIh5zqklPSXKg/H B4DPbHRHO1wViqXHRr9IcyQ5ojnNutbgzULjo6mbKGP0Fg3UCzB+jXQ77VY2cOKSlwLaHMnLWeJ 8cUMOIzBPsqBNgPhhAKxb290ek80aqjZy7CEsroza17U0nwk7UdGYHSJD0yQ37idtwcV6Whh/C8 kA7sXf7AeMcy28lgjRDpoIKuxQv57nX9NuckwqDVU1+UJWuu1JA0afjFdNoFmPBrMnDbD6z0GWj f/jpSyHBXFNgQiA== 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 new delegated_inode return pointer to vfs_mknod() and have the appropriate callers wait when there is an outstanding delegation. All other callers just set the pointer to NULL. Reviewed-by: Jan Kara Reviewed-by: NeilBrown Signed-off-by: Jeff Layton --- drivers/base/devtmpfs.c | 2 +- fs/ecryptfs/inode.c | 2 +- fs/init.c | 2 +- fs/namei.c | 25 +++++++++++++++++-------- fs/nfsd/vfs.c | 2 +- fs/overlayfs/overlayfs.h | 2 +- include/linux/fs.h | 4 ++-- net/unix/af_unix.c | 2 +- 8 files changed, 25 insertions(+), 16 deletions(-) diff --git a/drivers/base/devtmpfs.c b/drivers/base/devtmpfs.c index 104025104ef75381984fd94dfbd50feeaa8cdd22..2f576ecf18324f767cd5ac6cbd2= 8adbf9f46b958 100644 --- a/drivers/base/devtmpfs.c +++ b/drivers/base/devtmpfs.c @@ -231,7 +231,7 @@ static int handle_create(const char *nodename, umode_t = mode, kuid_t uid, return PTR_ERR(dentry); =20 err =3D vfs_mknod(&nop_mnt_idmap, d_inode(path.dentry), dentry, mode, - dev->devt); + dev->devt, NULL); if (!err) { struct iattr newattrs; =20 diff --git a/fs/ecryptfs/inode.c b/fs/ecryptfs/inode.c index 661709b157ce854c3bfdfdb13f7c10435fad9756..639ae42bcd56890d04592f7269e= 4ffc099b44f09 100644 --- a/fs/ecryptfs/inode.c +++ b/fs/ecryptfs/inode.c @@ -565,7 +565,7 @@ ecryptfs_mknod(struct mnt_idmap *idmap, struct inode *d= ir, rc =3D lock_parent(dentry, &lower_dentry, &lower_dir); if (!rc) rc =3D vfs_mknod(&nop_mnt_idmap, lower_dir, - lower_dentry, mode, dev); + lower_dentry, mode, dev, NULL); if (rc || d_really_is_negative(lower_dentry)) goto out; rc =3D ecryptfs_interpose(lower_dentry, dentry, dir->i_sb); diff --git a/fs/init.c b/fs/init.c index 895f8a09a71acfd03e11164e3b441a7d4e2de146..4f02260dd65b0dfcbfbf5812d2e= c6a33444a3b1f 100644 --- a/fs/init.c +++ b/fs/init.c @@ -157,7 +157,7 @@ int __init init_mknod(const char *filename, umode_t mod= e, unsigned int dev) error =3D security_path_mknod(&path, dentry, mode, dev); if (!error) error =3D vfs_mknod(mnt_idmap(path.mnt), path.dentry->d_inode, - dentry, mode, new_decode_dev(dev)); + dentry, mode, new_decode_dev(dev), NULL); end_creating_path(&path, dentry); return error; } diff --git a/fs/namei.c b/fs/namei.c index 7510942e0249de19df4363b92f813b3acdfc2254..7e400cbdbc6af1c72eb684f051d= 0571e944a27d7 100644 --- a/fs/namei.c +++ b/fs/namei.c @@ -4297,13 +4297,15 @@ inline struct dentry *start_creating_user_path( } EXPORT_SYMBOL(start_creating_user_path); =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 + * @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 + * @delegated_inode: returns parent inode, if the inode is delegated. * * Create a device node or file. * @@ -4314,7 +4316,8 @@ EXPORT_SYMBOL(start_creating_user_path); * 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) + 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); @@ -4338,6 +4341,10 @@ 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); @@ -4397,11 +4404,13 @@ static int do_mknodat(int dfd, struct filename *nam= e, umode_t mode, break; case S_IFCHR: case S_IFBLK: error =3D vfs_mknod(idmap, path.dentry->d_inode, - dentry, mode, new_decode_dev(dev)); + 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); + dentry, mode, 0, + &delegated_inode); break; } out2: diff --git a/fs/nfsd/vfs.c b/fs/nfsd/vfs.c index 7eaae44467188fab0909fabec986e103bcd52457..44debf3d0be450ddc245e2fa4f5= 7fe076e1454a2 100644 --- a/fs/nfsd/vfs.c +++ b/fs/nfsd/vfs.c @@ -1660,7 +1660,7 @@ nfsd_create_locked(struct svc_rqst *rqstp, struct svc= _fh *fhp, case S_IFIFO: case S_IFSOCK: host_err =3D vfs_mknod(&nop_mnt_idmap, dirp, dchild, - iap->ia_mode, rdev); + iap->ia_mode, rdev, NULL); break; default: printk(KERN_WARNING "nfsd: bad file type %o in nfsd_create\n", diff --git a/fs/overlayfs/overlayfs.h b/fs/overlayfs/overlayfs.h index d3123f5d97e86b58e4c9608cf6ef2abd1fcddbcd..87b82dada7ec1b8429299c68078= cda24176c5607 100644 --- a/fs/overlayfs/overlayfs.h +++ b/fs/overlayfs/overlayfs.h @@ -257,7 +257,7 @@ static inline int ovl_do_mknod(struct ovl_fs *ofs, struct inode *dir, struct dentry *dentry, umode_t mode, dev_t dev) { - int err =3D vfs_mknod(ovl_upper_mnt_idmap(ofs), dir, dentry, mode, dev); + int err =3D vfs_mknod(ovl_upper_mnt_idmap(ofs), dir, dentry, mode, dev, N= ULL); =20 pr_debug("mknod(%pd2, 0%o, 0%o) =3D %i\n", dentry, mode, dev, err); return err; diff --git a/include/linux/fs.h b/include/linux/fs.h index 5fcf64d9cf42ce135c0fbcbf6dfbf8816ae0bcb1..a1e1afe39e01a46bf0a81e241b9= 2690947402851 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h @@ -2115,7 +2115,7 @@ int vfs_create(struct mnt_idmap *, struct inode *, struct dentry *vfs_mkdir(struct mnt_idmap *, struct inode *, struct dentry *, umode_t, struct inode **); int vfs_mknod(struct mnt_idmap *, struct inode *, struct dentry *, - umode_t, dev_t); + umode_t, dev_t, struct inode **); int vfs_symlink(struct mnt_idmap *, struct inode *, struct dentry *, const char *); int vfs_link(struct dentry *, struct mnt_idmap *, struct inode *, @@ -2151,7 +2151,7 @@ static inline int vfs_whiteout(struct mnt_idmap *idma= p, struct inode *dir, struct dentry *dentry) { return vfs_mknod(idmap, dir, dentry, S_IFCHR | WHITEOUT_MODE, - WHITEOUT_DEV); + WHITEOUT_DEV, NULL); } =20 struct file *kernel_tmpfile_open(struct mnt_idmap *idmap, diff --git a/net/unix/af_unix.c b/net/unix/af_unix.c index 768098dec2310008632558ae928703b37c3cc8ef..db1fd8d6a84c2c7c0d45b43d9c5= a936b3d491b7b 100644 --- a/net/unix/af_unix.c +++ b/net/unix/af_unix.c @@ -1399,7 +1399,7 @@ static int unix_bind_bsd(struct sock *sk, struct sock= addr_un *sunaddr, idmap =3D mnt_idmap(parent.mnt); err =3D security_path_mknod(&parent, dentry, mode, 0); if (!err) - err =3D vfs_mknod(idmap, d_inode(parent.dentry), dentry, mode, 0); + err =3D vfs_mknod(idmap, d_inode(parent.dentry), dentry, mode, 0, NULL); if (err) goto out_path; err =3D mutex_lock_interruptible(&u->bindlock); --=20 2.51.0 From nobody Sun Feb 8 06:55:58 2026 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 8B1BF3491E5; Tue, 21 Oct 2025 15:26:29 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1761060389; cv=none; b=R9gYw9JqtuxbDaN982ScjE5nbN+51np8IAH0H4Nf7poSX6f0P45tfOPj5RLCH/jQrkp21DcFKoK3pE6ZJAODzt1eqvnG/yVyDC5ic5UQUOJm3B/wCHui5sfGReeMQZDzsYNqMXKJEYBze5HbwexE+6ngwdUhYat+rWXnEOLI0pQ= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1761060389; c=relaxed/simple; bh=4NHBIizTYeZIawZLQlZrsTm704FnFAPo2u/kNDBqYtI=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=lxO3TMRtR92hHl4MxgOXz4bFgM6kniaLkovAyzLYCksj4nSq2Z9Mpzq8FuTiPYmbtMMa5OE4pWcCAdTWDP4SifGLuOA1GFAo71VCDsZK+JkoWdtq9zL0SVgI+n8BfCEK0QBtKNRdPR18O4I/leOtPHUgK1QIjY/BvjZ8rHCGIEM= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=JsZ1uu/6; 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="JsZ1uu/6" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 43498C4CEF5; Tue, 21 Oct 2025 15:26:26 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1761060389; bh=4NHBIizTYeZIawZLQlZrsTm704FnFAPo2u/kNDBqYtI=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=JsZ1uu/6iDsPS/DmXUjyUGg2YYgq5qxauC3Ts9u79K0l4C8ltgN1l/LM6obvIO/tV udv22GlqOi1K8AoEfmnajjspWq9pAOeTFmfsrtZv795stqKTR9w7F++c2Iw8CFrZ8r NGGwLhMajg9G+RSEhBe9DKJ3RjhKOR/aLGJRp8nPUDAfLyRp651DJelWrNGRMVqIfm /xig5MxGOb/nruqB54sASRJHHIVu+jULlYiMXEuyeIONZJRB0UEXMzC/2LDn8nXyeX rP8QQeq4gemZpdsCU0B5MABm3+j4XBEWTYdiIs7YU9r5yJ++JLHhMVQHjajlF53B+O 6ceFi0oavh9yA== From: Jeff Layton Date: Tue, 21 Oct 2025 11:25:43 -0400 Subject: [PATCH v3 08/13] vfs: make vfs_symlink break delegations on parent dir 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: <20251021-dir-deleg-ro-v3-8-a08b1cde9f4c@kernel.org> References: <20251021-dir-deleg-ro-v3-0-a08b1cde9f4c@kernel.org> In-Reply-To: <20251021-dir-deleg-ro-v3-0-a08b1cde9f4c@kernel.org> To: Miklos Szeredi , 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 , Greg Kroah-Hartman , "Rafael J. Wysocki" , Danilo Krummrich , David Howells , Tyler Hicks , NeilBrown , Olga Kornievskaia , Dai Ngo , Amir Goldstein , Namjae Jeon , Steve French , Sergey Senozhatsky , Carlos Maiolino , Kuniyuki Iwashima , "David S. Miller" , Eric Dumazet , Jakub Kicinski , Paolo Abeni , Simon Horman 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, netfs@lists.linux.dev, ecryptfs@vger.kernel.org, linux-unionfs@vger.kernel.org, linux-xfs@vger.kernel.org, netdev@vger.kernel.org, Jeff Layton X-Mailer: b4 0.14.2 X-Developer-Signature: v=1; a=openpgp-sha256; l=5569; i=jlayton@kernel.org; h=from:subject:message-id; bh=4NHBIizTYeZIawZLQlZrsTm704FnFAPo2u/kNDBqYtI=; b=owEBbQKS/ZANAwAKAQAOaEEZVoIVAcsmYgBo96YFD8gEDdr0xMfhoaOoe6SQiM0eniYWOPjfN pC9nHhDYvqJAjMEAAEKAB0WIQRLwNeyRHGyoYTq9dMADmhBGVaCFQUCaPemBQAKCRAADmhBGVaC Fcm8EACjz3JjPoT5lOHPzhA+bnygMRpD3fh2wF6i4T7uTwVb1KWz7khVxZW4X+3lBVsXIwrv6cV b5di8H68GW8ufvJjQu5e1BahopVR/q22LX3GVNdjJeA/332gYvaWdtn36Mg7mtdd2Rxcs7N2OmH sDLWluOF7uWtpP53Af4wrWenU3Njp8vJ20Lhpk2TNl3QeeUqXBoKvcUoiQufOIFuKHG0gdZmSN1 697YbE+Q6LY9jqtjnLAZHiLhfZTSqJkVGQm+ro2s5bqdXJhPCz5Xm0zI6l3dsNWbdRtWIfLNZEN eY4E/0POfBuxzRtyKLE/WqW9tiUE55qe3ITvWlf4iJLu2zJQ5TwMaqgiis1YRdH8cH0JQQ/T4ZW mqJ5A/ePa6OWX7KKRKk43EtiqJlkcrahbk4eaLIG/JrpGCYoTN2388MCVKhiJ2OjdFnVaJAeSp2 auaSnr2+beSbO/rYQuoYQk8dWhVk3qQ+BTaIuFRlh/hShnvvo2qpU/c3t8P0vULrF8FpZUgTzGN YRVc5RBXBuQ3KJA33a7zQBFnaJvBVEuHp/gQqFiZClZR1flUKxYIwO2VGE0DPp6Ky0VMPW3Kd0i 2hkkhyDD6PE/VAI0570PiCVe3t1zX6/4QH8TRAxlg3zqaYr6Ei2zQ0Cs6MIv3kkt1mcmia53+OB QPtr7Tm+T4yIP4Q== X-Developer-Key: i=jlayton@kernel.org; a=openpgp; fpr=4BC0D7B24471B2A184EAF5D3000E684119568215 In order to add directory delegation support, we must break delegations on the parent on any change to the directory. Add a delegated_inode parameter to vfs_symlink() and have it break the delegation. do_symlinkat() can then wait on the delegation break before proceeding. Signed-off-by: Jeff Layton Reviewed-by: Jan Kara --- fs/ecryptfs/inode.c | 2 +- fs/init.c | 2 +- fs/namei.c | 16 ++++++++++++++-- fs/nfsd/vfs.c | 2 +- fs/overlayfs/overlayfs.h | 2 +- include/linux/fs.h | 2 +- 6 files changed, 19 insertions(+), 7 deletions(-) diff --git a/fs/ecryptfs/inode.c b/fs/ecryptfs/inode.c index 639ae42bcd56890d04592f7269e4ffc099b44f09..d430ec5a63094ea4cd42828e7d4= 4f0f8d918fcec 100644 --- a/fs/ecryptfs/inode.c +++ b/fs/ecryptfs/inode.c @@ -480,7 +480,7 @@ static int ecryptfs_symlink(struct mnt_idmap *idmap, if (rc) goto out_lock; rc =3D vfs_symlink(&nop_mnt_idmap, lower_dir, lower_dentry, - encoded_symname); + encoded_symname, NULL); kfree(encoded_symname); if (rc || d_really_is_negative(lower_dentry)) goto out_lock; diff --git a/fs/init.c b/fs/init.c index 4f02260dd65b0dfcbfbf5812d2ec6a33444a3b1f..e0f5429c0a49d046bd3f231a260= 954ed0f90ef44 100644 --- a/fs/init.c +++ b/fs/init.c @@ -209,7 +209,7 @@ int __init init_symlink(const char *oldname, const char= *newname) error =3D security_path_symlink(&path, dentry, oldname); if (!error) error =3D vfs_symlink(mnt_idmap(path.mnt), path.dentry->d_inode, - dentry, oldname); + dentry, oldname, NULL); end_creating_path(&path, dentry); return error; } diff --git a/fs/namei.c b/fs/namei.c index 7e400cbdbc6af1c72eb684f051d0571e944a27d7..71af256cdd941e200389570538f= 64a3f795e6c83 100644 --- a/fs/namei.c +++ b/fs/namei.c @@ -4851,6 +4851,7 @@ SYSCALL_DEFINE1(unlink, const char __user *, pathname) * @dir: inode of the parent directory * @dentry: dentry of the child symlink file * @oldname: name of the file to link to + * @delegated_inode: returns victim inode, if the inode is delegated. * * Create a symlink. * @@ -4861,7 +4862,8 @@ SYSCALL_DEFINE1(unlink, const char __user *, pathname) * raw inode simply pass @nop_mnt_idmap. */ int vfs_symlink(struct mnt_idmap *idmap, struct inode *dir, - struct dentry *dentry, const char *oldname) + struct dentry *dentry, const char *oldname, + struct inode **delegated_inode) { int error; =20 @@ -4876,6 +4878,10 @@ int vfs_symlink(struct mnt_idmap *idmap, struct inod= e *dir, if (error) return error; =20 + error =3D try_break_deleg(dir, delegated_inode); + if (error) + return error; + error =3D dir->i_op->symlink(idmap, dir, dentry, oldname); if (!error) fsnotify_create(dir, dentry); @@ -4889,6 +4895,7 @@ int do_symlinkat(struct filename *from, int newdfd, s= truct filename *to) struct dentry *dentry; struct path path; unsigned int lookup_flags =3D 0; + struct inode *delegated_inode =3D NULL; =20 if (IS_ERR(from)) { error =3D PTR_ERR(from); @@ -4903,8 +4910,13 @@ int do_symlinkat(struct filename *from, int newdfd, = struct filename *to) error =3D security_path_symlink(&path, dentry, from->name); if (!error) error =3D vfs_symlink(mnt_idmap(path.mnt), path.dentry->d_inode, - dentry, from->name); + dentry, from->name, &delegated_inode); end_creating_path(&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; diff --git a/fs/nfsd/vfs.c b/fs/nfsd/vfs.c index 44debf3d0be450ddc245e2fa4f57fe076e1454a2..386f454badce7ed448399ef93e9= c8edafbcc4d79 100644 --- a/fs/nfsd/vfs.c +++ b/fs/nfsd/vfs.c @@ -1829,7 +1829,7 @@ nfsd_symlink(struct svc_rqst *rqstp, struct svc_fh *f= hp, err =3D fh_fill_pre_attrs(fhp); if (err !=3D nfs_ok) goto out_unlock; - host_err =3D vfs_symlink(&nop_mnt_idmap, d_inode(dentry), dnew, path); + host_err =3D vfs_symlink(&nop_mnt_idmap, d_inode(dentry), dnew, path, NUL= L); err =3D nfserrno(host_err); cerr =3D fh_compose(resfhp, fhp->fh_export, dnew, fhp); if (!err) diff --git a/fs/overlayfs/overlayfs.h b/fs/overlayfs/overlayfs.h index 87b82dada7ec1b8429299c68078cda24176c5607..94bb4540f7ae2e0571b3b88393c= 180bd73c3c09c 100644 --- a/fs/overlayfs/overlayfs.h +++ b/fs/overlayfs/overlayfs.h @@ -267,7 +267,7 @@ static inline int ovl_do_symlink(struct ovl_fs *ofs, struct inode *dir, struct dentry *dentry, const char *oldname) { - int err =3D vfs_symlink(ovl_upper_mnt_idmap(ofs), dir, dentry, oldname); + int err =3D vfs_symlink(ovl_upper_mnt_idmap(ofs), dir, dentry, oldname, N= ULL); =20 pr_debug("symlink(\"%s\", %pd2) =3D %i\n", oldname, dentry, err); return err; diff --git a/include/linux/fs.h b/include/linux/fs.h index a1e1afe39e01a46bf0a81e241b92690947402851..d8c7245da3bf3200b435c7ea6ca= fcf7903ebf293 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h @@ -2117,7 +2117,7 @@ struct dentry *vfs_mkdir(struct mnt_idmap *, struct i= node *, int vfs_mknod(struct mnt_idmap *, struct inode *, struct dentry *, umode_t, dev_t, struct inode **); int vfs_symlink(struct mnt_idmap *, struct inode *, - struct dentry *, const char *); + struct dentry *, const char *, struct inode **); int vfs_link(struct dentry *, struct mnt_idmap *, struct inode *, struct dentry *, struct inode **); int vfs_rmdir(struct mnt_idmap *, struct inode *, struct dentry *, --=20 2.51.0 From nobody Sun Feb 8 06:55:58 2026 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 E0D2334B419; Tue, 21 Oct 2025 15:26: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=1761060394; cv=none; b=k8Zcda55mpqCASaVrO3TOidY5N/7tB8JlI1N3hvg97R6eqIyKAW7So2IQBZpqNdzohaEZeRmxd06gpq/DSW5nA3gUFVfRwGoOHUEziMDYYBDUdzTRjDw2CykHFaTi1h+QpzISx4Ef5kBU1aINRcELBAhARz73JTjZJenrW2WSEs= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1761060394; c=relaxed/simple; bh=3GlmIIbZmCr2QXgLwOVC+XsC0uT6drDrTKI/nBIEra8=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=TJlEi2UVN+bb2k9lPn84dX447w/bNk7L5PyOVQqY82JZFVZBjMHj6TR+SSAfl4XbzCSSV9EZRe+ynH/v/UeZ4TrhU2m06GwuARX5fqHizEWPrMX+qIvX39r3gJKGejI6iNLZuZo2WA9aCAWMTOCVd4Z1hU0QGWkn8mSSbgf29NI= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=naoi75RH; 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="naoi75RH" Received: by smtp.kernel.org (Postfix) with ESMTPSA id A5CFDC4CEF7; Tue, 21 Oct 2025 15:26:29 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1761060392; bh=3GlmIIbZmCr2QXgLwOVC+XsC0uT6drDrTKI/nBIEra8=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=naoi75RHkgNlTBKNN5hIFaDJDFFxqjQlXThRuRnIhe1jqLaC0g+83Tv7TyzU5wiRs a11Pp5BRjOpQ8taTdhUOzbLRlhLebAQp5maVh4qGEjwqHwLFEkmOkeAENGiD3xYAmv K2R8cTC8Td+voGi5qo1+1JvgepiRmNPbDwpS+nWW0HUgxLVynac5W6GAqBn4PkH/j0 HS0P390mcbl4VZYfk4IAOuBRJsLoTvBnWSBZ7Cpfi4yUdfSHn12wIDoB0+ssVu9emg wM0geWPEAu0IkAzBTPIwCO6SQuYIBINoJ9lIQL5flbjhNfcW4UHKOBn1avbMhMAYLw feH6F1hJwAHzw== From: Jeff Layton Date: Tue, 21 Oct 2025 11:25:44 -0400 Subject: [PATCH v3 09/13] 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: <20251021-dir-deleg-ro-v3-9-a08b1cde9f4c@kernel.org> References: <20251021-dir-deleg-ro-v3-0-a08b1cde9f4c@kernel.org> In-Reply-To: <20251021-dir-deleg-ro-v3-0-a08b1cde9f4c@kernel.org> To: Miklos Szeredi , 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 , Greg Kroah-Hartman , "Rafael J. Wysocki" , Danilo Krummrich , David Howells , Tyler Hicks , NeilBrown , Olga Kornievskaia , Dai Ngo , Amir Goldstein , Namjae Jeon , Steve French , Sergey Senozhatsky , Carlos Maiolino , Kuniyuki Iwashima , "David S. Miller" , Eric Dumazet , Jakub Kicinski , Paolo Abeni , Simon Horman 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, netfs@lists.linux.dev, ecryptfs@vger.kernel.org, linux-unionfs@vger.kernel.org, linux-xfs@vger.kernel.org, netdev@vger.kernel.org, Jeff Layton X-Mailer: b4 0.14.2 X-Developer-Signature: v=1; a=openpgp-sha256; l=1734; i=jlayton@kernel.org; h=from:subject:message-id; bh=3GlmIIbZmCr2QXgLwOVC+XsC0uT6drDrTKI/nBIEra8=; b=owEBbQKS/ZANAwAKAQAOaEEZVoIVAcsmYgBo96YFi4ys3PSq6TzdA5h4gvGtFYvqrbeEjvAAX lO4WmxTs2qJAjMEAAEKAB0WIQRLwNeyRHGyoYTq9dMADmhBGVaCFQUCaPemBQAKCRAADmhBGVaC FfoGD/4jaLSV8pLlgxtph3T3BATGjXMM9NbI6+Fgah+/VwDhhgYa21Y0g3UD1QfOfNGqCPRTUdi URMcGC+o4GTclMTHNX5CRquhW0c5eNEpv8drFyzotaX8phzHJiy0qG8rTYzggYBRbZRfXv38edg CffpzDE66YB9Uc2dnkrkBkWDUUmsFVw7k+Bzc0chpG0UuT9OpfdbEPfpWjtix/kidgAegdAXHFO JG1biEH4waBHBaz4VD/GnO1JAsy0BFNZT6dbfM1kRpTC3PvOjmaO1aimOMsiNYzjeiOxWVPa2sW AlP0LcLSpyoTu5rl6BO5zKMrrPtQ3AEU9EkAUhWh+T6iu7L0T7KbXHX7WFJx2nD0KidE49NSctc FSXSDFEUZ7W6RsNNB9qyOmRpPknswwJvu9agRM1hGH3jTQ9CF0rfxicLUXeI8Oyz6poJt1d/wCd ivsR4ugJeVY/s575prtQ9b/cpOK36DYDePkqRHM7EvBAAXZhiSc/CEjrXVdtxZLW4Fci3h4p774 QFHhoA3lJhrQ13aH6JlneEYjnYEFIV5wzXkbTu6T9I9aetAcJYjpJomFycfpfsvevozeEuftzGX J4YztguQCH4FdahFPa6CN6YoJmwLwS/S7JdwU4rW/WyaFOpz06Bi7JH10ISNLGHSioRSUacyCWz ULQN5cZM6cwaQ9A== 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. Write leases on directories are never allowed however, so continue to reject them. For now, there is no API for requesting delegations from userland, so ensure that userland is prevented from acquiring a lease on a directory. Reviewed-by: NeilBrown Signed-off-by: Jeff Layton Reviewed-by: Jan Kara --- fs/locks.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/fs/locks.c b/fs/locks.c index 0b16921fb52e602ea2e0c3de39d9d772af98ba7d..b47552106769ec5a189babfe125= 18e34aa59c759 100644 --- a/fs/locks.c +++ b/fs/locks.c @@ -1929,14 +1929,19 @@ static int generic_delete_lease(struct file *filp, = void *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) { case F_UNLCK: return generic_delete_lease(filp, *priv); - case F_RDLCK: case F_WRLCK: + if (S_ISDIR(inode->i_mode)) + return -EINVAL; + fallthrough; + case F_RDLCK: if (!(*flp)->fl_lmops->lm_break) { WARN_ON_ONCE(1); return -ENOLCK; @@ -2065,6 +2070,9 @@ static int do_fcntl_add_lease(unsigned int fd, struct= file *filp, int arg) */ int fcntl_setlease(unsigned int fd, struct file *filp, int arg) { + if (S_ISDIR(file_inode(filp)->i_mode)) + return -EINVAL; + if (arg =3D=3D F_UNLCK) return vfs_setlease(filp, F_UNLCK, NULL, (void **)&filp); return do_fcntl_add_lease(fd, filp, arg); --=20 2.51.0 From nobody Sun Feb 8 06:55:58 2026 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 A1DC734C992; Tue, 21 Oct 2025 15:26:36 +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=1761060396; cv=none; b=h9VWUdt2+P2Ryb94CIJxIhBh9ZRRWnWgGhIv8thyPZSRW4T9a2uzFyWSfQhuafCC2wjR+U6j9r1DAMTItT47ulr9uHKwraev936/CuErCa3sBJc4JFl4Hi7AmEGgg0kaC4uRcWBiOIEFvJBWWW+zH+V3oHCWq8H/UlG17iaqFRk= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1761060396; c=relaxed/simple; bh=MP4W7EqPdZca1WQgHgdKAkKp34XY8wVHuAMOFeV6ZCs=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=km0IYzFR57zxwBA8/ilOh1LJG/p4KW+GKVim/33cGipB6qZ/74+DJlLIQYJ9S0Jb1wC7WTZINZiVj82MUzPYGYgSDNTGyvIb2CosSAO6eEglOFnoOgvue2NHtY0eL3mcW66+ZqNrqeJoizDlkwE5pSfiJgIcA8C8O6HJuxUsNi0= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=lf3l4SMd; 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="lf3l4SMd" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 145E6C4CEFF; Tue, 21 Oct 2025 15:26:33 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1761060396; bh=MP4W7EqPdZca1WQgHgdKAkKp34XY8wVHuAMOFeV6ZCs=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=lf3l4SMdyTbGIsxtiKP/Xx0ZABwQIpdApc1NJXGQmntVpQIzzAKFza3K1VA7kXxm4 HYjvdm0TVNs+ee1BMO2jo5gF13v9/VNktCuTNdpi2wyOyDl5ByJurwUV1BqEu3RCoE eE4xPpVqhlL0gPozLtjQmt3P1BsGe9e4UjRZP9IOXto+kKxlere/15qDgE9fpxhpdk 4RVlhJXqIQ/0mK9/OSLF4xa4WK7gMo5NrwDVM2b2JM/gQgXEvZjd+N8et6isEDqdFE EIaqLC/D0zPuCJHZnwshjpRfItYxsiCScPIm607n3xXNAojEKKSwILUy1rKK36E74l AVzWeJHM+Lq8g== From: Jeff Layton Date: Tue, 21 Oct 2025 11:25:45 -0400 Subject: [PATCH v3 10/13] 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: <20251021-dir-deleg-ro-v3-10-a08b1cde9f4c@kernel.org> References: <20251021-dir-deleg-ro-v3-0-a08b1cde9f4c@kernel.org> In-Reply-To: <20251021-dir-deleg-ro-v3-0-a08b1cde9f4c@kernel.org> To: Miklos Szeredi , 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 , Greg Kroah-Hartman , "Rafael J. Wysocki" , Danilo Krummrich , David Howells , Tyler Hicks , NeilBrown , Olga Kornievskaia , Dai Ngo , Amir Goldstein , Namjae Jeon , Steve French , Sergey Senozhatsky , Carlos Maiolino , Kuniyuki Iwashima , "David S. Miller" , Eric Dumazet , Jakub Kicinski , Paolo Abeni , Simon Horman 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, netfs@lists.linux.dev, ecryptfs@vger.kernel.org, linux-unionfs@vger.kernel.org, linux-xfs@vger.kernel.org, netdev@vger.kernel.org, Jeff Layton X-Mailer: b4 0.14.2 X-Developer-Signature: v=1; a=openpgp-sha256; l=7422; i=jlayton@kernel.org; h=from:subject:message-id; bh=MP4W7EqPdZca1WQgHgdKAkKp34XY8wVHuAMOFeV6ZCs=; b=owEBbQKS/ZANAwAKAQAOaEEZVoIVAcsmYgBo96YFC5402XcUQ8VOdabN5K9Rh+lxbOgJldqfZ KC7AYLhUtuJAjMEAAEKAB0WIQRLwNeyRHGyoYTq9dMADmhBGVaCFQUCaPemBQAKCRAADmhBGVaC FSEBD/91FcWSP5VQ1WBORv7jdJJaNXwtg7ox3ryodZI1WmQ5zjn1+uMNhNx6sADVe9Inwrwp6SH rlNTPx3oGJSo4/QhE6kcIyaSKZ6LxHxWvzWABGTgOF1Ah5DjTNQeLtCMPs8JsdsP/F1+WvtCiO9 wDX2mSQjUOShw5zH8VTF6xOOwVKkrnVEc6TxuiD/7s2ixpv0ZjMEjg34Rd0Z5Bv27uYKLqz8h3O 4GOIdR65LqfCmzpymbzVGhFu94/1jflwEOOXLtfvhAcLchynu9t//FSbKjZBCx8WIna1nGckeTp zLnN4vm1ZDanx9n0GSU/yN6wYN6ey+m1dWxrObLy4a9Ci+2pkAoldAxp/qyPRFETKQSebeYqESW DXk/5dakZBMJT7+VufGWvd9g3ExpMurHfl8ecfVtKb5KNhop+9uRLL517nEn8TIZpIk+gcRxRvK N2NoMhyMUbqN2Z3Z9S0iPP7AY9JVVVkrlLQt3kYKQAxTXWGWtngkzFFc0b3hj3Okq3qMewf38e5 STE0IZpBkJl4mhWG9i4YuxFSKKj+OpPKT5YODIheRYT1VTUqvon0Hz2rBq9u3E+gbenhbtqb5Tv JwRuGi/8csCQeghXNmtRj6FQXWFnh9MQL/h6Lhgu9kGpOlLotXKf8jRVZG1NcAvs1Be7zpd5oVs qERMv7ISDjjgCog== X-Developer-Key: i=jlayton@kernel.org; a=openpgp; fpr=4BC0D7B24471B2A184EAF5D3000E684119568215 The filecache infrastructure will only handle S_IFREG files at the moment. Directory delegations will require adding support for opening S_IFDIR inodes. Plumb a "type" argument into nfsd_file_do_acquire() and have all of the existing callers set it to S_IFREG. Add a new nfsd_file_acquire_dir() wrapper that nfsd can call to request a nfsd_file that holds a directory open. For now, there is no need for a fsnotify_mark for directories, as CB_NOTIFY is not yet supported. Change nfsd_file_do_acquire() to avoid allocating one for non-S_IFREG inodes. Reviewed-by: Chuck Lever Reviewed-by: NeilBrown Signed-off-by: Jeff Layton --- fs/nfsd/filecache.c | 57 ++++++++++++++++++++++++++++++++++++++++---------= ---- fs/nfsd/filecache.h | 2 ++ fs/nfsd/vfs.c | 5 +++-- fs/nfsd/vfs.h | 2 +- 4 files changed, 49 insertions(+), 17 deletions(-) diff --git a/fs/nfsd/filecache.c b/fs/nfsd/filecache.c index a238b6725008a5c2988bd3da874d1f34ee778437..93798575b8075c63f95cd415b6d= 24df706ada0f6 100644 --- a/fs/nfsd/filecache.c +++ b/fs/nfsd/filecache.c @@ -1086,7 +1086,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; @@ -1097,13 +1097,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); @@ -1176,15 +1176,18 @@ nfsd_file_do_acquire(struct svc_rqst *rqstp, struct= net *net, =20 open_file: trace_nfsd_file_alloc(nf); - nf->nf_mark =3D nfsd_file_mark_find_or_create(inode); - if (nf->nf_mark) { + + if (type =3D=3D S_IFREG) + nf->nf_mark =3D nfsd_file_mark_find_or_create(inode); + + if (type !=3D S_IFREG || nf->nf_mark) { if (file) { get_file(file); nf->nf_file =3D file; 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); @@ -1246,7 +1249,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 /** @@ -1271,7 +1274,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 /** @@ -1314,8 +1317,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; } @@ -1344,7 +1347,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 e3d6ca2b60308e5e91ba4bb32d935f54527d8bda..b383dbc5b9218d21a29b852572f= 80fab08de9fa9 100644 --- a/fs/nfsd/filecache.h +++ b/fs/nfsd/filecache.h @@ -82,5 +82,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 386f454badce7ed448399ef93e9c8edafbcc4d79..f1c6b6e87d84fa6e1923b44a89b= af5183ede54b8 100644 --- a/fs/nfsd/vfs.c +++ b/fs/nfsd/vfs.c @@ -959,15 +959,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 c713ed0b04e0311ab606c5c456c8ce92dd506cce..12309426410f923492e73f6867c= d6597a9c0a097 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.51.0 From nobody Sun Feb 8 06:55:58 2026 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 0824134CFA2; Tue, 21 Oct 2025 15:26: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=1761060400; cv=none; b=lHRPe4KhXs+JbxkbhSBNHt+B7rO/EJAoNVhgATg7Hz0pM8lYzKTrDEAox4+quNCGETAEIpeX2eeZh9h774L9mUaUkkbtiKdU4G6uVxY3mpzLIbtgjo1/z5c5sAUCEXqfs+KkXLUQmc1SwGJxDz2OosRtrx01MYyq19uaQY61sSw= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1761060400; c=relaxed/simple; bh=5KL194cDy8pXTi8dv0lTe3U1RaJZS0i7BDkxSupOVDk=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=tD3CwBrB4f1W/1glTRoj/YzwjpjxXWdvFSAn/avzpW2pyqd06GotdjXDtv/xiV5YfZb3KNR9aSQ+ipK8x+g3r9uLWUt2WezSg8n6hLdsp3uuWyagujExncS3vounqMP7b3hFuvUdrUupOiirbFtSzudyCh3obslptXTyp/YdC0E= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=FmNbAiLK; 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="FmNbAiLK" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 778B9C4CEF7; Tue, 21 Oct 2025 15:26:36 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1761060399; bh=5KL194cDy8pXTi8dv0lTe3U1RaJZS0i7BDkxSupOVDk=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=FmNbAiLKdbuqj1n3+yLXw7edwgAi3YMmopkPxwUYu95iG6zbsPiWjeduKwLt1wvGj U2/Oe1pFeyQqi/TV2hyfTD8U/KTZz8V2yJW4ZRrw17bX26OpvDXejjASgoDyjx17Q4 trymAEPBcMdB4WH4FDQ/o6/sY7GyOKOWcF6gLhKMS95ASp2aicBAbjEEaLHszdA8Gs HGnWGS8ZN3qSMfSfMYafZz48pmTHXiX6Cvqw8eg88W7RDhatsUUd1cw7CKSD5Wmqys eDf0rgR5VhE0Zp9FxQ7EttIOGXk/TVNOEZe7+nYE5RrrvRyuGoLWMz9R+J4n0yctLH bUOoLmNBw7NbA== From: Jeff Layton Date: Tue, 21 Oct 2025 11:25:46 -0400 Subject: [PATCH v3 11/13] 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: <20251021-dir-deleg-ro-v3-11-a08b1cde9f4c@kernel.org> References: <20251021-dir-deleg-ro-v3-0-a08b1cde9f4c@kernel.org> In-Reply-To: <20251021-dir-deleg-ro-v3-0-a08b1cde9f4c@kernel.org> To: Miklos Szeredi , 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 , Greg Kroah-Hartman , "Rafael J. Wysocki" , Danilo Krummrich , David Howells , Tyler Hicks , NeilBrown , Olga Kornievskaia , Dai Ngo , Amir Goldstein , Namjae Jeon , Steve French , Sergey Senozhatsky , Carlos Maiolino , Kuniyuki Iwashima , "David S. Miller" , Eric Dumazet , Jakub Kicinski , Paolo Abeni , Simon Horman 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, netfs@lists.linux.dev, ecryptfs@vger.kernel.org, linux-unionfs@vger.kernel.org, linux-xfs@vger.kernel.org, netdev@vger.kernel.org, Jeff Layton X-Mailer: b4 0.14.2 X-Developer-Signature: v=1; a=openpgp-sha256; l=1228; i=jlayton@kernel.org; h=from:subject:message-id; bh=5KL194cDy8pXTi8dv0lTe3U1RaJZS0i7BDkxSupOVDk=; b=owEBbQKS/ZANAwAKAQAOaEEZVoIVAcsmYgBo96YGlGvZvStPLKVjUq7mDndmacDCTXRTakxh0 UxfxYQt60mJAjMEAAEKAB0WIQRLwNeyRHGyoYTq9dMADmhBGVaCFQUCaPemBgAKCRAADmhBGVaC Fdp8EACeFGg5hC0OvCKrPGcyj0JttbsPqGpdPyDWKECBezl2A5xaWxazaaKSL1q3wsP6XJRmj6U U4t7VNIBnGbA1mwWJqyknxwYCV3OX48poB8pGx1QJQRuPDebqhKv1RLwZ0R0prNvS3Ru5bS3O6s I6tQtIgobO/Gnmy5SW7AfFUcKgZdFupFClT0QSRn5rNk292ORayPgkG+Tw1RSCB02glbEkKnFzE M0zOWqFzUol0ES2ZGFamBOSv60tsf1Cud6Kq+M4f53DIuhYbVWgfdudppz6T3RC9TYMTwTNGIqM p2YpbPGtA7cUCuf4h9TifCod+tmsZODvlaO5x+oo7dzrWEcM+xYyunRZ6V99saH7Pq4l+tBS41k TSCJ2tB+NkuTLc2Z3qgv22+HxL6nWibgNd1iebonCau+at4mU0+SL4SNn8iYKZrkmbNdtWsa8qr 9GyU9Jt6ulr77IDz2VLV8mTQlItyrze2wYpE7PvI8tjHALuH1YWsdP47C7xMsK/m9q6zHYCvUEh VDeYY4SDS28sXTfCOLFoV8I3lzYFdIrIYLnzGyZn9zdDJc5N3ApfYjg7suZMF0J6DCud6bB+IkX SMo/VnXScB9HFHBgo9bCJLhd5w42vDbk5iinBeVDSFXx9xC1oVLW0P2xpKQfHnwY1PnO50bvxJv HZyXO82iJFuLEQw== 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. Reviewed-by: Chuck Lever Reviewed-by: NeilBrown 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 35004568d43eb27254802f6f5784a3c04c20fe08..8efa37055b21ca2202488e90377= d5162613b9343 100644 --- a/fs/nfsd/nfs4state.c +++ b/fs/nfsd/nfs4state.c @@ -7832,7 +7832,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.51.0 From nobody Sun Feb 8 06:55:58 2026 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 82F503370ED; Tue, 21 Oct 2025 15:26: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=1761060403; cv=none; b=ClXINiWtOGFN8XzChdrBC8AjSzLI1xvaR333ndf2J4W/KUAzRtrEmK/GnnX0y8d4Iuj2ppSxQORpi6lztjoFRHX7dJwPcs/VaC35ufomxnuM93O8twJ1dFDznCRValG/jfyMfzCoIsnP+OA3USB7n6JyhU2S5znGX/eTJY0O058= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1761060403; c=relaxed/simple; bh=tbkhNU6XkoF0KbeOuYLiTK96TlpVye1DLh0q82UO25c=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=sP/S7lGde0YuhkKCwNb+0xXCQL07Odg4q0u4reTDzfT5NXQs43cHFG3ajPwk73WWtalGskcv0tfzMj6HZSZjxHJMv8EcAX6l7Yrwqm+hM7qjHlOlrPr8gOLN8v/mDoP43TcDeLLwF+3IWPrPdXu/oSc6pUmQ/bSl4MkGMfmcpZ4= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=dyYUYCgH; 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="dyYUYCgH" Received: by smtp.kernel.org (Postfix) with ESMTPSA id D9AC1C116B1; Tue, 21 Oct 2025 15:26:39 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1761060403; bh=tbkhNU6XkoF0KbeOuYLiTK96TlpVye1DLh0q82UO25c=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=dyYUYCgHKc5Ydqi5NnksRf9NuhISqnWwhfKBP4CKOPxsgE5lja4NX6bRM97mF5kJE a0g0qCtaDNi908QtGf1X/2GzXay4lak8GrS6lti16Frd7k7sN+CpkFM3JQtdAj42rV 2zGgLdF1xHO82NflAHi2A7+gXyTMM+GeWsdzEq4R6hJomKN7I7RzKCiI+XoJyRxLUk kafPmITrcRMkJxO6yaeufoMJB7nS7uQttbx4SBTpJHYsxSobxo1WMs0YrGXeXinRUO VEursqIlxPE3dYJ5cerLY9x4e3b9FIvYZvT37WSRUxvsaJiGDWOQGYt2lALOrDp5w7 R9Lf2QF6ELqpg== From: Jeff Layton Date: Tue, 21 Oct 2025 11:25:47 -0400 Subject: [PATCH v3 12/13] 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: <20251021-dir-deleg-ro-v3-12-a08b1cde9f4c@kernel.org> References: <20251021-dir-deleg-ro-v3-0-a08b1cde9f4c@kernel.org> In-Reply-To: <20251021-dir-deleg-ro-v3-0-a08b1cde9f4c@kernel.org> To: Miklos Szeredi , 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 , Greg Kroah-Hartman , "Rafael J. Wysocki" , Danilo Krummrich , David Howells , Tyler Hicks , NeilBrown , Olga Kornievskaia , Dai Ngo , Amir Goldstein , Namjae Jeon , Steve French , Sergey Senozhatsky , Carlos Maiolino , Kuniyuki Iwashima , "David S. Miller" , Eric Dumazet , Jakub Kicinski , Paolo Abeni , Simon Horman 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, netfs@lists.linux.dev, ecryptfs@vger.kernel.org, linux-unionfs@vger.kernel.org, linux-xfs@vger.kernel.org, netdev@vger.kernel.org, Jeff Layton X-Mailer: b4 0.14.2 X-Developer-Signature: v=1; a=openpgp-sha256; l=5526; i=jlayton@kernel.org; h=from:subject:message-id; bh=tbkhNU6XkoF0KbeOuYLiTK96TlpVye1DLh0q82UO25c=; b=owEBbQKS/ZANAwAKAQAOaEEZVoIVAcsmYgBo96YGPIpUTjMhlpZiqNkjCVNhEOGJcwNKwTAnS Qk/24pWq8iJAjMEAAEKAB0WIQRLwNeyRHGyoYTq9dMADmhBGVaCFQUCaPemBgAKCRAADmhBGVaC FbPCD/sFGLUqbjJhuX8T756oh/4AhmcZa75nhq5H0yqdAlrYDuz++cDN9XQwd1x68RpQLvMmb1m gnTyabXCVMqs6upJBuN7AU5QPvevE/DrnVQU46rSHC3B8oTyxb1SpOKiQypv35uYSB0j0knLlFm quwgqrr3f3d/41Cpt3Q9dmiON4aUFGdLtDV7/xIQIP59Np1n7LPlccIRURuURhnKRlAfYO9OjVu 8bm081ymhykRnxvVNnV0Yn1Ao69lgldFTqFbNEX/lz4L4V90/ObjZsUpYzrTg1peYmIjhOuuQYC TXdg2imhtJ5rNTCjCu7O4aT3YFjIyq4tNdSBBbCTYoxLccmaq+f0z7ghWoCzDwB21uP5LGIohxg 9icYHZZ9kL51pIiygML6BuBWkkDEhlCIw1Ph4Qssl7jC2YfJVoou7oTequfuzodjhV2eXSOjRdq w4uzmupwpdP6p21z79iI+GcE1lDcw40yrrgZwgmYBfTwPLfyNeDZ2F323tT841Qx/ABe/QGMYM4 heLBuchPk693WFHJTO8hmlvNLO8zwHKXJwAf/7QflMnxqT4De66rBGzEs8qbm5ZsNgtRrMrUxKR tgu16XsmQHVbhBGCfjqPhuy3Zz02XEkOC06u+ty0NSg9/xvmBhb3bnjaWJGtvmdZc6PIsu5Itmg eAkfSUinIxbbyjw== X-Developer-Key: i=jlayton@kernel.org; a=openpgp; fpr=4BC0D7B24471B2A184EAF5D3000E684119568215 Add a new routine for acquiring a read delegation on a directory. These are recallable-only delegations with no support for CB_NOTIFY. That will be added in a later phase. Since the same CB_RECALL/DELEGRETURN infrastructure is used for regular and directory delegations, a normal nfs4_delegation is used to represent a directory delegation. Reviewed-by: NeilBrown Signed-off-by: Jeff Layton Reviewed-by: Chuck Lever --- fs/nfsd/nfs4proc.c | 22 +++++++++++- fs/nfsd/nfs4state.c | 100 ++++++++++++++++++++++++++++++++++++++++++++++++= ++++ fs/nfsd/state.h | 5 +++ 3 files changed, 126 insertions(+), 1 deletion(-) diff --git a/fs/nfsd/nfs4proc.c b/fs/nfsd/nfs4proc.c index 2222bb283baff35703b4035fa0fc593b54d8b937..4f0b1210702ecf4eaa20c74e548= aabbee33b7fd1 100644 --- a/fs/nfsd/nfs4proc.c +++ b/fs/nfsd/nfs4proc.c @@ -2342,6 +2342,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: @@ -2355,7 +2362,20 @@ 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); + nfsd_file_put(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 8efa37055b21ca2202488e90377d5162613b9343..808c24fb5c9a0b432d3271c051b= 409fcb75970cd 100644 --- a/fs/nfsd/nfs4state.c +++ b/fs/nfsd/nfs4state.c @@ -9367,3 +9367,103 @@ 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, *rfp; + int status =3D 0; + + fp =3D nfsd4_alloc_file(); + if (!fp) + return ERR_PTR(-ENOMEM); + + nfsd4_file_init(&cstate->current_fh, fp); + + rfp =3D nfsd4_file_hash_insert(fp, &cstate->current_fh); + if (unlikely(!rfp)) { + put_nfs4_file(fp); + return ERR_PTR(-ENOMEM); + } + + if (rfp !=3D fp) { + put_nfs4_file(fp); + fp =3D rfp; + } + + /* if this client already has one, return that it's unavailable */ + spin_lock(&state_lock); + spin_lock(&fp->fi_lock); + /* existing delegation? */ + if (nfs4_delegation_exists(clp, fp)) { + status =3D -EAGAIN; + } else if (!fp->fi_deleg_file) { + fp->fi_deleg_file =3D nfsd_file_get(nf); + fp->fi_delegees =3D 1; + } else { + ++fp->fi_delegees; + } + spin_unlock(&fp->fi_lock); + spin_unlock(&state_lock); + + if (status) { + put_nfs4_file(fp); + return ERR_PTR(status); + } + + /* 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 1e736f4024263ffa9c93bcc9ec48f44566a8cc77..b052c1effdc5356487c610db972= 8df8ecfe851d4 100644 --- a/fs/nfsd/state.h +++ b/fs/nfsd/state.h @@ -867,4 +867,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.51.0 From nobody Sun Feb 8 06:55:58 2026 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 C979E342CBB; Tue, 21 Oct 2025 15:26:46 +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=1761060408; cv=none; b=J7XjfdOfmthY2S2mWK0eF7Th121cER0hdrFvdrQEZSkbDhOGT9tAXIEChASVI2uuB5RmOIInpbecbbGh8XKRd6c/U13lf3AdjfTgqU+w39JbolrA5/GTkGxb0khZH4zNC9Bq5o+WByNK26VcXkPVJKIEzaNJRslhZq433G6fpKk= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1761060408; c=relaxed/simple; bh=WRzp2TQlTZchoT6m2ivAAefI4zmvljKPPT9tDXMZtL8=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=Hm1yfUWW+10GcotkF2gUzbd2bZkmoFSSu9OUEPm04jrHuPeTF9tj5+3HL6Xi1bOt36F3coMgCMpRkRe/yXMNuzaXHbsHtZKVhxOaIAjbF2zDQI+s5F8DQIQDF8MLGKcGWDYMDnwkmiOtyGwtwgpT6rmsxQSkPXepU5Z+/nQ+ZPk= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=n+FmqUcY; 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="n+FmqUcY" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 494E4C4CEF5; Tue, 21 Oct 2025 15:26:43 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1761060406; bh=WRzp2TQlTZchoT6m2ivAAefI4zmvljKPPT9tDXMZtL8=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=n+FmqUcYAgkei075A/8cGIUiLqlWli+96Xn28UrYT3CQ2x9JIehk4i1bTWJMNM6o0 FycuYs3ytk72UthUb7vw61+Zkig10GCvhJikLfvwRLURsrNbSWwji5IhaQH1rOUxFJ JQqfUYrgIvWL7HHeKLtFr10TgkIrmqyX77UIRpIfUYfnTZpeAy1o2UNEi6vUls/giS b3BhGyEla/6uuIspxu0KTcvqN2ZPAHVrlxil8IZMzUXIiCIVoymNnyb1mXU7migWWc gufjRskzI+bzjX4pD4w4ZmnUyJnUtNQNsUogaHShbpK0ytN4x77/9TDA28iI3wftPw bZ0MGWDQtHijw== From: Jeff Layton Date: Tue, 21 Oct 2025 11:25:48 -0400 Subject: [PATCH v3 13/13] vfs: expose delegation support to userland 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: <20251021-dir-deleg-ro-v3-13-a08b1cde9f4c@kernel.org> References: <20251021-dir-deleg-ro-v3-0-a08b1cde9f4c@kernel.org> In-Reply-To: <20251021-dir-deleg-ro-v3-0-a08b1cde9f4c@kernel.org> To: Miklos Szeredi , 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 , Greg Kroah-Hartman , "Rafael J. Wysocki" , Danilo Krummrich , David Howells , Tyler Hicks , NeilBrown , Olga Kornievskaia , Dai Ngo , Amir Goldstein , Namjae Jeon , Steve French , Sergey Senozhatsky , Carlos Maiolino , Kuniyuki Iwashima , "David S. Miller" , Eric Dumazet , Jakub Kicinski , Paolo Abeni , Simon Horman 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, netfs@lists.linux.dev, ecryptfs@vger.kernel.org, linux-unionfs@vger.kernel.org, linux-xfs@vger.kernel.org, netdev@vger.kernel.org, Jeff Layton X-Mailer: b4 0.14.2 X-Developer-Signature: v=1; a=openpgp-sha256; l=7870; i=jlayton@kernel.org; h=from:subject:message-id; bh=WRzp2TQlTZchoT6m2ivAAefI4zmvljKPPT9tDXMZtL8=; b=owEBbQKS/ZANAwAKAQAOaEEZVoIVAcsmYgBo96YG+lqopk+r/W1MoUjb/aRCWEUcUM376vNc7 uokTUn+zGmJAjMEAAEKAB0WIQRLwNeyRHGyoYTq9dMADmhBGVaCFQUCaPemBgAKCRAADmhBGVaC FSd9EACpg3fMTz1BEDjC8LY/SO85bg8i477SYR5KG2MrcAHKO8SUo/fZhyj8G4Nu+qBaClIlvwU Tq+2Hd4xxBM53VIeY/HBP5lfqDBl7MSua/mqDaekwBs4oCYwUZeVlmtq5X6nqTrxuLVCnlOstJr txLasYK//noELyGLZBoN1CW9UjgtHKWVPioDHi7l842TcTh1MsYT8AuwnnOlQhChhjq5+D4mSGS ZVOQpll1PDROw3S2/AVfqfLbvabHiUcMLW0K9e912rAvWJTIFmVyRLeFO0+psrBcT0PybZFPOnM +cLlwc/AVE8xt8m2bRmsY3jv5PuzY12IXO1L8N6nVTt7pYOgECHWAiO/enBlhbTZ5q8FYgizjYM gyliV3iKxCayC2tqKI+MTL/2tnqcaucbMbnNUONstBOZs1z0AVQJpTPPX57G/AwL0FvReZPHufz XqJSkPEfLZts8OslA1SOlbI8zYMVh/lNdt3Wmm1xst11oVvlN5y5RG3iXWBfPNLoIbzWO2ijFD+ PVduCqacE96IUhreKifx5nV23dsP8Nxnl5abj+FjVx3HxEICt829mJ7C7YcgSp75wWBU84ERp7K 3NkXd/uSHljpHMXDiCKMrSu5ubQuYJ2gtGGEV5/XZZ5Lfl9nDPlYvqspvWHspKQp2YEOJALT/G+ WhoDrAzmlMfpl6Q== X-Developer-Key: i=jlayton@kernel.org; a=openpgp; fpr=4BC0D7B24471B2A184EAF5D3000E684119568215 Now that support for recallable directory delegations is complete, expose this functionality to userland with new F_SETDELEG and F_GETDELEG commands for fcntl(). This also allows userland to request a FL_DELEG type lease on files too. Userland applications that do will get signalled when there are metadata changes in addition to just data changes (which is a limitation of FL_LEASE leases). These commands accept a new "struct delegation" argument that contains a flags field for future expansion. Signed-off-by: Jeff Layton --- fs/fcntl.c | 9 ++++++++ fs/locks.c | 53 ++++++++++++++++++++++++++++++++++++------= ---- include/linux/filelock.h | 12 +++++++++++ include/uapi/linux/fcntl.h | 10 +++++++++ 4 files changed, 73 insertions(+), 11 deletions(-) diff --git a/fs/fcntl.c b/fs/fcntl.c index 72f8433d9109889eecef56b32d20a85b4e12ea44..f34f0a07f993f9f95a60f2954bb= 4304d3c218498 100644 --- a/fs/fcntl.c +++ b/fs/fcntl.c @@ -445,6 +445,7 @@ static long do_fcntl(int fd, unsigned int cmd, unsigned= long arg, struct file *filp) { void __user *argp =3D (void __user *)arg; + struct delegation deleg; int argi =3D (int)arg; struct flock flock; long err =3D -EINVAL; @@ -550,6 +551,14 @@ static long do_fcntl(int fd, unsigned int cmd, unsigne= d long arg, case F_SET_RW_HINT: err =3D fcntl_set_rw_hint(filp, arg); break; + case F_GETDELEG: + err =3D fcntl_getdeleg(filp); + break; + case F_SETDELEG: + if (copy_from_user(&deleg, argp, sizeof(deleg))) + return -EFAULT; + err =3D fcntl_setdeleg(fd, filp, &deleg); + break; default: break; } diff --git a/fs/locks.c b/fs/locks.c index b47552106769ec5a189babfe12518e34aa59c759..fda62897e371fbc8d04b8073df3= d2267d2c7c430 100644 --- a/fs/locks.c +++ b/fs/locks.c @@ -585,7 +585,7 @@ static const struct lease_manager_operations lease_mana= ger_ops =3D { /* * Initialize a lease, use the default lock manager operations */ -static int lease_init(struct file *filp, int type, struct file_lease *fl) +static int lease_init(struct file *filp, unsigned int flags, int type, str= uct file_lease *fl) { if (assign_type(&fl->c, type) !=3D 0) return -EINVAL; @@ -594,13 +594,13 @@ static int lease_init(struct file *filp, int type, st= ruct file_lease *fl) fl->c.flc_pid =3D current->tgid; =20 fl->c.flc_file =3D filp; - fl->c.flc_flags =3D FL_LEASE; + fl->c.flc_flags =3D flags; fl->fl_lmops =3D &lease_manager_ops; return 0; } =20 /* Allocate a file_lock initialised to this type of lease */ -static struct file_lease *lease_alloc(struct file *filp, int type) +static struct file_lease *lease_alloc(struct file *filp, unsigned int flag= s, int type) { struct file_lease *fl =3D locks_alloc_lease(); int error =3D -ENOMEM; @@ -608,7 +608,7 @@ static struct file_lease *lease_alloc(struct file *filp= , int type) if (fl =3D=3D NULL) return ERR_PTR(error); =20 - error =3D lease_init(filp, type, fl); + error =3D lease_init(filp, flags, type, fl); if (error) { locks_free_lease(fl); return ERR_PTR(error); @@ -1548,10 +1548,9 @@ int __break_lease(struct inode *inode, unsigned int = mode, unsigned int type) int want_write =3D (mode & O_ACCMODE) !=3D O_RDONLY; LIST_HEAD(dispose); =20 - new_fl =3D lease_alloc(NULL, want_write ? F_WRLCK : F_RDLCK); + new_fl =3D lease_alloc(NULL, type, want_write ? F_WRLCK : F_RDLCK); if (IS_ERR(new_fl)) return PTR_ERR(new_fl); - new_fl->c.flc_flags =3D type; =20 /* typically we will check that ctx is non-NULL before calling */ ctx =3D locks_inode_context(inode); @@ -1697,7 +1696,7 @@ EXPORT_SYMBOL(lease_get_mtime); * XXX: sfr & willy disagree over whether F_INPROGRESS * should be returned to userspace. */ -int fcntl_getlease(struct file *filp) +static int __fcntl_getlease(struct file *filp, unsigned int flavor) { struct file_lease *fl; struct inode *inode =3D file_inode(filp); @@ -1713,7 +1712,8 @@ int fcntl_getlease(struct file *filp) list_for_each_entry(fl, &ctx->flc_lease, c.flc_list) { if (fl->c.flc_file !=3D filp) continue; - type =3D target_leasetype(fl); + if (fl->c.flc_flags & flavor) + type =3D target_leasetype(fl); break; } spin_unlock(&ctx->flc_lock); @@ -1724,6 +1724,16 @@ int fcntl_getlease(struct file *filp) return type; } =20 +int fcntl_getlease(struct file *filp) +{ + return __fcntl_getlease(filp, FL_LEASE); +} + +int fcntl_getdeleg(struct file *filp) +{ + return __fcntl_getlease(filp, FL_DELEG); +} + /** * check_conflicting_open - see if the given file points to an inode that = has * an existing open that would conflict with the @@ -2033,13 +2043,13 @@ vfs_setlease(struct file *filp, int arg, struct fil= e_lease **lease, void **priv) } EXPORT_SYMBOL_GPL(vfs_setlease); =20 -static int do_fcntl_add_lease(unsigned int fd, struct file *filp, int arg) +static int do_fcntl_add_lease(unsigned int fd, struct file *filp, unsigned= int flavor, int arg) { struct file_lease *fl; struct fasync_struct *new; int error; =20 - fl =3D lease_alloc(filp, arg); + fl =3D lease_alloc(filp, flavor, arg); if (IS_ERR(fl)) return PTR_ERR(fl); =20 @@ -2075,7 +2085,28 @@ int fcntl_setlease(unsigned int fd, struct file *fil= p, int arg) =20 if (arg =3D=3D F_UNLCK) return vfs_setlease(filp, F_UNLCK, NULL, (void **)&filp); - return do_fcntl_add_lease(fd, filp, arg); + return do_fcntl_add_lease(fd, filp, FL_LEASE, arg); +} + +/** + * fcntl_setdeleg - sets a delegation on an open file + * @fd: open file descriptor + * @filp: file pointer + * @deleg: delegation request from userland + * + * Call this fcntl to establish a delegation on the file. + * Note that you also need to call %F_SETSIG to + * receive a signal when the lease is broken. + */ +int fcntl_setdeleg(unsigned int fd, struct file *filp, struct delegation *= deleg) +{ + /* For now, no flags are supported */ + if (deleg->d_flags !=3D 0) + return -EINVAL; + + if (deleg->d_type =3D=3D F_UNLCK) + return vfs_setlease(filp, F_UNLCK, NULL, (void **)&filp); + return do_fcntl_add_lease(fd, filp, FL_DELEG, deleg->d_type); } =20 /** diff --git a/include/linux/filelock.h b/include/linux/filelock.h index c2ce8ba05d068b451ecf8f513b7e532819a29944..69b8fa8dce35dab670e6c7b288e= 13dc4caed1bc0 100644 --- a/include/linux/filelock.h +++ b/include/linux/filelock.h @@ -159,6 +159,8 @@ int fcntl_setlk64(unsigned int, struct file *, unsigned= int, =20 int fcntl_setlease(unsigned int fd, struct file *filp, int arg); int fcntl_getlease(struct file *filp); +int fcntl_setdeleg(unsigned int fd, struct file *filp, struct delegation *= deleg); +int fcntl_getdeleg(struct file *filp); =20 static inline bool lock_is_unlock(struct file_lock *fl) { @@ -271,6 +273,16 @@ static inline int fcntl_getlease(struct file *filp) return F_UNLCK; } =20 +static inline int fcntl_setdeleg(unsigned int fd, struct file *filp, struc= t delegation *deleg) +{ + return -EINVAL; +} + +static inline int fcntl_getdeleg(struct file *filp) +{ + return F_UNLCK; +} + static inline bool lock_is_unlock(struct file_lock *fl) { return false; diff --git a/include/uapi/linux/fcntl.h b/include/uapi/linux/fcntl.h index 3741ea1b73d8500061567b6590ccf5fb4c6770f0..aae88f4b5c05205b2b28ae46b21= bca9817197e04 100644 --- a/include/uapi/linux/fcntl.h +++ b/include/uapi/linux/fcntl.h @@ -79,6 +79,16 @@ */ #define RWF_WRITE_LIFE_NOT_SET RWH_WRITE_LIFE_NOT_SET =20 +/* Set/Get delegations */ +#define F_GETDELEG (F_LINUX_SPECIFIC_BASE + 15) +#define F_SETDELEG (F_LINUX_SPECIFIC_BASE + 16) + +/* Argument structure for F_GETDELEG and F_SETDELEG */ +struct delegation { + short d_type; /* F_RDLCK, F_WRLCK, F_UNLCK */ + unsigned int d_flags; +}; + /* * Types of directory notifications that may be requested. */ --=20 2.51.0