@@ -4381,37 +4381,32 @@ EXPORT_SYMBOL(vfs_link);
* with linux 2.0, and to avoid hard-linking to directories
* and other special files. --ADM
*/
-int do_linkat(int olddfd, struct filename *old, int newdfd,
- struct filename *new, int flags)
+static int try_linkat(int olddfd, struct filename *old, int newdfd,
+ struct filename *new, int flags, unsigned int how)
{
struct user_namespace *mnt_userns;
struct dentry *new_dentry;
struct path old_path, new_path;
struct inode *delegated_inode = NULL;
- int how = 0;
int error;
retry:
- if ((flags & ~(AT_SYMLINK_FOLLOW | AT_EMPTY_PATH)) != 0) {
- error = -EINVAL;
- goto out_putnames;
- }
+ if ((flags & ~(AT_SYMLINK_FOLLOW | AT_EMPTY_PATH)) != 0)
+ return -EINVAL;
/*
* To use null names we require CAP_DAC_READ_SEARCH
* This ensures that not everyone will be able to create
* handlink using the passed filedescriptor.
*/
- if (flags & AT_EMPTY_PATH && !capable(CAP_DAC_READ_SEARCH)) {
- error = -ENOENT;
- goto out_putnames;
- }
+ if (flags & AT_EMPTY_PATH && !capable(CAP_DAC_READ_SEARCH))
+ return -ENOENT;
if (flags & AT_SYMLINK_FOLLOW)
how |= LOOKUP_FOLLOW;
error = __filename_lookup(olddfd, old, how, &old_path, NULL);
if (error)
- goto out_putnames;
+ return error;
new_dentry = __filename_create(newdfd, new, &new_path,
(how & LOOKUP_REVAL));
@@ -4442,14 +4437,20 @@ int do_linkat(int olddfd, struct filename *old, int newdfd,
}
out_putpath:
path_put(&old_path);
-out_putnames:
- if (unlikely(retry_estale(error, how))) {
- how |= LOOKUP_REVAL;
- goto retry;
- }
+ return error;
+}
+
+int do_linkat(int olddfd, struct filename *old, int newdfd,
+ struct filename *new, int flags)
+{
+ int error;
+
+ error = try_linkat(olddfd, old, newdfd, new, flags, 0);
+ if (unlikely(retry_estale(error, 0)))
+ error = try_linkat(olddfd, old, newdfd, new, flags, LOOKUP_REVAL);
+
putname(old);
putname(new);
-
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/ Link: https://lore.kernel.org/io-uring/CAHk-=wiE_JVny73KRZ6wuhL_5U0RRSmAw678_Cnkh3OHM8C7Jg@mail.gmail.com/ Signed-off-by: Dmitry Kadashev <dkadashev@gmail.com> --- fs/namei.c | 37 +++++++++++++++++++------------------ 1 file changed, 19 insertions(+), 18 deletions(-)