]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
VFS: move delegated_inode retry loop into lookup_open()
authorNeilBrown <neil@brown.name>
Tue, 14 Jul 2026 23:04:13 +0000 (09:04 +1000)
committerChristian Brauner <brauner@kernel.org>
Thu, 23 Jul 2026 13:42:48 +0000 (15:42 +0200)
By moving this retry into lookup_open() we no longer need to pass around
the delegated_inode pointer.

Various variable assignments need to be moved out of the declaration
block so that they can be repeated after the "goto retry".

Reviewed-by: Jan Kara <jack@suse.cz>
Reviewed-by: Jori Koolstra <jkoolstra@xs4all.nl>
Signed-off-by: NeilBrown <neil@brown.name>
Link: https://patch.msgid.link/20260714230534.776886-3-neilb@ownmail.net
Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org>
fs/namei.c

index 711c7745e74727794a6b85398e1440825d8273a8..1ca738401afa93a126d3866fa78ab32b5ab64c99 100644 (file)
@@ -4402,17 +4402,23 @@ static struct dentry *atomic_open(const struct path *path, struct dentry *dentry
  * An error code is returned on failure.
  */
 static struct dentry *lookup_open(struct nameidata *nd, struct file *file,
-                                 const struct open_flags *op,
-                                 struct delegated_inode *delegated_inode)
+                                 const struct open_flags *op)
 {
+       struct delegated_inode delegated_inode = { };
        struct mnt_idmap *idmap;
        struct dentry *dir = nd->path.dentry;
        struct inode *dir_inode = dir->d_inode;
-       int open_flag = op->open_flag;
+       int open_flag;
        struct dentry *dentry;
-       int error, create_error = 0;
-       umode_t mode = op->mode;
-       bool got_write = false;
+       int error, create_error;
+       umode_t mode;
+       bool got_write;
+
+retry:
+       open_flag = op->open_flag;
+       got_write = false;
+       mode = op->mode;
+       create_error = 0;
 
        if (open_flag & (O_CREAT | O_TRUNC | O_WRONLY | O_RDWR)) {
                got_write = !mnt_want_write(nd->path.mnt);
@@ -4510,7 +4516,7 @@ static struct dentry *lookup_open(struct nameidata *nd, struct file *file,
        /* Negative dentry, just create the file */
        if (!dentry->d_inode && (open_flag & O_CREAT)) {
                /* but break the directory lease first! */
-               error = try_break_deleg(dir_inode, LEASE_BREAK_DIR_CREATE, delegated_inode);
+               error = try_break_deleg(dir_inode, LEASE_BREAK_DIR_CREATE, &delegated_inode);
                if (error)
                        goto out_dput;
 
@@ -4545,6 +4551,15 @@ out:
        if (got_write)
                mnt_drop_write(nd->path.mnt);
 
+       if (is_delegated(&delegated_inode)) {
+               /* Must have come through out_dput: dentry is an ERR_PTR() */
+               error = break_deleg_wait(&delegated_inode);
+
+               if (!error)
+                       goto retry;
+               dentry = ERR_PTR(error);
+       }
+
        return dentry;
 
 out_dput:
@@ -4592,7 +4607,6 @@ static struct dentry *lookup_fast_for_open(struct nameidata *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 = { };
        int open_flag = op->open_flag;
        struct dentry *dentry;
        const char *res;
@@ -4622,19 +4636,10 @@ static const char *open_last_lookups(struct nameidata *nd,
                                return ERR_PTR(-ECHILD);
                }
        }
-retry:
-       dentry = lookup_open(nd, file, op, &delegated_inode);
-
-       if (IS_ERR(dentry)) {
-               if (is_delegated(&delegated_inode)) {
-                       int error = break_deleg_wait(&delegated_inode);
 
-                       if (!error)
-                               goto retry;
-                       return ERR_PTR(error);
-               }
+       dentry = lookup_open(nd, file, op);
+       if (IS_ERR(dentry))
                return ERR_CAST(dentry);
-       }
 
        if (file->f_mode & (FMODE_OPENED | FMODE_CREATED)) {
                dput(nd->path.dentry);