]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
non-consuming variant of do_symlinkat()
authorAl Viro <viro@zeniv.linux.org.uk>
Wed, 7 Jan 2026 04:26:43 +0000 (23:26 -0500)
committerAl Viro <viro@zeniv.linux.org.uk>
Fri, 16 Jan 2026 17:48:16 +0000 (12:48 -0500)
similar to previous commit; replacement is filename_symlinkat()

Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Documentation/filesystems/porting.rst
fs/init.c
fs/internal.h
fs/namei.c
io_uring/fs.c

index e93ba90e3e4fec345e7f9dc447198717eb18b918..bb526ae9a1d716e1830e84a63853c88988085996 100644 (file)
@@ -1342,4 +1342,5 @@ in-tree filesystems have done).
 fs/namei.c primitives that consume filesystem references (do_renameat2(),
 do_linkat(), do_symlinkat(), do_mkdirat(), do_mknodat(), do_unlinkat()
 and do_rmdir()) are getting replaced with non-consuming analogues
-(filename_renameat2(), etc.)  Replaced so far: do_renameat2(), do_linkat().
+(filename_renameat2(), etc.)  Replaced so far: do_renameat2(), do_linkat(),
+do_symlinkat().
index f46e545529315f054e843aac5e672908366b903a..a54ef750ffe3a56ccdc00875e424d519d0d955e2 100644 (file)
--- a/fs/init.c
+++ b/fs/init.c
@@ -152,8 +152,9 @@ int __init init_link(const char *oldname, const char *newname)
 
 int __init init_symlink(const char *oldname, const char *newname)
 {
-       return do_symlinkat(getname_kernel(oldname), AT_FDCWD,
-                           getname_kernel(newname));
+       CLASS(filename_kernel, old)(oldname);
+       CLASS(filename_kernel, new)(newname);
+       return filename_symlinkat(old, AT_FDCWD, new);
 }
 
 int __init init_unlink(const char *pathname)
index c9b70c2716d1ab0e4e2230b4a0d5a450e273895c..4a63b89c02d7de3864028cc774024b2fffadbc8e 100644 (file)
@@ -61,7 +61,7 @@ int filename_renameat2(int olddfd, struct filename *oldname, int newdfd,
                 struct filename *newname, unsigned int flags);
 int do_mkdirat(int dfd, struct filename *name, umode_t mode);
 int do_mknodat(int dfd, struct filename *name, umode_t mode, unsigned int dev);
-int do_symlinkat(struct filename *from, int newdfd, struct filename *to);
+int filename_symlinkat(struct filename *from, int newdfd, struct filename *to);
 int filename_linkat(int olddfd, struct filename *old, int newdfd,
                        struct filename *new, int flags);
 int vfs_tmpfile(struct mnt_idmap *idmap,
index e5d494610c2c32228531fbe1021e0acf44d5a128..c88ad27f66c71b52555be87580834d5c335d4806 100644 (file)
@@ -5581,7 +5581,7 @@ 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 filename_symlinkat(struct filename *from, int newdfd, struct filename *to)
 {
        int error;
        struct dentry *dentry;
@@ -5589,15 +5589,13 @@ int do_symlinkat(struct filename *from, int newdfd, struct filename *to)
        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)
@@ -5613,21 +5611,22 @@ retry:
                lookup_flags |= LOOKUP_REVAL;
                goto retry;
        }
-out_putnames:
-       putname(to);
-       putname(from);
        return error;
 }
 
 SYSCALL_DEFINE3(symlinkat, const char __user *, oldname,
                int, newdfd, const char __user *, newname)
 {
-       return do_symlinkat(getname(oldname), newdfd, getname(newname));
+       CLASS(filename, old)(oldname);
+       CLASS(filename, new)(newname);
+       return filename_symlinkat(old, newdfd, new);
 }
 
 SYSCALL_DEFINE2(symlink, const char __user *, oldname, const char __user *, newname)
 {
-       return do_symlinkat(getname(oldname), AT_FDCWD, getname(newname));
+       CLASS(filename, old)(oldname);
+       CLASS(filename, new)(newname);
+       return filename_symlinkat(old, AT_FDCWD, new);
 }
 
 /**
index e39cd1ca194236f11a3ea3025d3902e74863febe..cd4d88d37795241a948a8c0d5350ebf42633b40e 100644 (file)
@@ -233,12 +233,13 @@ int io_symlinkat_prep(struct io_kiocb *req, const struct io_uring_sqe *sqe)
 int io_symlinkat(struct io_kiocb *req, unsigned int issue_flags)
 {
        struct io_link *sl = io_kiocb_to_cmd(req, struct io_link);
+       CLASS(filename_complete_delayed, old)(&sl->oldpath);
+       CLASS(filename_complete_delayed, new)(&sl->newpath);
        int ret;
 
        WARN_ON_ONCE(issue_flags & IO_URING_F_NONBLOCK);
 
-       ret = do_symlinkat(complete_getname(&sl->oldpath), sl->new_dfd,
-                          complete_getname(&sl->newpath));
+       ret = filename_symlinkat(old, sl->new_dfd, new);
 
        req->flags &= ~REQ_F_NEED_CLEANUP;
        io_req_set_res(req, ret, 0);