No functional changes, just move the main logic to a helper function to make the whole thing easier to follow. Cc: Linus Torvalds <torvalds@xxxxxxxxxxxxxxxxxxxx> Cc: Al Viro <viro@xxxxxxxxxxxxxxxxxx> Cc: Christian Brauner <christian.brauner@xxxxxxxxxx> Suggested-by: Linus Torvalds <torvalds@xxxxxxxxxxxxxxxxxxxx> Link: https://lore.kernel.org/io-uring/CAHk-=wiG+sN+2zSoAOggKCGue2kOJvw3rQySvQXsZstRQFTN+g@xxxxxxxxxxxxxx/ Link: https://lore.kernel.org/io-uring/CAHk-=wjFd0qn6asio=zg7zUTRmSty_TpAEhnwym1Qb=wFgCKzA@xxxxxxxxxxxxxx/ Signed-off-by: Dmitry Kadashev <dkadashev@xxxxxxxxx> --- fs/namei.c | 34 +++++++++++++++++++++------------- 1 file changed, 21 insertions(+), 13 deletions(-) diff --git a/fs/namei.c b/fs/namei.c index a75abff5a9a6..dce0e427b95a 100644 --- a/fs/namei.c +++ b/fs/namei.c @@ -4643,8 +4643,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 try_renameat(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; @@ -4653,16 +4654,15 @@ 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; - int error = -EINVAL; + unsigned int target_flags = LOOKUP_RENAME_TARGET; + int error; -retry: 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; if (flags & RENAME_EXCHANGE) target_flags = 0; @@ -4670,7 +4670,7 @@ int do_renameat2(int olddfd, struct filename *from, int newdfd, 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); @@ -4771,11 +4771,19 @@ int do_renameat2(int olddfd, struct filename *from, int newdfd, path_put(&new_path); exit1: path_put(&old_path); -put_names: - if (retry_estale(error, lookup_flags)) { - lookup_flags |= LOOKUP_REVAL; - goto retry; - } + return error; +} + +int do_renameat2(int olddfd, struct filename *from, int newdfd, + struct filename *to, unsigned int flags) +{ + int error; + + error = try_renameat(olddfd, from, newdfd, to, flags, 0); + if (unlikely(retry_estale(error, 0))) + error = try_renameat(olddfd, from, newdfd, to, flags, + LOOKUP_REVAL); + putname(from); putname(to); return error; -- 2.30.2