Skip to content

Commit 9d4b74a

Browse files
author
Christoph Hellwig
committed
fs: refactor do_utimes
Split out one helper each for path vs fd based operations. Signed-off-by: Christoph Hellwig <[email protected]> Acked-by: Linus Torvalds <[email protected]>
1 parent 863b67e commit 9d4b74a

File tree

1 file changed

+54
-46
lines changed

1 file changed

+54
-46
lines changed

fs/utimes.c

Lines changed: 54 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,57 @@ static int utimes_common(const struct path *path, struct timespec64 *times)
7070
return error;
7171
}
7272

73+
static int do_utimes_path(int dfd, const char __user *filename,
74+
struct timespec64 *times, int flags)
75+
{
76+
struct path path;
77+
int lookup_flags = 0, error;
78+
79+
if (times &&
80+
(!nsec_valid(times[0].tv_nsec) || !nsec_valid(times[1].tv_nsec)))
81+
return -EINVAL;
82+
if (flags & ~(AT_SYMLINK_NOFOLLOW | AT_EMPTY_PATH))
83+
return -EINVAL;
84+
85+
if (!(flags & AT_SYMLINK_NOFOLLOW))
86+
lookup_flags |= LOOKUP_FOLLOW;
87+
if (flags & AT_EMPTY_PATH)
88+
lookup_flags |= LOOKUP_EMPTY;
89+
90+
retry:
91+
error = user_path_at(dfd, filename, lookup_flags, &path);
92+
if (error)
93+
return error;
94+
95+
error = utimes_common(&path, times);
96+
path_put(&path);
97+
if (retry_estale(error, lookup_flags)) {
98+
lookup_flags |= LOOKUP_REVAL;
99+
goto retry;
100+
}
101+
102+
return error;
103+
}
104+
105+
static int do_utimes_fd(int fd, struct timespec64 *times, int flags)
106+
{
107+
struct fd f;
108+
int error;
109+
110+
if (times &&
111+
(!nsec_valid(times[0].tv_nsec) || !nsec_valid(times[1].tv_nsec)))
112+
return -EINVAL;
113+
if (flags)
114+
return -EINVAL;
115+
116+
f = fdget(fd);
117+
if (!f.file)
118+
return -EBADF;
119+
error = utimes_common(&f.file->f_path, times);
120+
fdput(f);
121+
return error;
122+
}
123+
73124
/*
74125
* do_utimes - change times on filename or file descriptor
75126
* @dfd: open file descriptor, -1 or AT_FDCWD
@@ -88,52 +139,9 @@ static int utimes_common(const struct path *path, struct timespec64 *times)
88139
long do_utimes(int dfd, const char __user *filename, struct timespec64 *times,
89140
int flags)
90141
{
91-
int error = -EINVAL;
92-
93-
if (times && (!nsec_valid(times[0].tv_nsec) ||
94-
!nsec_valid(times[1].tv_nsec))) {
95-
goto out;
96-
}
97-
98-
if (flags & ~(AT_SYMLINK_NOFOLLOW | AT_EMPTY_PATH))
99-
goto out;
100-
101-
if (filename == NULL && dfd != AT_FDCWD) {
102-
struct fd f;
103-
104-
if (flags)
105-
goto out;
106-
107-
f = fdget(dfd);
108-
error = -EBADF;
109-
if (!f.file)
110-
goto out;
111-
112-
error = utimes_common(&f.file->f_path, times);
113-
fdput(f);
114-
} else {
115-
struct path path;
116-
int lookup_flags = 0;
117-
118-
if (!(flags & AT_SYMLINK_NOFOLLOW))
119-
lookup_flags |= LOOKUP_FOLLOW;
120-
if (flags & AT_EMPTY_PATH)
121-
lookup_flags |= LOOKUP_EMPTY;
122-
retry:
123-
error = user_path_at(dfd, filename, lookup_flags, &path);
124-
if (error)
125-
goto out;
126-
127-
error = utimes_common(&path, times);
128-
path_put(&path);
129-
if (retry_estale(error, lookup_flags)) {
130-
lookup_flags |= LOOKUP_REVAL;
131-
goto retry;
132-
}
133-
}
134-
135-
out:
136-
return error;
142+
if (filename == NULL && dfd != AT_FDCWD)
143+
return do_utimes_fd(dfd, times, flags);
144+
return do_utimes_path(dfd, filename, times, flags);
137145
}
138146

139147
SYSCALL_DEFINE4(utimensat, int, dfd, const char __user *, filename,

0 commit comments

Comments
 (0)