From nobody Sun Feb 8 01:31:09 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 4B0FC3451BE; Fri, 17 Oct 2025 11:32:25 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1760700746; cv=none; b=Glv6tMcBX2G4KnJ3sK3PmAslQJybMGrIXEmAc0g966zjZqOBABAVOCiAe5C4TXCZDQJgMLj9jbBVrfmOYDsseYuzXSSJesqRjcsAXAMWe+RGUABhYOezISJeXdam795ufAG17MOZT2bh5K1A3WGTJg5yGQ9uKO0WO4d4+O+Gf9k= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1760700746; c=relaxed/simple; bh=s4rvzuIbyXzK6y+wPnL+4uRpK7mDo/eer/xGdjtob/k=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=nx4fCeXoGCqoxKa21n1HPDtsos3r3oyGrSPOkSYYhQaxRS2aPw1pk8b2MRa2Udds6pH+kNDFdSwQyI7TBbe1ziDiey3rzRtBTMjVw6aCWLFHFbjUUsa7IW1lx+r7SMJ+bpw/2NCxjhLPJ8wq2jCAFMiQ2Y2sF81i9GsyOLuKioQ= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=MMpZHhGi; 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="MMpZHhGi" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 97545C4CEFE; Fri, 17 Oct 2025 11:32:22 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1760700745; bh=s4rvzuIbyXzK6y+wPnL+4uRpK7mDo/eer/xGdjtob/k=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=MMpZHhGimGzVe0IiwpWahv0abICWYOv8gTvTxx/P+V0qoGnQ2DTeBIzxGftH+9921 x1rCSAaVDozwbBxHIvk/2okbt3ZvWmRDAinDxIWFlk1Z4Exav3F4IGi1dVUH09aWlK TEt6jx9FyTdA+Kfi85mGl5h2VLX/CQpckB085s+BW6EJAAVuvwadHDslIKIa0ttTIh poeFeOELmG/QIPcGplKwRQTbkkJnixNjdSEBy2oHAcIkaUKbkfvhrwyxeGU4KmFk3r xBLufYrXEpj05rqZyFLI1LTcGQGs82ekcVRra1mVihxMVUSqmlC3gdY0gAM49wWuVJ zn2lQr4EmG/lQ== From: Jeff Layton Date: Fri, 17 Oct 2025 07:31:53 -0400 Subject: [PATCH v2 01/11] 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: <20251017-dir-deleg-ro-v2-1-8c8f6dd23c8b@kernel.org> References: <20251017-dir-deleg-ro-v2-0-8c8f6dd23c8b@kernel.org> In-Reply-To: <20251017-dir-deleg-ro-v2-0-8c8f6dd23c8b@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=3409; i=jlayton@kernel.org; h=from:subject:message-id; bh=s4rvzuIbyXzK6y+wPnL+4uRpK7mDo/eer/xGdjtob/k=; b=owEBbQKS/ZANAwAKAQAOaEEZVoIVAcsmYgBo8ilA8aL4CnPyfaV9t/SWXvPqdJZ3P0s+8wOA+ KvLINJfAbCJAjMEAAEKAB0WIQRLwNeyRHGyoYTq9dMADmhBGVaCFQUCaPIpQAAKCRAADmhBGVaC Fd6bEACh6JeUKAw/8CkWtgnXscgMQ+cLyVSGl0oJdySpoPVb1vlmvjA5P2WxQZD2zO+0FTjlB4h Yui9nx0a2pn+U/knDhQs0BLYG3Z1FeCw6h6u6HnE7JSo8BJmUgjgtctBiYDDZ7EPs1aHTtTQMxZ /ILDU6DBF2lstn0YMUejGJwR70La4VTrS3GOcEBFz2VA+gCr7atugFJ/+JsfSQK0nRbvDtoWRBP Lt9UTLpG53FiY+KWI3UhBf861liynfDeqZ7qSS6M7iKgLrdWRJb7sjFRGeP09qpFCnrGwOuyaiQ uzhmKOk1C/JdTzFBeC0yBaCYLgn46LhDzKLZ+0xZyCIb/5zmhHVcPB/ET/emOhPrWuC5lmTGCSa Y5Iqgw7eZa/bgBMOynaDz/+6oFKceSQm46wCYeiK8TxD/hL3in2GYO+Ak9qttuCnATvOC6LExFB 6C7kRbmPvpzv2J+37pHafRJva0bPoxuqvUbGCv8zfwMeZ/CHE15Di2M4Kv6on7GcFyIG018j9dV QcOcDI7ZEE06fqk9/AfcwBvUqRaRp0JHDgdS22zRZwZ1M/veDjaqHeFSpc36WC26dqReYoPOB1u vrRnjKHQImDTRu1hcYSWEs9Pe8bVUlAz3JbC/dxt6lyqwshEKp1zKpL+DLB+flbWKsEc46hy2mi MzwrIrAQI5FGPBA== 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. Signed-off-by: Jeff Layton --- fs/fuse/dir.c | 1 + fs/locks.c | 5 +++-- fs/nfs/nfs4file.c | 2 ++ fs/smb/client/cifsfs.c | 3 +++ 4 files changed, 9 insertions(+), 2 deletions(-) diff --git a/fs/fuse/dir.c b/fs/fuse/dir.c index 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 05b1fa76e8ccf1e86f0c174593cd6e1acb84608d..03c44c1d9bb631b87a8b67aa16e= 481d6bb3c7d14 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 01:31:09 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 A08CC243969; Fri, 17 Oct 2025 11:32: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=1760700750; cv=none; b=qTVX9rBjhprn0e1k4DOdKDe7E0xzxkHasmB57aNijAxrE6I3DM/HxhECpVpsz7QWiUzcyL4bqOrjWGJofhrWBJhRHVPoDPM+THZtebG2vvd25n4tIIHZNoz13Nu+19lLiT1t2K0z9aEM1S58NFcQRx097DGuNwAaDQYBh7Lps7I= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1760700750; c=relaxed/simple; bh=DfXWfe3J6JP43Ux1a6sZKAEITJvGozUQi9wSKd1pfSk=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=AEKwwkLhKG3ndWRTZO/qa94iyb6nKRF+7cW27+kaFkhPe2xipJBC8zuli33ZiHAuAkVJEZ6hmugLSvVBJXOpvoUaLMpjy74l3VNwwGSHKc6+9fmknuNlpmvcpyTgZzRyU0Z7z1AZdv3DJ5Sl8uV4mvIE6xKS9r7qb6xphBCPWz0= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=DZQXdcqB; 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="DZQXdcqB" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 0593DC4CEFB; Fri, 17 Oct 2025 11:32:25 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1760700749; bh=DfXWfe3J6JP43Ux1a6sZKAEITJvGozUQi9wSKd1pfSk=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=DZQXdcqBXZBTDNpq92GVE2t0F4DVnA5PEccQJTxEvjp/uk/bbNwKsHV643BNEEZ90 zDw3GOJRIM9WUhfXLubrQpRVq02aKtyUTnUCVH5X/CUCw1zdT/y0MT23LS6NcurVNy ndFekQ2+PGBtq5WsuQtPHp9WvciwRCPJLDjesifXX4kKV4sjJg6FMYNQnhSj+buAkp v6JzAdmSuzm6DieTVTh7vmo5lIw4LZdQhyg3A/roUiJ9wOG9Rc6EyeVVhN74l9fzS2 0CIg0YSFp28SYVXYDFwJqV2DSTckLjmoRtepY5/vo5yz4kpfJGiWOxH4Zw69o3lO2z Xo+RD87i4Gn0w== From: Jeff Layton Date: Fri, 17 Oct 2025 07:31:54 -0400 Subject: [PATCH v2 02/11] 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: <20251017-dir-deleg-ro-v2-2-8c8f6dd23c8b@kernel.org> References: <20251017-dir-deleg-ro-v2-0-8c8f6dd23c8b@kernel.org> In-Reply-To: <20251017-dir-deleg-ro-v2-0-8c8f6dd23c8b@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=1835; i=jlayton@kernel.org; h=from:subject:message-id; bh=DfXWfe3J6JP43Ux1a6sZKAEITJvGozUQi9wSKd1pfSk=; b=owEBbQKS/ZANAwAKAQAOaEEZVoIVAcsmYgBo8ilAN+ikWjrHaX/OAFroMEY3fNO3V+zI3L/wQ aPqQB2Nub2JAjMEAAEKAB0WIQRLwNeyRHGyoYTq9dMADmhBGVaCFQUCaPIpQAAKCRAADmhBGVaC FXvbEADRwufv1CGsbQDcBQnYpIc8VIiT4K59XwkYcyy4KNnpVd7AZ/+sWJj1NxbjllepFE6kx+Q R/1mLpZoqyvnzMM0al01nsF0wzrz0dkM4tE9OuN5NUPq0e4V1yDdFYMjqnTvxtx4MqDvgB+sTfa LUk661uV6zik/3hdk/uCOLyLg6zxhyXO9jivEu7Y8TuNAkzBIaYOcSqngyMt8USh0C0sRQVsDEf rsCe0/0ErNkEUsq0HDMsMMCzbyDLijCzfqecv+zNndTXob7P8qS2B3+fT8yaAYcub/+0SweSw8u yGYwJHWhNQ38WXbOe6NKoNzMLLUjuXH3th/BYq8vZb2S6jrj3ueMeNgY9ULtD045W9vKYma1J9d px+yN5h7YFxKh/XTgUORi7X6eQHnxNlz3jQPEounbAwNMxOToRYgeBsSfYi9GH7hwAHXX6wUS02 YE3KcULTJXDd0dmBATpUQqkSWtp9S+x3U10EIkM0aMLOMXH1fOBU/ZW4jEjyqrRjv2qNbqVdXuk j+fqk5AeBKve3UzMgOnYJ5zxOJvwFAg4ITBRfDD1R1G7V7D3WGLnm30nqcNMGitnAExnZBE21A3 dVb5GAV+0+ci0jDEd9Ffdpg406SiXox6tZOZtO6BytSnQV4FN5OsADlBh+axBt+Edegk7neJJ+Z SnXY7F5EpBKnmgw== X-Developer-Key: i=jlayton@kernel.org; a=openpgp; fpr=4BC0D7B24471B2A184EAF5D3000E684119568215 In order to add directory delegation support, we need to break delegations on the parent whenever there is going to be a change in the directory. vfs_link, vfs_unlink, and vfs_rename all have existing delegation break handling for the children in the rename. Add the necessary calls for breaking delegations in the parent(s) as well. Signed-off-by: Jeff Layton --- fs/namei.c | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/fs/namei.c b/fs/namei.c index 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 01:31:09 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 27CB334DCCF; Fri, 17 Oct 2025 11:32: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=1760700753; cv=none; b=Yr2WFeNKHPWV9iY+E1z58vneeOJVnR4NQU1LjFrnRXwqYxgaaTqqwoafzQxgTX8UQH3px2vh2/OBqBBdcyuUtTSXNMVQa6mqztlHgVoJIAiyQIDYrC4OKQEICK2P0dKwuuSnxI9uQv/QxYmmDLPE1iUY6diT2EQICbwkuHSDqj4= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1760700753; c=relaxed/simple; bh=ByTod7HDyAv21f/noRnpajC/qkzdPRejO/up8HqOJg4=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=OrEvAZDOPGQlzeFgEzVBK0kcOnzK3o4EFPNd6AgzlAXWBj49QzKq2NohKuqYAwpFrkwnJUELoQA9pXl8Mfolzo4XSrsu9puRsquvbbNeCjtAWDZMxDEoBlQkdWEKwDxhs2aYaH/yuk5/LRH75RWCjyBTqdooPSTTHZWBeSWekEI= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=nNs8JU/N; 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="nNs8JU/N" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 676EDC4CEE7; Fri, 17 Oct 2025 11:32:29 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1760700752; bh=ByTod7HDyAv21f/noRnpajC/qkzdPRejO/up8HqOJg4=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=nNs8JU/NGI7hl9e5GLLjaQgjIYaNdvDrchufnyNy4d3C56MzQ4QMPrPMBW5ZxTtbr Fp0jlU1xxYh14fP2lJhX6go9un7S1doqD2wl7Uw+YXPRWLpKyjbmMOCfzJw8+QBZ3k RzNRjx7CDUovD1OcBwwc/V5WTmpB8dn8qGhe5yS8qhH3LTst0oFK2RsotgHyx3BKFw /QdkV/ViM+hxvu+C3jwT5+Iju5UBKG6J/Ko/HC0HOmKbKKfnsaLayWyB4W1Rsaadxd 0Weqt8i0vG0MEUxvEL0Gc6+LefR8GZEADSquxDh0sbb8WDf5/VVUNDs9t93w56gB/G leen8v8jRBvmQ== From: Jeff Layton Date: Fri, 17 Oct 2025 07:31:55 -0400 Subject: [PATCH v2 03/11] 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: <20251017-dir-deleg-ro-v2-3-8c8f6dd23c8b@kernel.org> References: <20251017-dir-deleg-ro-v2-0-8c8f6dd23c8b@kernel.org> In-Reply-To: <20251017-dir-deleg-ro-v2-0-8c8f6dd23c8b@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=9126; i=jlayton@kernel.org; h=from:subject:message-id; bh=ByTod7HDyAv21f/noRnpajC/qkzdPRejO/up8HqOJg4=; b=owEBbQKS/ZANAwAKAQAOaEEZVoIVAcsmYgBo8ilBaFi+wa66pNKNFX3t1nD3Is7iZH3plQgvl Onh5EtiFNWJAjMEAAEKAB0WIQRLwNeyRHGyoYTq9dMADmhBGVaCFQUCaPIpQQAKCRAADmhBGVaC FS09D/9jTc4G2YcTEKVBlWWZf9RaMtkX4fGHsQjRHrt0Sp9WuCRGQ9amfgNd4lqz+P+XZWJfC2r SheoEcDxdWRVMrUA4gIo7LnqyExSaqvnRy4J+tKsfnSsgZPrPl5AGOf4WKmEFBZQgnYYcbHOUlk YEtEatF0R+ZSgYsxMkfuaEKxAMZkcIe/WoiZmEV/b/kzn+ottJ2Ng1gOzHJExssNt17HY8VCyZh y+nzE24ybSSF2wK+dqDGKMNQB1PMfkzfLhtAFa/FXzMxJgjlEVN1LrQRCpuh7vdXACeAjaks5rO FPOtIZ4HaGvbiiAbsFz26feDC23bwCuM1Nl8dHhaqFQDB2PL2UT+FrXbYuUXdlMJYEHGK4/snb6 r7RssAj+/16mX3XWlWadAf1jB/2A2WKXCaJxKVFyXZY1robM7vUWiTUo/3QWs+LMPcXdPkGSqZ0 HXdtjluDqrUilOMWkNAZfg0R77/2KY+fDuihSSggfwCEhGoz0/EDtgKh65o19aKzblSSeHAASOF maGRGFAEa6O2a6anEC1ci/+8xo3ym0q7Tp55BdfRjVVhCjsS/kv1lxiO9YPzYzjS2mgFSgQPXLg snbTNLsYcvuMq/GIOUTxqhRDLR4ZYbhneNwZzC+mbP4Ua7mReyO20vwDJQQN4Ez+N2ZKe9IEiWF Y2hyO6MkqL/FvZQ== 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. 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 c41bb85e06822a82c86e2a33bd9a91e978c75965..3dfbb85c9a1166b56e56eb9f1d6= bfd140584730b 100644 --- a/fs/nfsd/nfs4recover.c +++ b/fs/nfsd/nfs4recover.c @@ -162,7 +162,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 f537a7b4ee01f49cfb864df9a92a9660b743a51e..447f5ab8e0b92288c9f220060ab= 15f32f2a84de9 100644 --- a/fs/nfsd/vfs.c +++ b/fs/nfsd/vfs.c @@ -1644,7 +1644,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 01:31:09 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 54ABE28A3FA; Fri, 17 Oct 2025 11:32: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=1760700756; cv=none; b=DFHE67gVigmwsi39jkFYGt4FiQzrd61oR0CoOdWn74Xa61s1/DAJYvU2OGAolHNyYVKRCD7SAeLczAej6jEo28jW7Tav+tzv9TjuVi3O8ts2UUWdyoWWClrTQfg5Dl2/EN4vrGnQtJYW7Kb0XQOO3by+2ABKgVRq+DyLi3LP1O8= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1760700756; c=relaxed/simple; bh=DITGPrxEBGAinDQ3TL6Rppcs0FME3zPsDBnrTn3EUy4=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=JC7h+0B8P2O2BcOAo8MV2qcqs9E5aTqCYsPo6ABs3G+8NwcZazdMP8lA2cDkFUXZSiNYy/CkWm1nyCKRuGcNxx9EiGO2nw53W4bMz7tYp9CNg646sMxWU3uSK1tlXx1ll9gYSF3RaKPTUE7r+5IPyfz9D7uZNEnsRbctWJb2gDE= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=m/Vqey2F; 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="m/Vqey2F" Received: by smtp.kernel.org (Postfix) with ESMTPSA id CA91DC4CEFB; Fri, 17 Oct 2025 11:32:32 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1760700756; bh=DITGPrxEBGAinDQ3TL6Rppcs0FME3zPsDBnrTn3EUy4=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=m/Vqey2FGjNvNYRNKfFA+VJKtBLFsFlvvungKu30w2u1Xm5scpMxGW/ZQ20p7XUpS RzfQtp4LfGZ8ayT9llgK9q305aMk610aJ2vusAxnnynR0rdVeQkdV3oT26ScJOucA4 wbuu/WYWFb8WrmyQGV4Gdhl2KF5MjBPfy0N3PUpyf8K1WXEz/aKmFA7AwmpHKHKnac j+iNVsakddb3R4y6KF9ftNyA7LpLE0/LoGeAGOM+FJUpVuezTuztpH0pbMozcrGudF Wb85Bz6cE9c212NZklA1in3q5Bh8Xq15YIzkIk8qxxfwee/8bTTr0yiDSVuDCA0isk YzBFR4gy+UXeg== From: Jeff Layton Date: Fri, 17 Oct 2025 07:31:56 -0400 Subject: [PATCH v2 04/11] 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: <20251017-dir-deleg-ro-v2-4-8c8f6dd23c8b@kernel.org> References: <20251017-dir-deleg-ro-v2-0-8c8f6dd23c8b@kernel.org> In-Reply-To: <20251017-dir-deleg-ro-v2-0-8c8f6dd23c8b@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=7725; i=jlayton@kernel.org; h=from:subject:message-id; bh=DITGPrxEBGAinDQ3TL6Rppcs0FME3zPsDBnrTn3EUy4=; b=owEBbQKS/ZANAwAKAQAOaEEZVoIVAcsmYgBo8ilBFHWbp7nQtOljMHFcQyFXCEC/22bbn5krC hRCoBTn5cGJAjMEAAEKAB0WIQRLwNeyRHGyoYTq9dMADmhBGVaCFQUCaPIpQQAKCRAADmhBGVaC FZqvEACQuKYB5J24NCIBBxCMcO4nEXeWGPvptt18r6fjOtZ/Mg3KREIlbFvLSXcPDOe+egOVDTB gBjZhvjq800orb+y4Z/e2w09rOhtJ0SP5++m1Evbs9BnwVi7zdHNBNIlpqauOS0X9qEhOyi9R7G EgM9ahunDsQtjFjRJcnKLZpG4RwlrU/X4dERjFEo0Rew2pZQnRQzOlzMr3GJijzzz73As0zS+gL b1oYv31OokfgTo6tpP7uXwHcuwqaVHW7vdwz8bMXvNNUs0a0HP3JkzqB2gNQIQIYwN1CzOC1dVp maAoQpr4FB8XhuxqoomKM62WLHYimRFTfmcnbvj2vpQDBCUKNE0CIgCaBgw5MNzoFG/+K0HEHXU AbWSB3Zbe+mvWVb0db4oMwUyN8SP+q+zSZKOJL8KZre7/P1H1Sji6T7cYoN0f7TzKtBZfetlr6w Vo+Yhs+eLBTxqNZqnpMPC40BohhCTJCfQV9y8BlyAuEHQ4b0w3RwXAzdTxMtiRtcTpbltVf4b3g L6UG1b7dC3bW+sKmzQU8HCaAiGTSs+zXaYPsO5aKaWs5aWGjxK0M0A+FxiJA+ydncfvNqVKGINl 4keXmXjCPGsfd/avLd1gUwGLfjTsCdZKqMfw+4yjzA9t/HQ2urcQsivx1pbAvtPz2wJCc1qUER8 lbjMVhVTbcLglxQ== 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. 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 3dfbb85c9a1166b56e56eb9f1d6bfd140584730b..ad3acbb956d90cac88f74e5f598= 719af6f1f8328 100644 --- a/fs/nfsd/nfs4recover.c +++ b/fs/nfsd/nfs4recover.c @@ -275,7 +275,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: @@ -367,7 +367,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 447f5ab8e0b92288c9f220060ab15f32f2a84de9..7d8cd2595f197be9741ee6320d4= 3ed6651896647 100644 --- a/fs/nfsd/vfs.c +++ b/fs/nfsd/vfs.c @@ -2194,7 +2194,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 01:31:09 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 E55743570BD; Fri, 17 Oct 2025 11:32: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=1760700760; cv=none; b=ld4DjwaG0A7WNp9YlCs3TrK5YJJsbPFIxLSGDFNo7xFYva49qmf+EXvf1SGGA8M9UwsqwTmIE20lCRAopZewOSHAxz1ZpHh+k7PWfj+3EodRazVSxfv6GcByRt1JJffbhoWbPsbq15eSWC4hBR/C4hiFsaU135tPmFV/5hAb8qg= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1760700760; c=relaxed/simple; bh=D4Q1z5eeaVUO9Z+ECTf/6Zqc/vYd4ncdAUbJ5tZDhnY=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=E4poEgnrNCSqOvEs7Bv5rJNE2fupfvu2MUyqn7FMhVt9VVHo58VrnNnk7L+MtqHCq8pR1ARiGDKtk4k1P6S34lLf+NjaWrC1jzbRbhYL5WY8xLI45zsq5T51LRi20Fv+pz4mijXy2XRr0ZXwFCU13LX2YDxqz6ZmyVKOizp1BuE= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=Nazua681; 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="Nazua681" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 3AE66C19422; Fri, 17 Oct 2025 11:32:36 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1760700759; bh=D4Q1z5eeaVUO9Z+ECTf/6Zqc/vYd4ncdAUbJ5tZDhnY=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=Nazua681MDmxCfAADBeKoKoXjKBoTE5qTGtfKw5xWgCx3wo857DQiydef7HU7/sec Hy+Cm4hWlc5ArNojD6Oygw8gujKQryeUuBAXBKVxYdHrFDGFBnvC37feBfsuFRbhMh gEiTkexyBcWYN7a7lntnuPnbJsMc6yQ4w6i7AiBMcRoawC5AQ2W33pFFIr26RI2iuL Iov0nCCpQlYF2BNhFfMiOc+Mi4KzPzb40twt1UF6TsqH3WiTVcFzK1PozieYXifn1w SBykJR30X+dvOrI/6alzuQd2uYubameM/QqlVxYSPcRPQulSXonaAH5l31TNyUziOV gYGsySYe9jQUQ== From: Jeff Layton Date: Fri, 17 Oct 2025 07:31:57 -0400 Subject: [PATCH v2 05/11] 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: <20251017-dir-deleg-ro-v2-5-8c8f6dd23c8b@kernel.org> References: <20251017-dir-deleg-ro-v2-0-8c8f6dd23c8b@kernel.org> In-Reply-To: <20251017-dir-deleg-ro-v2-0-8c8f6dd23c8b@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=2938; i=jlayton@kernel.org; h=from:subject:message-id; bh=D4Q1z5eeaVUO9Z+ECTf/6Zqc/vYd4ncdAUbJ5tZDhnY=; b=owEBbQKS/ZANAwAKAQAOaEEZVoIVAcsmYgBo8ilBNTnGzrb8DXfbDlwA6q/me4Sh1t39E3gG7 zGkjXhAEWmJAjMEAAEKAB0WIQRLwNeyRHGyoYTq9dMADmhBGVaCFQUCaPIpQQAKCRAADmhBGVaC FaZoEACN7N2X/NuqHDlhSOWJ++Tu6tmQYKHtTPY1W8zWpn6VLcXtNzK8NgaXqC6NGVTdB19mMlY yw50XHwCWIXtXty29UGSwOx+sZD69XNxcX+pjfd7Q0o3AxsBmvzKy4j3xJ9f6F/Yg0f7s2uWiW/ YS29dMN5B1z76Up6V+OiquUm57pvKK9c9fsS660otGUXzbTPcEo/5Nqm7qLEpxgQnTa+5es2jrz 4sEViVh/F2YfGNGGAzSg/nKSHajvY1y7ASdbRn81FGZKRTLHm1Lk5GbMKQ0CnYjT+KCugKT89c6 B8UE+aUYMHUpo/yXUytMpo34s5j47InA1ZPOB02tfqYj6eMhsd7+9+aBRmnV7Km545EnKpHNuC9 GQAmr1h1w85n5A+Z6/qrxcwkXIwli9LrB/ZT3HO7bDVQjqj6JwMenYnLTwxIkc1AjGVH2XnLWt9 vMj5EkNMJ3DSpFqjw80PtWGAtoKmPNZ3DY6yYFPmK9k5TtJPLuFFpZcnxCkz7MQLRqCjaSsCz5y ZD0+bgyPsK4uF79e+yMZoUNidPPHKRMCTxHvagPBE+auNyogEOnwJgK7UdPcEG875wNYqSZqOQH 1xUZFjBUXZRbVLdFijL1WGaeinMV9y/YIxIqP8sp/HHE5i9J4I2H1tnlnXpu2nbhxR3sqNKxvl6 bX7IDi9vvmCWThQ== X-Developer-Key: i=jlayton@kernel.org; a=openpgp; fpr=4BC0D7B24471B2A184EAF5D3000E684119568215 In order to add directory delegation support, we need to break delegations on the parent whenever there is going to be a change in the directory. Add a delegated_inode parameter to lookup_open and have it break the delegation. Then, open_last_lookups can wait for the delegation break and retry the call to lookup_open once it's done. Signed-off-by: Jeff Layton --- fs/namei.c | 22 ++++++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-) diff --git a/fs/namei.c b/fs/namei.c index 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 01:31:09 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 43B112E6106; Fri, 17 Oct 2025 11:32:42 +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=1760700763; cv=none; b=tjt3O7/HCTCgn2upUlsJ3rKVrL7c61W4Rzg/6abr8/B3mkEvAHbU5jaFtrE2HThWauLuneC+qj6sGMmc1mNb3jtsvVfd1S2TN0NH7jQgr7xH0Gjn7Nm3cOHtmKYXOwkc+LA6S37TZlEWze07wXQpjyeW5QrxuIIxuDN1WRctq/g= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1760700763; c=relaxed/simple; bh=3eMECg/xYHGrFwt7wDF0a07nGYeeRm/Z0p+5FBUu9A0=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=V6DhzbnvxR1XfR2zBSCaL0yYTITN3e0WZcZsHUamVFbzU0hL4jntiLURhR555461sVM78RemhEEVghWiZ6xDH+0K360n9UjcSzWphsg0cjgvowgJMevULOEb3cM7ZodLEMKUq4g7p0oUdZuAmas8hLCwbO+IDz97pX5W0SXlLQY= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=bEBSh0gt; 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="bEBSh0gt" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 9D5C0C4CEE7; Fri, 17 Oct 2025 11:32:39 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1760700762; bh=3eMECg/xYHGrFwt7wDF0a07nGYeeRm/Z0p+5FBUu9A0=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=bEBSh0gtVXtojF2fsd0sOeuD93IZCUuU3f/YYZLC77Kle9dEpDTMsYWD25pGEfZHZ 41VdsqLgmXVoJAJlvNxYS66W/esLTUGmZiTeSdY3xn73MKId4XVwfv3BnLBNqQhXp3 UkZQbZPFebLzfcstx/HiF5Cy/EvyLIpmewtN74+TcAnWUxLStb4hUctW0yaTBKX9gF tsKbQaaJhzbUsNBImEDN3Rfbnz6RBnK8ygk30FJ/+3h+Qtgq8WDKmSTjTwYI5uaDGd 4dRlv5Yb/po3WkDnw86hlmxwYDJ2JfDOgCMH9tYWwbrH3poTDdRrLpquBwAWqKK0wO Dc3KNR8dHeSsA== From: Jeff Layton Date: Fri, 17 Oct 2025 07:31:58 -0400 Subject: [PATCH v2 06/11] 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: <20251017-dir-deleg-ro-v2-6-8c8f6dd23c8b@kernel.org> References: <20251017-dir-deleg-ro-v2-0-8c8f6dd23c8b@kernel.org> In-Reply-To: <20251017-dir-deleg-ro-v2-0-8c8f6dd23c8b@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=7371; i=jlayton@kernel.org; h=from:subject:message-id; bh=3eMECg/xYHGrFwt7wDF0a07nGYeeRm/Z0p+5FBUu9A0=; b=owEBbQKS/ZANAwAKAQAOaEEZVoIVAcsmYgBo8ilBffB9t3CH95c5nJkhwKFZR8oHpS61LcS+6 SugTAvSMHuJAjMEAAEKAB0WIQRLwNeyRHGyoYTq9dMADmhBGVaCFQUCaPIpQQAKCRAADmhBGVaC FcK9D/9IKl5gJSEt7Bto+vzLCgGl6j6sC8dM5EN/RsfBDo6bRj7ud3ZAwh2hMsHzzHrkPpAtpbC qdtCKNkKPTx+5gS3Gz+LHdz0/aivYevYRehpXcCvxGWvAGGja4BgeZ0LDVqTDKVLLYIK8Opu59k HvGte9jT/1V2NrN83VmLZMoA+HcSPBvWj4S4lwh17Gw8TZhxG8jCVwxk+VHImIEx3ZKuiY1CQkf s1o5x04H2maZEQA4c0I/qdxWgsXNSKxxqsxoLLTkB5wQKjpDm+agVLjZoVZ/1N3rtGcqFpfLaK4 4Xl7br3om1YNqReTElcpx2cvJsPlrmxN9cWiLLvI04eRacJ32X0Cx9ZKECbx528AYjDc7p+rPcE x+2F7OKEJPL30ylmPDyy78yaFG+siUtqfcQ3Sx5pF3sgdUVI8lGqC3oHcUzjuaaJy2Luyne5wuE cG2g3w5728VLr+3la23LmihzU7xX1ipXPFFPqjjfbajE+tEX3VK4Lpq1bHu21RD3rcXYQcyczaW OQb+0v+BI1TnE8UykvcSjtWygf5lfjmQjOyfnsQ+ujsTCr0cAhPmzwqJfnunvFizcePXY8wso03 +51Wa37QkMJQuypBQAUWWPfQxF6RWn05ihL/AkeHK9VrqUEr6Ym3tmV3n2uVwXh5bbo2NeRMjX5 H1D4xEwJtIjpGSA== 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. 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 b6d03e1ef5f7a5e8dd111b0d56c061f1e91abff7..f3977c52fe27b4ff0c0e2d62cf8= c14b49bbd8b13 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 7d8cd2595f197be9741ee6320d43ed6651896647..8834bc59f5cfcc88797eb09189b= 6c12d29e98d10 100644 --- a/fs/nfsd/vfs.c +++ b/fs/nfsd/vfs.c @@ -1638,8 +1638,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 01:31:09 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 BC2FF393DD1; Fri, 17 Oct 2025 11:32: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=1760700766; cv=none; b=H+RNAzLUxe87JoN7yH8gRpsjc7bOYmDILY7MfWObFbJMctl69otMxtSqrUXA7ZFc5SkcDmU+JyihYwVGrnAzfkAd1xXOJhIq1oAQeevjB7lMd3XQNKjoRIGbIhZnJwoqBh+bFMBWadp/b6OHjAZM75qdbwkHYLl5AtVMXih5wwQ= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1760700766; c=relaxed/simple; bh=pRXSsS71LFZeRHo2CAIQuE5nNikfIVRL+adE2Hkq7eg=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=WJy/r7Y12qAWWkWL3GWWrl1osc1Ee8PtQYRLPWBjgiKTNZbApXE90Mnih6qloXjZB6IUpUuwscy8EE2WPoYAkMzRNdeIzohfU+KgHhxcCBD00c1dZDUdMGmmBQuNmWNqTreLXZssLNaaYv9Mfc/Z2AbTbRX1oBrrIqcrRuWhRS8= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=VaLSmYi2; 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="VaLSmYi2" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 0E04AC16AAE; Fri, 17 Oct 2025 11:32:42 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1760700766; bh=pRXSsS71LFZeRHo2CAIQuE5nNikfIVRL+adE2Hkq7eg=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=VaLSmYi2YrvcKQhais0jSVhwLDKwGuD3HS5ezymrPBS1EIoZOeQ5sMdGmwJx8MZv+ XCEQLH2J+LLuZeMxsNheQ+fBKrM4LsTTa5wT5JvpJLmH4cH9SwiQ6Bn/bHVXMZkwm8 tumyJFEQZ1cJVwgtFxDtfZ7vJfcKOBiE15EU/m8cZxnCQUDQukahdGyMI74JcXS6/R lhG9Ih2ysjUQHE7jd+ENac8bAedU4e50AChQwYDz86k/twR9LEq8bBnlKxRpn5vmYu MS6ZD4Wv5OmEKFTs+4HHdKQOinL0aebMeySnN3GRAaVDc3Qg2ap4eQHhLIiJUXbDKC afXtVSJIf/yoA== From: Jeff Layton Date: Fri, 17 Oct 2025 07:31:59 -0400 Subject: [PATCH v2 07/11] 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: <20251017-dir-deleg-ro-v2-7-8c8f6dd23c8b@kernel.org> References: <20251017-dir-deleg-ro-v2-0-8c8f6dd23c8b@kernel.org> In-Reply-To: <20251017-dir-deleg-ro-v2-0-8c8f6dd23c8b@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=7411; i=jlayton@kernel.org; h=from:subject:message-id; bh=pRXSsS71LFZeRHo2CAIQuE5nNikfIVRL+adE2Hkq7eg=; b=owEBbQKS/ZANAwAKAQAOaEEZVoIVAcsmYgBo8ilBIiNNTmXWa4hIACVNw6ttiamc3O/ozCUFF JCNGhwAUs6JAjMEAAEKAB0WIQRLwNeyRHGyoYTq9dMADmhBGVaCFQUCaPIpQQAKCRAADmhBGVaC FcnmD/9nGptK7dfCGVCPt+6dsRwL88loppUWbJxYVGxFuveaoeGzJunzadGbZdMDcF9m5Eta5+b 2xuVZLKZ76ZZ+3kP6TJnLMENvEt1zlnXdEHtlxcgydbQNqHhDAGnqTu4+sWJ4Et40FcTUYFgTf0 Ey5YbJHeyuVyn4/E+dvxm7kvmF4wRtST6ZLo4xcL0ppGr+NaRLltkeTwRmzQW+mF3UTJ4Oy3t6r dSILizXwos1qJlNrJXXlspgNOTf55OBKmu7IWhF0/EqTXLBOkPNRKthojPJtCH605yxjfii7zep gfczGUIJPU54jevJlPtF3H6kk4oJXPaBNkl4aafO6HZJDC5Lzm6SEMABNCQLAQ7EXl3JPJxu9Ok DfXaq3ct5T8hkJgsr9rGguOSQYO29mPa86n+EUuqR3lTqdxxMbFv3o5QE/8hy3IRmL6Yd82BCaB zU42guk9pSxwAfzaQ5/0/3qoDQo+Ggvj3k7vm+w88xZ3NQLR4nYjqiKGsCQn/Tza8htIADn/QKS t8XZhG8nwPIoajfK1h8Lq86LPsJxhi303Svi+eXF3MWCmHEyRz5NP/w7bTHWw4DcJmIvE1VpNC0 nazOEgf1zpNKvFTFz6Gwmbp6MAcW91hIYOEqN6a1dItRCb2808SnZ2wairk1+J4w9U8hfx7rtck PXxKEKFEE1c5zuQ== 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. 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 8834bc59f5cfcc88797eb09189b6c12d29e98d10..eeb138569eba5df6de361cf6ba2= 9604722e14af9 100644 --- a/fs/nfsd/vfs.c +++ b/fs/nfsd/vfs.c @@ -1659,7 +1659,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 01:31:09 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 15C0432ABCC; Fri, 17 Oct 2025 11:32:49 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1760700770; cv=none; b=DYBXmqjtu+9doA7p7VTKatp4wK1PPAQo4lLEttgHgRjSluXvfHdicRK3ZlnKUBUBPFq6XPQwtQlrpcY4QXrnB/Pdp/jojDsoVzmj2u+Axr83c+QnIXku2qBEllvtDXcc0cb79r5OGX324shVB4gkWIehsjQj546BVx7BYFV0PBo= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1760700770; c=relaxed/simple; bh=7ouSDOosTIdDvDzwqKZGyunTEJL8TukNeDPruKgCx+g=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=SWK6uxm/brIBOWwWjqkniNGmqVDi+xnWnaNFZDjVzLjFrXNtycH3suNw0MLYBx0xTaYgYfB0s9B5C3BQAxo6re1krEfesCdXH36atO/d8oQEvVL6ANjNoXVQWJjfktBovyCTisghW1viN99MhTGdgqeHS+9SGm2M78V7fd8udMM= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=tWYRf1xd; 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="tWYRf1xd" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 71D38C4CEFE; Fri, 17 Oct 2025 11:32:46 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1760700769; bh=7ouSDOosTIdDvDzwqKZGyunTEJL8TukNeDPruKgCx+g=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=tWYRf1xdniS2aZLqjrez6EYb1OUyyNOXtY98XbbPsKnUkloym5jiNW0RV76J2PtyA Z9sJJ9M5n85E/yRx7jmUFYSOGC1LFBSk9BJYEzW7gYHyxPLFUM6X7kQhYwuX3hFKXY fgKrRA69Y7ZLz9WgJAY/iAgrKzncmsarzaqvq0bALu9eHcj32NIN5sKY8UIeUNrluX QKRNLQGIvUSn7ZtVueIwiy8chGWWmvhbGJSVVWZRwm/jPjesSphoUXMx+lBpL5maeq 1mBGw+wtgMEdaQKI4RLNY0tY3/GODnEL1MyAHc5GqUuFN/iYGF9hXQmC2MBHNOaU+j CDW/+o8Hij+ug== From: Jeff Layton Date: Fri, 17 Oct 2025 07:32:00 -0400 Subject: [PATCH v2 08/11] 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: <20251017-dir-deleg-ro-v2-8-8c8f6dd23c8b@kernel.org> References: <20251017-dir-deleg-ro-v2-0-8c8f6dd23c8b@kernel.org> In-Reply-To: <20251017-dir-deleg-ro-v2-0-8c8f6dd23c8b@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=1169; i=jlayton@kernel.org; h=from:subject:message-id; bh=7ouSDOosTIdDvDzwqKZGyunTEJL8TukNeDPruKgCx+g=; b=owEBbQKS/ZANAwAKAQAOaEEZVoIVAcsmYgBo8ilC1nPcpTFPrRykGurmQp1c5BdVoOQ/LEtdf IZqVTJd7uiJAjMEAAEKAB0WIQRLwNeyRHGyoYTq9dMADmhBGVaCFQUCaPIpQgAKCRAADmhBGVaC Fdy5EACFvOjaDYYLSW+mtYsRPdC2EituaEEglgW74FPY7LgX+IgiwJZO3w3M6ljAdyoEZcbXMSr Sid7RI9EI65JUhL1TEyYX6L38fzLVY2c/uDSqMHl0TxyULZGSOpX35nkZ/J7FagdxE6HallPMQ6 VVxdHBb/GS/qKBwpbj4+9fH3rGPXZkrezb2rTANQPibi7g7594Q3DPrkZn0JH4DsBPNSW7pC4PR PQvXi+pRLyx4CuFQrQMOfNG+2YlmhZmx+vaVVcbgxgGEqPUIxKKoQeHBRTn+exmystrLt7XhNal Fgman+ubmN45Otd4Tjiki+0PU45XDXcifcRmzMdkxcqHsqpx/khxYT5bYZGsyYILCrDsYgHTOSH wPGNIp5IzgvV1Bqhx9mIUoDr+xV8B+L5o0osOc5WOEg0Wv4VLuv67GGx6SUu7DKbeISCzmi1PHa EFvU8KW1WVdR4iSqXGadIIV1bpzXbRQU+PqwTjQyfR+6TSMo+HqOlS7XW6vlQqfsFfe7GRpm0Ax TQNBvSi8jGhKJW8ge9Dh6qARYbfjGCIiGBvkNqYUIZflWdw7voeQCCnkLObO/jtOgvdTCHH0B7+ ccqRW9gg/2phfPDcHD7RyU1Oe1Ip1XAhVp5ILxf8kNBX1I5MMHmXVfRjswsVhN2jQU8IRHns2JW jvFcVJoU6mpE0uw== X-Developer-Key: i=jlayton@kernel.org; a=openpgp; fpr=4BC0D7B24471B2A184EAF5D3000E684119568215 With the addition of the try_break_lease calls in directory changing operations, allow generic_setlease to hand them out. Note that this also makes directory leases available to userland via fcntl(). Signed-off-by: Jeff Layton --- fs/locks.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/fs/locks.c b/fs/locks.c index 0b16921fb52e602ea2e0c3de39d9d772af98ba7d..b137cab18d362130cda5d1f0cdf= 50ba7e9aa2e12 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; --=20 2.51.0 From nobody Sun Feb 8 01:31:09 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 8BBFB32ABCC; Fri, 17 Oct 2025 11:32:53 +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=1760700773; cv=none; b=g3U5ydmdSqM3mTKQg2tTJFk8SBF1+KSouib0WdjEmic3r1TsFKv8SuABjf9jIlN6m+/F5UVCpIR1ioRhfY6kx49FybEYFbO9ac5o+C4PC1SzibFvB3MQlyRfVIiA3QNDlsdLqib9N/JIOWP80aaKQJD1TrAzSk8+NgEl+rqs7q0= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1760700773; c=relaxed/simple; bh=uYmt+xgpgfjV5pUDjXf8vIaxDhLKeg3D29C5gNEVvr4=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=V8LBKIBvHOPPD1ox6b1T8B5YytWZ4U3HX40PjkDxBsOkUcjYRP6YigYOmXSMMrdstdpzUCeZDP4PccSPddhUrSErY5J1GSUO4Jz7T1zuCW4x7kJmwu24WyzmEPXay2T8tb9yCQh5P/fTXI9dl2Ru5PCf1EnBslrRSRhY7vF2gw4= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=GfSfk0fK; 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="GfSfk0fK" Received: by smtp.kernel.org (Postfix) with ESMTPSA id D431FC4CEF9; Fri, 17 Oct 2025 11:32:49 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1760700773; bh=uYmt+xgpgfjV5pUDjXf8vIaxDhLKeg3D29C5gNEVvr4=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=GfSfk0fKMta4VyCo+fvRv0Gd8Hd2R4av107XEjH3ocZTGnQlPVzlV3XLlUuUl6Fki ks9KRb4Isng+GptK4PzQYQ/kf92qPgAlTB3qFVhAeS7afZCyduCrxbDkec1HBxlQX4 Y7d8j9QEeJdI42yRRsUHq2joVJjHYDFwdZNOOjA8t25RoQXFPaDgqbAIFPW5n/Y5kb j4FrVCOkiaogCtN+XHyQmSmTVtcQXXoWCkPLPO7DnmFaYu6/EyIUnnDZRmIkgq4q27 WJWetOHldB31UK2Mz8v+RNhYccj2jjkp4echbN0xR4tbyi7nnfjXZSC95IWvCD3CZA MLglHfOXBVyXA== From: Jeff Layton Date: Fri, 17 Oct 2025 07:32:01 -0400 Subject: [PATCH v2 09/11] 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: <20251017-dir-deleg-ro-v2-9-8c8f6dd23c8b@kernel.org> References: <20251017-dir-deleg-ro-v2-0-8c8f6dd23c8b@kernel.org> In-Reply-To: <20251017-dir-deleg-ro-v2-0-8c8f6dd23c8b@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=7329; i=jlayton@kernel.org; h=from:subject:message-id; bh=uYmt+xgpgfjV5pUDjXf8vIaxDhLKeg3D29C5gNEVvr4=; b=owEBbQKS/ZANAwAKAQAOaEEZVoIVAcsmYgBo8ilCek5nMbUu/3T0OrPHdiQ/X8EQGLIhIOfbc 3j9jXLvJ8SJAjMEAAEKAB0WIQRLwNeyRHGyoYTq9dMADmhBGVaCFQUCaPIpQgAKCRAADmhBGVaC FYLnD/9EYAnEltri88+1GueC8aeGe3mEvpxD8kjOqu1sAnm6lCMTSP4C2REJSj++3TOsqG47o66 j+ClrlrD6F2xCLrjKZZUHwVgzqUgekyBvEpQt10BuXUm/QExyOq92hfV8+tpPZw5mCxOD+DCqpj gVzg4ga8VbUNyfCMIxaLXWL6y4hnpuxgmgY+dqXcQyxpmhnJQ+TqpGexQqJr8WXUZRbLFG196Pv caHps56EwHaRVzkEKYRYKlORqvA/OvjBZuIaOkdZkDaTI1PxiUkqd/i7r3XVpHKuP/+Q5ADaxh1 lCtpyGlh/RMMDT+LJvLtJzQ4LsKJsbL4YG23YE/d084Lm79ekXByYMCE9QPiAIY8x3h62xbpevq baWDStEKB1JSSd1B7h59adx22XUu0NmTYRTX0YcqpVIpW9f5h1dW9g9EHs9GZP7A+NBUkuwKSak hbYVo+wZpUy9SOciNwlJuK0U8J/iDGbwcnPhQ/xqxKwipgNXn2CWpaHL7qWzfZkhL7WiVLfRnfx 1iYsTcKJvVRey1OwMjxYN6/8xtEQ16e8/MjobNnKSj4PXEd+S9yLZkCE/r3b8PByXE89FwY+80q 2/iai+uIvJ9myGe/nsAp9I+8pPN50V1tdCgtVRAcwuaxEq85SG38fu6tJ+YOABy5rusJcOkuYLX YRDVikb8Bc6RR/A== 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. Signed-off-by: Jeff Layton Reviewed-by: Chuck Lever --- 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 eeb138569eba5df6de361cf6ba29604722e14af9..12c33223b612664dbb3b18b591e= 97fc708165763 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 fa46f8b5f132079e3a2c45e71ecf9cc43181f6b0..ded2900d423f80d33fb6c8b809b= c5d9fc842ebfd 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 01:31:09 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 91F9F330331; Fri, 17 Oct 2025 11:32:56 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1760700776; cv=none; b=DAYZi/RzBO3cMggRJQIjWkIEo1u7Jme8roqkLFlvXGqiGDoStb7+JJ3+FzFVgiYCKAVh6kEtlsQImix1yZAxe2fCKAtLe+bNFHSIl8PJz5LDTx8StfaTZBgbJTpbnlc+rKdvEbvMUVhC44a++QwzTIY4GgHwPUVmLdsQoC5iRRM= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1760700776; c=relaxed/simple; bh=J5we6Oj9umwD8eK5iokfF/EbyCh2/ylz1MJttYCYqeQ=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=J0hUtn+YT9eBbH07Z/jbkwKQJB9QIlveEQ/VdSOgRJXa4EYgYnrbf0XZKF15jZj2/w3lxkyDjDeMtXDYB0mZdkShXeiZ2AC12deTVaxuwHtqMDUkK40IZnbHS7GhLBIhLR5O6iL5UWGet3ZYF7e3NC0RTq2tKT9ZOzRySrCfl+w= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=jjxqErQM; 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="jjxqErQM" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 44D00C4CEE7; Fri, 17 Oct 2025 11:32:53 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1760700776; bh=J5we6Oj9umwD8eK5iokfF/EbyCh2/ylz1MJttYCYqeQ=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=jjxqErQMA621E1yRf7VaipX9BIV9U5fm5gP/oKUKoCg98c09OSn/GxnRs8T4LIptU zIsyL/8y/7vhukEdnmoNBAl8t2XMTyT/I+FJNsDQqVnukrTYxHV7lD1+//gQ3dvclb x0hgXqSkxsbGzvRZsrNA6nU3/gXq2UUWCI85CMTwGBKpuAxDJcB6L/ycCN8tl5twRi nASX69izfqkVKLHgFAe1MypBrtO6buQL50un2wZ71D46wgorN7Wf3tA6r6n9f7pd4b N6MVrt6E3Y8WG7/1fd+ORwHqR7aZ8feGO51I/8MHzvZ3iWrBrFho3FHw9W21PJghjM vVUfnvkqJhEIg== From: Jeff Layton Date: Fri, 17 Oct 2025 07:32:02 -0400 Subject: [PATCH v2 10/11] 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: <20251017-dir-deleg-ro-v2-10-8c8f6dd23c8b@kernel.org> References: <20251017-dir-deleg-ro-v2-0-8c8f6dd23c8b@kernel.org> In-Reply-To: <20251017-dir-deleg-ro-v2-0-8c8f6dd23c8b@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=1135; i=jlayton@kernel.org; h=from:subject:message-id; bh=J5we6Oj9umwD8eK5iokfF/EbyCh2/ylz1MJttYCYqeQ=; b=owEBbQKS/ZANAwAKAQAOaEEZVoIVAcsmYgBo8ilCAGkGsw47MvRREQlQJQZ+ISsRDRTLDUtQv n7WoFo8rU2JAjMEAAEKAB0WIQRLwNeyRHGyoYTq9dMADmhBGVaCFQUCaPIpQgAKCRAADmhBGVaC FcD1EADKeSf58pm0DeMKqyvmt+MULuxJcMZopXd7TwRsuHlfEMlL3hbPqOabQo07QrZOht4s9Lu KHlPd3wa4O8DHV0yMnEqdRrkIKqFtXYpB76ap3Xcu5xFKswTCe4NNhc5A64i6p+8sZwQcFzF4nM 4qYY3FRUitA1uB+4SAHJr3FLUZ/SFj/FDPP0FVkQlGhcdtQE9R1jBUePP9fdvmBg9BWRdwDBx05 liHCcpZh4bKDeaxVmq8ZVX5hdTKIAwMgUZCrIbbn7et06+93zKzyng9mRDyLokn94E6KxUbDKKv 6db9BnUSXELDV2fxTTaFoVGLA/jgNyNEoX2jKd//h19/gAj3Hqrvq8myydGSm8OeYF5lOwmu76F AtBAB81glByya+IhvlvxHOFV6CVht1MlRFW0ByK7gLznf7S8nNFtmN2irZkSfNdH5KoLO0obQw+ 9+lgqiy6M1ZWU0wBziQiTekdia7W/fcPHZ6Ksdu/mzgO5KcXvC2dwwhrW+S5cU6PsQm6yUqNgR8 fSQBqqawg/8HyI7IBPi4emT9AQMwmhdqFbTo2RMNfqGEJJdADjcvjPrfGBNSFG/gfDWCjpQDXVi qowmDcJ9LmybVmQ16Y0zr6FvTUX98M8c7+VY5uvj90zJsb4ADza1fHPBLL1B7AXM7Sh4dE2GX4H QjXgjr3pkJcZwkg== X-Developer-Key: i=jlayton@kernel.org; a=openpgp; fpr=4BC0D7B24471B2A184EAF5D3000E684119568215 As Trond pointed out: "...provided that the presented stateid is actually valid, it is also sufficient to uniquely identify the file to which it is associated (see RFC8881 Section 8.2.4), so the filehandle should be considered mostly irrelevant for operations like DELEGRETURN." Don't ask fh_verify to filter on file type. Signed-off-by: Jeff Layton Reviewed-by: Chuck Lever --- 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 c9053ef4d79f074f49ecaf0c7a3db78ec147136e..b06591f154aa372db710e071c69= 260f4639956d7 100644 --- a/fs/nfsd/nfs4state.c +++ b/fs/nfsd/nfs4state.c @@ -7824,7 +7824,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 01:31:09 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 0042B331A66; Fri, 17 Oct 2025 11:32:59 +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=1760700780; cv=none; b=ImPOsq8BHpWb2hgypCtycBGeVhjjLZJUzlBLLzEZOEUN97PYUAT2E8qTjjKCFmWmJ/C7b12TaMF0sQUYTeBZ9OoOTPyCJf0Rj3H8xlCRR8Dx0X8Aw4jcr4UbDU8mfS3YhuhMfc70nXe80CXK2kxG0pr5IUsnaQzejh/9h2/vZ48= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1760700780; c=relaxed/simple; bh=8yVl2NH8wCRWT0BWB4xJxse7JadeLBTgspo6OepmR18=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=J3Xkq9jw7Av4ShijT7rJ02wlnYlGF5pR3SJxnCDIIPGi1/9kUBRzF20BdNZRHJcB/ozEjmEOMyK3wl98hlHlhjIy2XexL2RKfEKOQ0BuU2TxDjYaYSaJwh5rHP7bLmIrH6QKTs0HpS3Sd40P/bQoCRyBVjLNqPMkQ6nbSBCHkSk= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=W16aB5Ac; 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="W16aB5Ac" Received: by smtp.kernel.org (Postfix) with ESMTPSA id AA284C4CEFB; Fri, 17 Oct 2025 11:32:56 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1760700779; bh=8yVl2NH8wCRWT0BWB4xJxse7JadeLBTgspo6OepmR18=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=W16aB5AchRRIDFkXWh+tG5tlaQdVC1I34WsnKRmiAAJAWSmro3WLSZmQJse1q4OCj +aZNpXcLflrNtR0mCD36w96dlD4PZUDDMqhNxDoALx9q1i5CTP6ESbJCpuzkXqWNmU L5/JFM5WTwtg4Q5N2sVlbZvu986nCzrY8XWnP1Y+lDtNYQYyHS0qb2zFQQDA1Ply5B sO4pLudramXjUFoh37oPEH0lA3uHBbSJyWTjfE0c8Cuoj91WUTkugWUXADQe96AfMA eHaFNitHGpSoHvJrQr9vwfo/qrGD6nwLD8uFIqM96xSIPEi6YzY1g5ynHCKqdJbW9D jI8BfyxirEgeA== From: Jeff Layton Date: Fri, 17 Oct 2025 07:32:03 -0400 Subject: [PATCH v2 11/11] 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: <20251017-dir-deleg-ro-v2-11-8c8f6dd23c8b@kernel.org> References: <20251017-dir-deleg-ro-v2-0-8c8f6dd23c8b@kernel.org> In-Reply-To: <20251017-dir-deleg-ro-v2-0-8c8f6dd23c8b@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=5443; i=jlayton@kernel.org; h=from:subject:message-id; bh=8yVl2NH8wCRWT0BWB4xJxse7JadeLBTgspo6OepmR18=; b=owEBbQKS/ZANAwAKAQAOaEEZVoIVAcsmYgBo8ilCIHz7Y0CKC7YnK6gfkIqnxpWome0thgPpR +g2yqAYRpCJAjMEAAEKAB0WIQRLwNeyRHGyoYTq9dMADmhBGVaCFQUCaPIpQgAKCRAADmhBGVaC FTAaEAC+dHlJR18HGmzM64QSsr15Nzgmjhjn3B4u34VdeVcki8Z0M1Ia7NY+zBx2Mk+BlcfuhGh Du2a9DTnQHF+2TtGb71pGXempYuWufDsfnjvgtez9bbdvWgi2+owN3X1s9x55akZ83ymiItyl6y EthK4NbcNEaPSo0QQ3gEmkT3ZdS3ZTlg56NgRAkvLbVGAu6wNLHXMxMxPqht583P5mwLLcNoAHL 6WSQQjaxSg2K/tOOe/daEzD+Ip7I7QzrTTmqhYReiFc2r4qfv8/ZFlR7KHDYifTwKqOVJRJqbbL QZLjAvFOd01wTr/avX5rzPmDSlRrzlb107pBBh4VVVhdZgnFhg5fnM1P42OkpfcBYmrCDZgL/xo +70YWd7yaitvOg1ZTSQKqslBYMJ6hr/8xlOcNvuHXvhZ8ZR+LjFPP7X7Qhy7Z1z1jqrU7m3E09b GnT9b11qbWeu9a6Abuml6pf65yauM6Md2eQTfuaext5+hYSlc0qlwn5Wpp0dvxKjwjdyx5YsyFA RdZQzWOqkEgv0UwB5/P9ypSeSdMmi4FDDAMOT56+mJNBnkTHUFrcF+XYks+xlyUZVHwTh/Gi8F4 vRdvqGFLDThioSiuu1KtPF111VJG5853+p2RXcd3rvh/q5WS/CX12iya21b+CcLZvToFG6lIuy2 bsS1IsMN5vPKs0g== 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 infrastrure is used for regular and directory delegations, a normal nfs4_delegation is used to represent a directory delegation. Signed-off-by: Jeff Layton --- fs/nfsd/nfs4proc.c | 21 ++++++++++- fs/nfsd/nfs4state.c | 100 ++++++++++++++++++++++++++++++++++++++++++++++++= ++++ fs/nfsd/state.h | 5 +++ 3 files changed, 125 insertions(+), 1 deletion(-) diff --git a/fs/nfsd/nfs4proc.c b/fs/nfsd/nfs4proc.c index 7f7e6bb23a90d9a1cafd154c0f09e236df75b083..527f8dc52159803770964700170= 473509ec328ed 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,19 @@ nfsd4_get_dir_delegation(struct svc_rqst *rqstp, * return NFS4_OK with a non-fatal status of GDD4_UNAVAIL in this * situation. */ - gdd->gddrnf_status =3D GDD4_UNAVAIL; + dd =3D nfsd_get_dir_deleg(cstate, gdd, nf); + if (IS_ERR(dd)) { + int err =3D PTR_ERR(dd); + + if (err !=3D -EAGAIN) + return nfserrno(err); + gdd->gddrnf_status =3D GDD4_UNAVAIL; + return nfs_ok; + } + + gdd->gddrnf_status =3D GDD4_OK; + memcpy(&gdd->gddr_stateid, &dd->dl_stid.sc_stateid, sizeof(gdd->gddr_stat= eid)); + nfs4_put_stid(&dd->dl_stid); return nfs_ok; } =20 diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c index b06591f154aa372db710e071c69260f4639956d7..a63e8c885291fc377163f3255f2= 6f5f693704437 100644 --- a/fs/nfsd/nfs4state.c +++ b/fs/nfsd/nfs4state.c @@ -9359,3 +9359,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 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