From nobody Sat Feb 7 08:27:26 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id ABA4730DEDE; Mon, 3 Nov 2025 12:52: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=1762174374; cv=none; b=Hk7lARYCEnS7VR9ZeMJy82gblZnriL6wFhhKiE5fEe51W9KlfsD7cRMsjSPB+pSUemg9sV9YdjHXpCm/+amxOKIBYmMfqoS11OLJ7+f4J0Gw2BfB0FNvPN6kehlV4wZ7u+zh6nUOCCq511dZYXbDZwqrgt3AG0EVL2/8pZiaq1U= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1762174374; c=relaxed/simple; bh=DYoclxA9VZrJYyH2ZjWf3xD/XgnD9xjMazzJyvQdh7g=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=GrMkTBlLRSDBPcAA9hyOa4YAH3gSIlvgfb2LVGBXxW691ayEag8QmiPae3ZbiC1e/ZpVa94X11HIV5RbFoL1Hl+z18HBuPtogSwNKROVW1PdcS9BTWZMW9tvMEwZsk1vbqpNXPuTZ2mdC/2CdascpuFmhNa2woe8TV5Sf6bcDCg= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=NR1zJoP8; 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="NR1zJoP8" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 12CCFC19421; Mon, 3 Nov 2025 12:52:51 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1762174374; bh=DYoclxA9VZrJYyH2ZjWf3xD/XgnD9xjMazzJyvQdh7g=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=NR1zJoP8/qYNRoKn8wIVBBiJefwXKSiHbVyTKEZeNYBlHEr5slnC6gQNyeUyH2Chs 2ragPzFggE+LiABTAAEvH12jJjTcWZof+jNRXmshP51gqrxqDTGfSNO5IAjpk0C0MK XS3nBPUdG2ZRPs0a9FZfQgNKhBgHoZba/0vEFJ/Qq4ml6gIhBmI+3CzXgf2Cl0e70v MWKY7PTijxgRZ82RlvVeH4Tb+UqkZkzoqLg37UZD4kaWKTaFwkFqTyAyy/v70bxjmU JhbFH8EM/k4KwQvXAbkIq56Uyxq2jWwyfIdVOHJ1ZuMVEmFeqR0/QkSL3aKsaFEJKp qAg6QGe/ispPA== From: Jeff Layton Date: Mon, 03 Nov 2025 07:52:29 -0500 Subject: [PATCH v4 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: <20251103-dir-deleg-ro-v4-1-961b67adee89@kernel.org> References: <20251103-dir-deleg-ro-v4-0-961b67adee89@kernel.org> In-Reply-To: <20251103-dir-deleg-ro-v4-0-961b67adee89@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/ZANAwAKAQAOaEEZVoIVAcsmYgBpCKWbf4MlvbYriNtvr7x82KNxfScMHm+Kjrld9 eBtqKtwhSqJAjMEAAEKAB0WIQRLwNeyRHGyoYTq9dMADmhBGVaCFQUCaQilmwAKCRAADmhBGVaC FQfVEACNLUsYEx4R9itULq3/9BW5ZDttkRzCMZbER2qzLD6nxPBPhCS4tiqvmW0wEcAAzDz8OsP tFjwQXJG5+iibs7uQPZoZY0N46jBuiCkKp+VisgnDbVsx8lh9b03MfMYNrZ9RKZag91Ge7Gv+D9 D+IOG8hJIoresxeGFIT+cdb0OCQCZ1rmO1sRy/lHVbkpIqo+PWOu0plu4NlDpzC4yS92MbPlfaV Osd1hRInZ3m0Im7C1SS5p4QqloHpSrGd1F41x9p3Fl/0AhZzfLtFj3LC6s9r3+bww6wezfoC1LH 1Ok49UsPqfOKpQEWVh1jblkFXuM7xmsbJ7cdwiPFLZ0sDwAfDMlAkyEDQ6MqRFfLfe5masdBk9L DVtXJsSmq4SsQS5gAVxLmVASlV8azOroFZgQSL/d7zfxO2gfK3HKdm8g5ITkQiPo1h8ppMIsbqY SzoUzyLHCyaILwy0JEFc6Ti9cnWosePdQB2RCblDzxzePOKeDWGC5Wn8XwKe2NEbdGBbwRvnzHR h8ED+RkQm35+Cg8COgN86JLp8qGNPip8JvC8u08Ly4PAlss3wOeTeT3F+xpWKXV6XFkLN5p8csV oSNTw+xn4jAkr8iIB7AEIVdBDnVLsRL85ONTRusjj3rdqalNFhSMzWYUd9NyUrNJ/RImFfmCRNB oDlFM0dxKhGp31Q== 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 --- 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 Sat Feb 7 08:27:26 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 0B6E930EF7E; Mon, 3 Nov 2025 12:52: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=1762174378; cv=none; b=OkMvMhjvvgcpZavodAj21wO+9SHn8PHXJkU8NeZASj315K91QvdSyHtfwkjINr65g9QYZf98VIlXfCndwMZpncSOu+/Ic5x+vrttMNbPDHlXkHXL9px2KDMD9njxxdgH9BKp1OU0jpdUTSFWjdotwRS4d1cr1EKHgV1FaDK5nng= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1762174378; c=relaxed/simple; bh=GnymqP1pjrUzX2EzwRGc2AVY+sxr9dx2mMhp63lQzMg=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=Cu+8vrv6HGs1lcOqvpVI89jmVyyCspgmOqfGfgaQJK4xdwhexXKiqbcL1Pl/ZjiohtdURJ/cP4zZr0YE0gw7nBEE8Jw8tB3JfxRONpbfLFqVlcPPVES0f3HuEGUIqEgbzJxCjU+N4uA2YAWUPklD8FUwQzYdRjxzkPBQcj1GJfo= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=QqmkvBxH; 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="QqmkvBxH" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 75BFBC116B1; Mon, 3 Nov 2025 12:52:54 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1762174377; bh=GnymqP1pjrUzX2EzwRGc2AVY+sxr9dx2mMhp63lQzMg=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=QqmkvBxHD/A5VhiFk4JURGaW63GjoAw3rdD8bgIuYoGuxiutRfdKP1luJmWhLcVyq L0hrQ7R+nktgQzfW9sG59x2hjRDIB1oMSNkKPrHjlptsPYvLiNedWbSvPyphoIVxUT YGhwvusoxRA89sE43dSw51U4Fr3q2tbWeGjw6G3F/Et+wx6XkFzf1yap8j8YTWj3jM X9bLfCHuyMbFt/9tEVfCqXt7/BYlz++c2GldwCIog1dlvI2vaWA2LyzreOJokHCQ8e tewUP7ciC7B2hQLbW9PJXP2u/w1j594hxFlxNja1iE56P1lrSbiNT1rhCrJxm7WNDQ mGSjxNENvhj6g== From: Jeff Layton Date: Mon, 03 Nov 2025 07:52:30 -0500 Subject: [PATCH v4 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: <20251103-dir-deleg-ro-v4-2-961b67adee89@kernel.org> References: <20251103-dir-deleg-ro-v4-0-961b67adee89@kernel.org> In-Reply-To: <20251103-dir-deleg-ro-v4-0-961b67adee89@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/ZANAwAKAQAOaEEZVoIVAcsmYgBpCKWcGxXe9a/raZjhuA+PmjmirQgEt0MHFP1Gu 2W0Ge8sy2uJAjMEAAEKAB0WIQRLwNeyRHGyoYTq9dMADmhBGVaCFQUCaQilnAAKCRAADmhBGVaC FUvTD/4wqLWLTGbFndHVeqqaU+4Qa2xv1eXe1EPFsR2kZW7dioQ1gSZ7OzYzsLMCl+2mzobV/8f wo7qsRa+En+XnT4k9znXNPb03yp0Y4V78MaX8i5T5vPUheiG/CZVLOul1+1UKXtDhPjE5cogT4p Geo6Z2kTf1bfPHvaLFPOWIzxATuq/LZheyr+8ZEZZ901cmP5An7tt9r+ZMzOHiWbFrxFrSovA9w OLJHmb1SitkF2nPJk86GwO5SiyEMKlwI6jYSnyi25FNYyOgCXG3gL1JDou2nsmhSDzUJtXElbAV lrnfPyUXgZHP9QfkN70C1af8YLoVZmIWOtFMGo3MPUMxhtImo34mZnI/qAxbH5Mowo288NqXEfH A5JaPYtVic9sZ+hmlDSKysUUYKEyTxaJbGyABmTQNWmfDLIfZKynMESjtOR19ytme4PZlpFLoVe uvTPiK/M6INLPtmjncu2PixpAGci0eeD6vwO7LsW/BCZ45i+BwvbvAI963FQk/nA7+xvnWBmu5+ 5AV6BnQldUIKxX4jolSj1YPMmr1pdzbTNrKYybW7E8nF9witoRnP2nAAhdjM98m8Fa8VxcP+X2V qjDiHdXpxWsnmeHtj9kgr2StDBRfhlDmqzExpoCX7oK30B2ot4Fe5fZu7k4tLCRvxsawdzp9rG4 iQBf2T3ZbcGlKRw== 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 --- 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 Sat Feb 7 08:27:26 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id B5A8C30C602; Mon, 3 Nov 2025 12:53: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=1762174381; cv=none; b=gQIF84ed/jZv8baQ2VsGF9khslq1UJ43ggEd5xFbS8x1HL2YsrKei4kS4QYXWb63KjgVFtm8MmEXgD16HrDUfV3bV17PbAeoBx728G0wqwvnZtvHAWP2/mhdjfnNPG0mE5Vi8fPdWnN1AHxHUnt6T4SCKHrxGAQ3lnNRUqm1ThA= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1762174381; c=relaxed/simple; bh=NZgsNwo0HMF8Ou2ZnfkNmLyhRQ5oAfi4T4iI9rqixAU=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=ED9uhYOlX/eopKU4zXA+IySJPnEV8bh87Jjdhy5LDfirgKSvD4M77WGoUKuA3PfXMnI04OadUAYvrSJV4/B8ETNyK3AubsdLJLOYTzONbNY3bK8mwaHfx3SdAyas7l76dhhvdMAmaszuBOWjheYOwrHOif2Vm3QbWwrh0U9wUMI= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=BwsyZ4k7; 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="BwsyZ4k7" Received: by smtp.kernel.org (Postfix) with ESMTPSA id D76DDC116C6; Mon, 3 Nov 2025 12:52:57 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1762174381; bh=NZgsNwo0HMF8Ou2ZnfkNmLyhRQ5oAfi4T4iI9rqixAU=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=BwsyZ4k7niFBi8Q/HmR7wZp+/qLtY2LpOVODOA1jY/vN3LY3OiS7i8SO6O2/N4CIb FEmjTeLw1/w4whHBrYs+x18i2tZVVYRtMWWkQ6H4FRqEDQyPXz2kAcnAETFxcCVk8i SshtnCETMHZ2m+otr+8fogGjEplj9cmqvq/efm5CyUvehtZ/iIjxD4yUs4H+APDmOW zprsAATRS0Gvwn6MK8C5GjR7N5ZgNadSSorAgMC4p3su4sHNbYHDZmSghyDtpK8kSJ yBff4ayCCEf1HJxVFApN03NJLARiuvm2WInUQtzRZxRPQccUcq73LzeaBDDXvHICnK 6CnOgtlc2azwA== From: Jeff Layton Date: Mon, 03 Nov 2025 07:52:31 -0500 Subject: [PATCH v4 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: <20251103-dir-deleg-ro-v4-3-961b67adee89@kernel.org> References: <20251103-dir-deleg-ro-v4-0-961b67adee89@kernel.org> In-Reply-To: <20251103-dir-deleg-ro-v4-0-961b67adee89@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/ZANAwAKAQAOaEEZVoIVAcsmYgBpCKWcL2Hnh7sUzBumMUnRPuisbiJ14l72a4y4p tm1dXG6S1GJAjMEAAEKAB0WIQRLwNeyRHGyoYTq9dMADmhBGVaCFQUCaQilnAAKCRAADmhBGVaC FUlmD/kBhukQIws3mjwqXHQU7NrFjiSq/Upl+WGGHGFxJklRZbrAIoKJ4A1Sp8UzpjA4N9yqAAk xLI5prN3xDm1W/fzaR8t3qm6YPE2pSf2KG6ne8nz8eb9cO0FRVsC6TmCrTq1zuV0uMbW9v+hkrK 2dKh8tndVSoS5KbwYn5WUqSty8HQcj8MooGtdLeJxh9TAthFxHmij2jMQYkukbZC+MuxLqBhja8 enzZgsPbY7uHLLAHNtoIRb/5DuBLxRyId/sxJPu3yalyxUQy9UugPvJF0Znf1sEwR+RxeCjeKRj UgQEcGELWL5OgSQiGmkPUT1toMcxIliaLCOR902YiYY/LiZDNkKRIdBnP/SHPDmIX+9LMWKBX2/ 2cRN1E68vi9YlKzMZzd0mGwvCSrmxwD9WHiITnUxAwtoHGvZa+WlMtgZnbfBhvnbg6DTvNAzZw2 B5Ht6f3+Q5jdef0E7Y3/oK71xG6ISOtSxQR/IdEAVC/mLA3Vqz8Zw5DVg17j5WLo1u+hBQ+5BHt EF6SGYHmxeRMtZi3ejDMz6UT6eV4DdyXF7Yq/tw4g33iUFxA26XPrHl2S5lijAngRTHcDlq0Qkw GekEPT88fmTeSCMe0dUvKvHeoCAW6hW1kIL3mW+nCchxD2JwcJItKoToGWzliNpU5+vRBDoXXPJ 6z8bbedLDG81HgQ== 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 --- 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 Sat Feb 7 08:27:26 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 224563101B4; Mon, 3 Nov 2025 12:53: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=1762174385; cv=none; b=o5yNyf1pPd+yf7MiTwCyp7zDm1fTtjRdY85HLiXTSp1Pym9KUR/fB6qiAadvv68pX1iIxefdt4ViWQDkMGMB/EpJc0S0NVioR7RbfwqNyKtUZJsOX2F8rm20nvAayOXUieDidfbSgiMg83lnbbPp2lEw+i6gOZMVvOufkeDfaZA= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1762174385; c=relaxed/simple; bh=GcsMrS33yeMCZHbhLsrwn2fXghDYDgJpfU5BwKmzfzs=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=JYjePbRO4RUrix5zI2zbK6vhguXpQMyRJAwryc1lWp0d0kBz19Le1CrnA6hjDBZ3HJ33jTdIKbOKN7ZcNMI2vh0KQNSJ/s33KT7N6Ohbjom1l8TbTm8hMXT6e6LqkldDY8BT9mc/IjNQW43uiokEug/Fi9aD/c3lxtW4gLoX7CQ= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=dg4fQm5s; 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="dg4fQm5s" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 6E857C4CEFD; Mon, 3 Nov 2025 12:53:01 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1762174384; bh=GcsMrS33yeMCZHbhLsrwn2fXghDYDgJpfU5BwKmzfzs=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=dg4fQm5soAyKA3v+1JP2aNfcipOpouAI/3YdPAADtM+IHvepxzD3ZEkMa4HmGLHRN lcsuaKbsAQI2NzoLQuo1LsEQs2gCERf10dxbqOA5FU0z5JjUW8fXxpUMaAMU282mIP 5cvBE9tldxaEJG1V5cytTNMG5SAdNmzKrHXqgea4bYOI9Y1agm2DimU4AdgajEBLZN DxFAmpCwaSXex/8fPTVNnrgOx8IUBz10EEcjU6CfhgdE+2e6CoDdII5ax4AZVzTh9r bbIb2O3RU3piRAXYpY6meifjq7ebVdte+o4589bbp1OjC8SCpUVgdBxvzTTIYrBXAa RFuQJcPwLQskg== From: Jeff Layton Date: Mon, 03 Nov 2025 07:52:32 -0500 Subject: [PATCH v4 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: <20251103-dir-deleg-ro-v4-4-961b67adee89@kernel.org> References: <20251103-dir-deleg-ro-v4-0-961b67adee89@kernel.org> In-Reply-To: <20251103-dir-deleg-ro-v4-0-961b67adee89@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/ZANAwAKAQAOaEEZVoIVAcsmYgBpCKWc97ftCqyzCG7IGvXML5YmMsCRGcKaqblYR esf9TI/CTeJAjMEAAEKAB0WIQRLwNeyRHGyoYTq9dMADmhBGVaCFQUCaQilnAAKCRAADmhBGVaC FTRQEADQnOUc1rtYachjMJVYxJ+ro7m9R3DGgnYVF5HZgvodW1Q3oe3qjJiG1KD6/LmUhHxwtw0 nZiYqtKEW1e2vUUhWgWkqVt/NioQjjfil/Jerb0g5XqWn1sJAjCF6pfuUlbbQ9CI+smUjKFvdfE 0qzEFrjiXg95hYi+pI05maVzwQHt37BFUgR/le/knDbX5VfpNMUpgzk5j1K1t76fr15i+FBYE0q ae8nojCvlvJ4r7QIj8160xgIm0Uy8cDeyWGQRHdo5KrrciHJ2LzOlKAt/e47Cz4icrK2OJbBxh7 gcMmPaaOas2qqiFntW+jgIIdZsvrKS1kcp7UcAQDRbmLC/QBbJaySGKajIsAszmPjbNP0VCeTXm EMA8N2YufhyYcf3SbdpQAVYxDXy/PrGLz1qp+4bS2p+fpOo3xqvzRqf1mDAFNdF6Eqzl6eNJZcn qeLyHoNc68KmiH9l/H14JpobB18L31TgJ3PxXCO16hQz4QsqK09Lqx0a1TNP/NK2UnCfV6eajIb Wn/MrZFXWiJOOg7z90ItpH7fHA+v6kKd5hztLCym41yRhXnidkx+4YeRgQIYbLbSxoAu9V4DNvi Z0tbCDu1sbaPsYH3RfVjG0VdpeW4f7j4GKGIn4FAJLM8Y9GSPm4yBuOhn7TOEKrBAeoWxmaFGtl ZZFqYrMp2q6nWTg== 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 Sat Feb 7 08:27:26 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 7EABD311C1D; Mon, 3 Nov 2025 12:53: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=1762174388; cv=none; b=fL+T/JxSdF96ari4IrwiYuZMFFkcyI1B478+fxzTwcj2FRiEyYdz0A+8BIpeVaMo4MD0yV1VkilhXsjwzaNDSt4YJFvTDav9OPMSqKnN//uAJoNBZwB2sk6ndHVPENlQ70AvzF6dVv2m2s0INtpAZQhIq3P+uk+HMt9AdYMzexE= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1762174388; c=relaxed/simple; bh=3+ZClpFIpySqsQF9IacI3LgDcwpX/JfG6YtjN83vd9E=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=MyWtHGFuF7TGiRfiGelTZ9mQnzvDBJLW1GLXQ1Jx3LgmjKC2y+GQDM4p6AM1R7yH66X1QAX0uUMZMXCJJBqhu5REOUh7C3JZfXuET+YW+j9Ckn0sYz2jYJ1hljWov7zAmXqFxnPWaDXbNfwYZq7YwXijnbnmqcrt6R+l3qzOHN8= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=t8WNuQZf; 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="t8WNuQZf" Received: by smtp.kernel.org (Postfix) with ESMTPSA id D627AC19421; Mon, 3 Nov 2025 12:53:04 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1762174388; bh=3+ZClpFIpySqsQF9IacI3LgDcwpX/JfG6YtjN83vd9E=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=t8WNuQZf/kzSPGRjVLQyzGc7WYcDArrpNvuVtYBmgiak+XHJfo+zNiB3GdwPOEAR5 8REUMYjXWpcpF+XWu+L0bzkHygxUsIvUm9yvyL4zHbi6jqXJoRRgac6D2+IwcKPtuz uSxjKPLUAb0FKOiCt5tyZpA9eFxYuumJsi+SZ3ZuEQBvYgXy/AxU8OJpCNsLCf52v3 iNaTLXw8oA29Hsou8rZqA7ZQ46bIxHZlebaeCjTJOJelzSzxKKMlXmq0lQUNbVp4aa iitJdvAkSyhFxGBeHLqP0O4CvbanacMWZohgfaY2yVrzhPWQcEGhZxaFb6dWdUcFV1 ZKySgJ++7YK5A== From: Jeff Layton Date: Mon, 03 Nov 2025 07:52:33 -0500 Subject: [PATCH v4 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: <20251103-dir-deleg-ro-v4-5-961b67adee89@kernel.org> References: <20251103-dir-deleg-ro-v4-0-961b67adee89@kernel.org> In-Reply-To: <20251103-dir-deleg-ro-v4-0-961b67adee89@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/ZANAwAKAQAOaEEZVoIVAcsmYgBpCKWclntQx/8PRv2BbaTngqKuyH32QU2T1bZ/I soArbOjwd6JAjMEAAEKAB0WIQRLwNeyRHGyoYTq9dMADmhBGVaCFQUCaQilnAAKCRAADmhBGVaC FU1iD/46oyEma0ymTkvoMS8V+8HmUzthQ+9tuWdLHyybCM86sjRa8l3a8hXUUnwaUN/wywmzwGT 7a+0wiemnErUCEq870UsbCTeSoslaZYNWkjJtzirifVaKdEZB7cj/uoRXIRQty9ks14PuWaLc/V wP6OEM4zpRTK3q3hDd/b9A6pGAGPA6z2Xi/5BI6oQhAFWROKcupgF+J0IluG1d8Z/zKZtY0VmJz on5UOXJuTxYPyUdSuCMVG4kg9XQGkLSgOEHHOVpBNULJt//vZE2CvyPpAZoexXKA/jhE8raoTXt Okv5+nWY86QPiVR4t6IFhpG1DlIcYq928aMyCXYaup0j4QBhYl8CgNSw+iaVuwbhAW9DTTa0q2P H/QhWBLTSTWcU9MnC1iJVgy5W4zQF3PukKVJRGTgXG1PZOklXL7CIIMB7X6L7y6RvI5x4UQiNs+ NkfliFKkPBiK5DCxqTV9yP2bEL2Jw9dvH8I70i9fZqEDCGQUci1RhKv7+8H+nMYVxUVl47WQQaC c9YeTj3jD5LPrgL1lwlU5+P5zkCAFjTp5n8M/AZgeXOdWOnnqfP74MBvMFZox8tQDYLNobMatt4 qGjMpW3nAL7CtDWIP6J+BR9c5liexCLRZnt3CFO9ENNV/rlnzy+y2ccv7rJtOvMyJ//j+OKzmlT mANTXuVPQE00S/w== 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 Sat Feb 7 08:27:26 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 8E34A312811; Mon, 3 Nov 2025 12:53:11 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1762174391; cv=none; b=WG5qUQH9tX8krBl+exKskskHOGlLbdPRH8oYaj7T+wYk6xuYi5cMICV4p1rkAoRduPiNXSRTcCm4iat43H28JS7Tt+WKT8k/Ish3fAvndfNReb2E+00PfBcxA7npIfY2+xNY7J8cXqZd1PNS1PNdK4ElF3rISuxopvPIvBwDRAs= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1762174391; 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=IMvFH5Tnx3bbyq3TTs5yrmwxC7ZDjHqSuUp6EBLJVrtunQxqVG2WcqFo2CXrStneUQehmV/hC8Y6FTNRwLraJXpB7UkxrVZzYdYypdJPs6Vpl2AR3zKfpIxYmE5GCuX3oRZ2HO/ZhQOisK2Q4DMyU57gx9nXJc84flyihiMCUZQ= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=cGocjzKT; 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="cGocjzKT" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 43502C4CEFD; Mon, 3 Nov 2025 12:53:08 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1762174391; bh=Abg5p2Lt31TlE/xurhC/XlffrDJLd5VW/QAzqsSk4cE=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=cGocjzKTKwgkB0U5jYi+t8Nqft5Qr4+UVgUpOf+IdFuoW2sWzZICll24l8ERwOfMX 1laAbKKVAEbp3uVEEpO2gCR1ptiWwN5rqiKhoryxqANFdLx16r5XMxV2ar4NohsVKy ygscKqHIqbKuex1yVpQyhT154uaiZ2Entti1O9e2XR7tZZoHJERFNcyBWS/+37d0t/ 1wo5EoHgxDbwFVtPvZQOS1Roa0CEFEc0VkYEhlCHS+gEMG5Qd/8QLCSQxfnMod3XTB XYvb52suzu8s7l5Ot44h6jVkQ4ce3MlFVf81pm5PUFwSRRMKq963WBFOu25mCZkf0q 2YaUCiwqafxdg== From: Jeff Layton Date: Mon, 03 Nov 2025 07:52:34 -0500 Subject: [PATCH v4 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: <20251103-dir-deleg-ro-v4-6-961b67adee89@kernel.org> References: <20251103-dir-deleg-ro-v4-0-961b67adee89@kernel.org> In-Reply-To: <20251103-dir-deleg-ro-v4-0-961b67adee89@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/ZANAwAKAQAOaEEZVoIVAcsmYgBpCKWcR1Qht8ekwA0ZBgB01/KBRuqP23ouw+Byi 6wDZa2GfbiJAjMEAAEKAB0WIQRLwNeyRHGyoYTq9dMADmhBGVaCFQUCaQilnAAKCRAADmhBGVaC FajwD/oDNkM0xhUt8g+DQT4tQubhRSTHkKkCMKx1VhTGXNj4lWars4M58TcIjKmYBwbGl9KXYli u20zbC64lvl+/JC4D7lgEJNtqYzLzkbZDZ6YZ4dZOdpwIp7IHR6KxnmQaQjlq10pocmBoTGOHlv ETuxnjU+1RDH/hS70G7pTTYYgv3rSkBQdgaYDosc5LT9OrryhQISoG+b0i2WrlbywaFD5Gnd9Qh 4ecn5QDNwsLMAW6100srZZ07DM0Mw5Oe4Ub7q9GOdAjeVrqAOgomnvbbiPx+5UNIuTX0kss9oml RnZ6MTFBHIH1CNw+T0qC7qbvEdSHrRnSeoBaE/lTa/ANMRqFkWH62eJJ03QXrcS9LdLmR2axaEm eiOmnlghZk7ai4CXMO7gZNuDIkWdDujkENarQmLpxbXXrlHnbqQhZx2wj63hPDefEdN2gN37+Uj WbD3ZrApgp7J7FKFKcpEsMQtXtnzgsAmbb0BMuy4NMyNveEhfJZPtoveSZp0B0uYaCCjto2BhlJ FIIdDL47oPafJH42xze6vTD6xNrPfMMYeTSqHG+Rxb/Ip6S7Q1dPNREub6MGVds+sxRBnGKy8lW Zm0VF2uwlGRDIpO9UOyH+YDwofjsycuHpOV5KN/fbUdzEgXd9Ui22ke6sw/vhyOplidmsDU7d69 A4zwz+le6TmNPcQ== 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 Sat Feb 7 08:27:26 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 5354D30CD93; Mon, 3 Nov 2025 12:53:14 +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=1762174395; cv=none; b=W/8pJl0Gne4F2qop7pPB80Znw+g3x3Ll+ZPUlcoz+nFDz+pdf0AU590KxzHgY2mIZZmqOjXnyEXzuzmhDhYlfrnl74YB8bpDsoaTg8Jcel0wCot4oks11C6zqVZOo4qYa4KQqvbqgVac+yyYnfpIzOKoejszWX3GjPRTyqUceUc= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1762174395; 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=I9s23YrinoHAk7/ZyFeg0DxWFZoWxUoPWpreBhUylMJl3sUykyhGlwQiDPUAktsnLXPccXB6Z2ufS1U+aTkeOkOnU9IQwXJYA6WEtFabAujxntrEIzsk13kftPuKXIzx4iyzBLuOzrocTtZbhTqAyveuXHSDoasUZJAghdxIjM0= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=vEiT6zHT; 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="vEiT6zHT" Received: by smtp.kernel.org (Postfix) with ESMTPSA id A6FEBC113D0; Mon, 3 Nov 2025 12:53:11 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1762174394; bh=nVt7zfcxkLtFpIV/AjQcJVwofL/t6x0LVRGY+VtgUx0=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=vEiT6zHTzVQU/cRHnlZ9aCSYOOp9du0FhGDlg4JbggLJAsN3CVALf1WdBlMsHZ98v BScqORei480Q5rt8PPmQXdRxIysdi6zmF1rzYtKg5UNbfjkCmPVboz0B7wkP2rlamp dHX+HgQoxdIhUIHaWkKyyHwIHEGVY/ITMxS82iZ8cga6ePZc1Ldq57agaUEoc+cuvG vYgt2Gao8xsKjb2iDRIf+pvWxRAdT425rb+7m8VzpzwKOz6o2b3WFUhhzjXsd5mH5g 7+ebyid8HO+ZVjrXPY7f20YYoPfnNNeY7vWknFW0FFoTPCOyCAS68VMAPXfllIugIx BNk4+BsT4h++Q== From: Jeff Layton Date: Mon, 03 Nov 2025 07:52:35 -0500 Subject: [PATCH v4 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: <20251103-dir-deleg-ro-v4-7-961b67adee89@kernel.org> References: <20251103-dir-deleg-ro-v4-0-961b67adee89@kernel.org> In-Reply-To: <20251103-dir-deleg-ro-v4-0-961b67adee89@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/ZANAwAKAQAOaEEZVoIVAcsmYgBpCKWdVnH6iVO2egGrv8Hlrdun3EU7EQFW3JTsT aRMpOJ+/biJAjMEAAEKAB0WIQRLwNeyRHGyoYTq9dMADmhBGVaCFQUCaQilnQAKCRAADmhBGVaC Fd7XD/9fO9nevHI2uPTFOHWuK+62Fmkb9oL4/SiE1kLdQu95F2Yb1nxw+iihB0KAR7IISMp/pzD H3/MMhDkZ/D3nH2+sQxTUh499ygeNFwVxFcn6XhZClHsd7yYTuSjnmkG8KZrd9Qdi3Rc8ih6d2p JEHQXqK76cQ8MhcLCvFy0g69DiOJQAMyed2b1eepymyOhHJfB7ESHhirp1gxtkONfqVtmha14hp ZaLfKbg+D/06yDaH/VE1u5vHX6UolVcJ/7IfvDStYV4LuDW3+kWh71d55TJmI3OB2yQaNHwpmkp 0niz5gzLth0WF/CJdh2D4GMOLZKMq2pDYhMr9gP6dO95zMMWwF7um8eOqrudwNANZNVx5zeIfS2 z75aNFsBS2wg6IYCfyCI9Cz1afFKbrAwKv1gOdk7HYi+CKQBccOKVcAddkxw3lI1aQokdttITo2 lac9CWRKJqIk6+AKVQ6l2VM2IxFN9rHiH+0deqJVI7JSqFR8JN9xYa7ikUlFPG0McnkrqI3Zln8 V9ogdaN80wLouiyL7TsSM3iVnguqWpeZg4GW+N+3HhGc/p+RXhpVg4Yu8QXUMLqjl9dPFrLZ4t/ UJykevQyXtoF8zmmu6Tq/ypL9RlQAnvw41CF0SU7PymPLV3ivBqBoGS2tEA4+SDgdKh25f8eK6B Ta97Wt+mptUVcAg== 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 Sat Feb 7 08:27:26 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 67AE6313E08; Mon, 3 Nov 2025 12:53:18 +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=1762174398; cv=none; b=a5E4mIYPDqKoaeh7iMi8lR3JR2HlDNpbfo1ys5afYBzykR9tfF+Uw9/sNO4imJZzb2BRfp2h9L9beP2ktRdDwLbMHzuSbPHrGv8GBloCjOBzL8OCkMxomvMxw4KD5X/ehd2GvDCtDvdDlJM3GkGN6eUzRPALcj9EYtYOcFATEYE= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1762174398; c=relaxed/simple; bh=zBQyD4C+LOu4tUZSnzQKyrp9sE+YBQAdVnnbBh8HRrY=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=fZTmWH8siVnMBL2xE6F+ZzUoX/UVKF0LH06ee7rS8yWZ230jbfJ1HIZqtnKfoWmN8lf6L0Xr51wzjnquMICoSJ9s8Qz8tUh+A8UUaSmNPqIJj3vSg1rTKPaYprySNCHSc4lp4VfO64H7lTYJP5oOr8XuyDueCGt1Oz2DjM0lEv4= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=K005a3dC; 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="K005a3dC" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 15CDDC19421; Mon, 3 Nov 2025 12:53:15 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1762174398; bh=zBQyD4C+LOu4tUZSnzQKyrp9sE+YBQAdVnnbBh8HRrY=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=K005a3dClFRlVkCQx2mxrAew4WgX2j9tDcI9PhFNb8lWXC9k/cvqwfqktV33YBdES OxgO4iGpp/lvE5GrK76eKbhZtF1gUdp0ovjkPMYT88uHOwBUM/aHMVcR+ga61PXb6t 5xfFxD8/4HhKiN7z1tbKnvBxo3MZ+jd2v4dD9G9JiPJ00Fk5tAZFslMghlw4XJQR+h g52j6cxGu3WVUlMbHekYZW3VhTcVSn3JOhd57ijB0g/u19Or5I8FX6SaJ1cyRcPK4r vjwrpr01hEthr9OI/FVettQBV5PrZVgFu2FbC9lqnfrLBHr0S4NBq4jr1jz0FzPJKj FRBzYZJElwUJw== From: Jeff Layton Date: Mon, 03 Nov 2025 07:52:36 -0500 Subject: [PATCH v4 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: <20251103-dir-deleg-ro-v4-8-961b67adee89@kernel.org> References: <20251103-dir-deleg-ro-v4-0-961b67adee89@kernel.org> In-Reply-To: <20251103-dir-deleg-ro-v4-0-961b67adee89@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=owEBbQKS/ZANAwAKAQAOaEEZVoIVAcsmYgBpCKWdF28PWpNhmabGcgJBnMa4PUb64CV+jturl YtCe62Z/GqJAjMEAAEKAB0WIQRLwNeyRHGyoYTq9dMADmhBGVaCFQUCaQilnQAKCRAADmhBGVaC FUm3EADDrhqGTPH46E1VAb1qeQ2BvFl40DH/jHgjbwnbyGm7mAbh6WQiGsfUbc2ETePYVvd9mY5 sUU9YiU/+Y/dLxL/2zppKnYcs48WXE2XYWzBRNgvhdRSX7WdlFRGHFo8bmILDNiRI5J30CmhGh+ IY3p2mFxCZjHqEgnDBrPikwpjjZQeVnclyrIYN12kVBbnWYNIafHYKXlV4ZP6ghaOn1Q/6tbZ8G 0AamJGLaUmPTeY+ewLzGrPayeuUFgBJYTSuB+XgmswnqIMV09ucf0Y3ef2ull46egfNqf2nDtfL ilx7qi74O85CfcxxsdqIjiSgjXfZEUaRo3hfAcTD8pB5kYnrEePN9evuDxO+B3AZHrMPAZf7Y3t vGQ5ydRq69FNnJcJbEqTg05lQ1OPvvrZXEAncHbRHQBRO2yUNQgHQ8DnkmEW1LITMK+H3AnRADC aXoVABskPWA+J2zbhf4HxGjmSOCvrZijlZrSSXyWYMnhpdFxMNVQKTawfjnnhJHTva1e55bPZDV k714QBM6/D22IgM7GXURFpGrZhsINgAZhyq14kocIgWYHppKsJ4pcHBqFTgdiV/bUzMtEm+mdgh KsW4dZ7ibvGLfl66fe0aG/lFHiMyAmT7YmavLic3KVJtf0psICdkmL7fq76T6VFm252Xm2lqdMD FtQdIBCPgc/oLww== 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 Sat Feb 7 08:27:26 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id C9A2230DD23; Mon, 3 Nov 2025 12:53:21 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1762174401; cv=none; b=N+zgiN7awBgf4Sw2dyQ8NfB2y/JW8dbTCcDWgbFKmtp2TuDDq5fNJjchun5ffc9DysGD9KhUEFOHqXPDbiaMp/xml+Ye/vIclru/6ANo75Rhl6b5+veXCszp8aeS8hsN/4bUiXDcz5JfgocozgvhDG7bHTQUYndgy4l+980/BeE= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1762174401; c=relaxed/simple; bh=9qqxYTmkti/XE0jnEtcrEK19pEka9QAsFL9WwL3RtFA=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=aRcvTj4bKNNetJqxhjdKKtV/CbbQBbO1zwtjUAteLxSuXckiUgbsxMVuNiA0KZ7jL5NOiaFRfuERESmuzEGiHkNzuYTtF5CQk48BOwz+1XS6zIsmaWgedlpsZAqciAHCbDwY7v2sdKKCuRyWTpwtE275zriYF5u4AYZJUE7aBaE= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=RrenRr+X; 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="RrenRr+X" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 7788CC113D0; Mon, 3 Nov 2025 12:53:18 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1762174401; bh=9qqxYTmkti/XE0jnEtcrEK19pEka9QAsFL9WwL3RtFA=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=RrenRr+XJKzgRoR5koPB8mOl8niSorSfWE2rhDQKP61xKieAMY7R3vk8HhbMufvuC pqBfIcSWqBXTIh0K/h8ZGbJpIRRqqkqKuHznR4dZPsCnikF4N1Y8eJBbMCT/zXjYyo nQHACA1REZ2EZ43WdYkWvfzCFUsIGNNC8yLpTKE+J/kQmSG6sy4Z6ZM+Mj4j2l3+wR obueKTS/lOCxF/x8GwDkGPWrP6HgsWozXgbIXea5okGx2aBHFpH+h8RaV4kg/n9rpx An8qlRKYxsAyUQLvEyIyswTSQTg6ChH6KM9tXitjJ3voO36tUJ1ZR2x9/8cXK0co5a qUaVpHIF7frSQ== From: Jeff Layton Date: Mon, 03 Nov 2025 07:52:37 -0500 Subject: [PATCH v4 09/17] vfs: add struct createdata for passing arguments to 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: <20251103-dir-deleg-ro-v4-9-961b67adee89@kernel.org> References: <20251103-dir-deleg-ro-v4-0-961b67adee89@kernel.org> In-Reply-To: <20251103-dir-deleg-ro-v4-0-961b67adee89@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=9801; i=jlayton@kernel.org; h=from:subject:message-id; bh=9qqxYTmkti/XE0jnEtcrEK19pEka9QAsFL9WwL3RtFA=; b=owEBbQKS/ZANAwAKAQAOaEEZVoIVAcsmYgBpCKWd0zceYSjAxUd98e/4woWPyTt40Dx58/xAi xId39+B9iSJAjMEAAEKAB0WIQRLwNeyRHGyoYTq9dMADmhBGVaCFQUCaQilnQAKCRAADmhBGVaC FdPREADDxDX/Z+gC0PeTBwW7obHMQ82gbnNRawmHnk7XR+rkgF3F3DhgIgMOSZJHofm5DgHLnOu uQeJyg3SprXBdGtRxGT3EUKXekftnh5w6aekLepb5IGmCmT0h9nefQhwQea3z76hIEgbN9w6XoI MUWiH5/yWLUIgTDBk9V3MwGEV9p3xFu6LGL++ytXne9WlS7/CYw5Sc+cqK/NDIuMWgzUDkSNlQW +goh0yGVkYDfCXYA4nNSxlRAr8svUFOuVpiUoS7uW0duLzJiHKruDIYAeov2MH3TPFMjry1+ujq r2n4agesaIMsiB2hvG3F3QyNfUX7YsT7yTqM2YKi2WpLygW1UDzrJ4MM21A6h6ucJu6uhEZEJvn E2Ao4kereQEcLzkmjrzOdlAFO4HvTGt3TmXY6IfNgaSqxuQdgR2pwsc7WLdtqo8kjZeRMTPrr3T sx+kfsjbL+EMTRnAUd1gPIL7ojFbFeyasxEtWF5uI+Ne/PIVG3j98Nt7Hgpxp4Vz2OLoVg0FUa6 rzaCwhd2YppD6XSJ3Nu7XZA2NdloBF9P9Kk6Tjf2vJS8z+Sz+9Us3ZMIsq4vayunKxCz19FqoXj n5aPOo2iyRnKzLT4R2KLxov6XDrj6caZkA4i0UlMhwB1Z96kuPYlv5oWn5FKxRzfVWhsGiYz5m9 4EEW2SYvMbLFKqw== X-Developer-Key: i=jlayton@kernel.org; a=openpgp; fpr=4BC0D7B24471B2A184EAF5D3000E684119568215 vfs_create() has grown an uncomfortably long argument list, and a following patch will add another. Convert it to take a new struct createdata pointer and fix up the callers to pass one in. Signed-off-by: Jeff Layton --- fs/ecryptfs/inode.c | 11 ++++++++--- fs/namei.c | 33 ++++++++++++++++++++------------- fs/nfsd/nfs3proc.c | 9 ++++++++- fs/nfsd/vfs.c | 19 ++++++++++++------- fs/open.c | 9 ++++++--- fs/overlayfs/overlayfs.h | 7 ++++++- fs/smb/server/vfs.c | 9 +++++++-- include/linux/fs.h | 13 +++++++++++-- 8 files changed, 78 insertions(+), 32 deletions(-) diff --git a/fs/ecryptfs/inode.c b/fs/ecryptfs/inode.c index 88631291b32535f623a3fbe4ea9b6ed48a306ca0..51accd166dbf515eb5221b6a39b= 204622a6b0f7c 100644 --- a/fs/ecryptfs/inode.c +++ b/fs/ecryptfs/inode.c @@ -187,9 +187,14 @@ ecryptfs_do_create(struct inode *directory_inode, struct inode *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); + if (!rc) { + struct createdata args =3D { .idmap =3D &nop_mnt_idmap, + .dir =3D lower_dir, + .dentry =3D lower_dentry, + .mode =3D mode, + .excl =3D true }; + rc =3D vfs_create(&args); + } 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..fdf4e78cd041de8c564b7d1d89a= 46ba2aaf79d53 100644 --- a/fs/namei.c +++ b/fs/namei.c @@ -3460,23 +3460,22 @@ static inline umode_t vfs_prepare_mode(struct mnt_i= dmap *idmap, =20 /** * vfs_create - create new file - * @idmap: idmap of the mount the inode was found from - * @dir: inode of the parent directory - * @dentry: dentry of the child file - * @mode: mode of the child file - * @want_excl: whether the file must not yet exist + * @args: struct createdata describing create to be done * * Create a new file. * * If the inode has been found through an idmapped mount the idmap of - * the vfsmount must be passed through @idmap. This function will then take - * care to map the inode according to @idmap before checking permissions. + * the vfsmount must be passed through @args->idmap. This function will th= en take + * care to map the inode according to @args->idmap before checking permiss= ions. * 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 createdata *args) { + struct mnt_idmap *idmap =3D args->idmap; + struct inode *dir =3D args->dir; + struct dentry *dentry =3D args->dentry; + umode_t mode =3D args->mode; int error; =20 error =3D may_create(idmap, dir, dentry); @@ -3490,7 +3489,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, args->excl); if (!error) fsnotify_create(dir, dentry); return error; @@ -4382,12 +4381,20 @@ static int do_mknodat(int dfd, struct filename *nam= e, umode_t mode, =20 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); + case 0: + case S_IFREG: + { + struct createdata args =3D { .idmap =3D idmap, + .dir =3D path.dentry->d_inode, + .dentry =3D dentry, + .mode =3D mode, + .excl =3D true }; + + error =3D vfs_create(&args); if (!error) security_path_post_mknod(idmap, dentry); break; + } case S_IFCHR: case S_IFBLK: error =3D vfs_mknod(idmap, path.dentry->d_inode, dentry, mode, new_decode_dev(dev)); diff --git a/fs/nfsd/nfs3proc.c b/fs/nfsd/nfs3proc.c index b6d03e1ef5f7a5e8dd111b0d56c061f1e91abff7..dcd7de465e7e33d1c66ee0272c4= f220d55e85928 100644 --- a/fs/nfsd/nfs3proc.c +++ b/fs/nfsd/nfs3proc.c @@ -258,6 +258,7 @@ nfsd3_create_file(struct svc_rqst *rqstp, struct svc_fh= *fhp, struct nfsd_attrs attrs =3D { .na_iattr =3D iap, }; + struct createdata cargs =3D { }; __u32 v_mtime, v_atime; struct inode *inode; __be32 status; @@ -344,7 +345,13 @@ nfsd3_create_file(struct svc_rqst *rqstp, struct svc_f= h *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); + + cargs.idmap =3D &nop_mnt_idmap; + cargs.dir =3D inode; + cargs.dentry =3D child; + cargs.mode =3D iap->ia_mode; + cargs.excl =3D true; + host_err =3D vfs_create(&cargs); 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..e4ed1952f02c0a66c64528e5945= 3cc9b2352c18f 100644 --- a/fs/nfsd/vfs.c +++ b/fs/nfsd/vfs.c @@ -1527,11 +1527,12 @@ nfsd_create_locked(struct svc_rqst *rqstp, struct s= vc_fh *fhp, struct nfsd_attrs *attrs, int type, dev_t rdev, struct svc_fh *resfhp) { - struct dentry *dentry, *dchild; - struct inode *dirp; - struct iattr *iap =3D attrs->na_iattr; - __be32 err; - int host_err =3D 0; + struct dentry *dentry, *dchild; + struct inode *dirp; + struct iattr *iap =3D attrs->na_iattr; + __be32 err; + int host_err =3D 0; + struct createdata cargs =3D { }; =20 dentry =3D fhp->fh_dentry; dirp =3D d_inode(dentry); @@ -1552,8 +1553,12 @@ nfsd_create_locked(struct svc_rqst *rqstp, struct sv= c_fh *fhp, err =3D 0; switch (type) { case S_IFREG: - host_err =3D vfs_create(&nop_mnt_idmap, dirp, dchild, - iap->ia_mode, true); + cargs.idmap =3D &nop_mnt_idmap; + cargs.dir =3D dirp; + cargs.dentry =3D dchild; + cargs.mode =3D iap->ia_mode; + cargs.excl =3D true; + host_err =3D vfs_create(&cargs); if (!host_err) nfsd_check_ignore_resizing(iap); break; diff --git a/fs/open.c b/fs/open.c index fdaa6f08f6f4cac5c2fefd3eafa5e430e51f3979..006cc2aeb1fbbb3db48b32db798= 108da120f75c2 100644 --- a/fs/open.c +++ b/fs/open.c @@ -1164,6 +1164,11 @@ struct file *dentry_open_nonotify(const struct path = *path, int flags, struct file *dentry_create(const struct path *path, int flags, umode_t mod= e, const struct cred *cred) { + struct createdata cargs =3D { .idmap =3D mnt_idmap(path->mnt), + .dir =3D d_inode(path->dentry->d_parent), + .dentry =3D path->dentry, + .mode =3D mode, + .excl =3D true }; struct file *f; int error; =20 @@ -1171,9 +1176,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(&cargs); if (!error) error =3D vfs_open(path, f); =20 diff --git a/fs/overlayfs/overlayfs.h b/fs/overlayfs/overlayfs.h index d215d7349489686b66bb66e939b27046f7d836f6..5fa939ac842ed04df8f0088233f= 4cba4ac703c05 100644 --- a/fs/overlayfs/overlayfs.h +++ b/fs/overlayfs/overlayfs.h @@ -235,7 +235,12 @@ 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); + struct createdata cargs =3D { .idmap =3D ovl_upper_mnt_idmap(ofs), + .dir =3D dir, + .dentry =3D dentry, + .mode =3D mode, + .excl =3D true }; + int err =3D vfs_create(&cargs); =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..fbc3c34e14b870f1750b9453493= 35afb62d89d0d 100644 --- a/fs/smb/server/vfs.c +++ b/fs/smb/server/vfs.c @@ -173,6 +173,7 @@ void ksmbd_vfs_query_maximal_access(struct mnt_idmap *i= dmap, */ int ksmbd_vfs_create(struct ksmbd_work *work, const char *name, umode_t mo= de) { + struct createdata cargs =3D { }; struct path path; struct dentry *dentry; int err; @@ -188,8 +189,12 @@ int ksmbd_vfs_create(struct ksmbd_work *work, const ch= ar *name, umode_t mode) } =20 mode |=3D S_IFREG; - err =3D vfs_create(mnt_idmap(path.mnt), d_inode(path.dentry), - dentry, mode, true); + cargs.idmap =3D mnt_idmap(path.mnt); + cargs.dir =3D d_inode(path.dentry); + cargs.dentry =3D dentry; + cargs.mode =3D mode; + cargs.excl =3D true; + err =3D vfs_create(&cargs); 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..b61873767b37591aecadd147623= d7dfc866bef82 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h @@ -2111,8 +2111,17 @@ bool inode_owner_or_capable(struct mnt_idmap *idmap, /* * VFS helper functions.. */ -int vfs_create(struct mnt_idmap *, struct inode *, - struct dentry *, umode_t, bool); + +struct createdata { + struct mnt_idmap *idmap; // idmap of the mount the inode was found from + struct inode *dir; // inode of parent directory + struct dentry *dentry; // dentry of the child file + umode_t mode; // mode of the child file + bool excl; // whether the file must not yet exist +}; + +int vfs_create(struct createdata *); + 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 Sat Feb 7 08:27:26 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 85626314B63; Mon, 3 Nov 2025 12:53:25 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1762174405; cv=none; b=riXtg30pd5l/sRUzuE3Cmnu4fPwa2Qs2hYh0F3TaV8GMf3STEDdsw+bSkcYJ9rmkCkUrDVMXEm1sKuvqX1nwwFJ/YG/sCkXVzFEzUF9JwEG33dD7g7nRd72uTP5SaIFTxDT4IAaidF/Y8NXnTge1kL2Lj0wgft4hov+LYf+YNp4= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1762174405; c=relaxed/simple; bh=F4WtZaIk8X3USLdxrQ+aGC/g5Iz1UkZTcUMEmpFW0Y4=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=No+FuvUZNX0x+0TIQ+mrZ7oWeXzTYaemY6HO0kQB5AMWSygY/zHNaE66LWjWd6h4OwZaWBt+rKEJ3ZuK6h6pUImz88LgXfMOY3aNnAn4IHrmKzqv56pkZNf6sA0iCHbqlSi5CZlAKegveYB/6B/MGcyQNhdHSizNuOqC9HIX9Jw= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=K+ODCFN6; 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="K+ODCFN6" Received: by smtp.kernel.org (Postfix) with ESMTPSA id DAE8AC4CEE7; Mon, 3 Nov 2025 12:53:21 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1762174405; bh=F4WtZaIk8X3USLdxrQ+aGC/g5Iz1UkZTcUMEmpFW0Y4=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=K+ODCFN6I1BklSu5/DL83mSHkeKlpinDlIOMys+FtYVpLuA//bqfybPz3E6+Ns/bl 6nmeSBpa4MEghIFGFoa0+sw9o62g2v6iiY6jBZzL8uEtSU3TDsbMBr+0n2S/U1L1Po QeexrPQ3tVf7Iqr0L+ujMVd0E6NvNN0NRBaL9S5JmTloAvSj7Kyo6HKVzCG+SPLoap 5zXMd9IS7IjqTEylKv6pXQhEIIUdu6X/pVrRONzp2BKeWDN3z6tv+e+nfAzwTQyE+c lIdZcoe7bdBmAUy9CjMMFyhEwlP7ZZ+iM366Ude4/FIuth5dyKaGmtMP6CE2cQVEF/ FapauIFaH1sZw== From: Jeff Layton Date: Mon, 03 Nov 2025 07:52:38 -0500 Subject: [PATCH v4 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: <20251103-dir-deleg-ro-v4-10-961b67adee89@kernel.org> References: <20251103-dir-deleg-ro-v4-0-961b67adee89@kernel.org> In-Reply-To: <20251103-dir-deleg-ro-v4-0-961b67adee89@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=3405; i=jlayton@kernel.org; h=from:subject:message-id; bh=F4WtZaIk8X3USLdxrQ+aGC/g5Iz1UkZTcUMEmpFW0Y4=; b=owEBbQKS/ZANAwAKAQAOaEEZVoIVAcsmYgBpCKWdOJgsy8BidAoueXGiHed+Of/fHh9OsDTyH Cn2Z5eDBgiJAjMEAAEKAB0WIQRLwNeyRHGyoYTq9dMADmhBGVaCFQUCaQilnQAKCRAADmhBGVaC FWy/EACvFNMQGKPhqCrxadwV+eLgpp4fp8aG3Mj+VGe/hmrBFwhQiBQyc3aRkDAfrx2BOWR5bfl Auox/hpZUTj683sBgT43hAl/22/7ff/KanIFRdlPpsg9rJBWxvLbTe37NwM2ofricWPD74vS4YZ 4kkE6MLoKzaF/TxkVpaKlEpTQu6PJqxCz+o+bG9YWwjo7fcOjICKNcOFy7+0kdUd3tYpTG1ZJg5 1wVRhOxcQoSobdsMoIVSsEWBhDWSvN4GIhNtF7wXsho2l8D4dWPgAQz51zXo25nZMYwOFQwpvgY SrgDsz1bW5ObNgAZNxadlgq5jOAFT2sF2w0hoATd5YbvCOr/y35I2GzlE7hF1z1SLQbaoVffPwK ToCD4kPVkC9AOMcq//xHJ7W8t1KL6xCu152xMEKyRu/5mVZyhmXcL9+awgpbE7qtvvDZSj3cqXj /e0qx1/igFU+vgYahAH6SdPksX+MoO8B1wWnvS3E+5VpTf3C7H4pCsUr3T+ASjtYSIi8gKBr7Uw CXWB2ytG5aeJgtyCQS0cYNqD92jWIBZBBCk1bvpj9gZNCC7SZSmj+pbVPx74HboFdAwkVG9L0Wz wGqms6MRXt196LMJSdYg0mkzKxe3tIa2xG7/hfvUeBXbPC7x4ZZe2WzICxjuju3Ng1pPo2yz80U DDf9xjOt/ptbRaQ== 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 struct createdata. Most callers just leave that as a NULL pointer, but do_mknodat() is changed to wait for a delegation break if there is one. Signed-off-by: Jeff Layton --- fs/namei.c | 26 +++++++++++++++++--------- include/linux/fs.h | 2 +- 2 files changed, 18 insertions(+), 10 deletions(-) diff --git a/fs/namei.c b/fs/namei.c index fdf4e78cd041de8c564b7d1d89a46ba2aaf79d53..e8973000a312fb05ebb63a0d9bd= 83b9a5f8f805d 100644 --- a/fs/namei.c +++ b/fs/namei.c @@ -3487,6 +3487,9 @@ int vfs_create(struct createdata *args) =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, args->delegated_inode); if (error) return error; error =3D dir->i_op->create(idmap, dir, dentry, mode, args->excl); @@ -4359,6 +4362,8 @@ 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 delegated_inode =3D { }; + struct createdata cargs =3D { }; struct mnt_idmap *idmap; struct dentry *dentry; struct path path; @@ -4383,18 +4388,16 @@ static int do_mknodat(int dfd, struct filename *nam= e, umode_t mode, switch (mode & S_IFMT) { case 0: case S_IFREG: - { - struct createdata args =3D { .idmap =3D idmap, - .dir =3D path.dentry->d_inode, - .dentry =3D dentry, - .mode =3D mode, - .excl =3D true }; - - error =3D vfs_create(&args); + cargs.idmap =3D idmap, + cargs.dir =3D path.dentry->d_inode, + cargs.dentry =3D dentry, + cargs.delegated_inode =3D &delegated_inode; + cargs.mode =3D mode, + cargs.excl =3D true, + error =3D vfs_create(&cargs); if (!error) security_path_post_mknod(idmap, dentry); break; - } case S_IFCHR: case S_IFBLK: error =3D vfs_mknod(idmap, path.dentry->d_inode, dentry, mode, new_decode_dev(dev)); @@ -4406,6 +4409,11 @@ static int do_mknodat(int dfd, struct filename *name= , umode_t mode, } out2: 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/include/linux/fs.h b/include/linux/fs.h index b61873767b37591aecadd147623d7dfc866bef82..cfcb20a7c4ce4b6dcec98b3eccb= db5ec8bab6fa9 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h @@ -2116,12 +2116,12 @@ struct createdata { struct mnt_idmap *idmap; // idmap of the mount the inode was found from struct inode *dir; // inode of parent directory struct dentry *dentry; // dentry of the child file + struct delegated_inode *delegated_inode; // returns parent inode, if dele= gated umode_t mode; // mode of the child file bool excl; // whether the file must not yet exist }; =20 int vfs_create(struct createdata *); - 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 Sat Feb 7 08:27:26 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 9CA8330E0E2; Mon, 3 Nov 2025 12:53:28 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1762174408; cv=none; b=XS/LjPVQ4e8CL9Za66hm564zZ16ypTlCjHCyaVMrwjtSf57fl/6DHCJEaV1hDJgVJDw2NMQq1JG7NXpMFmvjp/pb4vXJ1NBtoMvfMBPb+hvMm0XDcG+gapGtE7sngzsKVvlxk30dB/048R0/nHdkNyeUXv8XF+hVv/Cwe8Omjac= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1762174408; c=relaxed/simple; bh=Lq/JBMu0T1h4/13uRSNeKNc8cdFPxVXxt0JHjoT6GJA=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=tXYt8rA8ZfLZ17vfoYKs5WkN1J81vfBpOuClAaYPf4kvwDcGshZZ5xvxjlOL0YWOyq1KFLaU5PA9kWWRzxHmXWfE7hyIYnfug/KcRHTbqj/ce++JaLiXxbiVSVWZyNiT9qcU1j3L/vThpLeVi67nrbvjXEjRBwWBqhyG2eFWH8k= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=OMpPjzOD; 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="OMpPjzOD" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 4A448C116C6; Mon, 3 Nov 2025 12:53:25 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1762174408; bh=Lq/JBMu0T1h4/13uRSNeKNc8cdFPxVXxt0JHjoT6GJA=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=OMpPjzODO5QzZVqkBunGNze6QHf8UIckZ1IDDAJGnhk5EEBDcv9ElTdioKsgkIlTk Peb9uzn3GHYTewPXn7/lN9WAzXwql6qecAHp8HKxV11dn2xk4SdNWVAohQT0xvoSSm siqU75CpKrqpeHT+USVUW7SWWPFkHBSOyBkXbBPxOKQ/oVM5CEJUwHGyTGQ4m0YhmP 4QGW3n2iAqn2duuAy5WrJIWE6WY8BFv+LmNL2wHxeVxeKUl7tsvzZ0XrhBgOCSVZRw 1sXTPaNahBYH/B84OipJV3/fRVcmFZqz/GiL+QrTnpIc3Hemu2CgvzhvxukBa6W4uu 36nzFs7kVVCRw== From: Jeff Layton Date: Mon, 03 Nov 2025 07:52:39 -0500 Subject: [PATCH v4 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: <20251103-dir-deleg-ro-v4-11-961b67adee89@kernel.org> References: <20251103-dir-deleg-ro-v4-0-961b67adee89@kernel.org> In-Reply-To: <20251103-dir-deleg-ro-v4-0-961b67adee89@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=7497; i=jlayton@kernel.org; h=from:subject:message-id; bh=Lq/JBMu0T1h4/13uRSNeKNc8cdFPxVXxt0JHjoT6GJA=; b=owEBbQKS/ZANAwAKAQAOaEEZVoIVAcsmYgBpCKWeAOcIMuv+JwM52+Bk5/rKW2T2lMhBOKyws 2HtWfRG1F2JAjMEAAEKAB0WIQRLwNeyRHGyoYTq9dMADmhBGVaCFQUCaQilngAKCRAADmhBGVaC FRreEACixXTl66tvn+CnX+Wl3fi0kIAS4S8nYRdqTF36EZJ3r9F4b1TeVKvhRQH/Yd6mv2mgyMk c2b38dm86dfEQjLT6h74vlVwuz3AbAb42ZFxwp5BF1oawyTyb9GFOMSONpkk85C7n8o49eTt/OR F4rNW+K2ayY/i7RcjnKJYypqOwjpqoSrpH0O62Fg7a1PL4k9h+f38TPD9DMDDkkOIhmrX1g5Q33 /yQDurOMZXlWcL697sz7ROzYplMmSGVNwmHwcu3j6+NliiSTvzcdytc6axmpzxvyRIBus9uDTqi FbW95MioJvNokgPVJQ5SEeejefMXHlxWCBS/kR5GIaHQpiBfnUkiYdMOW83W8n3tSeFrkR6ItIY 8DDLn9nth0oU8tVk41ZkptXvKraeAS4xAt1ZaJFd/TFhN+P78soJ4xVaAwqH2lLJf/SwOaiFO7f +LrhpNHju2JDkb8rtizi+GJ3JeceQmEJ3QxLijcLFiLk+wOBUuFxYA9k5rg37QTadV9Ot5/xQ4k UhOZxDYdCOHzX0rZlC6INrNkw2H9PauK3EZrdOSHd+vPs71D5oU1ZP+MAXgqqIUKsC8xJaaM2ln stYmPzmUfvfVF4YX19605+J09jiH0kjanhKKzOB7+VnkjticCp4klQNywjNqV+2tq1l7sqJttzx ytRGc2qBCQDj9Rw== 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 | 25 +++++++++++++++++-------- fs/nfsd/vfs.c | 2 +- fs/overlayfs/overlayfs.h | 2 +- include/linux/fs.h | 4 ++-- net/unix/af_unix.c | 2 +- 8 files changed, 25 insertions(+), 16 deletions(-) diff --git a/drivers/base/devtmpfs.c b/drivers/base/devtmpfs.c index 104025104ef75381984fd94dfbd50feeaa8cdd22..2f576ecf18324f767cd5ac6cbd2= 8adbf9f46b958 100644 --- a/drivers/base/devtmpfs.c +++ b/drivers/base/devtmpfs.c @@ -231,7 +231,7 @@ static int handle_create(const char *nodename, umode_t = mode, kuid_t uid, return PTR_ERR(dentry); =20 err =3D vfs_mknod(&nop_mnt_idmap, d_inode(path.dentry), dentry, mode, - dev->devt); + dev->devt, NULL); if (!err) { struct iattr newattrs; =20 diff --git a/fs/ecryptfs/inode.c b/fs/ecryptfs/inode.c index 51accd166dbf515eb5221b6a39b204622a6b0f7c..42d00f5080b8c52622a5e57bd70= a5659504da46e 100644 --- a/fs/ecryptfs/inode.c +++ b/fs/ecryptfs/inode.c @@ -570,7 +570,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 e8973000a312fb05ebb63a0d9bd83b9a5f8f805d..8851f0870f63ba1d3789300dbac= c8b9cce534900 100644 --- a/fs/namei.c +++ b/fs/namei.c @@ -4294,13 +4294,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. * @@ -4311,7 +4313,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); @@ -4335,6 +4338,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); @@ -4400,11 +4407,13 @@ static int do_mknodat(int dfd, struct filename *nam= e, umode_t mode, break; case S_IFCHR: case S_IFBLK: error =3D vfs_mknod(idmap, path.dentry->d_inode, - dentry, mode, new_decode_dev(dev)); + dentry, mode, new_decode_dev(dev), + &delegated_inode); break; case S_IFIFO: case S_IFSOCK: error =3D vfs_mknod(idmap, path.dentry->d_inode, - dentry, mode, 0); + dentry, mode, 0, + &delegated_inode); break; } out2: diff --git a/fs/nfsd/vfs.c b/fs/nfsd/vfs.c index e4ed1952f02c0a66c64528e59453cc9b2352c18f..ce8c653f7a4edab81a7f1b231a4= ae77dc82c073a 100644 --- a/fs/nfsd/vfs.c +++ b/fs/nfsd/vfs.c @@ -1579,7 +1579,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 5fa939ac842ed04df8f0088233f4cba4ac703c05..958531448cb85aeb3bfa174e9db= f25469384b53f 100644 --- a/fs/overlayfs/overlayfs.h +++ b/fs/overlayfs/overlayfs.h @@ -262,7 +262,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 cfcb20a7c4ce4b6dcec98b3eccbdb5ec8bab6fa9..47031dbb0b026c0b59661719df5= 51979717907a5 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h @@ -2125,7 +2125,7 @@ int vfs_create(struct createdata *); 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 *, @@ -2161,7 +2161,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 Sat Feb 7 08:27:26 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 417AE315D38; Mon, 3 Nov 2025 12:53:32 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1762174413; cv=none; b=VyhVQ7y96TZ6yxGF2hW2Z2ZW1EG30ikdw6h7jH7LTaOZ8pcIYaqO8txMqlCDQXpA69hItqPKUKtUlfID3/DFGVKE1ivuEegt1FOoOuBU03GCC9Jf/i3vMRFt6iGr53s8O40MiZtroI5yFqz4Vm+7ryLkWd6/m78BQnu85048+rQ= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1762174413; c=relaxed/simple; bh=D5V0UFm+9OUK4y+/EaRKtu56Yc3CDLhLRHYFSz9Ys84=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=FksU7U7rdGl1+aRlIthUdkVI3hSAtoUp5ah1qtHSIryHNGFwIcSZ7dKVQgakaqMcPg97SKTL0d0oFPafE1ZXwEivYsELOxJ82UBiz0KMmwr3KpORhvK8/s0z8JfR+U5V9eMFi+k5ss6MgaMqVNGVSoeEB/9J3QI5LmL1a/DVNBc= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=piHP4CCM; 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="piHP4CCM" Received: by smtp.kernel.org (Postfix) with ESMTPSA id AD205C16AAE; Mon, 3 Nov 2025 12:53:28 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1762174411; bh=D5V0UFm+9OUK4y+/EaRKtu56Yc3CDLhLRHYFSz9Ys84=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=piHP4CCM5hB9QLZP0faziwV56bKDvC1DxsiEoOuVCRsdhjVE8Q9/zQBTCYn3xZmMW WFE0hBn+6ciWLEc4Ya9HpTnI/jOB58HtuarleVd5y/GEPa4xygwrDOEjX08h5er5hT UaKvV3mYqMtxtaIvqyQQV8MngdH41aLlYZQZtP7HEtpFPsCoa0g0TG8GHMNWsYzoYM 3DTqtBK2f/Mw5qb7YO8Gv7Yms5AHN46jNvefawhcipWSzL6ChHSFjhRfOD/eBAq/Fg bcY6DAxmrpiDn1QbpZdNCEBvfOCOtli5UM3irMh5fVCq3so24Apdpy1An8gJ6EKz5I t3D9k4lQ2rDkQ== From: Jeff Layton Date: Mon, 03 Nov 2025 07:52:40 -0500 Subject: [PATCH v4 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: <20251103-dir-deleg-ro-v4-12-961b67adee89@kernel.org> References: <20251103-dir-deleg-ro-v4-0-961b67adee89@kernel.org> In-Reply-To: <20251103-dir-deleg-ro-v4-0-961b67adee89@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=D5V0UFm+9OUK4y+/EaRKtu56Yc3CDLhLRHYFSz9Ys84=; b=owEBbQKS/ZANAwAKAQAOaEEZVoIVAcsmYgBpCKWe25kDvzIUFEMcI8PZW6lHavHlY3cQCfQDV S7u3UR6x2KJAjMEAAEKAB0WIQRLwNeyRHGyoYTq9dMADmhBGVaCFQUCaQilngAKCRAADmhBGVaC FQr5D/9/bWoDn1lQiat35yZ2f6ohat3fC7JS/FnJI63iLRx8/cHR2mF0vj82fi6a1FBb/PeFMpM R82Ng7od8if9kPRhieD+muVBIu3fYQQxCCrFNY4Ohv78lVE2s+hj8AklaC5WtBuk1cN8IfP3WMU Wqtlo+XQK8Vi9qgXw36VVS5+p5OkhHcs/lZMd6mpnb/psZHy3wRpnN+JT0mmrzXx3LSSVVYzspF 9xzeR6J1BnwNpJ7yIdnD+9txMstScfPfwJk+WhffFcIF2K82Er1GlZnSlEel0Q0uXC0P6KkDiUH 7schL4zRpwE9Hyn2xLGNiFSNDkwjDiAvwZeYZS+up+2UCiHANncOSLGCbf2gsSJ/kZQ7LRPEBzT G/wHv6kF1xeOmz+dY6F+ji7C5lRLzQH3188IbHqrTHBOmw5jeC5xRepk8mteeTRPlWxSMLAqg/Q qv/xLej717aYVmn7vztG7UrICLSK+A5IqiE302B/qYEblCgpYcnxXTIad30aUPB6wXgObamTs48 qIQ1a9t/knkUsdfL3TUfeYwOkB137fuU3FijP+9ebY5/qj0/Oy+Dwpch7kHwJ7GwnRE6aEazVGD vAHIu+QxEQg17M3Dj/oqMJZsGmZD0PWcqfOXAgxBxDq3nukjNDuJceZZ+mc7uTnUAWP99ZuSoq1 ZjpxIKB9TSnusRg== 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 42d00f5080b8c52622a5e57bd70a5659504da46e..c52bd187f21437fa1a0deb8f3dc= d60c8930154ef 100644 --- a/fs/ecryptfs/inode.c +++ b/fs/ecryptfs/inode.c @@ -485,7 +485,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 8851f0870f63ba1d3789300dbacc8b9cce534900..7071cdbfc587c108ebd777746f7= 36d854feb68e7 100644 --- a/fs/namei.c +++ b/fs/namei.c @@ -4854,6 +4854,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. * @@ -4864,7 +4865,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 @@ -4879,6 +4881,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); @@ -4892,6 +4898,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); @@ -4906,8 +4913,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 ce8c653f7a4edab81a7f1b231a4ae77dc82c073a..edcc8c05e435a4abba27dd2eb07= facf4b5ed3243 100644 --- a/fs/nfsd/vfs.c +++ b/fs/nfsd/vfs.c @@ -1748,7 +1748,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 958531448cb85aeb3bfa174e9dbf25469384b53f..3e4774a979976c65f2984bbc212= bd403e440644e 100644 --- a/fs/overlayfs/overlayfs.h +++ b/fs/overlayfs/overlayfs.h @@ -272,7 +272,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 47031dbb0b026c0b59661719df551979717907a5..8cd1804a2c3dcfa0153b1bc1c02= 50f5a989c857c 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h @@ -2127,7 +2127,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 Sat Feb 7 08:27:26 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id B7ADD30E828; Mon, 3 Nov 2025 12:53:35 +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=1762174415; cv=none; b=UsVB9ZqAwqBMkmzPcIxXFH2R3EDOVXizHy7E8GKQhmHB51yC9wou+DpjProdBAO7rUezH1gZ76VTkuYpGA1yRCFDjCbg1+Dtl7I6HP13wEd3u0w/X+mIJ1KnueOnbwT0OgbjWv16zCwTfIMlrnb+CwAJwPfm6UoU92YzWjPnDgc= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1762174415; c=relaxed/simple; bh=fAStZ1VGox28sSBTaeIOxtIwVEbCulrkhuzHCrifXdg=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=CvCdKWknA3SMC1PRwQ8ohgU23GdPDeRxHuBoWuaTVtvVIuvhT0mLlZ0Jj1YURRYKGdcNCdT6+kVIFZO+UHzdpnwNuBjSakGpv6vGv4ZUL65I/PgLi5Al3Gkv6OyVhhoz9HGjU4EXa6gGvkJXPHGU1Wt48IRlI+IU2ZkIPItswEE= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=GlIGZDqU; 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="GlIGZDqU" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 1CD3BC116B1; Mon, 3 Nov 2025 12:53:32 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1762174415; bh=fAStZ1VGox28sSBTaeIOxtIwVEbCulrkhuzHCrifXdg=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=GlIGZDqUHetc2450ZHmmkS8cLtoED4qaEyDWrLL7sgqMB6y7O1Jp/Ls/4o08dn8KA qZsPAgwQEcYABla/xdezJFCzDyONhom/1tZJOClCGXhlnrQ89Z4N2N+W6KVfDzOyQe LUFLPshLT8YJfl5CZxNKYX9FVs1n//E2U2VvQjJRpeWZLZQIkMn7lxzM4/H9949sSt ipVZGlcirxhCfNKouU5Xibvjvj+LCJvJdcB7Q0RiEQoB5HG7iszENKnq8jwsS6MzY+ Nm2gz53a2xFg36g9AtA2FKblLXr/wj6/CtyvUujbZ2ppSPpoWpgQJsPJMqC9Tz1PrM OHrLpooEtUSfQ== From: Jeff Layton Date: Mon, 03 Nov 2025 07:52:41 -0500 Subject: [PATCH v4 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: <20251103-dir-deleg-ro-v4-13-961b67adee89@kernel.org> References: <20251103-dir-deleg-ro-v4-0-961b67adee89@kernel.org> In-Reply-To: <20251103-dir-deleg-ro-v4-0-961b67adee89@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/ZANAwAKAQAOaEEZVoIVAcsmYgBpCKWeZxaSzbRnP+HDlhpPctVnbqfGrRC1V8YxE oZtToTbH6+JAjMEAAEKAB0WIQRLwNeyRHGyoYTq9dMADmhBGVaCFQUCaQilngAKCRAADmhBGVaC FbenEACbMPmeDuff/GDAt5OB9dYhRo+Q+oT275O1d/yBl82BrIN5VTAtFQjKIJyJw0snHqc38qX eVaSzt72WO57+DokAfihTvCe5UthsojJIKJ6h0ciZhH+KBBmT1i8mzMvakv5Fku3Rse5bLvWU6k SbIvhmfXdjvhB2XeeRGf+GrR3wplzWalJHcK76YklTajmJjuaEnx75Aib+rNge6ZPM4gdWBPFqA DjkqbSrWHBKLLU+YsOH9LA8OkyJ9YcDtI3LlElgDxzFLE1V1vcn8XpNr9HcbI5e08wq3/1NnymE Ui54ekwESIysx8SwEcDTjI+9IbjcpHNghEMvErNSujALUOMBbZAj5NRME3Z8jehynHVoPRr/FWx tRSS6J9TZ+ia/EafHJ4yFtu2qpd5VduNC0LP7x3kgzCAZWQ196V+2Py4tyMltvaQGCPW6LkILZ7 I+ZGlV24jT4K0A2hle3IoJy+7zkRZEOO4vRQHjZyUia7ZnVAa7AwoIEhkTOvzVJ+XnmD+PuNw2O QG0seOiDurZM9wO7V6oOr7PTQThvXZlvo9HdeDro/UrRqF7a9jGz6nuXpAWs3jtpr5EhxpNlGLg X1Jfzq7nqSuhG4AvIaydSRYlnYsGJqBDDtWm/1T9mentCOqwxSZu3UTwLzG+5CvNd0gbI3b0EB4 XIr2K9Nxc+KiK/g== 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 Sat Feb 7 08:27:26 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id DA3E4316908; Mon, 3 Nov 2025 12:53:38 +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=1762174419; cv=none; b=s9CfYpEkizpOOJ0nSMNzWseZ32+nXhV05CTws+Xv/TYPrpMAsgDTymHwlLR3aHoLpgG+Ct+sj7EFMZyhzw9oaK/u3C3v7aq2iGfBfsl5TNuoXc8KkYTjjQt+ldZ5RJnvkm/RKbZo1cCY+m2YW7UwIxg1hJmZKg8whBi3HH4XDpc= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1762174419; c=relaxed/simple; bh=YhL5OvzR8GSJpMDvQ8tbMUForHK8kp34QnTLaEJR2wE=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=CmVoFcKdjFHp1aU8b3i7MHzTLKyhLV/UxEIVN5cz1GgooZ6/vem1VUOFnMxhAPW+upsmx6p8Jvyc3tWt/7J1GDz1u+bHUVxeAlqm3AyVrM6sxZLqIGLVgB6d6O7jfcggGwvKlx/5MwA3aETRaYA4dWbQdhZb29sJMkFKVN3jswM= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=I2AURiXt; 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="I2AURiXt" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 80C9FC16AAE; Mon, 3 Nov 2025 12:53:35 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1762174418; bh=YhL5OvzR8GSJpMDvQ8tbMUForHK8kp34QnTLaEJR2wE=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=I2AURiXtC+hFf4PwdxLP4aL6s+W6oTHRI+Vt47k4cvN74/zKr1mC5v2481ePxuWrd Wl7GlsOJ4K4J1Vnhm2qpprjSahehHTqETQ4MadbskvxJQyFqcCAZ6bCcaUgx/VRZ3t zr3ruydRMrbQfF+jMMgKIk2TP1mH/ULtFcMxGIsVE9MwsKqRESEk3iRJBuX0gXxQv5 bLstOdOUO7MUBEXij2FTInqYr/6kPIQjdVUQFsytUaxj83fL3E329Fu/+x677TPUsd POwppa8kfKwgYQ+tLfmWY6eKd7vMVG7T5ByuFfWfv7dt8grm+oj5Njbgb+yPF+fcxe 4Dn0P7T8tGeSw== From: Jeff Layton Date: Mon, 03 Nov 2025 07:52:42 -0500 Subject: [PATCH v4 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: <20251103-dir-deleg-ro-v4-14-961b67adee89@kernel.org> References: <20251103-dir-deleg-ro-v4-0-961b67adee89@kernel.org> In-Reply-To: <20251103-dir-deleg-ro-v4-0-961b67adee89@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=YhL5OvzR8GSJpMDvQ8tbMUForHK8kp34QnTLaEJR2wE=; b=owEBbQKS/ZANAwAKAQAOaEEZVoIVAcsmYgBpCKWeczgx1Z+RTzva+DQqLRnYoPMZ++BxuPOcP PjJUuDNuemJAjMEAAEKAB0WIQRLwNeyRHGyoYTq9dMADmhBGVaCFQUCaQilngAKCRAADmhBGVaC FUcREACPZg/hOfAPtSpgqZTOoGfLPBrjfAULd07qptKhcWtQqcxl0YuZLXcqiB0EV9arND8Bh3j Tg2QRYMXRg/y/KMoyns4SbgZHk19rRlK4a6cE4B8AD2u/GZUONbef5fRIYNL3Z/ZYT3lVwAYfx0 SXhUrPppYnCiKq0gh4Hx2y2ZM/OZSkr6GuMUxGOzpRtHtWZJgh3fdHxdNcWqQdk31T8p/uypEBZ B+cE7cAYzIQ+p4vLm52YQiUucmXuCeotCOEp9o5odD8mIZHwkS1gOHv+0YTu/PvIHLwIB+K/Gqt faTkBW6DsG7Y2yHpikaAQuvn73oHxnx0MU9c9Rm3o8mZoy9BJgODcmL++7QXGqKWdDYUKgQrZ9H Lr6Jdd3rOznGLTfaxE9Jd+2AzQslvNzxRrMYdHp2MTGU1BmyDSKX4MmGkXV5YR8bEKikV/vIC8l EJ7i96VsQ+2c6RvjvDsDhpiDR3rzBrYdHjANu632DcU7O2y7UU0rUjT8zFpHYDe72qQ/Sm7bWVf nerOd20fVcuypMl3wmldE71VAJncbVX6BI1bFOXLXbfs2WPVVQKeXCSpUmZolJcCAux/A60NFON sSajyAvCCpLh4af4jTFwT2t3F1rGFWDPOyktFRce2RqKtEt5afei1ZIkovx5rjWqxE/9S97Op1o 6UHjFBSpc1wUvDw== 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 edcc8c05e435a4abba27dd2eb07facf4b5ed3243..e94747ae5897b1a33e2d09b7a3c= bf6f5ad1ca417 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 Sat Feb 7 08:27:26 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 3A114316900; Mon, 3 Nov 2025 12:53:42 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1762174422; cv=none; b=Kowduqz8Ir4l0qTOF028XWSpoY+gOcJVjA3Ip8bkQiWCWA4EaQEjy++LHRwbSuDWqFKrEFyDbVzLqzaGuowMY9l9VVZCdevMoa2WCcDNzOApSirLGTuTJUAeG12lzj7ikFWBfOWgCHumOBcsuaJwpH58xUQbicIBGc6Hc9Dq20k= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1762174422; c=relaxed/simple; bh=yulLeJZn1mX+cSvDuaJcOgJyv8hH6SOCKBioc8zxN20=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=QGt52B45iXfpHOEZNQ2YE9JWFH7heYe9CZweo+wjfR+iFjMoVtDJJ5MEg3LP+yIahjCgWvdpqrX2sR4MI03JVPTWv+VA5wGUdpw3vs8+v3xmsg1Kt1imETag5HhrE2QIc+BEoLH+MnNIUAmpvhjeu5D/nUE7ui3/k/VxOlgiX0M= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=UHssLS+E; 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="UHssLS+E" Received: by smtp.kernel.org (Postfix) with ESMTPSA id E56ADC4CEE7; Mon, 3 Nov 2025 12:53:38 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1762174422; bh=yulLeJZn1mX+cSvDuaJcOgJyv8hH6SOCKBioc8zxN20=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=UHssLS+EqhPcmq4VX9kZY0n2kc8tsCfVCjt6DuBstuv8EC32KZlxDwa9aLUG4Y5RW bzDFE+AjQiL/+4Dmglxi9BQE7ek244+mr2ZVlLtff0GkpjA2GwpkhybdhtsFro4RH+ zKrsUc9P+wtgp7fxV6PApqlPVF6FIGl8VBKRzQjtdzHqOF9xzCdoi0DVd/xRPG7BYW 0zeeadflKBwib7ooXitByso+Gr9wLB5VwH4uC6UxMHmIZN+nGuVCPMG7pj9djf3gA+ MuvY6e5z1u7rFwcu1qRKGA2wTrCiOmVMfrap5MLOYv3Rqwq0IXmtve0nNBeJ9kPy0j KKAZ/WDXXGLCA== From: Jeff Layton Date: Mon, 03 Nov 2025 07:52:43 -0500 Subject: [PATCH v4 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: <20251103-dir-deleg-ro-v4-15-961b67adee89@kernel.org> References: <20251103-dir-deleg-ro-v4-0-961b67adee89@kernel.org> In-Reply-To: <20251103-dir-deleg-ro-v4-0-961b67adee89@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/ZANAwAKAQAOaEEZVoIVAcsmYgBpCKWeE480+wABQYqJklPZE2R0cp6NeFSJ3AyaC XhUBRMgxMSJAjMEAAEKAB0WIQRLwNeyRHGyoYTq9dMADmhBGVaCFQUCaQilngAKCRAADmhBGVaC FYB3D/9XuPIJashthYWvmksA9OtHQX/KiRSuH5SXxC6mf62tXE1cHMJBoaV0gLHl7Ak4fMX9aKI Ma2wZG111/8u42PZ0/Z5UNJ5Jx6Q6ptO0ltEgYl4vJpHmh4tI81ZE+QevqnRna8pJkBkINIzjjm 9KOurX4bg34tzdE0VIYx6FKy8nFUb5+JHTprjcAyy44pGpezXMzXgB9T/Ynpm7AeAQwi1XbqUzW P9aaeOiVeMJmUXJBI4Qm62zrzno8dgXr68e0HdmuGn1qH8DrMJOrN9t6gGNcRaulahmuw5z1yf5 pDK8SPa9xx3cOit33yNTkn3T39600VZW/XGtmUmTE/VTjcWOt74sP+belIqSsh1M3KJhflOxFuD u4yjtb7B5dImLrxYjVFZL39P1H4WqA8YierlxIZa/wCaegLFaed4GCOys0BeLzkiJTcXraRpkPf FmPfuwjshGemRACFaiAmvlNZso3YDV5iSbMmeNghgCPl2XV7XKwzHOd1l9PWyXedupt/NdqQ7Ls v6aDsu7jBXjaAFxgfb27K4hSTXM0tlMkJpJTDXql5fjRvnWoheqDqOmdGLwvtLQcQT5eYOGkwaa 2TGBEUJBJ6S4H5z2muhfDa0rZ50UldQK+7a8N6dGNKcQ5Sv48tobCc+9eNdP5Gix3IqVyFtJnSJ qUTozEBnALhX8Ww== 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 Sat Feb 7 08:27:26 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id DB2DF316900; Mon, 3 Nov 2025 12:53:45 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1762174426; cv=none; b=t4Bo9JmaBogps6Kff72DjzvbiXl9kepFmUhalNs57JNKw+JTgXe8KOVG+WicAOPNlG5/Wr73KbvVwazwsuEPpJ3+unHjry1amqc3HRDr+pw20YygnNm9ZbAY9KrmAvhZiTzIeclIIu2wzygNvO4sNXYX9avL1JPq0xeBST8yZN0= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1762174426; c=relaxed/simple; bh=8uFhmfmnSTsd3LwYNioQRWlGjzSH6flkvXdmZ7xJmTo=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=EbsEUkDF2UWRLq76QZq2IUIpLp/r0e0/Jd49uncc3NQ0d8/ldb+CBZgejQQ1aigxm7aZZMIbltepfeHpTkLeXZxqX4yzypemScabHMG34+Y6bqObMkBr8xJ7D3rKZ1efbgC7fTc+mwIJoC8gStjH6n/RjF+OtUhbIU2S29yz1xU= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=UZy46lcd; 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="UZy46lcd" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 55065C4CEFD; Mon, 3 Nov 2025 12:53:42 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1762174425; bh=8uFhmfmnSTsd3LwYNioQRWlGjzSH6flkvXdmZ7xJmTo=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=UZy46lcdxkdwdD7k/LcTRSceh8zX3S3g9dEPASZINosJ0wq4VudvTign/zucCqkhO U/HumBS/ogNj0UAHdCoLb9SWwMDbvJiUqJ8hO/g+9Jl33NZ8GpH2NTc7ceqGdQoyPL BPnu3Vo2PbaZM+NhGNbw+pmP9m7Se+cKjl60VcJj3pVNEIroOY2e/vxdaRbxo2QCOJ svPO6nesEO007JYL9lchSAERwiMnJ1IrXaDZbqweDgnH60fyvX2q2RTIdJoz7WnpuL ocjZA5DIerFY00vxv4cwzrHI24HTV5WG+WPYwPB+Z3UDfFj4N3/nwKY+h+rBiy7m3/ 8VMAOXSqRHDbA== From: Jeff Layton Date: Mon, 03 Nov 2025 07:52:44 -0500 Subject: [PATCH v4 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: <20251103-dir-deleg-ro-v4-16-961b67adee89@kernel.org> References: <20251103-dir-deleg-ro-v4-0-961b67adee89@kernel.org> In-Reply-To: <20251103-dir-deleg-ro-v4-0-961b67adee89@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/ZANAwAKAQAOaEEZVoIVAcsmYgBpCKWfuwFT2jEz8HsBpKAxWSpBqIDGBnPTtbdUR TefQwcfJUiJAjMEAAEKAB0WIQRLwNeyRHGyoYTq9dMADmhBGVaCFQUCaQilnwAKCRAADmhBGVaC FQblEAC1N4C5LWOgklJgo3ot9s4EGU4EZzaVsg1uSo1fQyE41EdTxffLfjU0Mo54CyLSD2CyjCo m94VupgYqRs+L04sCL0oC9qBh83+5VaHycbjcNa/sikzRU5Pe72iyBZR7xYtPvuLtyHZG3J84W2 Jm0J0QQ1vJW7aD5PbDpmoPASR8LETzr3C1NZ4YdcpQCkb86/YSBRlsnospRJWG5zTSDUf48bw+F J/qtiqQgVj7Dhp4r673icKUWEmjp0C2D8UDwbHFo41FWeBM9SsABprwFNfQI3OyFZdvsCoKGLfa 8SpvDo7scukAdm0YhZtTolDqdyxiYu7FvCbkquRlkzTRNn9U2jYke/4ntIJOTKXHGCb5xf+IAod MiuBd2h+IsKFYAgo8HkEOMH5jJHCrXF33E2CyWulWiE1dGPUmGGarFPg2wPxN1zokh851CGNmpC zhIMjcy15rjMfmYet6UodM/bG1lZ089cj1x5MiaV+N3a1nAzW6XkOONj+KrSul5Fsl4JV/+Pdae dI0hrXO1pSl4I2sUkeHBo2UtBjqUnzEKRijCc89toa2MPnM4zvON2SV6f3uUU4XVncvMZwieDZE wK5VDB+OerbT5mXhiSGRv681eW6Mm6ImtoeZdL8alkvXJHVPIjDD6uw+8TYxTQM34UBm/VOioQX /TD/1O2IKWZX56g== 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 Sat Feb 7 08:27:26 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 4C85431A564; Mon, 3 Nov 2025 12:53:49 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1762174429; cv=none; b=eqDXfUe4BiZA/YUOUoXB+H2vGhTp71lghSuo2mEsAI7b1BH6uOo4Vj1XVzLmwCRhU6YA6Cn5vzZFaS/B9Jpl61Rg+twmp1iR5EaQQHzk4tpLEJ+16OAjwRhZoMrJ47sGLElUIELg+FWsKsIj/5+0RhB0LH5yOPuzxqS+OTiohGo= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1762174429; c=relaxed/simple; bh=5vnEsFLmQTNGsjzc9nlp6oQVoid1mJ5o3l9cHdo2eoU=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=ZSo9f8HP68sQLgUpRROUKPuubLujBpJeoYtnjwmEeR03D0nP+1QAAegkFsyhrEp5Wziu6qmBcZOS6PW9NN2x72gO9O1ppGdpC4EwfDT6UNAsj9IKhzEKPNMmwLwyCcywsFKZ3VwWRedwsB1qlhu5eV71oCzVQU8PyWX0orpMphg= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=YwfojEvQ; 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="YwfojEvQ" Received: by smtp.kernel.org (Postfix) with ESMTPSA id B98ECC4CEE7; Mon, 3 Nov 2025 12:53:45 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1762174428; bh=5vnEsFLmQTNGsjzc9nlp6oQVoid1mJ5o3l9cHdo2eoU=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=YwfojEvQFoTNEWx92dDbQY9YwM2gMVZbl+HVm2qYIb4bEdRAKAFfXcjEUTdDW9tfA 7qXTMn/4SphtVmKx7owviI2gqf+g28D6onZp70Dxl2KaYswfcWV98lpmJV4MOBcgCj Wag9u0li54jMktkldlTwPf3QPOYjN0yCg0ufsprjCOKUMsB4NJR9vtyx1urhXyMK/y VbMFkgGAAtJPuB3kj+igWAVCsbRmSvWIaUIHNtrmv9DaM6ZAgfcKN0eMi4AwG+ZWLI ooxWF6PEQPSNB5dQlfTSkYL/QkAO3JLSOnbPwqh+V5VUYE80VrSbGTba3GyIiELZIz I2Ur7jxHtbysQ== From: Jeff Layton Date: Mon, 03 Nov 2025 07:52:45 -0500 Subject: [PATCH v4 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: <20251103-dir-deleg-ro-v4-17-961b67adee89@kernel.org> References: <20251103-dir-deleg-ro-v4-0-961b67adee89@kernel.org> In-Reply-To: <20251103-dir-deleg-ro-v4-0-961b67adee89@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=6381; i=jlayton@kernel.org; h=from:subject:message-id; bh=5vnEsFLmQTNGsjzc9nlp6oQVoid1mJ5o3l9cHdo2eoU=; b=owEBbQKS/ZANAwAKAQAOaEEZVoIVAcsmYgBpCKWfL5rEDvoecb6h2EtHSx6vtxVMPU49VDa09 uywOyfKWUeJAjMEAAEKAB0WIQRLwNeyRHGyoYTq9dMADmhBGVaCFQUCaQilnwAKCRAADmhBGVaC FT1vEADNkNWiGMlbqP7jUf8X5h6MV4sgqioLwoiaAFjuRU5X4KuPCYmeDsJwj9wB/gZ4ja/oL3g lr2Frya3Vi29F7gQOaEIk57edySLRufmHXUcdYbA4OEPTczEiLh/gX+YaFxnddpBLYXjSUPUBCz GAcnAXnCfnM6S67Pld55yVeOH+A3hSTo3tUHOpZ2WxgalhLWaNaVgrzWKkF05O1fj91Ca69FeLx 8Nk1SXdCZsF4SjEhBkUVqniNL97JKW+uL9fAUUt2n61XHohfJpZL4SSb96u+PghRlcOithDDZNW Yz3H+qOm2+UyrSKq/23CsCJpmPmBQJMWC3hQHgDfPKk/DmUstkYEphjo6MHP5JN/xh0xy+Fjc46 vkcKFu0oJjyk4Cgg6N2VaSvnFlKF1CGhjTVwiyCf9S+r/NbfjkXEfTEfcuoMHVqA54X3HaL8Vei hVNqXr1t1/TWUJHoMFmSZdxgfdTmZ8/b1C5rnNNniSFnQcRktterb61H46ibbSoskjzhVpa5Rg6 Npj3xwO1qGDqxlAoBqrzc4tkJcF2Z51uP8MuxufprmSzvr+n21c5g2bjvHEqoJ4BuKcsTfQMu8t 285nYgJNzuxJzNtQbtllD1d/nd6IjJOA/4kNVIDBwbHOiqmWfk22Ekl+QIh9dbCU51bkH5cS1kk CX67UzGREA7+Yug== 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 | 14 ++++++++++++++ fs/locks.c | 42 +++++++++++++++++++++++++++++++++++++----- include/linux/filelock.h | 12 ++++++++++++ include/uapi/linux/fcntl.h | 10 ++++++++++ 4 files changed, 73 insertions(+), 5 deletions(-) diff --git a/fs/fcntl.c b/fs/fcntl.c index 72f8433d9109889eecef56b32d20a85b4e12ea44..8d57a6e34076d68228b6d8d9bb3= 81f78a751b151 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,19 @@ 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; + fcntl_getdeleg(filp, &deleg); + if (copy_to_user(argp, &deleg, sizeof(deleg))) + return -EFAULT; + err =3D 0; + 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..1e29aecf79b8df66a6c67ca5f59= cec40a376b9bc 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,16 @@ int fcntl_getlease(struct file *filp) return type; } =20 +int fcntl_getlease(struct file *filp) +{ + return __fcntl_getlease(filp, FL_LEASE); +} + +void fcntl_getdeleg(struct file *filp, struct delegation *deleg) +{ + deleg->d_type =3D __fcntl_getlease(filp, FL_DELEG); +} + /** * check_conflicting_open - see if the given file points to an inode that = has * an existing open that would conflict with the @@ -2039,13 +2050,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 +2092,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..4384c6f61fad8f21d15974fac1d= 0f77747155f0f 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); +void 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 F_UNLCK; +} + static inline bool lock_is_unlock(struct file_lock *fl) { return false; diff --git a/include/uapi/linux/fcntl.h b/include/uapi/linux/fcntl.h index 3741ea1b73d8500061567b6590ccf5fb4c6770f0..aae88f4b5c05205b2b28ae46b21= bca9817197e04 100644 --- a/include/uapi/linux/fcntl.h +++ b/include/uapi/linux/fcntl.h @@ -79,6 +79,16 @@ */ #define RWF_WRITE_LIFE_NOT_SET RWH_WRITE_LIFE_NOT_SET =20 +/* Set/Get delegations */ +#define F_GETDELEG (F_LINUX_SPECIFIC_BASE + 15) +#define F_SETDELEG (F_LINUX_SPECIFIC_BASE + 16) + +/* Argument structure for F_GETDELEG and F_SETDELEG */ +struct delegation { + short d_type; /* F_RDLCK, F_WRLCK, F_UNLCK */ + unsigned int d_flags; +}; + /* * Types of directory notifications that may be requested. */ --=20 2.51.1