[PATCH 7/7] namei: clean up do_renameat retry logic
From: Dmitry Kadashev <hidden>
Date: 2021-07-12 12:37:24
Also in:
linux-fsdevel
Subsystem:
filesystems (vfs and infrastructure), the rest · Maintainers:
Alexander Viro, Christian Brauner, Linus Torvalds
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 <redacted> Suggested-by: Linus Torvalds <torvalds@linux-foundation.org> Link: https://lore.kernel.org/io-uring/CAHk-=wiG+sN+2zSoAOggKCGue2kOJvw3rQySvQXsZstRQFTN+g@mail.gmail.com/ (local) Signed-off-by: Dmitry Kadashev <redacted> --- fs/namei.c | 36 ++++++++++++++++++++---------------- 1 file changed, 20 insertions(+), 16 deletions(-)
diff --git a/fs/namei.c b/fs/namei.c
index 5e4fa8b65a8d..023ee19aa5ed 100644
--- a/fs/namei.c
+++ b/fs/namei.c@@ -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;
--
2.30.2