Skip to content

Commit

Permalink
fs: refactor do_utimes
Browse files Browse the repository at this point in the history
Split out one helper each for path vs fd based operations.

Signed-off-by: Christoph Hellwig <hch@lst.de>
Acked-by: Linus Torvalds <torvalds@linux-foundation.org>
  • Loading branch information
Christoph Hellwig committed Jul 31, 2020
1 parent 863b67e commit 9d4b74a
Showing 1 changed file with 54 additions and 46 deletions.
100 changes: 54 additions & 46 deletions fs/utimes.c
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,57 @@ static int utimes_common(const struct path *path, struct timespec64 *times)
return error;
}

static int do_utimes_path(int dfd, const char __user *filename,
struct timespec64 *times, int flags)
{
struct path path;
int lookup_flags = 0, error;

if (times &&
(!nsec_valid(times[0].tv_nsec) || !nsec_valid(times[1].tv_nsec)))
return -EINVAL;
if (flags & ~(AT_SYMLINK_NOFOLLOW | AT_EMPTY_PATH))
return -EINVAL;

if (!(flags & AT_SYMLINK_NOFOLLOW))
lookup_flags |= LOOKUP_FOLLOW;
if (flags & AT_EMPTY_PATH)
lookup_flags |= LOOKUP_EMPTY;

retry:
error = user_path_at(dfd, filename, lookup_flags, &path);
if (error)
return error;

error = utimes_common(&path, times);
path_put(&path);
if (retry_estale(error, lookup_flags)) {
lookup_flags |= LOOKUP_REVAL;
goto retry;
}

return error;
}

static int do_utimes_fd(int fd, struct timespec64 *times, int flags)
{
struct fd f;
int error;

if (times &&
(!nsec_valid(times[0].tv_nsec) || !nsec_valid(times[1].tv_nsec)))
return -EINVAL;
if (flags)
return -EINVAL;

f = fdget(fd);
if (!f.file)
return -EBADF;
error = utimes_common(&f.file->f_path, times);
fdput(f);
return error;
}

/*
* do_utimes - change times on filename or file descriptor
* @dfd: open file descriptor, -1 or AT_FDCWD
Expand All @@ -88,52 +139,9 @@ static int utimes_common(const struct path *path, struct timespec64 *times)
long do_utimes(int dfd, const char __user *filename, struct timespec64 *times,
int flags)
{
int error = -EINVAL;

if (times && (!nsec_valid(times[0].tv_nsec) ||
!nsec_valid(times[1].tv_nsec))) {
goto out;
}

if (flags & ~(AT_SYMLINK_NOFOLLOW | AT_EMPTY_PATH))
goto out;

if (filename == NULL && dfd != AT_FDCWD) {
struct fd f;

if (flags)
goto out;

f = fdget(dfd);
error = -EBADF;
if (!f.file)
goto out;

error = utimes_common(&f.file->f_path, times);
fdput(f);
} else {
struct path path;
int lookup_flags = 0;

if (!(flags & AT_SYMLINK_NOFOLLOW))
lookup_flags |= LOOKUP_FOLLOW;
if (flags & AT_EMPTY_PATH)
lookup_flags |= LOOKUP_EMPTY;
retry:
error = user_path_at(dfd, filename, lookup_flags, &path);
if (error)
goto out;

error = utimes_common(&path, times);
path_put(&path);
if (retry_estale(error, lookup_flags)) {
lookup_flags |= LOOKUP_REVAL;
goto retry;
}
}

out:
return error;
if (filename == NULL && dfd != AT_FDCWD)
return do_utimes_fd(dfd, times, flags);
return do_utimes_path(dfd, filename, times, flags);
}

SYSCALL_DEFINE4(utimensat, int, dfd, const char __user *, filename,
Expand Down

0 comments on commit 9d4b74a

Please sign in to comment.