more explicit in what we do, lower odds of ending up with a leak,
fewer gotos...

... and if at some point in the future we decide to make some of those
non-consuming, it would be less noisy.

Signed-off-by: Al Viro <[email protected]>
---
 fs/namei.c | 51 +++++++++++++++++++++------------------------------
 1 file changed, 21 insertions(+), 30 deletions(-)

diff --git a/fs/namei.c b/fs/namei.c
index f6b5d6a657da..fbf306fe8414 100644
--- a/fs/namei.c
+++ b/fs/namei.c
@@ -5575,23 +5575,22 @@ int vfs_symlink(struct mnt_idmap *idmap, struct inode 
*dir,
 }
 EXPORT_SYMBOL(vfs_symlink);
 
-int do_symlinkat(struct filename *from, int newdfd, struct filename *to)
+int do_symlinkat(struct filename *__from, int newdfd, struct filename *__to)
 {
+       CLASS(filename_consume, from)(__from);
+       CLASS(filename_consume, to)(__to);
        int error;
        struct dentry *dentry;
        struct path path;
        unsigned int lookup_flags = 0;
        struct delegated_inode delegated_inode = { };
 
-       if (IS_ERR(from)) {
-               error = PTR_ERR(from);
-               goto out_putnames;
-       }
+       if (IS_ERR(from))
+               return PTR_ERR(from);
 retry:
        dentry = filename_create(newdfd, to, &path, lookup_flags);
-       error = PTR_ERR(dentry);
        if (IS_ERR(dentry))
-               goto out_putnames;
+               return PTR_ERR(dentry);
 
        error = security_path_symlink(&path, dentry, from->name);
        if (!error)
@@ -5607,9 +5606,6 @@ int do_symlinkat(struct filename *from, int newdfd, 
struct filename *to)
                lookup_flags |= LOOKUP_REVAL;
                goto retry;
        }
-out_putnames:
-       putname(to);
-       putname(from);
        return error;
 }
 
@@ -5724,9 +5720,11 @@ EXPORT_SYMBOL(vfs_link);
  * with linux 2.0, and to avoid hard-linking to directories
  * and other special files.  --ADM
  */
-int do_linkat(int olddfd, struct filename *old, int newdfd,
-             struct filename *new, int flags)
+int do_linkat(int olddfd, struct filename *__old, int newdfd,
+             struct filename *__new, int flags)
 {
+       CLASS(filename_consume, old)(__old);
+       CLASS(filename_consume, new)(__new);
        struct mnt_idmap *idmap;
        struct dentry *new_dentry;
        struct path old_path, new_path;
@@ -5734,10 +5732,8 @@ int do_linkat(int olddfd, struct filename *old, int 
newdfd,
        int how = 0;
        int error;
 
-       if ((flags & ~(AT_SYMLINK_FOLLOW | AT_EMPTY_PATH)) != 0) {
-               error = -EINVAL;
-               goto out_putnames;
-       }
+       if ((flags & ~(AT_SYMLINK_FOLLOW | AT_EMPTY_PATH)) != 0)
+               return -EINVAL;
        /*
         * To use null names we require CAP_DAC_READ_SEARCH or
         * that the open-time creds of the dfd matches current.
@@ -5752,7 +5748,7 @@ int do_linkat(int olddfd, struct filename *old, int 
newdfd,
 retry:
        error = filename_lookup(olddfd, old, how, &old_path, NULL);
        if (error)
-               goto out_putnames;
+               return error;
 
        new_dentry = filename_create(newdfd, new, &new_path,
                                        (how & LOOKUP_REVAL));
@@ -5788,10 +5784,6 @@ int do_linkat(int olddfd, struct filename *old, int 
newdfd,
        }
 out_putpath:
        path_put(&old_path);
-out_putnames:
-       putname(old);
-       putname(new);
-
        return error;
 }
 
@@ -6022,9 +6014,11 @@ int vfs_rename(struct renamedata *rd)
 }
 EXPORT_SYMBOL(vfs_rename);
 
-int do_renameat2(int olddfd, struct filename *from, int newdfd,
-                struct filename *to, unsigned int flags)
+int do_renameat2(int olddfd, struct filename *__from, int newdfd,
+                struct filename *__to, unsigned int flags)
 {
+       CLASS(filename_consume, from)(__from);
+       CLASS(filename_consume, to)(__to);
        struct renamedata rd;
        struct path old_path, new_path;
        struct qstr old_last, new_last;
@@ -6032,20 +6026,20 @@ int do_renameat2(int olddfd, struct filename *from, int 
newdfd,
        struct delegated_inode delegated_inode = { };
        unsigned int lookup_flags = 0;
        bool should_retry = false;
-       int error = -EINVAL;
+       int error;
 
        if (flags & ~(RENAME_NOREPLACE | RENAME_EXCHANGE | RENAME_WHITEOUT))
-               goto put_names;
+               return -EINVAL;
 
        if ((flags & (RENAME_NOREPLACE | RENAME_WHITEOUT)) &&
            (flags & RENAME_EXCHANGE))
-               goto put_names;
+               return -EINVAL;
 
 retry:
        error = filename_parentat(olddfd, from, lookup_flags, &old_path,
                                  &old_last, &old_type);
        if (error)
-               goto put_names;
+               return error;
 
        error = filename_parentat(newdfd, to, lookup_flags, &new_path, 
&new_last,
                                  &new_type);
@@ -6122,9 +6116,6 @@ int do_renameat2(int olddfd, struct filename *from, int 
newdfd,
                lookup_flags |= LOOKUP_REVAL;
                goto retry;
        }
-put_names:
-       putname(from);
-       putname(to);
        return error;
 }
 
-- 
2.47.3


Reply via email to