@@ -4234,22 +4234,18 @@ int vfs_symlink(struct user_namespace *mnt_userns, struct inode *dir,
}
EXPORT_SYMBOL(vfs_symlink);
-int do_symlinkat(struct filename *from, int newdfd, struct filename *to)
+static int try_symlinkat(struct filename *from, int newdfd, struct filename *to,
+ unsigned int lookup_flags)
{
int error;
struct dentry *dentry;
struct path path;
- unsigned int lookup_flags = 0;
-retry:
- if (IS_ERR(from)) {
- error = PTR_ERR(from);
- goto out;
- }
+ if (IS_ERR(from))
+ return PTR_ERR(from);
dentry = __filename_create(newdfd, to, &path, lookup_flags);
- error = PTR_ERR(dentry);
if (IS_ERR(dentry))
- goto out;
+ return PTR_ERR(dentry);
error = security_path_symlink(&path, dentry, from->name);
if (!error) {
@@ -4260,11 +4256,17 @@ int do_symlinkat(struct filename *from, int newdfd, struct filename *to)
from->name);
}
done_path_create(&path, dentry);
-out:
- if (unlikely(retry_estale(error, lookup_flags))) {
- lookup_flags |= LOOKUP_REVAL;
- goto retry;
- }
+ return error;
+}
+
+int do_symlinkat(struct filename *from, int newdfd, struct filename *to)
+{
+ int error;
+
+ error = try_symlinkat(from, newdfd, to, 0);
+ if (unlikely(retry_estale(error, 0)))
+ error = try_symlinkat(from, newdfd, to, LOOKUP_REVAL);
+
putname(to);
putname(from);
return error;
No functional changes, just move the main logic to a helper function to make the whole thing easier to follow. Cc: Linus Torvalds <torvalds@linux-foundation.org> Cc: Al Viro <viro@zeniv.linux.org.uk> Cc: Christian Brauner <christian.brauner@ubuntu.com> Suggested-by: Linus Torvalds <torvalds@linux-foundation.org> Link: https://lore.kernel.org/io-uring/CAHk-=wiG+sN+2zSoAOggKCGue2kOJvw3rQySvQXsZstRQFTN+g@mail.gmail.com/ Signed-off-by: Dmitry Kadashev <dkadashev@gmail.com> --- fs/namei.c | 30 ++++++++++++++++-------------- 1 file changed, 16 insertions(+), 14 deletions(-)