From nobody Fri Dec 19 14:23:26 2025 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 20D8D33A01E; Wed, 5 Nov 2025 16:54:13 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1762361653; cv=none; b=OtBY+aF+GtwfNup+UEPQ/Yt5S+W6zOdzZzQBd/q5u8iwzXpUfu35WLYez4KQ/4PtHf1a3fcCHlAF5BMQkiH/iBe1CfzA2hppajMq2iafXg+zFqZ1r1ZrWqELzYqfkJpm3ZtFIUug37iWtv5BWBibzxRDZLDxSqXzgsr5RIesrso= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1762361653; c=relaxed/simple; bh=DYoclxA9VZrJYyH2ZjWf3xD/XgnD9xjMazzJyvQdh7g=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=vGVbzLa7fW2dfhdTKdDCTkYA4bGrU6ZND532r5k7sgIfK1tUljcS7lNSC0wALx8tw5a8tEZ6f1a7C7HFNJRszjhd7aMmT5CxhLLPjfN1DnWD5QRx7FexH9uHavZ82jybXQ6Y7GQTek6BeJYyOkq0055Slj4fAvOIcymyRGCzcR8= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=MSunfpXA; 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="MSunfpXA" Received: by smtp.kernel.org (Postfix) with ESMTPSA id C4877C4CEF8; Wed, 5 Nov 2025 16:54:09 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1762361653; bh=DYoclxA9VZrJYyH2ZjWf3xD/XgnD9xjMazzJyvQdh7g=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=MSunfpXAiHU10vX26TynV+xjoGR3m2gF21iTbqZu0X7sA1ZC1lNIY+E7xko38Pyhi GwD73zrZKA8qrefjZtulEHAMZ+tlhv1CUqNm9Q1pOfCnK/pcOP2XnsrAVbcEc+Q/kQ Uvv1wwC3Xiu0CGP723hg+jayrcTSCM+V0rjZSEtjB/IpH0WiqrEOcZbh20swDHBHuE Vp7IlWmrgiEo99kB1N3L5LKMywDBOKKINKgk+p5EsZ+bGZeS2ZjdCT3JSPu6TZKQef gDy3/2Rrqv7fUcDHIAhlgRmRgZNEXrluPkrqxZkGVViOEM545kVZyrl534JMtORdp3 2KAf38wQYAqzw== From: Jeff Layton Date: Wed, 05 Nov 2025 11:53:47 -0500 Subject: [PATCH v5 01/17] filelock: make lease_alloc() take a flags argument 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: <20251105-dir-deleg-ro-v5-1-7ebc168a88ac@kernel.org> References: <20251105-dir-deleg-ro-v5-0-7ebc168a88ac@kernel.org> In-Reply-To: <20251105-dir-deleg-ro-v5-0-7ebc168a88ac@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=2663; i=jlayton@kernel.org; h=from:subject:message-id; bh=DYoclxA9VZrJYyH2ZjWf3xD/XgnD9xjMazzJyvQdh7g=; b=owEBbQKS/ZANAwAKAQAOaEEZVoIVAcsmYgBpC4EqjML62xgq4XzaEsV/ZpAKPBdfsBad5mp8n BweQfxpDxiJAjMEAAEKAB0WIQRLwNeyRHGyoYTq9dMADmhBGVaCFQUCaQuBKgAKCRAADmhBGVaC FTH4EADFNLAXOZY5/FqKKq3Pc0xk3auYMqXcagPZUiQ8LMgYCJhcDj89OwubY7e9eD/P1IIZ3G6 bFmpqBwPMcN1F2CxQO2JjjSLy5u1pJev8LHEtc6btKl2ZisfzLIc/iK0O70gBW8c5ZnLj5U+mml BTYlviVP+PQhWwb5B3akfo/YlQ3/F9nQbYakfbqSiQg3nTIZ3e1/gaBBNsszdzrgPeVNCtKd3M/ tRd4WeV8dx/nnf+abpPJ68661CHImIudCfPxZhFHB58a0wmsFkJrKTzRrMK3DefQ5qJg7kwA2ZE SatErv6BGvap2bkXQ0PcKKi1wAlHSUfd+l/EfClKsgMlP+tjGyisYW5YQmc6H25J6YlirwHfzy/ 8mz7ITi711PRWrbqed7J97XccW0QjjNlQkLVwC8CURRhyM03yV+Fh11fi2z7JTTVIci8Fq5Tt56 WkC0ij9z40VYeZdgjt+hZvKtIO+HROd88k8HKclic8tUQPF03ARaELvWzgX8yX0ieULsr6gkNrO RMrIr6cM3m6huMlr7YSQrTj6DtJ86q3EhqywAoqB5sfXfGt9fw2Nn+E5ZZVxuJiYxIvHR++jRbB kRHrrkmXKbUSxsoa6i1wWWcXYY8aJ6NW0Tsj1mXS+YXw4Ge12KShvGcEvoIlAffTkPm+3fzWmsB zR5DOL8RlwLxMhA== X-Developer-Key: i=jlayton@kernel.org; a=openpgp; fpr=4BC0D7B24471B2A184EAF5D3000E684119568215 __break_lease() currently overrides the flc_flags field in the lease after allocating it. A forthcoming patch will add the ability to request a FL_DELEG type lease. Instead of overriding the flags field, add a flags argument to lease_alloc() and lease_init() so it's set correctly after allocating. Signed-off-by: Jeff Layton Reviewed-by: Jan Kara --- fs/locks.c | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/fs/locks.c b/fs/locks.c index 04a3f0e2072461b6e2d3d1cd12f2b089d69a7db3..b33c327c21dcd49341fbeac47ca= eb72cdf7455db 100644 --- a/fs/locks.c +++ b/fs/locks.c @@ -585,7 +585,7 @@ static const struct lease_manager_operations lease_mana= ger_ops =3D { /* * Initialize a lease, use the default lock manager operations */ -static int lease_init(struct file *filp, int type, struct file_lease *fl) +static int lease_init(struct file *filp, unsigned int flags, int type, str= uct file_lease *fl) { if (assign_type(&fl->c, type) !=3D 0) return -EINVAL; @@ -594,13 +594,13 @@ static int lease_init(struct file *filp, int type, st= ruct file_lease *fl) fl->c.flc_pid =3D current->tgid; =20 fl->c.flc_file =3D filp; - fl->c.flc_flags =3D FL_LEASE; + fl->c.flc_flags =3D flags; fl->fl_lmops =3D &lease_manager_ops; return 0; } =20 /* Allocate a file_lock initialised to this type of lease */ -static struct file_lease *lease_alloc(struct file *filp, int type) +static struct file_lease *lease_alloc(struct file *filp, unsigned int flag= s, int type) { struct file_lease *fl =3D locks_alloc_lease(); int error =3D -ENOMEM; @@ -608,7 +608,7 @@ static struct file_lease *lease_alloc(struct file *filp= , int type) if (fl =3D=3D NULL) return ERR_PTR(error); =20 - error =3D lease_init(filp, type, fl); + error =3D lease_init(filp, flags, type, fl); if (error) { locks_free_lease(fl); return ERR_PTR(error); @@ -1548,10 +1548,9 @@ int __break_lease(struct inode *inode, unsigned int = mode, unsigned int type) int want_write =3D (mode & O_ACCMODE) !=3D O_RDONLY; LIST_HEAD(dispose); =20 - new_fl =3D lease_alloc(NULL, want_write ? F_WRLCK : F_RDLCK); + new_fl =3D lease_alloc(NULL, type, want_write ? F_WRLCK : F_RDLCK); if (IS_ERR(new_fl)) return PTR_ERR(new_fl); - new_fl->c.flc_flags =3D type; =20 /* typically we will check that ctx is non-NULL before calling */ ctx =3D locks_inode_context(inode); @@ -2033,7 +2032,7 @@ static int do_fcntl_add_lease(unsigned int fd, struct= file *filp, int arg) struct fasync_struct *new; int error; =20 - fl =3D lease_alloc(filp, arg); + fl =3D lease_alloc(filp, FL_LEASE, arg); if (IS_ERR(fl)) return PTR_ERR(fl); =20 --=20 2.51.1 From nobody Fri Dec 19 14:23:26 2025 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id C92C13385BC; Wed, 5 Nov 2025 16:54:16 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1762361657; cv=none; b=ByOXqAmpuO04K5+1E2dgetf4O1lYVoO8BA+AS9stdqqalWEFaDlEb4AoGqyeCx8N03E2wnt2ewT0O84X3L5zzOfdtFNSuxW9FnXn3vO/ZboUTEkQTBRm6VRkJvIasCPswBw6uDVjqONtK55FzXbndI1dEr4PIm3z6NBRsdwWMP8= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1762361657; c=relaxed/simple; bh=GnymqP1pjrUzX2EzwRGc2AVY+sxr9dx2mMhp63lQzMg=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=sUlb4x0Zs9VGOnl4YelYOWx9SiMqELC1YuMs9euKJm0FeOSz+2Ctpxtb4AH8vCyGp930R1HJNfWko3T2YfMisTK7JnA+wxwiFgd9QkXYCpmHD093NNZY1OyUMYsbaWGU2LYb1ZKCO9e4D936gKwDGhybYFtuwijBkz6J7bsbnt8= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=Ssyu0wjB; 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="Ssyu0wjB" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 374AFC116B1; Wed, 5 Nov 2025 16:54:13 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1762361656; bh=GnymqP1pjrUzX2EzwRGc2AVY+sxr9dx2mMhp63lQzMg=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=Ssyu0wjBLztyEO0NpAjSd5Ts5bVddB1l87h/A+XU0SqN12fdm4ykIkN5p69qAnSf4 cuipg8BT+dwjlTG6KrUpWyo/63SqmP0o/yWuyAiCFHqsus3C4pZT8NAl5ToMdV+UYh WN6APCO/05bN3RJLIYPW6vJ3XKlblAUx/ZmyhIQwJQwDae3nNNBmEclsJkUgttls7+ RjmQX7od4Y7PYC8pdcTMHmXUbIXm6susotUt0FfWn5xL/hvBTy6Q+8c95EGLQl36UQ Bn1fIvv+14zIdwGxWW9z+LqT9fOYMBjoRPWPlfr50TFZi2J9yzsLstJSgybK035eXG GZah8dVlzVUzQ== From: Jeff Layton Date: Wed, 05 Nov 2025 11:53:48 -0500 Subject: [PATCH v5 02/17] filelock: rework the __break_lease API to use flags Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20251105-dir-deleg-ro-v5-2-7ebc168a88ac@kernel.org> References: <20251105-dir-deleg-ro-v5-0-7ebc168a88ac@kernel.org> In-Reply-To: <20251105-dir-deleg-ro-v5-0-7ebc168a88ac@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=7009; i=jlayton@kernel.org; h=from:subject:message-id; bh=GnymqP1pjrUzX2EzwRGc2AVY+sxr9dx2mMhp63lQzMg=; b=owEBbQKS/ZANAwAKAQAOaEEZVoIVAcsmYgBpC4EqGpJT2uSMD0Zg5LVNzajiLtEt8+gmiWB3f SofTpcQwNuJAjMEAAEKAB0WIQRLwNeyRHGyoYTq9dMADmhBGVaCFQUCaQuBKgAKCRAADmhBGVaC FeiVEACrjPUYdZxXw/jUy1SdViYprZIaOpkdsQEeB9UdTO+uRoCZ43GNan4EUCQnHKZJCzEWFKF Fxckex30N18LHml154x7MMwD7x5Q52tXJVhRof3T6SLPtmVLL3w7nLb/OJFXOEY8OVXKZelA+o3 G/AvyumQF345UhA3qe+0XOAeS0daPg8kqQs0LO6qMwnnEj4NiuLGBj1nNnKI5K4ZKHsh9uBmS+/ MbtOa0zXh5ND3/9zt4BFCSO8xNrPAoDOSQ2BDMdwgdR6kX0KMkYRYYs/UHHIznjc4FrC/sF+AZ4 aXD8UmW2UDLQN0dwSwRPTl5LhXbhHuiCXKO2YNqAgYwrybEd0ZxTHNcuYT/RGmxh1MmwvOBpl6r cuToxSTTGRBYX99pd25E1ajultjfw4ZLYxGU8AjB1eV1Df7XKYToad2qcPD6yjur9nMA8XlMTnp 6mYxJspJ3Z6ykY15K0JqZ0FzIXZQEi949IHduaqd3qD4K93Y0ItEiKyYW1CkHtZdm0brWfUFumj iuApa3YjuY7PZrp0iQv0TwcWlJoQ3F3z+iWwihUNxoLS0yfbD4GPoOFlq+7rUFHNYpgd0dbLzlZ W8+N7SctnNRwPU0gKD4dy+jQebdihOKZcESWY0WZqjbwkZYrtojt1qVcyFaXJgnCc5oF6nGSNXN OCumg91RWmhQLrw== X-Developer-Key: i=jlayton@kernel.org; a=openpgp; fpr=4BC0D7B24471B2A184EAF5D3000E684119568215 Currently __break_lease takes both a type and an openmode. With the addition of directory leases, that makes less sense. Declare a set of LEASE_BREAK_* flags that can be used to control how lease breaks work instead of requiring a type and an openmode. Signed-off-by: Jeff Layton Reviewed-by: Jan Kara --- fs/locks.c | 29 +++++++++++++++++---------- include/linux/filelock.h | 52 +++++++++++++++++++++++++++++++++++---------= ---- 2 files changed, 56 insertions(+), 25 deletions(-) diff --git a/fs/locks.c b/fs/locks.c index b33c327c21dcd49341fbeac47caeb72cdf7455db..3cdd84a0fbedc9bd1b47725a9cf= 963342aafbce9 100644 --- a/fs/locks.c +++ b/fs/locks.c @@ -1529,24 +1529,31 @@ any_leases_conflict(struct inode *inode, struct fil= e_lease *breaker) /** * __break_lease - revoke all outstanding leases on file * @inode: the inode of the file to return - * @mode: O_RDONLY: break only write leases; O_WRONLY or O_RDWR: - * break all leases - * @type: FL_LEASE: break leases and delegations; FL_DELEG: break - * only delegations + * @flags: LEASE_BREAK_* flags * * break_lease (inlined for speed) has checked there already is at least * some kind of lock (maybe a lease) on this file. Leases are broken on - * a call to open() or truncate(). This function can sleep unless you - * specified %O_NONBLOCK to your open(). + * a call to open() or truncate(). This function can block waiting for the + * lease break unless you specify LEASE_BREAK_NONBLOCK. */ -int __break_lease(struct inode *inode, unsigned int mode, unsigned int typ= e) +int __break_lease(struct inode *inode, unsigned int flags) { - int error =3D 0; - struct file_lock_context *ctx; struct file_lease *new_fl, *fl, *tmp; + struct file_lock_context *ctx; unsigned long break_time; - int want_write =3D (mode & O_ACCMODE) !=3D O_RDONLY; + unsigned int type; LIST_HEAD(dispose); + bool want_write =3D !(flags & LEASE_BREAK_OPEN_RDONLY); + int error =3D 0; + + if (flags & LEASE_BREAK_LEASE) + type =3D FL_LEASE; + else if (flags & LEASE_BREAK_DELEG) + type =3D FL_DELEG; + else if (flags & LEASE_BREAK_LAYOUT) + type =3D FL_LAYOUT; + else + return -EINVAL; =20 new_fl =3D lease_alloc(NULL, type, want_write ? F_WRLCK : F_RDLCK); if (IS_ERR(new_fl)) @@ -1595,7 +1602,7 @@ int __break_lease(struct inode *inode, unsigned int m= ode, unsigned int type) if (list_empty(&ctx->flc_lease)) goto out; =20 - if (mode & O_NONBLOCK) { + if (flags & LEASE_BREAK_NONBLOCK) { trace_break_lease_noblock(inode, new_fl); error =3D -EWOULDBLOCK; goto out; diff --git a/include/linux/filelock.h b/include/linux/filelock.h index c2ce8ba05d068b451ecf8f513b7e532819a29944..47da6aa28d8dc9122618d02c660= 8deda0f3c4d3e 100644 --- a/include/linux/filelock.h +++ b/include/linux/filelock.h @@ -212,7 +212,14 @@ int locks_lock_inode_wait(struct inode *inode, struct = file_lock *fl); void locks_init_lease(struct file_lease *); void locks_free_lease(struct file_lease *fl); struct file_lease *locks_alloc_lease(void); -int __break_lease(struct inode *inode, unsigned int flags, unsigned int ty= pe); + +#define LEASE_BREAK_LEASE BIT(0) // break leases and delegations +#define LEASE_BREAK_DELEG BIT(1) // break delegations only +#define LEASE_BREAK_LAYOUT BIT(2) // break layouts only +#define LEASE_BREAK_NONBLOCK BIT(3) // non-blocking break +#define LEASE_BREAK_OPEN_RDONLY BIT(4) // readonly open event + +int __break_lease(struct inode *inode, unsigned int flags); void lease_get_mtime(struct inode *, struct timespec64 *time); int generic_setlease(struct file *, int, struct file_lease **, void **priv= ); int kernel_setlease(struct file *, int, struct file_lease **, void **); @@ -367,7 +374,7 @@ static inline int locks_lock_inode_wait(struct inode *i= node, struct file_lock *f return -ENOLCK; } =20 -static inline int __break_lease(struct inode *inode, unsigned int mode, un= signed int type) +static inline int __break_lease(struct inode *inode, unsigned int flags) { return 0; } @@ -428,6 +435,17 @@ static inline int locks_lock_file_wait(struct file *fi= lp, struct file_lock *fl) } =20 #ifdef CONFIG_FILE_LOCKING +static inline unsigned int openmode_to_lease_flags(unsigned int mode) +{ + unsigned int flags =3D 0; + + if ((mode & O_ACCMODE) =3D=3D O_RDONLY) + flags |=3D LEASE_BREAK_OPEN_RDONLY; + if (mode & O_NONBLOCK) + flags |=3D LEASE_BREAK_NONBLOCK; + return flags; +} + static inline int break_lease(struct inode *inode, unsigned int mode) { struct file_lock_context *flctx; @@ -443,11 +461,11 @@ static inline int break_lease(struct inode *inode, un= signed int mode) return 0; smp_mb(); if (!list_empty_careful(&flctx->flc_lease)) - return __break_lease(inode, mode, FL_LEASE); + return __break_lease(inode, LEASE_BREAK_LEASE | openmode_to_lease_flags(= mode)); return 0; } =20 -static inline int break_deleg(struct inode *inode, unsigned int mode) +static inline int break_deleg(struct inode *inode, unsigned int flags) { struct file_lock_context *flctx; =20 @@ -461,8 +479,10 @@ static inline int break_deleg(struct inode *inode, uns= igned int mode) if (!flctx) return 0; smp_mb(); - if (!list_empty_careful(&flctx->flc_lease)) - return __break_lease(inode, mode, FL_DELEG); + if (!list_empty_careful(&flctx->flc_lease)) { + flags |=3D LEASE_BREAK_DELEG; + return __break_lease(inode, flags); + } return 0; } =20 @@ -470,7 +490,7 @@ static inline int try_break_deleg(struct inode *inode, = struct inode **delegated_ { int ret; =20 - ret =3D break_deleg(inode, O_WRONLY|O_NONBLOCK); + ret =3D break_deleg(inode, LEASE_BREAK_NONBLOCK); if (ret =3D=3D -EWOULDBLOCK && delegated_inode) { *delegated_inode =3D inode; ihold(inode); @@ -482,7 +502,7 @@ static inline int break_deleg_wait(struct inode **deleg= ated_inode) { int ret; =20 - ret =3D break_deleg(*delegated_inode, O_WRONLY); + ret =3D break_deleg(*delegated_inode, 0); iput(*delegated_inode); *delegated_inode =3D NULL; return ret; @@ -491,20 +511,24 @@ static inline int break_deleg_wait(struct inode **del= egated_inode) static inline int break_layout(struct inode *inode, bool wait) { smp_mb(); - if (inode->i_flctx && !list_empty_careful(&inode->i_flctx->flc_lease)) - return __break_lease(inode, - wait ? O_WRONLY : O_WRONLY | O_NONBLOCK, - FL_LAYOUT); + if (inode->i_flctx && !list_empty_careful(&inode->i_flctx->flc_lease)) { + unsigned int flags =3D LEASE_BREAK_LAYOUT; + + if (!wait) + flags |=3D LEASE_BREAK_NONBLOCK; + + return __break_lease(inode, flags); + } return 0; } =20 #else /* !CONFIG_FILE_LOCKING */ -static inline int break_lease(struct inode *inode, unsigned int mode) +static inline int break_lease(struct inode *inode, bool wait) { return 0; } =20 -static inline int break_deleg(struct inode *inode, unsigned int mode) +static inline int break_deleg(struct inode *inode, unsigned int flags) { return 0; } --=20 2.51.1 From nobody Fri Dec 19 14:23:26 2025 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 5137933EB15; Wed, 5 Nov 2025 16:54:19 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1762361660; cv=none; b=OhFvOHZUrpkcuPXSjLBQYWHZejjwtcglL2z/CD4d+gI1qXmvkGlq+PXvFL8PmE53sV0lvYhNObS5AT0+XVFXESE2PI9JjUYqwuUg3JaVJ1IgH6iBFsAYRvLXpb65Rwso1hcNiP37J7esi8/YXzOEL0oCKprvPiwcH7vZzYY68m4= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1762361660; c=relaxed/simple; bh=NZgsNwo0HMF8Ou2ZnfkNmLyhRQ5oAfi4T4iI9rqixAU=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=CEDSMDt24e1d1iVsMs26V3ucnW38r5uCzFvo1WEVlWN2b5aZDWB4jALZ6qn/XHbaCLrwaNQJzcwwDKlAcixBfxLXeqBHDK6uAssEpfq4yDprjR0wJ7tEezWVBdiBGz86jNcstFbigeaIQGNWKKf9AemTxFPW9C/BYcSsT+PjFFA= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=cVv54QY1; 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="cVv54QY1" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 9EAC3C116C6; Wed, 5 Nov 2025 16:54:16 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1762361659; bh=NZgsNwo0HMF8Ou2ZnfkNmLyhRQ5oAfi4T4iI9rqixAU=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=cVv54QY1D4dGvONZws36DhmfCt8xGgtGkL5h1Bp1nn4bGNV/pvQ3ioq2gY2FQ3WHh aJXLWQbAtxPFhU3SRbNDGQ2yVGKJ5mY4FnUw+oGRKznxWnU4TnMi91iQX6B9R08Cz1 pVQOQh7HxI/Crk9C6L1jrwI5HwdnF/4278UXVLBxobM8dGzSdqN3eHz0TKc6qgkq4L krh6MZrbHwU8FW3ZcW+6onGoYXNDXZih/Wybsx2NmHSUcQd5i6DMq1ECxykf8ZHvw5 9pbWbQQPruM5eVMjnQ+MkyLYv7RNN9m2Zf4/n37wUROH/ypT3NptjVPdMzJ5t1An21 kdjGUTuT/4ynQ== From: Jeff Layton Date: Wed, 05 Nov 2025 11:53:49 -0500 Subject: [PATCH v5 03/17] filelock: add struct delegated_inode Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20251105-dir-deleg-ro-v5-3-7ebc168a88ac@kernel.org> References: <20251105-dir-deleg-ro-v5-0-7ebc168a88ac@kernel.org> In-Reply-To: <20251105-dir-deleg-ro-v5-0-7ebc168a88ac@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=15488; i=jlayton@kernel.org; h=from:subject:message-id; bh=NZgsNwo0HMF8Ou2ZnfkNmLyhRQ5oAfi4T4iI9rqixAU=; b=owEBbQKS/ZANAwAKAQAOaEEZVoIVAcsmYgBpC4ErN5Y1l3fk92NAJ923DrEdx3egrOyv3Uy/G cjrXKEnZYaJAjMEAAEKAB0WIQRLwNeyRHGyoYTq9dMADmhBGVaCFQUCaQuBKwAKCRAADmhBGVaC FY3LEADEFPh13XplyHFHDnGf+ALJyUQ1kSZ09+PLRb92PMmc2sTs6k42Zj4XHXcWy2qKtywgbCy YbrYu7hPK98eFKhSS696bTjly2KhQVuAge4MRSih8ryS6HOKdF2RrdnvCf853ClSfPdi4Fx1+6D fQTTSoudaNpaLL54ujFGLpkra4MFdaumm/1YdLyHcBw6hwKUtsukEGWqCWmyWr46uC7oJi4NoJf BCR7uwn68+zQsrMIIiv/ny2RfalPg/EcVTn+Z42ZbzYrw6yDj7aO9qQh+x7hEMM19kRA3vZWu2R +GC0mdpk85a0gGXy+gAAQgEUjQLOQnijbVT/Gm/xeH0xpLKh90KPRqiCDTW4ZiGK1B2pgH86l1o NTC6L/UNi5fcZIocXNd5SYoKvbV6adkrLgSWhExeZKCSetFUf3+kT9Nmkq0aAAfmlWIX/2TNxgQ wbtk5h4ALpuaNbt4cqfFPgaS3KISNu0tnw1LVTgHIfrLpLwdeZmCitYNKzNsawJCdgPwbFALVjW rniNrCcpf6C0MJx6+54hK/F0dmI3gg/wJaCQpT1rqzDVxHy3yMUDRVeGBDaFgVQImDHrNg8rQ8N kz3s/0McfkmZMTI/ypWax9CN9SiQFI7KQPGZNC9hlLvPmty9QCR7SaG0a3LpQgWV42p/7SSFohz Plz/S+8elZtVDNg== X-Developer-Key: i=jlayton@kernel.org; a=openpgp; fpr=4BC0D7B24471B2A184EAF5D3000E684119568215 The current API requires a pointer to an inode pointer. It's easy for callers to get this wrong. Add a new delegated_inode structure and use that to pass back any inode that needs to be waited on. Signed-off-by: Jeff Layton Reviewed-by: Jan Kara --- fs/attr.c | 2 +- fs/namei.c | 18 +++++++++--------- fs/open.c | 8 ++++---- fs/posix_acl.c | 8 ++++---- fs/utimes.c | 4 ++-- fs/xattr.c | 12 ++++++------ include/linux/filelock.h | 36 +++++++++++++++++++++++++++--------- include/linux/fs.h | 9 +++++---- include/linux/xattr.h | 4 ++-- 9 files changed, 60 insertions(+), 41 deletions(-) diff --git a/fs/attr.c b/fs/attr.c index 795f231d00e8eaaadf5b62f241655cb4b69cb507..b9ec6b47bab2fc2b561677b6396= 33bd32994022f 100644 --- a/fs/attr.c +++ b/fs/attr.c @@ -415,7 +415,7 @@ EXPORT_SYMBOL(may_setattr); * performed on the raw inode simply pass @nop_mnt_idmap. */ int notify_change(struct mnt_idmap *idmap, struct dentry *dentry, - struct iattr *attr, struct inode **delegated_inode) + struct iattr *attr, struct delegated_inode *delegated_inode) { struct inode *inode =3D dentry->d_inode; umode_t mode =3D inode->i_mode; diff --git a/fs/namei.c b/fs/namei.c index 7377020a2cba02501483020e0fc93c279fb38d3e..bf42f146f847a5330fc581595c7= 256af28d9db90 100644 --- a/fs/namei.c +++ b/fs/namei.c @@ -4648,7 +4648,7 @@ SYSCALL_DEFINE1(rmdir, const char __user *, pathname) * raw inode simply pass @nop_mnt_idmap. */ int vfs_unlink(struct mnt_idmap *idmap, struct inode *dir, - struct dentry *dentry, struct inode **delegated_inode) + struct dentry *dentry, struct delegated_inode *delegated_inode) { struct inode *target =3D dentry->d_inode; int error =3D may_delete(idmap, dir, dentry, 0); @@ -4706,7 +4706,7 @@ int do_unlinkat(int dfd, struct filename *name) struct qstr last; int type; struct inode *inode =3D NULL; - struct inode *delegated_inode =3D NULL; + struct delegated_inode delegated_inode =3D { }; unsigned int lookup_flags =3D 0; retry: error =3D filename_parentat(dfd, name, lookup_flags, &path, &last, &type); @@ -4743,7 +4743,7 @@ int do_unlinkat(int dfd, struct filename *name) if (inode) iput(inode); /* truncate the inode here */ inode =3D NULL; - if (delegated_inode) { + if (is_delegated(&delegated_inode)) { error =3D break_deleg_wait(&delegated_inode); if (!error) goto retry_deleg; @@ -4892,7 +4892,7 @@ SYSCALL_DEFINE2(symlink, const char __user *, oldname= , const char __user *, newn */ int vfs_link(struct dentry *old_dentry, struct mnt_idmap *idmap, struct inode *dir, struct dentry *new_dentry, - struct inode **delegated_inode) + struct delegated_inode *delegated_inode) { struct inode *inode =3D old_dentry->d_inode; unsigned max_links =3D dir->i_sb->s_max_links; @@ -4968,7 +4968,7 @@ int do_linkat(int olddfd, struct filename *old, int n= ewdfd, struct mnt_idmap *idmap; struct dentry *new_dentry; struct path old_path, new_path; - struct inode *delegated_inode =3D NULL; + struct delegated_inode delegated_inode =3D { }; int how =3D 0; int error; =20 @@ -5012,7 +5012,7 @@ int do_linkat(int olddfd, struct filename *old, int n= ewdfd, new_dentry, &delegated_inode); out_dput: end_creating_path(&new_path, new_dentry); - if (delegated_inode) { + if (is_delegated(&delegated_inode)) { error =3D break_deleg_wait(&delegated_inode); if (!error) { path_put(&old_path); @@ -5098,7 +5098,7 @@ int vfs_rename(struct renamedata *rd) struct inode *new_dir =3D d_inode(rd->new_parent); struct dentry *old_dentry =3D rd->old_dentry; struct dentry *new_dentry =3D rd->new_dentry; - struct inode **delegated_inode =3D rd->delegated_inode; + struct delegated_inode *delegated_inode =3D rd->delegated_inode; unsigned int flags =3D rd->flags; bool is_dir =3D d_is_dir(old_dentry); struct inode *source =3D old_dentry->d_inode; @@ -5261,7 +5261,7 @@ int do_renameat2(int olddfd, struct filename *from, i= nt newdfd, struct path old_path, new_path; struct qstr old_last, new_last; int old_type, new_type; - struct inode *delegated_inode =3D NULL; + struct delegated_inode delegated_inode =3D { }; unsigned int lookup_flags =3D 0, target_flags =3D LOOKUP_RENAME_TARGET | LOOKUP_CREATE; bool should_retry =3D false; @@ -5369,7 +5369,7 @@ int do_renameat2(int olddfd, struct filename *from, i= nt newdfd, exit3: unlock_rename(new_path.dentry, old_path.dentry); exit_lock_rename: - if (delegated_inode) { + if (is_delegated(&delegated_inode)) { error =3D break_deleg_wait(&delegated_inode); if (!error) goto retry_deleg; diff --git a/fs/open.c b/fs/open.c index 3d64372ecc675e4795eb0a0deda10f8f67b95640..fdaa6f08f6f4cac5c2fefd3eafa= 5e430e51f3979 100644 --- a/fs/open.c +++ b/fs/open.c @@ -631,7 +631,7 @@ SYSCALL_DEFINE1(chroot, const char __user *, filename) int chmod_common(const struct path *path, umode_t mode) { struct inode *inode =3D path->dentry->d_inode; - struct inode *delegated_inode =3D NULL; + struct delegated_inode delegated_inode =3D { }; struct iattr newattrs; int error; =20 @@ -651,7 +651,7 @@ int chmod_common(const struct path *path, umode_t mode) &newattrs, &delegated_inode); out_unlock: inode_unlock(inode); - if (delegated_inode) { + if (is_delegated(&delegated_inode)) { error =3D break_deleg_wait(&delegated_inode); if (!error) goto retry_deleg; @@ -756,7 +756,7 @@ int chown_common(const struct path *path, uid_t user, g= id_t group) struct mnt_idmap *idmap; struct user_namespace *fs_userns; struct inode *inode =3D path->dentry->d_inode; - struct inode *delegated_inode =3D NULL; + struct delegated_inode delegated_inode =3D { }; int error; struct iattr newattrs; kuid_t uid; @@ -791,7 +791,7 @@ int chown_common(const struct path *path, uid_t user, g= id_t group) error =3D notify_change(idmap, path->dentry, &newattrs, &delegated_inode); inode_unlock(inode); - if (delegated_inode) { + if (is_delegated(&delegated_inode)) { error =3D break_deleg_wait(&delegated_inode); if (!error) goto retry_deleg; diff --git a/fs/posix_acl.c b/fs/posix_acl.c index 4050942ab52f95741da2df13d191ade5c5ca12a2..768f027c142811ea907fe854515= 5ba7abd016305 100644 --- a/fs/posix_acl.c +++ b/fs/posix_acl.c @@ -1091,7 +1091,7 @@ int vfs_set_acl(struct mnt_idmap *idmap, struct dentr= y *dentry, int acl_type; int error; struct inode *inode =3D d_inode(dentry); - struct inode *delegated_inode =3D NULL; + struct delegated_inode delegated_inode =3D { }; =20 acl_type =3D posix_acl_type(acl_name); if (acl_type < 0) @@ -1141,7 +1141,7 @@ int vfs_set_acl(struct mnt_idmap *idmap, struct dentr= y *dentry, out_inode_unlock: inode_unlock(inode); =20 - if (delegated_inode) { + if (is_delegated(&delegated_inode)) { error =3D break_deleg_wait(&delegated_inode); if (!error) goto retry_deleg; @@ -1212,7 +1212,7 @@ int vfs_remove_acl(struct mnt_idmap *idmap, struct de= ntry *dentry, int acl_type; int error; struct inode *inode =3D d_inode(dentry); - struct inode *delegated_inode =3D NULL; + struct delegated_inode delegated_inode =3D { }; =20 acl_type =3D posix_acl_type(acl_name); if (acl_type < 0) @@ -1249,7 +1249,7 @@ int vfs_remove_acl(struct mnt_idmap *idmap, struct de= ntry *dentry, out_inode_unlock: inode_unlock(inode); =20 - if (delegated_inode) { + if (is_delegated(&delegated_inode)) { error =3D break_deleg_wait(&delegated_inode); if (!error) goto retry_deleg; diff --git a/fs/utimes.c b/fs/utimes.c index c7c7958e57b22f91646ca9f76d18781b64d371a3..bf9f45bdef54947de7ac55c9f87= 3ae9d0336dafa 100644 --- a/fs/utimes.c +++ b/fs/utimes.c @@ -22,7 +22,7 @@ int vfs_utimes(const struct path *path, struct timespec64= *times) int error; struct iattr newattrs; struct inode *inode =3D path->dentry->d_inode; - struct inode *delegated_inode =3D NULL; + struct delegated_inode delegated_inode =3D { }; =20 if (times) { if (!nsec_valid(times[0].tv_nsec) || @@ -66,7 +66,7 @@ int vfs_utimes(const struct path *path, struct timespec64= *times) error =3D notify_change(mnt_idmap(path->mnt), path->dentry, &newattrs, &delegated_inode); inode_unlock(inode); - if (delegated_inode) { + if (is_delegated(&delegated_inode)) { error =3D break_deleg_wait(&delegated_inode); if (!error) goto retry_deleg; diff --git a/fs/xattr.c b/fs/xattr.c index 8851a5ef34f5ab34383975dd4cef537de3f6391e..32d445fb60aaf2aaf4b16b62934= dc99bad378067 100644 --- a/fs/xattr.c +++ b/fs/xattr.c @@ -274,7 +274,7 @@ int __vfs_setxattr_noperm(struct mnt_idmap *idmap, int __vfs_setxattr_locked(struct mnt_idmap *idmap, struct dentry *dentry, const char *name, const void *value, size_t size, - int flags, struct inode **delegated_inode) + int flags, struct delegated_inode *delegated_inode) { struct inode *inode =3D dentry->d_inode; int error; @@ -305,7 +305,7 @@ vfs_setxattr(struct mnt_idmap *idmap, struct dentry *de= ntry, const char *name, const void *value, size_t size, int flags) { struct inode *inode =3D dentry->d_inode; - struct inode *delegated_inode =3D NULL; + struct delegated_inode delegated_inode =3D { }; const void *orig_value =3D value; int error; =20 @@ -322,7 +322,7 @@ vfs_setxattr(struct mnt_idmap *idmap, struct dentry *de= ntry, flags, &delegated_inode); inode_unlock(inode); =20 - if (delegated_inode) { + if (is_delegated(&delegated_inode)) { error =3D break_deleg_wait(&delegated_inode); if (!error) goto retry_deleg; @@ -533,7 +533,7 @@ EXPORT_SYMBOL(__vfs_removexattr); int __vfs_removexattr_locked(struct mnt_idmap *idmap, struct dentry *dentry, const char *name, - struct inode **delegated_inode) + struct delegated_inode *delegated_inode) { struct inode *inode =3D dentry->d_inode; int error; @@ -567,7 +567,7 @@ vfs_removexattr(struct mnt_idmap *idmap, struct dentry = *dentry, const char *name) { struct inode *inode =3D dentry->d_inode; - struct inode *delegated_inode =3D NULL; + struct delegated_inode delegated_inode =3D { }; int error; =20 retry_deleg: @@ -576,7 +576,7 @@ vfs_removexattr(struct mnt_idmap *idmap, struct dentry = *dentry, name, &delegated_inode); inode_unlock(inode); =20 - if (delegated_inode) { + if (is_delegated(&delegated_inode)) { error =3D break_deleg_wait(&delegated_inode); if (!error) goto retry_deleg; diff --git a/include/linux/filelock.h b/include/linux/filelock.h index 47da6aa28d8dc9122618d02c6608deda0f3c4d3e..208d108df2d73a9df65e5dc9968= d074af385f881 100644 --- a/include/linux/filelock.h +++ b/include/linux/filelock.h @@ -486,25 +486,35 @@ static inline int break_deleg(struct inode *inode, un= signed int flags) return 0; } =20 -static inline int try_break_deleg(struct inode *inode, struct inode **dele= gated_inode) +struct delegated_inode { + struct inode *di_inode; +}; + +static inline bool is_delegated(struct delegated_inode *di) +{ + return di->di_inode; +} + +static inline int try_break_deleg(struct inode *inode, + struct delegated_inode *di) { int ret; =20 ret =3D break_deleg(inode, LEASE_BREAK_NONBLOCK); - if (ret =3D=3D -EWOULDBLOCK && delegated_inode) { - *delegated_inode =3D inode; + if (ret =3D=3D -EWOULDBLOCK && di) { + di->di_inode =3D inode; ihold(inode); } return ret; } =20 -static inline int break_deleg_wait(struct inode **delegated_inode) +static inline int break_deleg_wait(struct delegated_inode *di) { int ret; =20 - ret =3D break_deleg(*delegated_inode, 0); - iput(*delegated_inode); - *delegated_inode =3D NULL; + ret =3D break_deleg(di->di_inode, 0); + iput(di->di_inode); + di->di_inode =3D NULL; return ret; } =20 @@ -523,6 +533,13 @@ static inline int break_layout(struct inode *inode, bo= ol wait) } =20 #else /* !CONFIG_FILE_LOCKING */ +struct delegated_inode { }; + +static inline bool is_delegated(struct delegated_inode *di) +{ + return false; +} + static inline int break_lease(struct inode *inode, bool wait) { return 0; @@ -533,12 +550,13 @@ static inline int break_deleg(struct inode *inode, un= signed int flags) return 0; } =20 -static inline int try_break_deleg(struct inode *inode, struct inode **dele= gated_inode) +static inline int try_break_deleg(struct inode *inode, + struct delegated_inode *delegated_inode) { return 0; } =20 -static inline int break_deleg_wait(struct inode **delegated_inode) +static inline int break_deleg_wait(struct delegated_inode *delegated_inode) { BUG(); return 0; diff --git a/include/linux/fs.h b/include/linux/fs.h index c895146c1444be36e0a779df55622cc38c9419ff..909a88e3979d4f1ba3104f3d051= 45e1096ed44d5 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h @@ -80,6 +80,7 @@ struct fs_context; struct fs_parameter_spec; struct file_kattr; struct iomap_ops; +struct delegated_inode; =20 extern void __init inode_init(void); extern void __init inode_init_early(void); @@ -2119,10 +2120,10 @@ int vfs_mknod(struct mnt_idmap *, struct inode *, s= truct dentry *, int vfs_symlink(struct mnt_idmap *, struct inode *, struct dentry *, const char *); int vfs_link(struct dentry *, struct mnt_idmap *, struct inode *, - struct dentry *, struct inode **); + struct dentry *, struct delegated_inode *); int vfs_rmdir(struct mnt_idmap *, struct inode *, struct dentry *); int vfs_unlink(struct mnt_idmap *, struct inode *, struct dentry *, - struct inode **); + struct delegated_inode *); =20 /** * struct renamedata - contains all information required for renaming @@ -2140,7 +2141,7 @@ struct renamedata { struct dentry *old_dentry; struct dentry *new_parent; struct dentry *new_dentry; - struct inode **delegated_inode; + struct delegated_inode *delegated_inode; unsigned int flags; } __randomize_layout; =20 @@ -3071,7 +3072,7 @@ static inline int bmap(struct inode *inode, sector_t= *block) #endif =20 int notify_change(struct mnt_idmap *, struct dentry *, - struct iattr *, struct inode **); + struct iattr *, struct delegated_inode *); int inode_permission(struct mnt_idmap *, struct inode *, int); int generic_permission(struct mnt_idmap *, struct inode *, int); static inline int file_permission(struct file *file, int mask) diff --git a/include/linux/xattr.h b/include/linux/xattr.h index 86b0d47984a16d935dd1c45ca80a3b8bb5b7295b..64e9afe7d647dc38f686a4b5c6f= 765e061cde54c 100644 --- a/include/linux/xattr.h +++ b/include/linux/xattr.h @@ -85,12 +85,12 @@ int __vfs_setxattr_noperm(struct mnt_idmap *, struct de= ntry *, const char *, const void *, size_t, int); int __vfs_setxattr_locked(struct mnt_idmap *, struct dentry *, const char *, const void *, size_t, int, - struct inode **); + struct delegated_inode *); int vfs_setxattr(struct mnt_idmap *, struct dentry *, const char *, const void *, size_t, int); int __vfs_removexattr(struct mnt_idmap *, struct dentry *, const char *); int __vfs_removexattr_locked(struct mnt_idmap *, struct dentry *, - const char *, struct inode **); + const char *, struct delegated_inode *); int vfs_removexattr(struct mnt_idmap *, struct dentry *, const char *); =20 ssize_t generic_listxattr(struct dentry *dentry, char *buffer, size_t buff= er_size); --=20 2.51.1 From nobody Fri Dec 19 14:23:26 2025 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id A51EA33FE06; Wed, 5 Nov 2025 16:54:23 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1762361663; cv=none; b=gsT/RIr9r8e2RpC2vANOlrUozQZZLLFt0Amfx/+u/uRmA06B+ySCtAg+yv3t/D5vVWikqmwlIul4uw+sz82N1Z1ikxpU5PMo2C2OljW7vYPw4Qqf9wLnVRXQaeCkwX70JPXBlgqrvhvxX7A4OX42uMHmd7Wn83W2P45qCEhi/RE= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1762361663; c=relaxed/simple; bh=GcsMrS33yeMCZHbhLsrwn2fXghDYDgJpfU5BwKmzfzs=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=kVU3Ddqkm06RKJEUSsrYaFnES5G068PBSWD3cY+UBpOkJBqSlCZhDgDuZSJb/X9GxbLHXwf/iae4W8biVd5ShoiR03F7twBc3wnMVqFG4GOpyIGBSMd3Wpn0b+L2CVcM8Z+r1UXyk2zpMJ1wxNIGZEQUgquYe35h9b2um3MI01A= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=mXZ9ry9u; 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="mXZ9ry9u" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 11480C19422; Wed, 5 Nov 2025 16:54:19 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1762361663; bh=GcsMrS33yeMCZHbhLsrwn2fXghDYDgJpfU5BwKmzfzs=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=mXZ9ry9uCFohj8MJfSEi+CHA6qNy71q1klGXvWiTbQoGJQKRzbaZuqXpsB1E28chK laOslj5Pcq2S8iGLUM7xBzNoDyuzGOEkc3dIpVFGaUw50BUFHPYcfSW9ID7upBhB1+ 17V9QBO05hVMefueSj5gNLLm3nuKrGnndmBuhhntCnt5UNDGa1vvahTpyH36nMw+Zt S7ygyeeub3tfRTAHHhdhig9exQZIlHPZOaNdoxC1Js0xNp5YQHPvHeT5m52wqHqRHw SI8JrbthqwakOLKY2x5kBHnKq4JTSh64bOEV7OoLS5PtjB/MPfJfVs2Jo1GOHTHbho 1VaPAZrRmuW7w== From: Jeff Layton Date: Wed, 05 Nov 2025 11:53:50 -0500 Subject: [PATCH v5 04/17] 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: <20251105-dir-deleg-ro-v5-4-7ebc168a88ac@kernel.org> References: <20251105-dir-deleg-ro-v5-0-7ebc168a88ac@kernel.org> In-Reply-To: <20251105-dir-deleg-ro-v5-0-7ebc168a88ac@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=3489; i=jlayton@kernel.org; h=from:subject:message-id; bh=GcsMrS33yeMCZHbhLsrwn2fXghDYDgJpfU5BwKmzfzs=; b=owEBbQKS/ZANAwAKAQAOaEEZVoIVAcsmYgBpC4ErMfLW3WwdkEqkBaw9YAj//ntzrQ4bSHKpI +WthUOzcZqJAjMEAAEKAB0WIQRLwNeyRHGyoYTq9dMADmhBGVaCFQUCaQuBKwAKCRAADmhBGVaC FSEOD/sGnl4nXGxrUiH4HV74LVigfLgxBGvcCvofbPESbST6oRhyTftwB8j847ijjWuZtJiC0Bk W4YzdfbjE6obkTq1+/wRiq3b45ztWVhsQo3hRi/YKm8WqRpU7GqMm0wBuCO9RX9FiGNknkZcsek 6Sj8PYI4WIF9Iyt/+gmnge9iWAugQ7OcT53c+NOdKNNu6c9I0J6yu6ztOPsR44+hxJEWRRCgQav hghq2Fe6ApKmD2CRWjXSFavfaMNFhcSbrLskz2WgHs8lug72m352YQaoOtku5pqTkplEG5IJR05 efdytOESy80DNxhmzMABrI0QD7sY/Fntq3vpDgNWGEawyyWvyEbhOw1h0B9uGzZ3rz7SDaBwTNR ldj1OsoAHBLuGkFG2thkoQTDhvzdOHCj8hXG4PD2GAn43y116K44sYShVtJVQh7lMDoiEIdFAKz Toz/GV6oIL/9FeBLHSrzIOd32XpGvVF2x5IloZ42SAgEdwcb2B0cTI6ELJ5tTL67vEKZD4M09A8 tyHsD2XCM1DE0O+WP4htcMrYqpHJC8++/P27568fvxqL327SrwPn/5KVy8JL5o4fMMpqYEZ/NK8 22MTIDkdVHi6kyAzxosrAPqKP2I9oq10y3OjRTTDqJzbVd0GPtPzT1iFnJ8vg4qVPGYhnIcJmYG 2fX3dKB+yWG5ceg== X-Developer-Key: i=jlayton@kernel.org; a=openpgp; fpr=4BC0D7B24471B2A184EAF5D3000E684119568215 When nfsd starts requesting directory delegations, setlease handlers may see requests for leases on directories. Push the !S_ISREG check down into the non-trivial setlease handlers, so we can selectively enable them where they're supported. FUSE is special: It's the only filesystem that supports atomic_open and allows kernel-internal leases. atomic_open is issued when the VFS doesn't know the state of the dentry being opened. If the file doesn't exist, it may be created, in which case the dir lease should be broken. The existing kernel-internal lease implementation has no provision for this. Ensure that we don't allow directory leases by default going forward by explicitly disabling them there. Reviewed-by: NeilBrown Reviewed-by: Jan Kara 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 3cdd84a0fbedc9bd1b47725a9cf963342aafbce9..f5b210a2dc34c70ac36e972436c= 62482bbe32ca6 100644 --- a/fs/locks.c +++ b/fs/locks.c @@ -1935,6 +1935,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); @@ -2024,8 +2027,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.1 From nobody Fri Dec 19 14:23:26 2025 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 21D70341ACC; Wed, 5 Nov 2025 16:54:26 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1762361667; cv=none; b=C4GSMixImEwx+TIRfUH/lflCPq82lWKN9VMkH8w9rZ4pNh0sSoZgGppY/8TnM6N9y5jE1yy26YZolsnLQvFL06PQTgMkhWVU4Eup6VGBaxJjB8AfgokAVXTS1Nt6VrUBf1UK4GyKXO4LVVRzOStEDLK+aJRnS7wUxS7A31eTEHo= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1762361667; c=relaxed/simple; bh=3+ZClpFIpySqsQF9IacI3LgDcwpX/JfG6YtjN83vd9E=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=oZfGoQdau5Z8SxpB5EjD/X0dFOcYByUAaAYOaoC8EDbO511vdTs4GIKCdujJbMUhqIAMJdZy5t6skoF2/vTk9FxNhSt5WvT4aasvDReYJFueqygq538GLB+W1jI1lizuS20dsp5AWVb5rVd4BLDd20pD6L9JkwFPkYPnJXlBMg4= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=P6QU04ya; 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="P6QU04ya" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 768BDC4CEF5; Wed, 5 Nov 2025 16:54:23 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1762361666; bh=3+ZClpFIpySqsQF9IacI3LgDcwpX/JfG6YtjN83vd9E=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=P6QU04yaFVASh9D9aUDxbgzVCRgbIYXAI3/IkF++zTRdI/MSgRg1TcXF1TE8W4Et4 VMWOQnVKkCo/mCIUVYqNpwbGiUJXKdxoH9gKXpy1TmMCOjTzC9uz7DLkLC7GWhgYoI wkSD6Jelon2Y2kXHr1L/OMKzCZeh20SLj37p1kHOoTLHMQxaY1Jo54lDe1xWC4aMi6 kAvAtAsU2/ue8nMbVpBVKZaB29c9CPqlzMygtuLWnKZ1SYQuDRO0nJ201THIjIF8ZW wgnC4RqPHh9zoGZealY3hw+TVhmDmGhJ2vkMZTJcKywzOlrhlNBu4uilHJxyqT8pE4 2wP0fLskJH4KA== From: Jeff Layton Date: Wed, 05 Nov 2025 11:53:51 -0500 Subject: [PATCH v5 05/17] 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: <20251105-dir-deleg-ro-v5-5-7ebc168a88ac@kernel.org> References: <20251105-dir-deleg-ro-v5-0-7ebc168a88ac@kernel.org> In-Reply-To: <20251105-dir-deleg-ro-v5-0-7ebc168a88ac@kernel.org> To: Miklos Szeredi , Alexander Viro , Christian Brauner , Jan Kara , Chuck Lever , Alexander Aring , Trond Myklebust , Anna Schumaker , Steve French , Paulo Alcantara , Ronnie Sahlberg , Shyam Prasad N , Tom Talpey , Bharath SM , Greg Kroah-Hartman , "Rafael J. Wysocki" , Danilo Krummrich , David Howells , Tyler Hicks , NeilBrown , Olga Kornievskaia , Dai Ngo , Amir Goldstein , Namjae Jeon , Steve French , Sergey Senozhatsky , Carlos Maiolino , Kuniyuki Iwashima , "David S. Miller" , Eric Dumazet , Jakub Kicinski , Paolo Abeni , Simon Horman Cc: linux-fsdevel@vger.kernel.org, linux-kernel@vger.kernel.org, linux-nfs@vger.kernel.org, linux-cifs@vger.kernel.org, samba-technical@lists.samba.org, netfs@lists.linux.dev, ecryptfs@vger.kernel.org, linux-unionfs@vger.kernel.org, linux-xfs@vger.kernel.org, netdev@vger.kernel.org, Jeff Layton X-Mailer: b4 0.14.2 X-Developer-Signature: v=1; a=openpgp-sha256; l=1915; i=jlayton@kernel.org; h=from:subject:message-id; bh=3+ZClpFIpySqsQF9IacI3LgDcwpX/JfG6YtjN83vd9E=; b=owEBbQKS/ZANAwAKAQAOaEEZVoIVAcsmYgBpC4ErSTvwO6KqZ2UnxssHQPNA/tzdjcWxFtshh 3hCPwzM80SJAjMEAAEKAB0WIQRLwNeyRHGyoYTq9dMADmhBGVaCFQUCaQuBKwAKCRAADmhBGVaC Fb6PD/9g4scqOiSBEL+2vOllOWmp0Sh6Zpy8m/gtGl+pukCZirrupXBCuBiQtAfgAv/L5WDaXjO 2/zx31lESIUJnq03f+Ty9wpvmQQ2BlrOANAXuqiC3RzwN596eMrvylxxbCL5VguATwfwgfdMCFQ LwQSCE1yz2AUyEXmwS+YqjaIuAMxdcRBVCTHj6sofsJR4Y/xh+zU+Web2rGfV+ADXkX9lHlBfZj znObtjZmiOkmg5MXUOQnSgJLGFHgGl+9YRQQoIa/XlKye2DurfasWVqUtX6bYDKrSHQE87g5Bte 5RRn4RL22A6VEpwbpWokmkBOZZ7hqa6RO+/vXJ9Obgow2UZZEjWXv4p1nhV4T50XSlUWyRvnMuy l3y4sSZibjE0A+6yOupBi/S4lG9Stxa+cq2eV02yGIFkBnZUcBwM/J1UDXps1bsECsxMGZeEwQf 2PTudQ6duXGBKeLgAehexXrGLcmQvebhF/mdHUsuKFCf79/wgRaufZPUVPiwRI7QWfzEDu24F/x zJ0R9PK4vl080tFzA4wGs3ZlfusgVXy+NrNbN463WvXzDphdaTAiI2nxxbyL3H9SfM40iih0QMH /+PXHoHj7q63elF9RWQkBn7iLUPxEtEbxvFrNq0cN4zdjgTO7bZ0KDo95+9mbhVf+4fepuKXQjy bBLLG+gJrDT/lpA== X-Developer-Key: i=jlayton@kernel.org; a=openpgp; fpr=4BC0D7B24471B2A184EAF5D3000E684119568215 In order to add directory delegation support, we need to break delegations on the parent whenever there is going to be a change in the directory. vfs_link, vfs_unlink, and vfs_rename all have existing delegation break handling for the children in the rename. Add the necessary calls for breaking delegations in the parent(s) as well. Reviewed-by: Jan Kara Reviewed-by: NeilBrown Signed-off-by: Jeff Layton --- fs/namei.c | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/fs/namei.c b/fs/namei.c index bf42f146f847a5330fc581595c7256af28d9db90..5bcf3e93d350ffd290f72725c37= 8d3dffeeae364 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.1 From nobody Fri Dec 19 14:23:26 2025 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 795BC3431EE; Wed, 5 Nov 2025 16:54:30 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1762361670; cv=none; b=OI9dpWgjhNspH1dQmPr0gM6Ev9MpKcq0pbUl1qXiLRJW2WjiHn6Xa5FiasY0ggEK/LT37izKAv5lzz+FRxcJVlkEBk+LlpQDRsxERcNk505aL1qXpoRju35BG/CcPNQmuRfMtga46w/wiNWhfpkazxLGS6GkpIHV/zLnAxnTZFo= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1762361670; c=relaxed/simple; bh=Abg5p2Lt31TlE/xurhC/XlffrDJLd5VW/QAzqsSk4cE=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=Vdrq9VtpElyRtBvRqRvJxCdQZ0exPJ/xdULMy++J9YgOKM8OYXgGGJ+Q6jHfwgptd5/rRCfxtyzC53M/ZzTM7oFI2Vevh6cNROq8reFEPk1X2gB/nhHwA6hHKxxHv7VqHv3yKRH3LfxW00zZm9QayhmCKdNDGyLp1egSjuX97V0= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=kzcY4jLd; 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="kzcY4jLd" Received: by smtp.kernel.org (Postfix) with ESMTPSA id DBC8EC116B1; Wed, 5 Nov 2025 16:54:26 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1762361670; bh=Abg5p2Lt31TlE/xurhC/XlffrDJLd5VW/QAzqsSk4cE=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=kzcY4jLdm5x41jTmk2yP5H+ubT3RCBv49kZiynyKMHF/BAeiv9571buAIUEHhZUkp TXuBUEPK/VVJPIMer64QjBHl2ZC6cUg6iYmErEgTMK6x8uQEvkvwZxva9ClhzBh32K EC8dTpSiziEQy0BhDh/vq0zFOhCRru8OSFTORRqDpLnzVarRdi3jaP7rOZNepX4gRu iOSstR5NkL7Z10eC3scGkV5rSp9cR11OLIQwUV19gj0GyGLjamJpWm8h0SCQSgRvtl Q/9U/Yof1xh+K09F200MEiTxY96ixgVa+ntaQo1chhrf8ccD/HZer/KMg1xYNHI3EP YnihzVpYxlw6g== From: Jeff Layton Date: Wed, 05 Nov 2025 11:53:52 -0500 Subject: [PATCH v5 06/17] 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: <20251105-dir-deleg-ro-v5-6-7ebc168a88ac@kernel.org> References: <20251105-dir-deleg-ro-v5-0-7ebc168a88ac@kernel.org> In-Reply-To: <20251105-dir-deleg-ro-v5-0-7ebc168a88ac@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=9247; i=jlayton@kernel.org; h=from:subject:message-id; bh=Abg5p2Lt31TlE/xurhC/XlffrDJLd5VW/QAzqsSk4cE=; b=owEBbQKS/ZANAwAKAQAOaEEZVoIVAcsmYgBpC4ErV/9oxpJgH+QoTmiHgrQGeg5qirpyKW5oG bi8h0/c8MqJAjMEAAEKAB0WIQRLwNeyRHGyoYTq9dMADmhBGVaCFQUCaQuBKwAKCRAADmhBGVaC FVyTD/9OeH0Ygz/xCZCfaXSsC+8xQaYJuhOxGev75L6VHRjQot/1ZYFAHvl5mOzECSpO9d4xN3s YAsMzsOQgqJ1XWSST71DAxD+v791tYEyiY6U3CBHyWEcc0/9W1PGu5lbKrqEVlkavmD3IUqs2s8 EV/XUB6Ri3htuderyli2+GVipMsOvFZINGJ9JrtXOv8wKEWC347L2GSKq4zUAlx5AbPNMxsn9va mKVh4k7CoqQ2sYn7IRPym+vtsh4mSNLOnmVWiQv7kYf2cUyPZKWLcw6NhtcOz42cshXaSQ8WZAA PQ42EG/uFXut0V8gHEbBXZgcw1l7W8io71emi2ATOMDaxWqsVg3vUguU2gyMxnR30rvuRXfodzB WhRQETxxnS3R7jbKhF3bi7X8jugFa5kNW58vs4dRg9ZEvS6d+aBweeHcjbREjOMAcjZxE2vjHI7 9oPok4G+YWr+qwJ9BDYf478QX+76z8Dhh1yjOrTrRZvdTzBJPcLNlOufNbYCguY+FTabK+uRsqr 6SKgS7RXHH0mstwUIrZg1Ztmsh+UUdxg01ZlwokktMo4OFA2S2VagoAQaiOq2UhByWY+iqfW4Er tCP/MSSVAYYG+DEuu00XcouM2unzLTbKdS/Ou0k1bIgNUd0+jDdxIzmt9kJz6E0J8zpZxlI9S+6 9/wtdpxwykwkVmA== X-Developer-Key: i=jlayton@kernel.org; a=openpgp; fpr=4BC0D7B24471B2A184EAF5D3000E684119568215 In order to add directory delegation support, we need to break delegations on the parent whenever there is going to be a change in the directory. Add a new delegated_inode parameter to vfs_mkdir. All of the existing callers set that to NULL for now, except for do_mkdirat which will properly block until the lease is gone. Reviewed-by: Jan Kara Reviewed-by: NeilBrown Signed-off-by: Jeff Layton --- drivers/base/devtmpfs.c | 2 +- fs/cachefiles/namei.c | 2 +- fs/ecryptfs/inode.c | 2 +- fs/init.c | 2 +- fs/namei.c | 24 ++++++++++++++++++------ fs/nfsd/nfs4recover.c | 2 +- fs/nfsd/vfs.c | 2 +- fs/overlayfs/overlayfs.h | 2 +- fs/smb/server/vfs.c | 2 +- fs/xfs/scrub/orphanage.c | 2 +- include/linux/fs.h | 2 +- 11 files changed, 28 insertions(+), 16 deletions(-) diff --git a/drivers/base/devtmpfs.c b/drivers/base/devtmpfs.c index 9d4e46ad8352257a6a65d85526ebdbf9bf2d4b19..0e79621cb0f79870003b867ca38= 4199171ded4e0 100644 --- a/drivers/base/devtmpfs.c +++ b/drivers/base/devtmpfs.c @@ -180,7 +180,7 @@ static int dev_mkdir(const char *name, umode_t mode) if (IS_ERR(dentry)) return PTR_ERR(dentry); =20 - dentry =3D vfs_mkdir(&nop_mnt_idmap, d_inode(path.dentry), dentry, mode); + dentry =3D vfs_mkdir(&nop_mnt_idmap, d_inode(path.dentry), dentry, mode, = NULL); if (!IS_ERR(dentry)) /* mark as kernel-created inode */ d_inode(dentry)->i_private =3D &thread; diff --git a/fs/cachefiles/namei.c b/fs/cachefiles/namei.c index d1edb2ac38376c4f9d2a18026450bb3c774f7824..50c0f9c76d1fd4c05db90d7d0d1= bad574523ead0 100644 --- a/fs/cachefiles/namei.c +++ b/fs/cachefiles/namei.c @@ -130,7 +130,7 @@ struct dentry *cachefiles_get_directory(struct cachefil= es_cache *cache, goto mkdir_error; ret =3D cachefiles_inject_write_error(); if (ret =3D=3D 0) - subdir =3D vfs_mkdir(&nop_mnt_idmap, d_inode(dir), subdir, 0700); + subdir =3D vfs_mkdir(&nop_mnt_idmap, d_inode(dir), subdir, 0700, NULL); else subdir =3D ERR_PTR(ret); if (IS_ERR(subdir)) { diff --git a/fs/ecryptfs/inode.c b/fs/ecryptfs/inode.c index ed1394da8d6bd7065f2a074378331f13fcda17f9..35830b3144f8f71374a78b3e746= 3b864f4fc216e 100644 --- a/fs/ecryptfs/inode.c +++ b/fs/ecryptfs/inode.c @@ -508,7 +508,7 @@ static struct dentry *ecryptfs_mkdir(struct mnt_idmap *= idmap, struct inode *dir, goto out; =20 lower_dentry =3D vfs_mkdir(&nop_mnt_idmap, lower_dir, - lower_dentry, mode); + lower_dentry, mode, NULL); rc =3D PTR_ERR(lower_dentry); if (IS_ERR(lower_dentry)) goto out; diff --git a/fs/init.c b/fs/init.c index 07f592ccdba868509d0f3aaf9936d8d890fdbec5..895f8a09a71acfd03e11164e3b4= 41a7d4e2de146 100644 --- a/fs/init.c +++ b/fs/init.c @@ -233,7 +233,7 @@ int __init init_mkdir(const char *pathname, umode_t mod= e) error =3D security_path_mkdir(&path, dentry, mode); if (!error) { dentry =3D vfs_mkdir(mnt_idmap(path.mnt), path.dentry->d_inode, - dentry, mode); + dentry, mode, NULL); if (IS_ERR(dentry)) error =3D PTR_ERR(dentry); } diff --git a/fs/namei.c b/fs/namei.c index 5bcf3e93d350ffd290f72725c378d3dffeeae364..76c0587d991ff7307e3dde69497= 719d716c8d7b8 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 delegated_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 delegated_inode delegated_inode =3D { }; =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 (is_delegated(&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 e2b9472e5c78c9f03731090ffdfb26eb5de38fe0..1f56834b2072fcee1d0d400bbb5= 54b0c949ecab4 100644 --- a/fs/nfsd/nfs4recover.c +++ b/fs/nfsd/nfs4recover.c @@ -213,7 +213,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 9cb20d4aeab159ef3ba3584d1a3a33ef16ba4dea..97aef140cbf5fca4c41738fdcac= cba3b57886463 100644 --- a/fs/nfsd/vfs.c +++ b/fs/nfsd/vfs.c @@ -1558,7 +1558,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 909a88e3979d4f1ba3104f3d05145e1096ed44d5..20bb4c8a4e8e1be7e11047d228c= 05920ea6c388d 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h @@ -2114,7 +2114,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 delegated_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.1 From nobody Fri Dec 19 14:23:26 2025 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 9FCD734404B; Wed, 5 Nov 2025 16:54:33 +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=1762361673; cv=none; b=jVtLlR4KpMtD08ZKtkuimCuH9jgcnu9eOIsuKXESKjJbYL0uB9HaQoXTEqPvViwaerqDJtq/fWmKHe8tv5XSGLqYmjI4u71iIbCFErc+haMa2uihdXJgdk8YCVuwHHHoMm1bj0qG1tK5XrcAI7ZoRpIG5QeXH2gGIhnUxDTMYF4= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1762361673; c=relaxed/simple; bh=nVt7zfcxkLtFpIV/AjQcJVwofL/t6x0LVRGY+VtgUx0=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=s4lI6sczMp4fbeK2gT30oh6HvQusX0v4eWWGd6h6dCYfmdq7aMWl4EwyRo9PDFPiE4bRwblrSZKaKKaeZPn4Ps8J2j2OLDyJAxTKIKwgPiefz+1n0QBAa+uFCbxgph6EMm6Xzo5V2kghoynE+3YwasMXUI7+ix6eT8qfYUjLuPE= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=T1yuvNPh; 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="T1yuvNPh" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 4E1FAC116C6; Wed, 5 Nov 2025 16:54:30 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1762361673; bh=nVt7zfcxkLtFpIV/AjQcJVwofL/t6x0LVRGY+VtgUx0=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=T1yuvNPhetJCADnWOKxP2SxMDylyBlzZFXbDiRWDJsWQ6HZaVPD3h47hWMJ3z9Br6 0wnjjCzesrB2Apehde8xCZ6FT3tRF52UrAjV0iBhv98BLq5eOhxLX0yBPKQ3Nysyr4 yXxhGmf74zVAcSnb7/aN2g95ZFIcwWS/ouP7uPfaPNSDgwYCfxSc8cBD+K44Wvu02q zc1fLFB5whPDXAd8HAbNAzmjzMXv2ReKzfpt4PJcOuHRBOIUShyyuqyPtum8W6CLRj XtcC88YeBytxsXR9IEqQ5C3ZYavf74mkHi4UrLDInxv0kO8rXHJrWr05a0rH+Flkxe GjK38XC8gmPNQ== From: Jeff Layton Date: Wed, 05 Nov 2025 11:53:53 -0500 Subject: [PATCH v5 07/17] 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: <20251105-dir-deleg-ro-v5-7-7ebc168a88ac@kernel.org> References: <20251105-dir-deleg-ro-v5-0-7ebc168a88ac@kernel.org> In-Reply-To: <20251105-dir-deleg-ro-v5-0-7ebc168a88ac@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=7777; i=jlayton@kernel.org; h=from:subject:message-id; bh=nVt7zfcxkLtFpIV/AjQcJVwofL/t6x0LVRGY+VtgUx0=; b=owEBbQKS/ZANAwAKAQAOaEEZVoIVAcsmYgBpC4Er/oilxewvUaJv+DVl82MHZmHENJoYL2app G2kbBu4Y5yJAjMEAAEKAB0WIQRLwNeyRHGyoYTq9dMADmhBGVaCFQUCaQuBKwAKCRAADmhBGVaC FX41D/42+M+KQCSzsaid1QETi47k3GYB6A4R+TZRNjsT2zyfVUMs8ycwyC+Ag/AWoTrN1egwZrc osw8ipGpljH3Gn1Y4gWXeFRrLnHf+Vk+gCPc+Cl3ml9s7/JQ5tZMbSnQWAw8k2fiBo28Wp7Wy61 Eq5gtJyDr/yrrYtDM+TJJyN+6ZX3Jtp8+wCsf2kf1XAyC4sjJ+rVWJVAU597Fb/gSCNxj7yIMVQ hXYmVWMqyUN2sB7e069DfCLDA1gg5otSk0tsGGz9zZ9p3ORZLfReeb5ZgZWQnEqdIcofKux8BEs oc5V/9OsRkEQ8PvIoaBtc8sKO5ZSXP++d8OazGl/CforQ7TXX+aZma9L7jf2GDxXlxqrXYj1S1f 2AxOfoy2rWufgxCj4Dp3JJ4TYSKnR3sQkkT/LkMkMUnH5vw2fWlRjeAkQRjjt2YTmMCCmzDj6/C 1W+bma6dHgWZmvttlbWi59g2RtPplYVQnHKD7/Y0f6FknnLu+mYlQnSGlLZhukbkoSrBPNwbr1d Vu9XoRePWjyTV71LFquiSdW3zUbvAZUu69RQvUPMdUVBsyF9UhWX8+Eai3LCbJ53WYC7lTT9tbw gk36bvS0ygNs9BBA2NWdEobtyo65qsXN6zp5U4gKVhxrBZXbw+hw/x04mDafqGJQgLXdQQu1tl/ S7jdAOhls+IvOXw== 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 struct to vfs_rmdir() and populate that pointer with the parent inode if it's non-NULL. Most existing in-kernel callers pass in a NULL pointer. Reviewed-by: Jan Kara Reviewed-by: NeilBrown Signed-off-by: Jeff Layton --- drivers/base/devtmpfs.c | 2 +- fs/ecryptfs/inode.c | 2 +- fs/namei.c | 22 +++++++++++++++++----- fs/nfsd/nfs4recover.c | 4 ++-- fs/nfsd/vfs.c | 2 +- fs/overlayfs/overlayfs.h | 2 +- fs/smb/server/vfs.c | 4 ++-- include/linux/fs.h | 3 ++- 8 files changed, 27 insertions(+), 14 deletions(-) diff --git a/drivers/base/devtmpfs.c b/drivers/base/devtmpfs.c index 0e79621cb0f79870003b867ca384199171ded4e0..104025104ef75381984fd94dfbd= 50feeaa8cdd22 100644 --- a/drivers/base/devtmpfs.c +++ b/drivers/base/devtmpfs.c @@ -261,7 +261,7 @@ static int dev_rmdir(const char *name) return PTR_ERR(dentry); if (d_inode(dentry)->i_private =3D=3D &thread) err =3D vfs_rmdir(&nop_mnt_idmap, d_inode(parent.dentry), - dentry); + dentry, NULL); else err =3D -EPERM; =20 diff --git a/fs/ecryptfs/inode.c b/fs/ecryptfs/inode.c index 35830b3144f8f71374a78b3e7463b864f4fc216e..88631291b32535f623a3fbe4ea9= b6ed48a306ca0 100644 --- a/fs/ecryptfs/inode.c +++ b/fs/ecryptfs/inode.c @@ -540,7 +540,7 @@ static int ecryptfs_rmdir(struct inode *dir, struct den= try *dentry) if (d_unhashed(lower_dentry)) rc =3D -EINVAL; else - rc =3D vfs_rmdir(&nop_mnt_idmap, lower_dir, lower_dentry); + rc =3D vfs_rmdir(&nop_mnt_idmap, lower_dir, lower_dentry, NULL); } if (!rc) { clear_nlink(d_inode(dentry)); diff --git a/fs/namei.c b/fs/namei.c index 76c0587d991ff7307e3dde69497719d716c8d7b8..9e0393a92091ac522b5324fcdad= 8c5592a948e8d 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 delegated_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 delegated_inode delegated_inode =3D { }; 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 (is_delegated(&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 1f56834b2072fcee1d0d400bbb554b0c949ecab4..30bae93931d9c9f8900dfcf96f7= 9403db4f3f458 100644 --- a/fs/nfsd/nfs4recover.c +++ b/fs/nfsd/nfs4recover.c @@ -337,7 +337,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: @@ -427,7 +427,7 @@ purge_old(struct dentry *parent, struct dentry *child, = struct nfsd_net *nn) if (nfs4_has_reclaimed_state(name, nn)) goto out_free; =20 - 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 97aef140cbf5fca4c41738fdcaccba3b57886463..c400ea94ff2e837fd59719bf2c4= b79ef1d064743 100644 --- a/fs/nfsd/vfs.c +++ b/fs/nfsd/vfs.c @@ -2108,7 +2108,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 20bb4c8a4e8e1be7e11047d228c05920ea6c388d..12873214e1c7811735ea5d2dee3= d57e2a5604d8f 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h @@ -2121,7 +2121,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 delegated_inode *); -int vfs_rmdir(struct mnt_idmap *, struct inode *, struct dentry *); +int vfs_rmdir(struct mnt_idmap *, struct inode *, struct dentry *, + struct delegated_inode *); int vfs_unlink(struct mnt_idmap *, struct inode *, struct dentry *, struct delegated_inode *); =20 --=20 2.51.1 From nobody Fri Dec 19 14:23:26 2025 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 1C66133B970; Wed, 5 Nov 2025 16:54:37 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1762361677; cv=none; b=QoDktXGvXt3JBdOdJnmHsV/47q71qjbwuLHSprcrop+PZqhV+KmXPCSD1bOjJxLUPSSUOrwOesNKdBnbuHSUaKWQ7W7D9LG7RM3AGdiA4mXpcuSC2OVyyT/M1baLtPjpYK1ztmCOAErdwLPpfm1nCUG/3v7jaiHw7LY0+ShcObs= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1762361677; c=relaxed/simple; bh=zBQyD4C+LOu4tUZSnzQKyrp9sE+YBQAdVnnbBh8HRrY=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=Pst66u5DBmSzQ76tfjqsKYm0lD6nymhWcSaU5VBlYF3JEnTJb0dcnpmXtAUwl7epKb1cROblmE0i+E5TLCce7NQZxoiDJJWrtCyQyCEJhICSa562RQoSZjvKAfbLd8nmt/+/2S8RNy4ZRSPGpKhjlXEUdxBirI8i+ecw00tOu80= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=Y45UKCTr; 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="Y45UKCTr" Received: by smtp.kernel.org (Postfix) with ESMTPSA id B838FC19424; Wed, 5 Nov 2025 16:54:33 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1762361676; bh=zBQyD4C+LOu4tUZSnzQKyrp9sE+YBQAdVnnbBh8HRrY=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=Y45UKCTrpPCHbOODGNYGhrqPcwh9QMORc2Iyz6c2TydWutN+pdFX1HreFFIQRPtCe 6asDG6ipL0d9pxWRisEaO7QWXSTpMtFsQ8wq6wGYDNt8R+fiRMfF1tqH+4QG33YooA 8zYWcmkMK6WdgsDPJroDJnSGpOti1nyDNubfKLn38B8Jd29x0h+7xAwnMqcmuoMaFu P5g/HuH3dnHXNj+4nyCTQkrKO5TGaAjn4qL6EpJtVALD0TBFfJvNtGb6hBjwR/Bixc 05PaKuUNwtYsYz6NoC7C8V2sXF21gd+7QU55Gkg8+QKjNoPOWBH7/jl9lpbM3QV6ov qlHxohoxT/FxQ== From: Jeff Layton Date: Wed, 05 Nov 2025 11:53:54 -0500 Subject: [PATCH v5 08/17] 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: <20251105-dir-deleg-ro-v5-8-7ebc168a88ac@kernel.org> References: <20251105-dir-deleg-ro-v5-0-7ebc168a88ac@kernel.org> In-Reply-To: <20251105-dir-deleg-ro-v5-0-7ebc168a88ac@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=3106; i=jlayton@kernel.org; h=from:subject:message-id; bh=zBQyD4C+LOu4tUZSnzQKyrp9sE+YBQAdVnnbBh8HRrY=; b=kA0DAAoBAA5oQRlWghUByyZiAGkLgSzIfD1XscOsnPbbHAdNqYpqIdL5OUrLyaIN/CbYAXxBi IkCMwQAAQoAHRYhBEvA17JEcbKhhOr10wAOaEEZVoIVBQJpC4EsAAoJEAAOaEEZVoIVPJEP/3lu M+FOxIMmf5JXzwv8WAfgTWMjrkrQP2yNCluaH9t2WckVoCX8k2i8Z9IMk6RpcnurWyLeBC5yXs6 vrHXrDYq2iWwRWRFzsQLdNHNqw9quw8bC8sLzETQypmCMp+D3o/ntHc9r4vH8F7YyHqHOd/kZRq qZFRRJC1xJ5U4YKLRB+JIJBV66YX1fgka5hVROBLiLAr2EXsCltwld6M2TfXPB7UBaCZO1VlOmR t1UjhWuyHouL8fuU3BVV2jt290QTlk2TnDKkEDHtkvm/pY4kauWSu8UARWxnvCDV4OZnD59h5dm nJy0mV0/fNaGyV8x4bT6ml/E/q9b+jR2DDSGuwWWNShsVLAKJeYBKhEyugTZY2Uc/9Xt/TSofGs hjx38h2EERwrb7gRqjy/E9Nqjk4VKXveI+lLUCHY+38XiJ/2zOUabUQEIn+4XRsfktxC2pYejgD S4cwpuM4/sZCjTSxU3rsiQFYM7acpF/MpuHQFeeThhsK3Fv1TOTS6Q3qO9ae9DCpKH4I6zb/KSV slvwM336m0CeuS7VNysDj1OR0TIXiOtO2+jHaVvDhuY5KC4zaPwItijFDqwzQWG5BqWIisyKVko g7QAdM9U2L9YngwwsGWu7TFHDTZJEI6qHVyrSqm8MFc06Y6/ChRDZ8r4zB5nnCOv0HUh+8YkYLh Qe8AH X-Developer-Key: i=jlayton@kernel.org; a=openpgp; fpr=4BC0D7B24471B2A184EAF5D3000E684119568215 In order to add directory delegation support, we need to break delegations on the parent whenever there is going to be a change in the directory. Add a delegated_inode parameter to lookup_open and have it break the delegation. Then, open_last_lookups can wait for the delegation break and retry the call to lookup_open once it's done. Reviewed-by: Jan Kara Reviewed-by: NeilBrown Signed-off-by: Jeff Layton --- fs/namei.c | 22 ++++++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-) diff --git a/fs/namei.c b/fs/namei.c index 9e0393a92091ac522b5324fcdad8c5592a948e8d..f439429bdfa271ccc64c937771e= f4175597feb53 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 delegated_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) { @@ -3848,6 +3853,7 @@ static struct dentry *lookup_fast_for_open(struct nam= eidata *nd, int open_flag) static const char *open_last_lookups(struct nameidata *nd, struct file *file, const struct open_flags *op) { + struct delegated_inode delegated_inode =3D { }; struct dentry *dir =3D nd->path.dentry; int open_flag =3D op->open_flag; bool got_write =3D false; @@ -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 (is_delegated(&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.1 From nobody Fri Dec 19 14:23:26 2025 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id DCFF333B970; Wed, 5 Nov 2025 16:54:40 +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=1762361681; cv=none; b=ZdGCMo8mcepU6dNRo2ZWOSSFGGF2PEhjnB7dyAyU3MzRpmG8/jyFFeBLG8Rt/cTpxdDxak2ztCsy0lF2N1ZUp9RfCiET6X40pwkSFs59A7KreO+vIIpFFYGAFT7wY3amaP7v+h3aQC5kNzyDZxKtYWSXjBui69uOwg5EGFUN7wE= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1762361681; c=relaxed/simple; bh=4nVJZFd2d/Rjh95mS/P/b1sCz4UVYDxkm9LfEMOl0LY=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=DVnKIqnY98huPGfw2Yir2/ZY/pYz04DdWWDvztE5blDy1GpRLlOHowIfx8z24B20o9mO1YWaqe8aDfgZHNx8fAXWPoEKPFrt522nCCptDolfb66gkd1EeZlFDCAg1LvJv9qjAdeoSDnWAj6teqEn0Tn+TiW4D50D3aUzKuT5XX4= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=XWTpsunj; 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="XWTpsunj" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 2AE2BC4CEF5; Wed, 5 Nov 2025 16:54:37 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1762361680; bh=4nVJZFd2d/Rjh95mS/P/b1sCz4UVYDxkm9LfEMOl0LY=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=XWTpsunjrlrR9H3MKUO+WuoGhTKFe+gT5MuOtbcgVGCXgyxhMA5JD/TM1drbpyv/Z AbW/dSo0urwpWKJFhEYop+UkTdM2aodsuGooP5nSbxyM9WEN9UPnnMwQfJc4vEFtyg u2E/BDg+dJB/M7s3u1pVZt3Cs7QlYtInPUvl36lc10rXbntRhrpQ3QE3gK5JHaLnnU /DQwielOy+Csl3jPWU/WFl8U4FrezKCm9+I8rWPzeFxfTzBV6iCHb99mWy4vgJQ2oX FS3NE1NoO9Hdym8jMcNQpti+8xRpc77Hu9nyONLEPlCIyF5E6zrcWnn4nL5uwoeLK9 gadsJbiPPcuZw== From: Jeff Layton Date: Wed, 05 Nov 2025 11:53:55 -0500 Subject: [PATCH v5 09/17] vfs: clean up argument list for vfs_create() 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: <20251105-dir-deleg-ro-v5-9-7ebc168a88ac@kernel.org> References: <20251105-dir-deleg-ro-v5-0-7ebc168a88ac@kernel.org> In-Reply-To: <20251105-dir-deleg-ro-v5-0-7ebc168a88ac@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 , NeilBrown X-Mailer: b4 0.14.2 X-Developer-Signature: v=1; a=openpgp-sha256; l=6719; i=jlayton@kernel.org; h=from:subject:message-id; bh=4nVJZFd2d/Rjh95mS/P/b1sCz4UVYDxkm9LfEMOl0LY=; b=owEBbQKS/ZANAwAKAQAOaEEZVoIVAcsmYgBpC4EsSmf683IMJJEkFQDDeFR8KQ9kJOcPWCS9j Ld41lk/MnyJAjMEAAEKAB0WIQRLwNeyRHGyoYTq9dMADmhBGVaCFQUCaQuBLAAKCRAADmhBGVaC FSKWEADSYwweto3Ce2brU+Y+1k6HqzD/C/qVi8dORz9LzEbHPGW0a6q+7pxVRFbjIavSSUkor8T 9AWETxZVVdGV8psXf9+VAYWXIkdviyQmasv/ZbQC4jWVbRpwmqk/gV6BEItcu+BjtZm2sjZtxBT zcoSoNmNOBH1eDvhzsaejoXNvqn82d3UruM8AYdCsmnS36qO00MN7vxTxI/1APCf6NtSKTDpy2Y 77Bf89BEZfSTCCm3b4irIMnCetkQFz/5UZKjJIPgZ1cHwGp25xBWb4ZnpN2uWrykf4Lqew5YKkp G+UovgCywrg97O8D5+nnr9GfAfToGvvSGyr9yvHbz2O8n5XgNpnKkubXsx+izh6y9lW+ScvbNmj dWNxOJVPk/0pBUTJkcXIixt8dGBX1o1gkOaNuib65t2g85UJqNKL2IYhbHFyhIwORt7RLFite+S EMmLnQNrwF2NTtkXrk1DLVyXrQ7Ip2et+/FLGyDK4Hz97lsDpCe4EKnq75WnTasQqyQw0AR9QIA +B0tFN9gyA8hYJ6v1bvaYAUIR7HcbURu6Lhb5qVW/dlJrV1k6qkQzzcqXhDFH2kEJyNIDjS+W7T 6WQAtrwcct9BZ4smbdBOeW9ISyQgpqjqd+eU1qrYAWTg7+WWrGhExXQ3hgl84fQmgosNyZACiA2 40LOJJKY7nDVlGA== X-Developer-Key: i=jlayton@kernel.org; a=openpgp; fpr=4BC0D7B24471B2A184EAF5D3000E684119568215 As Neil points out: "I would be in favour of dropping the "dir" arg because it is always d_inode(dentry->d_parent) which is stable." ...and... "Also *every* caller of vfs_create() passes ".excl =3D true". So maybe we don't need that arg at all." Drop both arguments from vfs_create() and fix up the callers. Suggested-by: NeilBrown Signed-off-by: Jeff Layton Reviewed-by: Jan Kara Reviewed-by: NeilBrown --- fs/ecryptfs/inode.c | 3 +-- fs/namei.c | 11 ++++------- fs/nfsd/nfs3proc.c | 2 +- fs/nfsd/vfs.c | 3 +-- fs/open.c | 4 +--- fs/overlayfs/overlayfs.h | 2 +- fs/smb/server/vfs.c | 3 +-- include/linux/fs.h | 3 +-- 8 files changed, 11 insertions(+), 20 deletions(-) diff --git a/fs/ecryptfs/inode.c b/fs/ecryptfs/inode.c index 88631291b32535f623a3fbe4ea9b6ed48a306ca0..d109e3763a88150bfe64cd2d556= 4dc9802ef3386 100644 --- a/fs/ecryptfs/inode.c +++ b/fs/ecryptfs/inode.c @@ -188,8 +188,7 @@ ecryptfs_do_create(struct inode *directory_inode, =20 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); + rc =3D vfs_create(&nop_mnt_idmap, lower_dentry, mode); 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 f439429bdfa271ccc64c937771ef4175597feb53..9586c6aba6eae05a9fc3c103b85= 01d98767bef53 100644 --- a/fs/namei.c +++ b/fs/namei.c @@ -3461,10 +3461,8 @@ static inline umode_t vfs_prepare_mode(struct mnt_id= map *idmap, /** * 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 * * Create a new file. * @@ -3474,9 +3472,9 @@ static inline umode_t vfs_prepare_mode(struct mnt_idm= ap *idmap, * On non-idmapped mounts or if permission checking is to be performed on = the * 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) +int vfs_create(struct mnt_idmap *idmap, struct dentry *dentry, umode_t mod= e) { + struct inode *dir =3D d_inode(dentry->d_parent); int error; =20 error =3D may_create(idmap, dir, dentry); @@ -3490,7 +3488,7 @@ int vfs_create(struct mnt_idmap *idmap, struct inode = *dir, error =3D security_inode_create(dir, dentry, mode); if (error) return error; - error =3D dir->i_op->create(idmap, dir, dentry, mode, want_excl); + error =3D dir->i_op->create(idmap, dir, dentry, mode, true); if (!error) fsnotify_create(dir, dentry); return error; @@ -4383,8 +4381,7 @@ static int do_mknodat(int dfd, struct filename *name,= umode_t mode, idmap =3D mnt_idmap(path.mnt); switch (mode & S_IFMT) { case 0: case S_IFREG: - error =3D vfs_create(idmap, path.dentry->d_inode, - dentry, mode, true); + error =3D vfs_create(idmap, dentry, mode); if (!error) security_path_post_mknod(idmap, dentry); break; diff --git a/fs/nfsd/nfs3proc.c b/fs/nfsd/nfs3proc.c index b6d03e1ef5f7a5e8dd111b0d56c061f1e91abff7..30ea7ffa2affdb9a959b0fd15a6= 30de056d6dc3c 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, child, iap->ia_mode); if (host_err < 0) { status =3D nfserrno(host_err); goto out; diff --git a/fs/nfsd/vfs.c b/fs/nfsd/vfs.c index c400ea94ff2e837fd59719bf2c4b79ef1d064743..464fd54675f3b16fce9ae5f05ad= 22e0e6b363eb3 100644 --- a/fs/nfsd/vfs.c +++ b/fs/nfsd/vfs.c @@ -1552,8 +1552,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, dchild, iap->ia_mode); if (!host_err) nfsd_check_ignore_resizing(iap); break; diff --git a/fs/open.c b/fs/open.c index fdaa6f08f6f4cac5c2fefd3eafa5e430e51f3979..e440f58e3ce81e137aabdf00510= d839342a19219 100644 --- a/fs/open.c +++ b/fs/open.c @@ -1171,9 +1171,7 @@ struct file *dentry_create(const struct path *path, i= nt flags, umode_t mode, if (IS_ERR(f)) return f; =20 - error =3D vfs_create(mnt_idmap(path->mnt), - d_inode(path->dentry->d_parent), - path->dentry, mode, true); + error =3D vfs_create(mnt_idmap(path->mnt), path->dentry, mode); if (!error) error =3D vfs_open(path, f); =20 diff --git a/fs/overlayfs/overlayfs.h b/fs/overlayfs/overlayfs.h index d215d7349489686b66bb66e939b27046f7d836f6..2bdc434941ebc70f6d4f57cca4f= 68125112a7bc4 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), dentry, mode); =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..83ece2de4b23bf9209137e7ca41= 4a72439b5cc2e 100644 --- a/fs/smb/server/vfs.c +++ b/fs/smb/server/vfs.c @@ -188,8 +188,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); + err =3D vfs_create(mnt_idmap(path.mnt), dentry, mode); 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 12873214e1c7811735ea5d2dee3d57e2a5604d8f..21876ef1fec90181b9878372c7c= 7e710773aae9f 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h @@ -2111,8 +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); +int vfs_create(struct mnt_idmap *, struct dentry *, umode_t); struct dentry *vfs_mkdir(struct mnt_idmap *, struct inode *, struct dentry *, umode_t, struct delegated_inode *); int vfs_mknod(struct mnt_idmap *, struct inode *, struct dentry *, --=20 2.51.1 From nobody Fri Dec 19 14:23:26 2025 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 3FEF1346E52; Wed, 5 Nov 2025 16:54:43 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1762361684; cv=none; b=bAfK/fEs3I35F8JNZDW4SvpkPpwbuFUhz0Z7mJ0X4rPEXEuGM5bAg68Xy23Glj+x8H+yvUfM1ylbmCASP7L1wY+5ATVdMcso1F7j/s6gId4UHAraYfNH+btCgwdux1odPYeQiit8ETaZ8XJxfBa1djlACBHb/Hx3NP5VsEB7jBQ= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1762361684; c=relaxed/simple; bh=lN/bhsS6C0iz3//+qsII4EritkMB9eULzkMq+tuTUUM=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=btmD5u1/sTFFa8YgN5EQLYby6JVY6t6FYI4ZdXrNtI5aSe2lLJ15a3PA5BXZ7TX7QSKBNj3ucMzfxEmD8EGNL6Pcc+5OD0h+dJT9SOoa4/vyflZYxr8ydBHr9hdEHCupQjstkRnZ0ed2k0854S2JYfdxPmIQJPEpqrsTBw5lgA8= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=ITvJ9JY3; 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="ITvJ9JY3" Received: by smtp.kernel.org (Postfix) with ESMTPSA id A657EC4CEF8; Wed, 5 Nov 2025 16:54:40 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1762361683; bh=lN/bhsS6C0iz3//+qsII4EritkMB9eULzkMq+tuTUUM=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=ITvJ9JY3lYnCgMQ9zea+jQrd2q6kq+NkqbG4XRWeK0AUI2K72p9nZvY+72gtxo4AN nY2r2CASA2LUsUu0O7WnuZgdBfPZ/xHWJ5HxrAHF6yQP+UsVba9KnYxWXrmaKAvQoM FdzHMfSk/L+x1Ea2VTRNx+1LQ1YsY8odZqjRvz4z/DHrKii1IlD+A+X6ntWxdW8qU4 vORZK4Ije+1mwOnwkgZ9aE83UbWmU9rJcEyYMocP7ZddJuljT0pAieN4N7COHiWiP6 O0GuaiUd4r8XoOdnquSz82YVm2/GkyQzO1QLKaRjVk3EYRS878wNbEYjLDEcN5sFh4 MGEksl/rweh8w== From: Jeff Layton Date: Wed, 05 Nov 2025 11:53:56 -0500 Subject: [PATCH v5 10/17] 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: <20251105-dir-deleg-ro-v5-10-7ebc168a88ac@kernel.org> References: <20251105-dir-deleg-ro-v5-0-7ebc168a88ac@kernel.org> In-Reply-To: <20251105-dir-deleg-ro-v5-0-7ebc168a88ac@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=7095; i=jlayton@kernel.org; h=from:subject:message-id; bh=lN/bhsS6C0iz3//+qsII4EritkMB9eULzkMq+tuTUUM=; b=owEBbQKS/ZANAwAKAQAOaEEZVoIVAcsmYgBpC4EsGBpNNEVl3f7Yuoe1m8iaqJoxfdKIel9od si+inDUwbiJAjMEAAEKAB0WIQRLwNeyRHGyoYTq9dMADmhBGVaCFQUCaQuBLAAKCRAADmhBGVaC FTRhD/9VEezVvF0Z3nEJPUotQyPXaZ15ENNl3mZiatIm/jaYcwzSNv6pU5kElv2DT+k017YHWCq DSBOxR2Uo10CrRjkoroT5NITg1i88Aadrrlpqd2oCidQgYt6ckeXNKWpJOwJnl0XBRviav4UXJm UouDxHefnFaOeRWh9EpjvvES1dPXVDriFRosfQ03nszcG5rFUHDkKeQ4zb42eAqs19sl16B0Vri Vyy7QsBVlRSnmzfgA4JOC2ZvMd2+DubwaObFEicYsSdX674FepfP4zHXuvI8VNLY/Ixu2Zgz5SX jGc79pjR6prrGRpzqNESGuhEGaSJ8fW/DqTq6uZLws8H74S2w3MiCmCXSxc215D9UKXYAV4/DXr B8BlrpsdNQBd33k2b/4FQjeUig94ySfdAcHXdu/dvkaExViWTu6AYbvr5UF0i2YtXJo2pj5GFmj H0syqi2W7u6farEaF5FNXm/MkNcUelqLNvYjNemr34frrlV5CNUdaEdD9nBnXIkmjQgKDWI3faT DyHFIqOLdYq2UHKrWx1bYbIwevgxBTK/ymJXBt+usZORssxfDpUJYEgGYX3MvgWBr1ZmGgUuvzI pEfumkHh1289bVLWMBwgPsqkHHW0jJY5oSfa8SpQbyNARLMcnM9Y1+kwAza5g6xVRkHCpwIbSsH VCBttzLCcK8jG2A== X-Developer-Key: i=jlayton@kernel.org; a=openpgp; fpr=4BC0D7B24471B2A184EAF5D3000E684119568215 In order to add directory delegation support, we need to break delegations on the parent whenever there is going to be a change in the directory. Add a delegated_inode parameter to vfs_create. Most callers are converted to pass in NULL, but do_mknodat() is changed to wait for a delegation break if there is one. Reviewed-by: Jan Kara Reviewed-by: NeilBrown Signed-off-by: Jeff Layton --- fs/ecryptfs/inode.c | 2 +- fs/namei.c | 15 +++++++++++++-- fs/nfsd/nfs3proc.c | 2 +- fs/nfsd/vfs.c | 2 +- fs/open.c | 2 +- fs/overlayfs/overlayfs.h | 2 +- fs/smb/server/vfs.c | 2 +- include/linux/fs.h | 3 ++- 8 files changed, 21 insertions(+), 9 deletions(-) diff --git a/fs/ecryptfs/inode.c b/fs/ecryptfs/inode.c index d109e3763a88150bfe64cd2d5564dc9802ef3386..3341f00dd08753c8feab184dd82= b8bfa63d3724a 100644 --- a/fs/ecryptfs/inode.c +++ b/fs/ecryptfs/inode.c @@ -188,7 +188,7 @@ ecryptfs_do_create(struct inode *directory_inode, =20 rc =3D lock_parent(ecryptfs_dentry, &lower_dentry, &lower_dir); if (!rc) - rc =3D vfs_create(&nop_mnt_idmap, lower_dentry, mode); + rc =3D vfs_create(&nop_mnt_idmap, lower_dentry, mode, 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 9586c6aba6eae05a9fc3c103b8501d98767bef53..b20f053374a578d36fb764e0df8= 0fb7db9230dbe 100644 --- a/fs/namei.c +++ b/fs/namei.c @@ -3463,6 +3463,7 @@ static inline umode_t vfs_prepare_mode(struct mnt_idm= ap *idmap, * @idmap: idmap of the mount the inode was found from * @dentry: dentry of the child file * @mode: mode of the child file + * @di: returns parent inode, if the inode is delegated. * * Create a new file. * @@ -3472,7 +3473,8 @@ static inline umode_t vfs_prepare_mode(struct mnt_idm= ap *idmap, * On non-idmapped mounts or if permission checking is to be performed on = the * raw inode simply pass @nop_mnt_idmap. */ -int vfs_create(struct mnt_idmap *idmap, struct dentry *dentry, umode_t mod= e) +int vfs_create(struct mnt_idmap *idmap, struct dentry *dentry, umode_t mod= e, + struct delegated_inode *di) { struct inode *dir =3D d_inode(dentry->d_parent); int error; @@ -3486,6 +3488,9 @@ int vfs_create(struct mnt_idmap *idmap, struct dentry= *dentry, umode_t mode) =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, di); if (error) return error; error =3D dir->i_op->create(idmap, dir, dentry, mode, true); @@ -4358,6 +4363,7 @@ static int may_mknod(umode_t mode) static int do_mknodat(int dfd, struct filename *name, umode_t mode, unsigned int dev) { + struct delegated_inode di =3D { }; struct mnt_idmap *idmap; struct dentry *dentry; struct path path; @@ -4381,7 +4387,7 @@ static int do_mknodat(int dfd, struct filename *name,= umode_t mode, idmap =3D mnt_idmap(path.mnt); switch (mode & S_IFMT) { case 0: case S_IFREG: - error =3D vfs_create(idmap, dentry, mode); + error =3D vfs_create(idmap, dentry, mode, &di); if (!error) security_path_post_mknod(idmap, dentry); break; @@ -4396,6 +4402,11 @@ static int do_mknodat(int dfd, struct filename *name= , umode_t mode, } out2: end_creating_path(&path, dentry); + if (is_delegated(&di)) { + error =3D break_deleg_wait(&di); + 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 30ea7ffa2affdb9a959b0fd15a630de056d6dc3c..2cb972b5ed994d69995146aeeac= 8651c1c04fa46 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, child, iap->ia_mode); + host_err =3D vfs_create(&nop_mnt_idmap, child, iap->ia_mode, 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 464fd54675f3b16fce9ae5f05ad22e0e6b363eb3..de5f46f8c6d3ab24fabddeed9bd= 59adbe7a486df 100644 --- a/fs/nfsd/vfs.c +++ b/fs/nfsd/vfs.c @@ -1552,7 +1552,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, dchild, iap->ia_mode); + host_err =3D vfs_create(&nop_mnt_idmap, dchild, iap->ia_mode, NULL); if (!host_err) nfsd_check_ignore_resizing(iap); break; diff --git a/fs/open.c b/fs/open.c index e440f58e3ce81e137aabdf00510d839342a19219..92cf2e11781b0efd16fe0b75128= 6ce943ea6b4e2 100644 --- a/fs/open.c +++ b/fs/open.c @@ -1171,7 +1171,7 @@ struct file *dentry_create(const struct path *path, i= nt flags, umode_t mode, if (IS_ERR(f)) return f; =20 - error =3D vfs_create(mnt_idmap(path->mnt), path->dentry, mode); + error =3D vfs_create(mnt_idmap(path->mnt), path->dentry, mode, NULL); if (!error) error =3D vfs_open(path, f); =20 diff --git a/fs/overlayfs/overlayfs.h b/fs/overlayfs/overlayfs.h index 2bdc434941ebc70f6d4f57cca4f68125112a7bc4..e30441cc9c63ff8b6c055db80be= 7974501d0023b 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), dentry, mode); + int err =3D vfs_create(ovl_upper_mnt_idmap(ofs), dentry, mode, 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 83ece2de4b23bf9209137e7ca414a72439b5cc2e..3747851b61c8bad4c00e49866c3= 80c32e9f53a4b 100644 --- a/fs/smb/server/vfs.c +++ b/fs/smb/server/vfs.c @@ -188,7 +188,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), dentry, mode); + err =3D vfs_create(mnt_idmap(path.mnt), dentry, mode, 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 21876ef1fec90181b9878372c7c7e710773aae9f..83b05aec4e10c846d3168018fb6= 2284e45ceb1a8 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h @@ -2111,7 +2111,8 @@ bool inode_owner_or_capable(struct mnt_idmap *idmap, /* * VFS helper functions.. */ -int vfs_create(struct mnt_idmap *, struct dentry *, umode_t); +int vfs_create(struct mnt_idmap *, struct dentry *, umode_t, + struct delegated_inode *); struct dentry *vfs_mkdir(struct mnt_idmap *, struct inode *, struct dentry *, umode_t, struct delegated_inode *); int vfs_mknod(struct mnt_idmap *, struct inode *, struct dentry *, --=20 2.51.1 From nobody Fri Dec 19 14:23:26 2025 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id A81C7347FE7; Wed, 5 Nov 2025 16:54:47 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1762361687; cv=none; b=pbWnois6KZYXlXupCJX7O+A1dwtphsPAGhZAX+B4DOnjJltVSTQZhUng9ue+01jXvC4BPixOB5A5BscceiBXsETqaCjnCD0ofiLcjk7m61urZ8yswUEJ0eZx6gjt4eikJ009LRzM4udl0WqHJC3nPOFy+m0Ja7NWB+DrcDdab3Q= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1762361687; c=relaxed/simple; bh=enwRSJtPuTCJax9ReM6vLhCWhCDrTpDxateSqGDz3Cs=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=TRB7L7ZV5uGus2rTmF8rQn1yT8WCd1stHHDTRf0EqV9WvicLfpgXH0U61nRmwN2BAWGLhy0IMyHhtj0JHOZ3F5WueBjbrXpHic6wumovuHv1zGH0VADa7wteo9UzXZc2u5A3C6yyN/Rdn/y3qyi62jl4+R9KWbN8ICEEmbweNfo= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=eY9wqaZT; 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="eY9wqaZT" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 1AEC8C4CEF5; Wed, 5 Nov 2025 16:54:44 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1762361687; bh=enwRSJtPuTCJax9ReM6vLhCWhCDrTpDxateSqGDz3Cs=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=eY9wqaZTGXiMaYlGu6x40FbDllAugWb9R3dizymjdrIogos1md+U9eF5bSF4HRwYx D9uO8wXvGW6DkQ3ra7lseTnfHYBof73gcdauTvSs18i9fSQy0HNd0/woHRCQ+zyttv bkLWwktaRr+ZodyIkpvoMf0GapxrK3TGimNKCoTlaJLWDt7IlrKbF3OSpJCDXCo7HJ 8Pjduc3f5nQSOt91L9UR8re0WT3JuasxMM+3bhWpeui+g1AL/SWYpfQDvMR+07K/V+ I7FPw9wLd3cYoP/gZC2GEpV43sLffaAjWnnEtdZO20SXCS2Mdsa8FpllDQbmVPtrbw k/NgJGRZwGZJQ== From: Jeff Layton Date: Wed, 05 Nov 2025 11:53:57 -0500 Subject: [PATCH v5 11/17] 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: <20251105-dir-deleg-ro-v5-11-7ebc168a88ac@kernel.org> References: <20251105-dir-deleg-ro-v5-0-7ebc168a88ac@kernel.org> In-Reply-To: <20251105-dir-deleg-ro-v5-0-7ebc168a88ac@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=7475; i=jlayton@kernel.org; h=from:subject:message-id; bh=enwRSJtPuTCJax9ReM6vLhCWhCDrTpDxateSqGDz3Cs=; b=owEBbQKS/ZANAwAKAQAOaEEZVoIVAcsmYgBpC4EsKClzzmFe3+aVQaOdkV21j38hqbV9HdNa5 8gtElydNtyJAjMEAAEKAB0WIQRLwNeyRHGyoYTq9dMADmhBGVaCFQUCaQuBLAAKCRAADmhBGVaC FVKgEAC3o3liCkhkHJrxsl59eWlDlPOWm2a1UAd/3qGurTt7bUYnYyLLTDfOCcD8ustraVHy7it RMrER4nZ89a8fDi8fdJ0jsmn0m3KDdDIEqqQAkkIR/+sen05pNx095o3NvyE2N+Ob9d6uZuzfH6 7Akk/3e7Ru+CrAkmLoozJR5W+8ErgxhaqJEt5n2gs0WEV3T9k+uqxUc9VoAY0yjng4ApoOzEXsI DEG6LaK7CY266/XX0MAoY2zbTwZAP0yRQhNOxCj33ePAqH8kRBB3joeVq+9Ahz7hcf9geiaVfbX aajAv/2igKPh0Cf27z2hjzHL92Z+eahsHKILyrJ1id1F40Qfu36Ii7gVKEJInifjBdHgmySsvyp K/UgqSeLWE5HBVBR3Svad3hG1tXKDxosWxIrfW67k9WPwf2+sVCUgkarWZS7+lT86X/slamJ22/ N+TD2gtcUt/zTmGDiOMf5QYugivWCVFnouj9HsGnQcv2Pq1MNsvMLS27T7JyUAEILi4aOfgaRs5 vr4rEDO6tle3EOkFbcaETafiDvVByRMhAbjXQnjdwYFBPwW9780QxfVzMN3hmsEBAVWn0isOxiv hflVLKU8b35tB+GTlPz0wsMFO8f5qV4y9Cde5yYyH+gxi7UOfb2f6yB7Jhm2Ud8vXGvi6UrQJX5 ZWBODeDqJV47jAw== 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 pointer to vfs_mknod() and have the appropriate callers wait when there is an outstanding delegation. All other callers just set the pointer to NULL. Reviewed-by: Jan Kara Reviewed-by: NeilBrown Signed-off-by: Jeff Layton --- drivers/base/devtmpfs.c | 2 +- fs/ecryptfs/inode.c | 2 +- fs/init.c | 2 +- fs/namei.c | 23 +++++++++++++++-------- fs/nfsd/vfs.c | 2 +- fs/overlayfs/overlayfs.h | 2 +- include/linux/fs.h | 4 ++-- net/unix/af_unix.c | 2 +- 8 files changed, 23 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 3341f00dd08753c8feab184dd82b8bfa63d3724a..83f06452476dec4025cc8f50e08= 2ae6ccbbc7914 100644 --- a/fs/ecryptfs/inode.c +++ b/fs/ecryptfs/inode.c @@ -564,7 +564,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 b20f053374a578d36fb764e0df80fb7db9230dbe..e9616134390fb7f0d09a759be69= bf677f8800bc5 100644 --- a/fs/namei.c +++ b/fs/namei.c @@ -4295,13 +4295,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. * @@ -4312,7 +4314,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 delegated_inode *delegated_inode) { bool is_whiteout =3D S_ISCHR(mode) && dev =3D=3D WHITEOUT_DEV; int error =3D may_create(idmap, dir, dentry); @@ -4336,6 +4339,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); @@ -4393,11 +4400,11 @@ 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), &di); break; case S_IFIFO: case S_IFSOCK: error =3D vfs_mknod(idmap, path.dentry->d_inode, - dentry, mode, 0); + dentry, mode, 0, &di); break; } out2: diff --git a/fs/nfsd/vfs.c b/fs/nfsd/vfs.c index de5f46f8c6d3ab24fabddeed9bd59adbe7a486df..6684935007b17ed40723ff0a744= 045fd187ace5e 100644 --- a/fs/nfsd/vfs.c +++ b/fs/nfsd/vfs.c @@ -1573,7 +1573,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 e30441cc9c63ff8b6c055db80be7974501d0023b..afd95721f76ea761cfe7133c390= 2028550f3e359 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 83b05aec4e10c846d3168018fb62284e45ceb1a8..1a5d86cfafaa97fc89d15cd1a15= 6968b8c3dd377 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h @@ -2116,7 +2116,7 @@ int vfs_create(struct mnt_idmap *, struct dentry *, u= mode_t, struct dentry *vfs_mkdir(struct mnt_idmap *, struct inode *, struct dentry *, umode_t, struct delegated_inode *); int vfs_mknod(struct mnt_idmap *, struct inode *, struct dentry *, - umode_t, dev_t); + umode_t, dev_t, struct delegated_inode *); int vfs_symlink(struct mnt_idmap *, struct inode *, struct dentry *, const char *); int vfs_link(struct dentry *, struct mnt_idmap *, struct inode *, @@ -2152,7 +2152,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.1 From nobody Fri Dec 19 14:23:26 2025 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 250A234B1AC; Wed, 5 Nov 2025 16:54:50 +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=1762361692; cv=none; b=Qk7qJghDuFVOTz7fEtI+kv8jx3vZExzOugjm1fAmoB/HUP2X7loxKuEsl6jiTEXq5F7w+FVHWpHT69WOYtLSXweK3KzfdGR4BjuvIFA8AKgyzNf0/hdkgRrR5ska/n6FdBrqr7gPL+Hd+CWsnOn87VZh2Bue+BN275k8DHrPpBA= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1762361692; c=relaxed/simple; bh=J0QOs1yYKO976WkbjbVTMOts98MrgGnpdHVhMu0ydug=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=M3cmZJkx8IE2IjjwHcNfRf6aNMB31qSyL49YzDnIZ39GXNNA5ypJwVVf5msWG0TMZlsWGSFGXqQ8G0gvVsN3FcGK164QP0qxUAarJsxOzpDTHdLLn69Fy8gJ1zoxAtkpdQewMbxVzzFJWmh1QUrDotwg50yyVrROp02IXK9UlNI= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=Lz3ZoRpZ; 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="Lz3ZoRpZ" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 82A08C4CEF8; Wed, 5 Nov 2025 16:54:47 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1762361690; bh=J0QOs1yYKO976WkbjbVTMOts98MrgGnpdHVhMu0ydug=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=Lz3ZoRpZt3rujfl4kXxHqjXMYsZ5b8CpLjSaKKn3jwrhfo6Btx29lGJVPWdGUgTIA hP4zKJikAj9ztTuRFSUARrXg/hRj4R9faRnlC7HcnKR8cqIQ3FnZV3IP3L/8KfJaz+ azDNQqBCiNuLtEx86AfdoZsocgdprekIqeGFI4YGoAOl3/BHm6z5CywUCKZO8kpbMA ZrjTLKtpKjvFbvii5iwf1VgD8qAnBVjC32HHZugBIsMpwNxyiZf0ZmhKCWjm6M6jha SR/VkCnKZcvNrSZwpziLNsPJz7J9WOZTRYpJOMsVwZ5fzz6IA4RTwyASYux2mK8Yz0 QWZJvx+euDxLQ== From: Jeff Layton Date: Wed, 05 Nov 2025 11:53:58 -0500 Subject: [PATCH v5 12/17] vfs: make vfs_symlink break delegations on parent dir Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20251105-dir-deleg-ro-v5-12-7ebc168a88ac@kernel.org> References: <20251105-dir-deleg-ro-v5-0-7ebc168a88ac@kernel.org> In-Reply-To: <20251105-dir-deleg-ro-v5-0-7ebc168a88ac@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=5708; i=jlayton@kernel.org; h=from:subject:message-id; bh=J0QOs1yYKO976WkbjbVTMOts98MrgGnpdHVhMu0ydug=; b=owEBbQKS/ZANAwAKAQAOaEEZVoIVAcsmYgBpC4Eskg4XkSvabUSBnpqakaub2rvmBNpOYR8iD TVcpj0x7rOJAjMEAAEKAB0WIQRLwNeyRHGyoYTq9dMADmhBGVaCFQUCaQuBLAAKCRAADmhBGVaC Fd1BEAClj5dA2kD7PSJEz+ptBhsPLDqcYFNvAxxcn3VyXJJgQG3/XneRmGDmz2iqLWzIeqcLkgj UqSq78IgAI434yjw8J+OYzfibzv0f86F+B/F44J/B/iVwEi+49FD52ZaXy14cguH+bg009sph1b VBHccCWud68gZonoAb9OvsNIAuwNfWRUzrHJOROFTLz+7k8crMMjS8iXaw1zMIY9JsKKrppf13G /xKv7pvrZgSHLTz7I7SkoDX7TeAR6vxDbN2OaPKUev1iKUdjdFedckVitT/elR4HpscuaWsxT3d DNnNc2yg3nSjnPeOLbagKls/zJra3rYxlzIE78lUNnnzJFZxIbwezkwrg5ApDog5Bbq8zbLQS+g 7Bp+eq7cz7kj0HQGdTabyTl0zBVbwDS/nikYtto6dqXmUkoI63qBDoFbatprgRtiqHk526ZPyb6 D+Dfe9xMdF9wofGBz6ngTlsaCbK86DkMv1IrnKuxsJ/YyFBuSGy/wPzPFohcvVcIcm0aoLokVSM uajA+MUo2oBjd1ivrJMeYDIo9BTa40eoLgZWkj04JppT66wxHagdAvWjNPKAvzZUaBsRTMfuF6/ VPjhk/MnHwscAoVmi319IluZj3EPAx6uHHlWyxZ3XlDPdKaYU+sRamWdI9jE6CO6VEOH7zjilTU bX8MdhQz6lZSLbw== X-Developer-Key: i=jlayton@kernel.org; a=openpgp; fpr=4BC0D7B24471B2A184EAF5D3000E684119568215 In order to add directory delegation support, we must break delegations on the parent on any change to the directory. Add a delegated_inode parameter to vfs_symlink() and have it break the delegation. do_symlinkat() can then wait on the delegation break before proceeding. Reviewed-by: Jan Kara Reviewed-by: NeilBrown Signed-off-by: Jeff Layton --- fs/ecryptfs/inode.c | 2 +- fs/init.c | 2 +- fs/namei.c | 16 ++++++++++++++-- fs/nfsd/vfs.c | 2 +- fs/overlayfs/overlayfs.h | 2 +- include/linux/fs.h | 2 +- 6 files changed, 19 insertions(+), 7 deletions(-) diff --git a/fs/ecryptfs/inode.c b/fs/ecryptfs/inode.c index 83f06452476dec4025cc8f50e082ae6ccbbc7914..ba15e7359dfa6e150b577205991= 010873a633511 100644 --- a/fs/ecryptfs/inode.c +++ b/fs/ecryptfs/inode.c @@ -479,7 +479,7 @@ static int ecryptfs_symlink(struct mnt_idmap *idmap, if (rc) goto out_lock; rc =3D vfs_symlink(&nop_mnt_idmap, lower_dir, lower_dentry, - encoded_symname); + encoded_symname, NULL); kfree(encoded_symname); if (rc || d_really_is_negative(lower_dentry)) goto out_lock; diff --git a/fs/init.c b/fs/init.c index 4f02260dd65b0dfcbfbf5812d2ec6a33444a3b1f..e0f5429c0a49d046bd3f231a260= 954ed0f90ef44 100644 --- a/fs/init.c +++ b/fs/init.c @@ -209,7 +209,7 @@ int __init init_symlink(const char *oldname, const char= *newname) error =3D security_path_symlink(&path, dentry, oldname); if (!error) error =3D vfs_symlink(mnt_idmap(path.mnt), path.dentry->d_inode, - dentry, oldname); + dentry, oldname, NULL); end_creating_path(&path, dentry); return error; } diff --git a/fs/namei.c b/fs/namei.c index e9616134390fb7f0d09a759be69bf677f8800bc5..d5ab28947b2b6c6e19c7bb4a914= 0ccec407dc07c 100644 --- a/fs/namei.c +++ b/fs/namei.c @@ -4845,6 +4845,7 @@ SYSCALL_DEFINE1(unlink, const char __user *, pathname) * @dir: inode of the parent directory * @dentry: dentry of the child symlink file * @oldname: name of the file to link to + * @delegated_inode: returns victim inode, if the inode is delegated. * * Create a symlink. * @@ -4855,7 +4856,8 @@ SYSCALL_DEFINE1(unlink, const char __user *, pathname) * raw inode simply pass @nop_mnt_idmap. */ int vfs_symlink(struct mnt_idmap *idmap, struct inode *dir, - struct dentry *dentry, const char *oldname) + struct dentry *dentry, const char *oldname, + struct delegated_inode *delegated_inode) { int error; =20 @@ -4870,6 +4872,10 @@ int vfs_symlink(struct mnt_idmap *idmap, struct inod= e *dir, if (error) return error; =20 + error =3D try_break_deleg(dir, delegated_inode); + if (error) + return error; + error =3D dir->i_op->symlink(idmap, dir, dentry, oldname); if (!error) fsnotify_create(dir, dentry); @@ -4883,6 +4889,7 @@ int do_symlinkat(struct filename *from, int newdfd, s= truct filename *to) struct dentry *dentry; struct path path; unsigned int lookup_flags =3D 0; + struct delegated_inode delegated_inode =3D { }; =20 if (IS_ERR(from)) { error =3D PTR_ERR(from); @@ -4897,8 +4904,13 @@ int do_symlinkat(struct filename *from, int newdfd, = struct filename *to) error =3D security_path_symlink(&path, dentry, from->name); if (!error) error =3D vfs_symlink(mnt_idmap(path.mnt), path.dentry->d_inode, - dentry, from->name); + dentry, from->name, &delegated_inode); end_creating_path(&path, dentry); + if (is_delegated(&delegated_inode)) { + error =3D break_deleg_wait(&delegated_inode); + if (!error) + goto retry; + } if (retry_estale(error, lookup_flags)) { lookup_flags |=3D LOOKUP_REVAL; goto retry; diff --git a/fs/nfsd/vfs.c b/fs/nfsd/vfs.c index 6684935007b17ed40723ff0a744045fd187ace5e..28710da4cce7cc7fc1e14d29420= 239dc357316f6 100644 --- a/fs/nfsd/vfs.c +++ b/fs/nfsd/vfs.c @@ -1742,7 +1742,7 @@ nfsd_symlink(struct svc_rqst *rqstp, struct svc_fh *f= hp, err =3D fh_fill_pre_attrs(fhp); if (err !=3D nfs_ok) goto out_unlock; - host_err =3D vfs_symlink(&nop_mnt_idmap, d_inode(dentry), dnew, path); + host_err =3D vfs_symlink(&nop_mnt_idmap, d_inode(dentry), dnew, path, NUL= L); err =3D nfserrno(host_err); cerr =3D fh_compose(resfhp, fhp->fh_export, dnew, fhp); if (!err) diff --git a/fs/overlayfs/overlayfs.h b/fs/overlayfs/overlayfs.h index afd95721f76ea761cfe7133c3902028550f3e359..5065961bd370628c9afe914ea57= 0d9998a096660 100644 --- a/fs/overlayfs/overlayfs.h +++ b/fs/overlayfs/overlayfs.h @@ -267,7 +267,7 @@ static inline int ovl_do_symlink(struct ovl_fs *ofs, struct inode *dir, struct dentry *dentry, const char *oldname) { - int err =3D vfs_symlink(ovl_upper_mnt_idmap(ofs), dir, dentry, oldname); + int err =3D vfs_symlink(ovl_upper_mnt_idmap(ofs), dir, dentry, oldname, N= ULL); =20 pr_debug("symlink(\"%s\", %pd2) =3D %i\n", oldname, dentry, err); return err; diff --git a/include/linux/fs.h b/include/linux/fs.h index 1a5d86cfafaa97fc89d15cd1a156968b8c3dd377..64323e618724bc20dc101db1303= 5b042f5f88e4d 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h @@ -2118,7 +2118,7 @@ struct dentry *vfs_mkdir(struct mnt_idmap *, struct i= node *, int vfs_mknod(struct mnt_idmap *, struct inode *, struct dentry *, umode_t, dev_t, struct delegated_inode *); int vfs_symlink(struct mnt_idmap *, struct inode *, - struct dentry *, const char *); + struct dentry *, const char *, struct delegated_inode *); int vfs_link(struct dentry *, struct mnt_idmap *, struct inode *, struct dentry *, struct delegated_inode *); int vfs_rmdir(struct mnt_idmap *, struct inode *, struct dentry *, --=20 2.51.1 From nobody Fri Dec 19 14:23:26 2025 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 414F934B662; Wed, 5 Nov 2025 16:54:54 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1762361694; cv=none; b=O0TfdinASDTxC4IvP7NlkfhHty3zX+thEMDt3JzQVj7ZiMshddPh+V5j6pegKjRBJUO/e0Ma477b+c91KJv97BSc1Er8pR2y4eG29wlxFf88il9t7zNav++SARF20X0gw+1QffwzKcJSE5mcljZqViq2BoB9kJDPvZJa6M56XGs= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1762361694; c=relaxed/simple; bh=fAStZ1VGox28sSBTaeIOxtIwVEbCulrkhuzHCrifXdg=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=LLiOl4TxerrNVPqWMMdOMeE69nUeRr0DoqFDS3mjEK9PFVRLAsGXic+fXFaSvJGRxF2eANly07tOdULbbr2cMYgd7ILdwD2sJ9523dKTPn0pFwQlypv8eBZJOGSaPfahLrO61GKDWbIFdpfxW8+69NttAdhRx/s5bSeqRDqnVS4= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=H1ZQoNee; 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="H1ZQoNee" Received: by smtp.kernel.org (Postfix) with ESMTPSA id EA7DEC4CEF5; Wed, 5 Nov 2025 16:54:50 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1762361694; bh=fAStZ1VGox28sSBTaeIOxtIwVEbCulrkhuzHCrifXdg=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=H1ZQoNeer59mVzfoI5KLKHzzxHa7RVoi1N+nfH/nDbfadRbWm6PFG7kOFMd6iyqLI 7H+916dmGFXfy5VyJXkcYm9zTcCLCxIQlU4gtcwlqQ5Xow6WhtHSDSTI+20x6Q4czn 0EXMPiP6/4Q5yIFa7zujGvLpxo83IQiPTwmYR6qrD2bB6J6rWEFj6G9w5+OOQlG8ys RJHV1c39R9eZ1Y2PeahRRX8MXzbQoh4KKGFP1QVuIWCEJ71x1zE7KZp90uvpfRBs0b Zv34GCj8O4VXFw2GeJXy58m1EShYcWB3IQ1QrgQCMfopPVlP/1moDppmRmmVjxjq+Q JNxhTnVIA3viw== From: Jeff Layton Date: Wed, 05 Nov 2025 11:53:59 -0500 Subject: [PATCH v5 13/17] 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: <20251105-dir-deleg-ro-v5-13-7ebc168a88ac@kernel.org> References: <20251105-dir-deleg-ro-v5-0-7ebc168a88ac@kernel.org> In-Reply-To: <20251105-dir-deleg-ro-v5-0-7ebc168a88ac@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=1772; i=jlayton@kernel.org; h=from:subject:message-id; bh=fAStZ1VGox28sSBTaeIOxtIwVEbCulrkhuzHCrifXdg=; b=owEBbQKS/ZANAwAKAQAOaEEZVoIVAcsmYgBpC4EtCPJ/HbYX2CLLwDMaCwhbx/1zHseY6+3ib DlLJ5T5GwiJAjMEAAEKAB0WIQRLwNeyRHGyoYTq9dMADmhBGVaCFQUCaQuBLQAKCRAADmhBGVaC FRDdEACkON+zuK06pcKuiFx+1l8HFqDDgfS3n6gmhCsYA8lWTPOj9Gwf3XZ/RgUD6nLZudz81DZ MogCxZdlBSslI/6x6qJ6px9OqEXW0OWIQBqdecEpY6e+xfWX+6uYRy9Q2MXZM0IDWGEAQ/ys3zH Lp/NDfOsCKqZnqxgx4xRZyd9n7FTFdhhA2GxHEaUn+ThsykJqUt0NifKUcUbWiUbCKfsc9ek91O 0VTpN8nK+yePmnk8/fZjvQTYdOTBsDeCsCKLKepcDMNZeH5uUK67QmAw4boJuWgkdH/l7fH4jm3 5JdbsoU2v757mOk6EpTKCZ3BNF/JgO6rrC1/DOcRVDdbuEUuzNDAxWwXewpffQFKuWqRV0RLSlN fd842uYZBdDj9vIFDVsIqEmJdrrtZ7oT4JnRZf90MA7k+KlofnwwLhvpiXLLaEvogydpsRjZ/gh 8D+fn3iODh9rXM0v/2xCpLt9+TVJc7aUG9sLuvHa793aKs0igRwKm8MUjv00PBukFWWa484d0V9 kaINWBPpr1HLLvBPesJ82ef0fL+E6U0B4g1L1FPDCuVJYtb9654jBqz1XbRU8f6A8+D8xkn6aEx gKh8SkuIy+xw039564DHh1AcTIEMLRSdiKjsWfbgWAp0O4HIM5h4WXR7/lq7Ko3xnKsM20+y3Uu 7fHM8ADhhPZTXBA== X-Developer-Key: i=jlayton@kernel.org; a=openpgp; fpr=4BC0D7B24471B2A184EAF5D3000E684119568215 With the addition of the try_break_lease calls in directory changing operations, allow generic_setlease to hand them out. Write leases on directories are never allowed however, so continue to reject them. For now, there is no API for requesting delegations from userland, so ensure that userland is prevented from acquiring a lease on a directory. Reviewed-by: Jan Kara Reviewed-by: NeilBrown Signed-off-by: Jeff Layton --- fs/locks.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/fs/locks.c b/fs/locks.c index f5b210a2dc34c70ac36e972436c62482bbe32ca6..dd290a87f58eb5d522f03fa99d6= 12fbad84dacf3 100644 --- a/fs/locks.c +++ b/fs/locks.c @@ -1935,14 +1935,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; @@ -2071,6 +2076,9 @@ static int do_fcntl_add_lease(unsigned int fd, struct= file *filp, int arg) */ int fcntl_setlease(unsigned int fd, struct file *filp, int arg) { + if (S_ISDIR(file_inode(filp)->i_mode)) + return -EINVAL; + if (arg =3D=3D F_UNLCK) return vfs_setlease(filp, F_UNLCK, NULL, (void **)&filp); return do_fcntl_add_lease(fd, filp, arg); --=20 2.51.1 From nobody Fri Dec 19 14:23:26 2025 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id AFB5534D4F8; Wed, 5 Nov 2025 16:54:57 +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=1762361697; cv=none; b=D1wS7efUE8ok0sGcW0O1pbd6V/SAZk0LadajmzGf5WV7JoQhBmvuAeOw7POm5pKqAwxdj6dOo3P+Yfu5O25nZVDQq4x7o1ZwsgdCKF23kI2sDlj7t18yhH781+QcxUiKxPiKoFsM4yHgYlmGu6Q5pYsvwkDemXLbnmC01OYHEx4= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1762361697; c=relaxed/simple; bh=G0m38I9O+Xy6gwLh+3apyDgrdcwDPUcZ3ukE2nInTzc=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=DFImf7jQe7C2LlwKsMWRdwNjHGKX6kaGn+B0YoGlJA5wtDNUTUOaQ/drocKLFUTY6vAS28OO2WbB9SYwlz5Vw+g6Pf/y0d0yJHCy/BDo/xUkxCQGLDxSL8WANieU0eX9cbXniFxD8wPP2Bo79g2l2vb5ODSJSwhEWx7PRM2FWyQ= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=pIhafmxk; 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="pIhafmxk" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 5C02BC4CEF8; Wed, 5 Nov 2025 16:54:54 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1762361697; bh=G0m38I9O+Xy6gwLh+3apyDgrdcwDPUcZ3ukE2nInTzc=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=pIhafmxkLGXXxmHcDbfYFQrqONgdD2VU+s092OKlNEP3AkARYCls+yQChsUM9uvD7 JHvleF9bXfw5G4lxvsDUafm1dz3Ns/SF3RCYR84yB5T/2ucGRzXEFDmcCCux1+gXb8 FsX1A4XIdazQV3xxeUmvwIy8Luyh1PSnNhxOVakHH9CFJjpQn0KXh4S5vYLibGn81E S5R7f3LSjxZXdbHJYNCvk+4ix1P29Ok3H5568eoep7VZE3+N/8RybK4oQcaaZFHu8T wAEdA+RTKBF/Eln3kaqUyyRB0ddRi2K4ID4HhN2t14gLMP/Bo4GcDOeJ2rXM+YR9V9 46GbgBpGw/ENw== From: Jeff Layton Date: Wed, 05 Nov 2025 11:54:00 -0500 Subject: [PATCH v5 14/17] 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: <20251105-dir-deleg-ro-v5-14-7ebc168a88ac@kernel.org> References: <20251105-dir-deleg-ro-v5-0-7ebc168a88ac@kernel.org> In-Reply-To: <20251105-dir-deleg-ro-v5-0-7ebc168a88ac@kernel.org> To: Miklos Szeredi , Alexander Viro , Christian Brauner , Jan Kara , Chuck Lever , Alexander Aring , Trond Myklebust , Anna Schumaker , Steve French , Paulo Alcantara , Ronnie Sahlberg , Shyam Prasad N , Tom Talpey , Bharath SM , Greg Kroah-Hartman , "Rafael J. Wysocki" , Danilo Krummrich , David Howells , Tyler Hicks , NeilBrown , Olga Kornievskaia , Dai Ngo , Amir Goldstein , Namjae Jeon , Steve French , Sergey Senozhatsky , Carlos Maiolino , Kuniyuki Iwashima , "David S. Miller" , Eric Dumazet , Jakub Kicinski , Paolo Abeni , Simon Horman Cc: linux-fsdevel@vger.kernel.org, linux-kernel@vger.kernel.org, linux-nfs@vger.kernel.org, linux-cifs@vger.kernel.org, samba-technical@lists.samba.org, netfs@lists.linux.dev, ecryptfs@vger.kernel.org, linux-unionfs@vger.kernel.org, linux-xfs@vger.kernel.org, netdev@vger.kernel.org, Jeff Layton X-Mailer: b4 0.14.2 X-Developer-Signature: v=1; a=openpgp-sha256; l=7422; i=jlayton@kernel.org; h=from:subject:message-id; bh=G0m38I9O+Xy6gwLh+3apyDgrdcwDPUcZ3ukE2nInTzc=; b=owEBbQKS/ZANAwAKAQAOaEEZVoIVAcsmYgBpC4EtIm6eYsYgxcntowp09WIkEvRyEAogXm4gX cx+mXnJvA6JAjMEAAEKAB0WIQRLwNeyRHGyoYTq9dMADmhBGVaCFQUCaQuBLQAKCRAADmhBGVaC FWW2D/0c+om1Ucx1g8f4epimbGNM62WQniOoQEsEgLuQoVSUvdSzo4uKff3061ngMx2EquEvjc1 kKC1vRKd6WYz2fqLgvYj1S4k6sg11DGAe4gOZTmDvzNTYGGR7lhY1zinO9fwRWgcLdmaorPnOyY jTmFk4Ngiy0WaxCYR71TzNPOnAX4Qf8Gtt6Jhf0szLIlvfPp/ucRckeqJKMjuOtDTZ5UdkBoUdS rXuZoDjQiW/AbU7edUlOjqzvtlbwTQIB7fpvVX1TvQCig51dIPSu2S30RTJCSWNsByWWMLP0dlP MFvFFKvtAFcL0NrvabuK4kkgbzQ0KkBLjkAsLpNQwbBggPi7XlMpkcawVwibHS4kY6iTAzfPFn2 mvKxmLOa2i8z3kLSbPRApNiF75xRiHLkvgoDYbolzJ+Ze9ytm/xsgKOgPM00uFoMYxppGGnqYLI VewIqLjx3sBRRcXCfWbn9OUxd5Lk8ETT2Utfit664G5qJQ3xDx13BaY7iVlq/iGgy/NDVMfHI1D KBShlGckogIE37SXtLfDwG4xFPxJVd6UBG1ANP/QtExnC7KgfkRA6KVt2t9pn4MfJCOVBDOBFn9 oJW/iI2/a7s25F7Rx0hgay4rxGN/RR5fwXxUPU3bKwd0U+VX5GB2msId2IjWXDwjb8TT8n6mFqr BtuPAMulxu/eCBg== X-Developer-Key: i=jlayton@kernel.org; a=openpgp; fpr=4BC0D7B24471B2A184EAF5D3000E684119568215 The filecache infrastructure will only handle S_IFREG files at the moment. Directory delegations will require adding support for opening S_IFDIR inodes. Plumb a "type" argument into nfsd_file_do_acquire() and have all of the existing callers set it to S_IFREG. Add a new nfsd_file_acquire_dir() wrapper that nfsd can call to request a nfsd_file that holds a directory open. For now, there is no need for a fsnotify_mark for directories, as CB_NOTIFY is not yet supported. Change nfsd_file_do_acquire() to avoid allocating one for non-S_IFREG inodes. Reviewed-by: Chuck Lever Reviewed-by: NeilBrown Signed-off-by: Jeff Layton --- fs/nfsd/filecache.c | 57 ++++++++++++++++++++++++++++++++++++++++---------= ---- fs/nfsd/filecache.h | 2 ++ fs/nfsd/vfs.c | 5 +++-- fs/nfsd/vfs.h | 2 +- 4 files changed, 49 insertions(+), 17 deletions(-) diff --git a/fs/nfsd/filecache.c b/fs/nfsd/filecache.c index a238b6725008a5c2988bd3da874d1f34ee778437..93798575b8075c63f95cd415b6d= 24df706ada0f6 100644 --- a/fs/nfsd/filecache.c +++ b/fs/nfsd/filecache.c @@ -1086,7 +1086,7 @@ nfsd_file_do_acquire(struct svc_rqst *rqstp, struct n= et *net, struct auth_domain *client, struct svc_fh *fhp, unsigned int may_flags, struct file *file, - struct nfsd_file **pnf, bool want_gc) + umode_t type, bool want_gc, struct nfsd_file **pnf) { unsigned char need =3D may_flags & NFSD_FILE_MAY_MASK; struct nfsd_file *new, *nf; @@ -1097,13 +1097,13 @@ nfsd_file_do_acquire(struct svc_rqst *rqstp, struct= net *net, int ret; =20 retry: - if (rqstp) { - status =3D fh_verify(rqstp, fhp, S_IFREG, + if (rqstp) + status =3D fh_verify(rqstp, fhp, type, may_flags|NFSD_MAY_OWNER_OVERRIDE); - } else { - status =3D fh_verify_local(net, cred, client, fhp, S_IFREG, + else + status =3D fh_verify_local(net, cred, client, fhp, type, may_flags|NFSD_MAY_OWNER_OVERRIDE); - } + if (status !=3D nfs_ok) return status; inode =3D d_inode(fhp->fh_dentry); @@ -1176,15 +1176,18 @@ nfsd_file_do_acquire(struct svc_rqst *rqstp, struct= net *net, =20 open_file: trace_nfsd_file_alloc(nf); - nf->nf_mark =3D nfsd_file_mark_find_or_create(inode); - if (nf->nf_mark) { + + if (type =3D=3D S_IFREG) + nf->nf_mark =3D nfsd_file_mark_find_or_create(inode); + + if (type !=3D S_IFREG || nf->nf_mark) { if (file) { get_file(file); nf->nf_file =3D file; status =3D nfs_ok; trace_nfsd_file_opened(nf, status); } else { - ret =3D nfsd_open_verified(fhp, may_flags, &nf->nf_file); + ret =3D nfsd_open_verified(fhp, type, may_flags, &nf->nf_file); if (ret =3D=3D -EOPENSTALE && stale_retry) { stale_retry =3D false; nfsd_file_unhash(nf); @@ -1246,7 +1249,7 @@ nfsd_file_acquire_gc(struct svc_rqst *rqstp, struct s= vc_fh *fhp, unsigned int may_flags, struct nfsd_file **pnf) { return nfsd_file_do_acquire(rqstp, SVC_NET(rqstp), NULL, NULL, - fhp, may_flags, NULL, pnf, true); + fhp, may_flags, NULL, S_IFREG, true, pnf); } =20 /** @@ -1271,7 +1274,7 @@ nfsd_file_acquire(struct svc_rqst *rqstp, struct svc_= fh *fhp, unsigned int may_flags, struct nfsd_file **pnf) { return nfsd_file_do_acquire(rqstp, SVC_NET(rqstp), NULL, NULL, - fhp, may_flags, NULL, pnf, false); + fhp, may_flags, NULL, S_IFREG, false, pnf); } =20 /** @@ -1314,8 +1317,8 @@ nfsd_file_acquire_local(struct net *net, struct svc_c= red *cred, const struct cred *save_cred =3D get_current_cred(); __be32 beres; =20 - beres =3D nfsd_file_do_acquire(NULL, net, cred, client, - fhp, may_flags, NULL, pnf, false); + beres =3D nfsd_file_do_acquire(NULL, net, cred, client, fhp, may_flags, + NULL, S_IFREG, false, pnf); put_cred(revert_creds(save_cred)); return beres; } @@ -1344,7 +1347,33 @@ nfsd_file_acquire_opened(struct svc_rqst *rqstp, str= uct svc_fh *fhp, struct nfsd_file **pnf) { return nfsd_file_do_acquire(rqstp, SVC_NET(rqstp), NULL, NULL, - fhp, may_flags, file, pnf, false); + fhp, may_flags, file, S_IFREG, false, pnf); +} + +/** + * nfsd_file_acquire_dir - Get a struct nfsd_file with an open directory + * @rqstp: the RPC transaction being executed + * @fhp: the NFS filehandle of the file to be opened + * @pnf: OUT: new or found "struct nfsd_file" object + * + * The nfsd_file_object returned by this API is reference-counted + * but not garbage-collected. The object is unhashed after the + * final nfsd_file_put(). This opens directories only, and only + * in O_RDONLY mode. + * + * Return values: + * %nfs_ok - @pnf points to an nfsd_file with its reference + * count boosted. + * + * On error, an nfsstat value in network byte order is returned. + */ +__be32 +nfsd_file_acquire_dir(struct svc_rqst *rqstp, struct svc_fh *fhp, + struct nfsd_file **pnf) +{ + return nfsd_file_do_acquire(rqstp, SVC_NET(rqstp), NULL, NULL, fhp, + NFSD_MAY_READ|NFSD_MAY_64BIT_COOKIE, + NULL, S_IFDIR, false, pnf); } =20 /* diff --git a/fs/nfsd/filecache.h b/fs/nfsd/filecache.h index e3d6ca2b60308e5e91ba4bb32d935f54527d8bda..b383dbc5b9218d21a29b852572f= 80fab08de9fa9 100644 --- a/fs/nfsd/filecache.h +++ b/fs/nfsd/filecache.h @@ -82,5 +82,7 @@ __be32 nfsd_file_acquire_opened(struct svc_rqst *rqstp, s= truct svc_fh *fhp, __be32 nfsd_file_acquire_local(struct net *net, struct svc_cred *cred, struct auth_domain *client, struct svc_fh *fhp, unsigned int may_flags, struct nfsd_file **pnf); +__be32 nfsd_file_acquire_dir(struct svc_rqst *rqstp, struct svc_fh *fhp, + struct nfsd_file **pnf); int nfsd_file_cache_stats_show(struct seq_file *m, void *v); #endif /* _FS_NFSD_FILECACHE_H */ diff --git a/fs/nfsd/vfs.c b/fs/nfsd/vfs.c index 28710da4cce7cc7fc1e14d29420239dc357316f6..8c3ffacc533e9de0d506fb2ec22= 2387446ba8e9f 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 0c0292611c6de3daf6f3ed51e2c61c0ad2751de4..09de48c50cbef8e7c4828b38dcb= 663b529514a30 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.1 From nobody Fri Dec 19 14:23:26 2025 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 1FD2F34DB46; Wed, 5 Nov 2025 16:55:01 +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=1762361701; cv=none; b=tmSBuhFfqjOj1G8+ziyBlTLc+JGAnP8WQ2HGwAWM/FsrYbSKLhkee1VWq492tnpysABibq11UPDM/yei0/j++EDHCkGVtjbzInS4T4GT8kKTlJi/DfTctYeTVD1qOw30G6fHaK7qKOCEkHVECTWLq4G/0/HFLEdmtBufKAJ9mwM= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1762361701; c=relaxed/simple; bh=yulLeJZn1mX+cSvDuaJcOgJyv8hH6SOCKBioc8zxN20=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=kb3uObcbriNeVYPod0qHnjKrDv3R8T1T2zAR9XfkUT492XpPlxq5Op8jTuJxXT4aSPSDcWxAv6cfMZa63jDacqe7kev8yIAbKeq4GKjJy0G1uETGgo68ETRTw8P6XOVbdFgRY6tZ0AYPggNCI9ottf7lYNmoef/Y67ywzEq3VsA= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=knfdSpUQ; 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="knfdSpUQ" Received: by smtp.kernel.org (Postfix) with ESMTPSA id C2532C4CEF5; Wed, 5 Nov 2025 16:54:57 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1762361701; bh=yulLeJZn1mX+cSvDuaJcOgJyv8hH6SOCKBioc8zxN20=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=knfdSpUQnWPn3itXlZlQDx/8tNajmeoKCSJ7DuRO9rI1Qdov/KedLOSm9T96JJlFJ YtPlj+PgoVMLh0Be5iCCEoQO1JFzk5bDjkDwLv3I5lkf19qj+CC+tT1o5PatGPRF3M 2IH7GV7JtO+JEl32SYC9iBQ118iIkjVEcfnDXXPymEJv8ezfkhjW/OU3c3zlXwG8Bc samk4zx7TE453p8UakAZVOU0WPhB2igoxMd8atpUFlTRU8lPlz2+18muxQSKJM5iYz oZoPThxlI0SRWVlxANzmvKdhu9tZ4U4+pi8yA2o7c1/9WmhT6HyWMogT5HP8gK++fm NlP7wzS42Ol4A== From: Jeff Layton Date: Wed, 05 Nov 2025 11:54:01 -0500 Subject: [PATCH v5 15/17] 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: <20251105-dir-deleg-ro-v5-15-7ebc168a88ac@kernel.org> References: <20251105-dir-deleg-ro-v5-0-7ebc168a88ac@kernel.org> In-Reply-To: <20251105-dir-deleg-ro-v5-0-7ebc168a88ac@kernel.org> To: Miklos Szeredi , Alexander Viro , Christian Brauner , Jan Kara , Chuck Lever , Alexander Aring , Trond Myklebust , Anna Schumaker , Steve French , Paulo Alcantara , Ronnie Sahlberg , Shyam Prasad N , Tom Talpey , Bharath SM , Greg Kroah-Hartman , "Rafael J. Wysocki" , Danilo Krummrich , David Howells , Tyler Hicks , NeilBrown , Olga Kornievskaia , Dai Ngo , Amir Goldstein , Namjae Jeon , Steve French , Sergey Senozhatsky , Carlos Maiolino , Kuniyuki Iwashima , "David S. Miller" , Eric Dumazet , Jakub Kicinski , Paolo Abeni , Simon Horman Cc: linux-fsdevel@vger.kernel.org, linux-kernel@vger.kernel.org, linux-nfs@vger.kernel.org, linux-cifs@vger.kernel.org, samba-technical@lists.samba.org, netfs@lists.linux.dev, ecryptfs@vger.kernel.org, linux-unionfs@vger.kernel.org, linux-xfs@vger.kernel.org, netdev@vger.kernel.org, Jeff Layton X-Mailer: b4 0.14.2 X-Developer-Signature: v=1; a=openpgp-sha256; l=1228; i=jlayton@kernel.org; h=from:subject:message-id; bh=yulLeJZn1mX+cSvDuaJcOgJyv8hH6SOCKBioc8zxN20=; b=owEBbQKS/ZANAwAKAQAOaEEZVoIVAcsmYgBpC4EttPFxRPGR+DCRBfozxNBfOp+kzrdRKFxz7 noCX+Ay2kGJAjMEAAEKAB0WIQRLwNeyRHGyoYTq9dMADmhBGVaCFQUCaQuBLQAKCRAADmhBGVaC Fc6GD/90HKaWLqhYzTjprv+oduTewzG4BBOMbV4qDkuJwfCgjx/MK51Ie5Q1TXGZkSmv4OqYYCU lMUug/7A79bJpNe1fb1L+tYySlZG8FVCYFngqLzt80zjStQuHTJy40bURvtPDVYJFNwIrv2dA0m GuD6E+3ibyQw0LIEQoiz7LcTJBuuj9jSxMcz4MZdUZc0ueXwSmR3SIHx1ZUBRR0TOEFNIP/wiaA BYNeTw+y+/mMC6ETFzpXyxrcfxwqJnGBiLJ8u6kjYcR7gNjC1Xo+L4Fzu4pFGSTpuDgseyw5Kc/ VyVXhGs+CP34+LwjfMHmNQxZwdE7k6uHd7/ePTtn9KJQzX+xK8UzIuOVFzZUo3PoNfVa5ZfzvRJ JZQTibc4EH02p/G79FV5p2E9ByP+faSi0In2VyHzeDrl8KRbJofc5ZV7oxDRCaLL7r21cFL+9bQ cyv77nNUw/EA0qW5us/bK9iSWmzl8teC0buXooh92ZnI8N9miYfmiXZw8C/W3Sb0jq9sBhV1YIv ae4JWmP56hQtGGKRbWesdqPjp74qO7ZC2+OWM6ENDjUG6KWGY7nEwHkDzCn0QnursNbSg9StrZp 0TP5gHffpIDIhZM1uz4gm8zjMr+QSsQDZ/7naG56/AOO44ploBGkZlhFNL3PVjGj6olYlL1X7Bj 0/gZ3gCwg9yDDOg== X-Developer-Key: i=jlayton@kernel.org; a=openpgp; fpr=4BC0D7B24471B2A184EAF5D3000E684119568215 As Trond pointed out: "...provided that the presented stateid is actually valid, it is also sufficient to uniquely identify the file to which it is associated (see RFC8881 Section 8.2.4), so the filehandle should be considered mostly irrelevant for operations like DELEGRETURN." Don't ask fh_verify to filter on file type. Reviewed-by: Chuck Lever Reviewed-by: NeilBrown Signed-off-by: Jeff Layton --- fs/nfsd/nfs4state.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c index 81fa7cc6c77b3cdc5ff22bc60ab0654f95dc258d..da66798023aba4c36c38208cec7= 333db237e46e0 100644 --- a/fs/nfsd/nfs4state.c +++ b/fs/nfsd/nfs4state.c @@ -7828,7 +7828,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.1 From nobody Fri Dec 19 14:23:26 2025 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 97AF934DB46; Wed, 5 Nov 2025 16:55:04 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1762361704; cv=none; b=OPDO5NDYrGQlRK0djNyfoWL1RzdJzGJb8eFNtB4P3yxmBXROVjvJ7OyGUA5HguXBTJoI1dSVisBd+auPF0QN4T6H0JxbNZrlky5nfxGsUe1vtHxfymjY2hNjSUh35dEXvASbZIYx5d6xQ6ttOv0hTwUy/hipltHXAqNC4uyE3RM= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1762361704; c=relaxed/simple; bh=8uFhmfmnSTsd3LwYNioQRWlGjzSH6flkvXdmZ7xJmTo=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=ORNKYIM1wbi5GGEwOOwvAgELcBH1kV6V03jbTobn5hGoHfF14iVa9Beh4vh4iHbUqXNgkl2CsR1erF4hdBcmCdKXlKmQt2AHgSqW+tnJCq8S6/nLiz5h7GYEWgzYox5apN5SC+Hhe6JGwYHtp8OhQnrSZt2Fb4DYRLrfq6uXa80= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=f5Oenf/S; 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="f5Oenf/S" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 473F2C116B1; Wed, 5 Nov 2025 16:55:01 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1762361704; bh=8uFhmfmnSTsd3LwYNioQRWlGjzSH6flkvXdmZ7xJmTo=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=f5Oenf/SvFAFjRdyni7XQijTep2IHierotWbgMU2UbOTpksiQsROt1aF+dPbNuCH2 1oUKbKzhFqYLnyn8JhgnONeFClnDzW8M9TGesb6LwYtWJuKxjsSbbs1h8WxRaWYIku FJ57ri0MQ0uxUTufrEk5zhCmAkFAQ7VmW8mldA2Yz/ApMrrQ3+dm/w0Pz4iAWkG5LJ umYmGXuujNQbIo8Zte0Td4zJfysJEylWTl2UYkVi1/93DRbi1KJjqDd9Ga6ZVgLDh6 SZR74lxKruPDtv3zTQmLrs+cJRcNK2D6HFXXlPN4jtgbao5GWNEqIhb64uOsS1Te5i qsZlLrSUFn8qw== From: Jeff Layton Date: Wed, 05 Nov 2025 11:54:02 -0500 Subject: [PATCH v5 16/17] 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: <20251105-dir-deleg-ro-v5-16-7ebc168a88ac@kernel.org> References: <20251105-dir-deleg-ro-v5-0-7ebc168a88ac@kernel.org> In-Reply-To: <20251105-dir-deleg-ro-v5-0-7ebc168a88ac@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=5577; i=jlayton@kernel.org; h=from:subject:message-id; bh=8uFhmfmnSTsd3LwYNioQRWlGjzSH6flkvXdmZ7xJmTo=; b=owEBbQKS/ZANAwAKAQAOaEEZVoIVAcsmYgBpC4EtKjXEEAavufgz3/17T2+K75udF1YHhM8p1 kLLoOFSASaJAjMEAAEKAB0WIQRLwNeyRHGyoYTq9dMADmhBGVaCFQUCaQuBLQAKCRAADmhBGVaC Fb9xD/0SrANaaUs/KwJlwN9tPXS96N80QDXhAa3/aQiaUd38olFHdxjgtSPwz6fVN7C1NS/8N2M Y9GmCgY8SHLYhnxhx/iCJwOleWwCFWmuMdkZFV9/1gA3tOQOLBL865n/f5m+ZRStY5poVfIIILu QfhhswKVyGxN0uHjsPfRuudcAVBU/1eUk3RdxpE8MChbCbgBCzFmpK94I+Xy2hCSAKUPDzjLXFc jauSu6SmQzJhluP3AP5KxGBgsizOV/8ZwakjK+qL3eOw2E9awNueo7rijaJnKpkKsn13pZwPYRP NMdz0PoSm1sZDc9jsPjYjRV954z1kT5USy2LsMU5Boo6/0LopQ+Q1ohSQYIvq9t2QeQYK0O8z57 jzSivucdoTuLJkMX1HjMQ1K0CExea8CqgWo8lz+yUWu9d+WBxkXXePCSzKXXwSjZiNymqx09lFG G7lHF9Eu5wiZMYrLtWkdcWEZG1H0LSJndAcF+RuyqV/icgFU1vwqvQPdgDk4WcPoYopYUXx/FhQ nhM83yNV3bpUQ/m46YDkW7zjaHpU3Zsm7GCpG110w2rp2Wx7fgcjX+nOwXu6AkFjJ6inHLsMpnl rgvcZDfAZmpEEtQ7rwDEo9e0HORqkLdmWFuD5q3hFC0gYkUis+Ww48x201kxjnMS/iWMZJ3xkaA yKs0Ihu73wXrnuQ== X-Developer-Key: i=jlayton@kernel.org; a=openpgp; fpr=4BC0D7B24471B2A184EAF5D3000E684119568215 Add a new routine for acquiring a read delegation on a directory. These are recallable-only delegations with no support for CB_NOTIFY. That will be added in a later phase. Since the same CB_RECALL/DELEGRETURN infrastructure is used for regular and directory delegations, a normal nfs4_delegation is used to represent a directory delegation. Reviewed-by: NeilBrown Reviewed-by: Chuck Lever Signed-off-by: Jeff Layton --- fs/nfsd/nfs4proc.c | 22 +++++++++++- fs/nfsd/nfs4state.c | 100 ++++++++++++++++++++++++++++++++++++++++++++++++= ++++ fs/nfsd/state.h | 5 +++ 3 files changed, 126 insertions(+), 1 deletion(-) diff --git a/fs/nfsd/nfs4proc.c b/fs/nfsd/nfs4proc.c index e466cf52d7d7e1a78c3a469613a85ab3546d6d17..517968dddf4a33651313658d300= f9f929f83c5af 100644 --- a/fs/nfsd/nfs4proc.c +++ b/fs/nfsd/nfs4proc.c @@ -2341,6 +2341,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: @@ -2354,7 +2361,20 @@ nfsd4_get_dir_delegation(struct svc_rqst *rqstp, * return NFS4_OK with a non-fatal status of GDD4_UNAVAIL in this * situation. */ - gdd->gddrnf_status =3D GDD4_UNAVAIL; + dd =3D nfsd_get_dir_deleg(cstate, gdd, nf); + nfsd_file_put(nf); + if (IS_ERR(dd)) { + int err =3D PTR_ERR(dd); + + if (err !=3D -EAGAIN) + return nfserrno(err); + gdd->gddrnf_status =3D GDD4_UNAVAIL; + return nfs_ok; + } + + gdd->gddrnf_status =3D GDD4_OK; + memcpy(&gdd->gddr_stateid, &dd->dl_stid.sc_stateid, sizeof(gdd->gddr_stat= eid)); + nfs4_put_stid(&dd->dl_stid); return nfs_ok; } =20 diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c index da66798023aba4c36c38208cec7333db237e46e0..8f8c9385101e15b64883eabec71= 775f26b14f890 100644 --- a/fs/nfsd/nfs4state.c +++ b/fs/nfsd/nfs4state.c @@ -9347,3 +9347,103 @@ nfsd4_deleg_getattr_conflict(struct svc_rqst *rqstp= , struct dentry *dentry, nfs4_put_stid(&dp->dl_stid); return status; } + +/** + * nfsd_get_dir_deleg - attempt to get a directory delegation + * @cstate: compound state + * @gdd: GET_DIR_DELEGATION arg/resp structure + * @nf: nfsd_file opened on the directory + * + * Given a GET_DIR_DELEGATION request @gdd, attempt to acquire a delegation + * on the directory to which @nf refers. Note that this does not set up any + * sort of async notifications for the delegation. + */ +struct nfs4_delegation * +nfsd_get_dir_deleg(struct nfsd4_compound_state *cstate, + struct nfsd4_get_dir_delegation *gdd, + struct nfsd_file *nf) +{ + struct nfs4_client *clp =3D cstate->clp; + struct nfs4_delegation *dp; + struct file_lease *fl; + struct nfs4_file *fp, *rfp; + int status =3D 0; + + fp =3D nfsd4_alloc_file(); + if (!fp) + return ERR_PTR(-ENOMEM); + + nfsd4_file_init(&cstate->current_fh, fp); + + rfp =3D nfsd4_file_hash_insert(fp, &cstate->current_fh); + if (unlikely(!rfp)) { + put_nfs4_file(fp); + return ERR_PTR(-ENOMEM); + } + + if (rfp !=3D fp) { + put_nfs4_file(fp); + fp =3D rfp; + } + + /* if this client already has one, return that it's unavailable */ + spin_lock(&state_lock); + spin_lock(&fp->fi_lock); + /* existing delegation? */ + if (nfs4_delegation_exists(clp, fp)) { + status =3D -EAGAIN; + } else if (!fp->fi_deleg_file) { + fp->fi_deleg_file =3D nfsd_file_get(nf); + fp->fi_delegees =3D 1; + } else { + ++fp->fi_delegees; + } + spin_unlock(&fp->fi_lock); + spin_unlock(&state_lock); + + if (status) { + put_nfs4_file(fp); + return ERR_PTR(status); + } + + /* Try to set up the lease */ + status =3D -ENOMEM; + dp =3D alloc_init_deleg(clp, fp, NULL, NFS4_OPEN_DELEGATE_READ); + if (!dp) + goto out_delegees; + + fl =3D nfs4_alloc_init_lease(dp); + if (!fl) + goto out_put_stid; + + status =3D kernel_setlease(nf->nf_file, + fl->c.flc_type, &fl, NULL); + if (fl) + locks_free_lease(fl); + if (status) + goto out_put_stid; + + /* + * Now, try to hash it. This can fail if we race another nfsd task + * trying to set a delegation on the same file. If that happens, + * then just say UNAVAIL. + */ + spin_lock(&state_lock); + spin_lock(&clp->cl_lock); + spin_lock(&fp->fi_lock); + status =3D hash_delegation_locked(dp, fp); + spin_unlock(&fp->fi_lock); + spin_unlock(&clp->cl_lock); + spin_unlock(&state_lock); + + if (!status) + return dp; + + /* Something failed. Drop the lease and clean up the stid */ + kernel_setlease(fp->fi_deleg_file->nf_file, F_UNLCK, NULL, (void **)&dp); +out_put_stid: + nfs4_put_stid(&dp->dl_stid); +out_delegees: + put_deleg_file(fp); + return ERR_PTR(status); +} diff --git a/fs/nfsd/state.h b/fs/nfsd/state.h index 1e736f4024263ffa9c93bcc9ec48f44566a8cc77..b052c1effdc5356487c610db972= 8df8ecfe851d4 100644 --- a/fs/nfsd/state.h +++ b/fs/nfsd/state.h @@ -867,4 +867,9 @@ static inline bool try_to_expire_client(struct nfs4_cli= ent *clp) =20 extern __be32 nfsd4_deleg_getattr_conflict(struct svc_rqst *rqstp, struct dentry *dentry, struct nfs4_delegation **pdp); + +struct nfsd4_get_dir_delegation; +struct nfs4_delegation *nfsd_get_dir_deleg(struct nfsd4_compound_state *cs= tate, + struct nfsd4_get_dir_delegation *gdd, + struct nfsd_file *nf); #endif /* NFSD4_STATE_H */ --=20 2.51.1 From nobody Fri Dec 19 14:23:26 2025 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 5FF0534EEE0; Wed, 5 Nov 2025 16:55:08 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1762361708; cv=none; b=LsiqCrR/N3gQXe8nwodkmFjKAK2Yur8bonzX0oKJSIldU9iTEe/guEqYUzoXWK+fh0uqLkJ74rtQuto9aUS1ELzhY1NK7e3wQpK+xnk1BIoceYorIDva6nweV8BgHUaEzqheL7PmvRMAEIQrBtVxoCxpgldW1aI1+UKc9CC3oco= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1762361708; c=relaxed/simple; bh=pHQnZqDye2qaTatSgq4OXFwdAwiLQyPYO+69SCCQtfM=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=oYr8VpgxKkawxjrdTXnAkfe3aaNLfy20JMWwGBp4vbWF0SIK0SNLoBCCYhoM0+KYNTkD94smDR7ws+pXy0T0KgWQrsd9lg8eh3Ll9evt+6Pd0i0S7p5LAH1QLIrG5MoWtyxqKTIZgz8BKwrcjVsaUn2WsIPKV+wjkAs8gkkwi1g= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=JBTGik+K; 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="JBTGik+K" Received: by smtp.kernel.org (Postfix) with ESMTPSA id AF21DC4CEF5; Wed, 5 Nov 2025 16:55:04 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1762361707; bh=pHQnZqDye2qaTatSgq4OXFwdAwiLQyPYO+69SCCQtfM=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=JBTGik+KGApcRDnD7tKuXfLlvy24pAkGW/q/bC63SLiap3dfvi7Vs6ett37VtjOen xto6nlKVTSV4c6LZsGCdHGYiG26WAX5proiv8Z+OY5aPsMU1igjguxdPlNxRuVbi0P M6E22Fu0GKuobJCoHB5MINTTmDLrHSxy9H58xqP5gPbnFrkgQdsaK0dORT10MIp0sE sz2XXa6v90jPU/xEHQtg6if2It/aINMrzwc6W09RSUkFB2t3+LeLdlib0GR760XUiZ Uds/IaKZsdGXVBsFhEUz+IxVikU8ZoKqsfvIxJZMSwcSbczNKJ2AzJ9cAMANUcObtj ChLoRbEVH38Jw== From: Jeff Layton Date: Wed, 05 Nov 2025 11:54:03 -0500 Subject: [PATCH v5 17/17] vfs: expose delegation support to userland Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20251105-dir-deleg-ro-v5-17-7ebc168a88ac@kernel.org> References: <20251105-dir-deleg-ro-v5-0-7ebc168a88ac@kernel.org> In-Reply-To: <20251105-dir-deleg-ro-v5-0-7ebc168a88ac@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=6459; i=jlayton@kernel.org; h=from:subject:message-id; bh=pHQnZqDye2qaTatSgq4OXFwdAwiLQyPYO+69SCCQtfM=; b=owEBbQKS/ZANAwAKAQAOaEEZVoIVAcsmYgBpC4EtYO9g213M0+4Xu08/XD5YLvG/YRoCjGRHa a023/sFBO2JAjMEAAEKAB0WIQRLwNeyRHGyoYTq9dMADmhBGVaCFQUCaQuBLQAKCRAADmhBGVaC FURQD/4ooSEC0PkLMBZot7lnVw7U+E5RpTPjIttF+PRS2fFgtiPU7b1k+61+KC6ofprR9z6D3LC hW1FT+ESskSFFKFhpVdWnT2QTOstrQUgmAxRXcp8wbvK4KHruI7lIVPiEaZvQ31sh13EvOh3I0p EYMSUlXppIGTMPK22+n3Iy5N3YpnoWOyEsI8jWsoP1otSbdsBUgFfF5Tpvttyhc23Jz+0Mo+9pq Ia2qZc24IFGaJiRuwuFSR2n0aKaRfhCbY9AnNoepz0qozHqzAbNfj9eLEvT5i1E329tx9+RhsT0 GcJxKnGYQymJWyCq2O6Ejcpr8IY8LdomLqk11j0KsxDcwCjXLUDreOoJK0bkowc2qRlRsREDu6G Uz4TkBJfqUZUPhx9+Z1W8WnZ9euI5vbXzQ4yfo0u4pelNlMi/cct5u4H/xHf5NaBLRIBopYArTX kBOAmkM/cDswicc6yhP8bSFGdeqbxd18uuFSugh78VgyDIDfXWFcz+YDx4HC2e9kY+jWL0yLoy/ jDXO44D5ile0ijwAWUUffYcEBRUpcI3dXXrrLh56bLeBIm712SVpQ9Jdg4vlK3SOHg3nX9GQkkD /3L8R7eBKN46swf7iqCXc9zQIAjYygxEgl6MbcEoIP21XnO4hUjO6aneT5FSU5A0l0EGoP+qLRP d50Ibh1FhDJARgg== X-Developer-Key: i=jlayton@kernel.org; a=openpgp; fpr=4BC0D7B24471B2A184EAF5D3000E684119568215 Now that support for recallable directory delegations is available, expose this functionality to userland with new F_SETDELEG and F_GETDELEG commands for fcntl(). Note that this also allows userland to request a FL_DELEG type lease on files too. Userland applications that do will get signalled when there are metadata changes in addition to just data changes (which is a limitation of FL_LEASE leases). These commands accept a new "struct delegation" argument that contains a flags field for future expansion. Signed-off-by: Jeff Layton --- fs/fcntl.c | 13 +++++++++++++ fs/locks.c | 45 ++++++++++++++++++++++++++++++++++++++++--= --- include/linux/filelock.h | 12 ++++++++++++ include/uapi/linux/fcntl.h | 10 ++++++++++ 4 files changed, 75 insertions(+), 5 deletions(-) diff --git a/fs/fcntl.c b/fs/fcntl.c index 72f8433d9109889eecef56b32d20a85b4e12ea44..f93dbca0843557d197bd1e02351= 9cfa0f00ad78f 100644 --- a/fs/fcntl.c +++ b/fs/fcntl.c @@ -445,6 +445,7 @@ static long do_fcntl(int fd, unsigned int cmd, unsigned= long arg, struct file *filp) { void __user *argp =3D (void __user *)arg; + struct delegation deleg; int argi =3D (int)arg; struct flock flock; long err =3D -EINVAL; @@ -550,6 +551,18 @@ static long do_fcntl(int fd, unsigned int cmd, unsigne= d long arg, case F_SET_RW_HINT: err =3D fcntl_set_rw_hint(filp, arg); break; + case F_GETDELEG: + if (copy_from_user(&deleg, argp, sizeof(deleg))) + return -EFAULT; + err =3D fcntl_getdeleg(filp, &deleg); + if (!err && copy_to_user(argp, &deleg, sizeof(deleg))) + return -EFAULT; + break; + case F_SETDELEG: + if (copy_from_user(&deleg, argp, sizeof(deleg))) + return -EFAULT; + err =3D fcntl_setdeleg(fd, filp, &deleg); + break; default: break; } diff --git a/fs/locks.c b/fs/locks.c index dd290a87f58eb5d522f03fa99d612fbad84dacf3..c52f6a7b6a5c633ff0157624990= d81aaa055f1ec 100644 --- a/fs/locks.c +++ b/fs/locks.c @@ -1703,7 +1703,7 @@ EXPORT_SYMBOL(lease_get_mtime); * XXX: sfr & willy disagree over whether F_INPROGRESS * should be returned to userspace. */ -int fcntl_getlease(struct file *filp) +static int __fcntl_getlease(struct file *filp, unsigned int flavor) { struct file_lease *fl; struct inode *inode =3D file_inode(filp); @@ -1719,7 +1719,8 @@ int fcntl_getlease(struct file *filp) list_for_each_entry(fl, &ctx->flc_lease, c.flc_list) { if (fl->c.flc_file !=3D filp) continue; - type =3D target_leasetype(fl); + if (fl->c.flc_flags & flavor) + type =3D target_leasetype(fl); break; } spin_unlock(&ctx->flc_lock); @@ -1730,6 +1731,19 @@ int fcntl_getlease(struct file *filp) return type; } =20 +int fcntl_getlease(struct file *filp) +{ + return __fcntl_getlease(filp, FL_LEASE); +} + +int fcntl_getdeleg(struct file *filp, struct delegation *deleg) +{ + if (deleg->d_flags !=3D 0) + return -EINVAL; + deleg->d_type =3D __fcntl_getlease(filp, FL_DELEG); + return 0; +} + /** * check_conflicting_open - see if the given file points to an inode that = has * an existing open that would conflict with the @@ -2039,13 +2053,13 @@ vfs_setlease(struct file *filp, int arg, struct fil= e_lease **lease, void **priv) } EXPORT_SYMBOL_GPL(vfs_setlease); =20 -static int do_fcntl_add_lease(unsigned int fd, struct file *filp, int arg) +static int do_fcntl_add_lease(unsigned int fd, struct file *filp, unsigned= int flavor, int arg) { struct file_lease *fl; struct fasync_struct *new; int error; =20 - fl =3D lease_alloc(filp, FL_LEASE, arg); + fl =3D lease_alloc(filp, flavor, arg); if (IS_ERR(fl)) return PTR_ERR(fl); =20 @@ -2081,7 +2095,28 @@ int fcntl_setlease(unsigned int fd, struct file *fil= p, int arg) =20 if (arg =3D=3D F_UNLCK) return vfs_setlease(filp, F_UNLCK, NULL, (void **)&filp); - return do_fcntl_add_lease(fd, filp, arg); + return do_fcntl_add_lease(fd, filp, FL_LEASE, arg); +} + +/** + * fcntl_setdeleg - sets a delegation on an open file + * @fd: open file descriptor + * @filp: file pointer + * @deleg: delegation request from userland + * + * Call this fcntl to establish a delegation on the file. + * Note that you also need to call %F_SETSIG to + * receive a signal when the lease is broken. + */ +int fcntl_setdeleg(unsigned int fd, struct file *filp, struct delegation *= deleg) +{ + /* For now, no flags are supported */ + if (deleg->d_flags !=3D 0) + return -EINVAL; + + if (deleg->d_type =3D=3D F_UNLCK) + return vfs_setlease(filp, F_UNLCK, NULL, (void **)&filp); + return do_fcntl_add_lease(fd, filp, FL_DELEG, deleg->d_type); } =20 /** diff --git a/include/linux/filelock.h b/include/linux/filelock.h index 208d108df2d73a9df65e5dc9968d074af385f881..54b824c05299261e6bd6acc4175= cb277ea35b35d 100644 --- a/include/linux/filelock.h +++ b/include/linux/filelock.h @@ -159,6 +159,8 @@ int fcntl_setlk64(unsigned int, struct file *, unsigned= int, =20 int fcntl_setlease(unsigned int fd, struct file *filp, int arg); int fcntl_getlease(struct file *filp); +int fcntl_setdeleg(unsigned int fd, struct file *filp, struct delegation *= deleg); +int fcntl_getdeleg(struct file *filp, struct delegation *deleg); =20 static inline bool lock_is_unlock(struct file_lock *fl) { @@ -278,6 +280,16 @@ static inline int fcntl_getlease(struct file *filp) return F_UNLCK; } =20 +static inline int fcntl_setdeleg(unsigned int fd, struct file *filp, struc= t delegation *deleg) +{ + return -EINVAL; +} + +static inline int fcntl_getdeleg(struct file *filp, struct delegation *del= eg) +{ + return -EINVAL; +} + static inline bool lock_is_unlock(struct file_lock *fl) { return false; diff --git a/include/uapi/linux/fcntl.h b/include/uapi/linux/fcntl.h index 3741ea1b73d8500061567b6590ccf5fb4c6770f0..8123fe70e03cfb1ba9ce1b5e20d= 61b62e462a7ea 100644 --- a/include/uapi/linux/fcntl.h +++ b/include/uapi/linux/fcntl.h @@ -79,6 +79,16 @@ */ #define RWF_WRITE_LIFE_NOT_SET RWH_WRITE_LIFE_NOT_SET =20 +/* Set/Get delegations */ +#define F_GETDELEG (F_LINUX_SPECIFIC_BASE + 15) +#define F_SETDELEG (F_LINUX_SPECIFIC_BASE + 16) + +/* Argument structure for F_GETDELEG and F_SETDELEG */ +struct delegation { + unsigned int d_flags; /* Must be 0 */ + short d_type; /* F_RDLCK, F_WRLCK, F_UNLCK */ +}; + /* * Types of directory notifications that may be requested. */ --=20 2.51.1