@@ -4658,8 +4658,9 @@ 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)
+static int renameat_helper(int olddfd, struct filename *from, int newdfd,
+ struct filename *to, unsigned int flags,
+ unsigned int lookup_flags)
{
struct renamedata rd;
struct dentry *old_dentry, *new_dentry;
@@ -4668,25 +4669,23 @@ int do_renameat2(int olddfd, struct filename *from, int newdfd,
struct qstr old_last, new_last;
int old_type, new_type;
struct inode *delegated_inode = NULL;
- unsigned int lookup_flags = 0, target_flags = LOOKUP_RENAME_TARGET;
- bool should_retry = false;
+ unsigned int target_flags = LOOKUP_RENAME_TARGET;
int error = -EINVAL;
if (flags & ~(RENAME_NOREPLACE | RENAME_EXCHANGE | RENAME_WHITEOUT))
- goto put_names;
+ return error;
if ((flags & (RENAME_NOREPLACE | RENAME_WHITEOUT)) &&
(flags & RENAME_EXCHANGE))
- goto put_names;
+ return error;
if (flags & RENAME_EXCHANGE)
target_flags = 0;
-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);
@@ -4784,17 +4783,22 @@ int do_renameat2(int olddfd, struct filename *from, int newdfd,
}
mnt_drop_write(old_path.mnt);
exit2:
- if (retry_estale(error, lookup_flags))
- should_retry = true;
path_put(&new_path);
exit1:
path_put(&old_path);
- if (should_retry) {
- should_retry = false;
- lookup_flags |= LOOKUP_REVAL;
- goto retry;
- }
-put_names:
+ return error;
+}
+
+int do_renameat2(int olddfd, struct filename *from, int newdfd,
+ struct filename *to, unsigned int flags)
+{
+ int error;
+
+ error = renameat_helper(olddfd, from, newdfd, to, flags, 0);
+ if (retry_estale(error, 0))
+ error = renameat_helper(olddfd, from, newdfd, to, flags,
+ LOOKUP_REVAL);
+
putname(from);
putname(to);
return error;
Moving the main logic to a helper function makes the whole thing much 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 | 36 ++++++++++++++++++++---------------- 1 file changed, 20 insertions(+), 16 deletions(-)