Linux-Fsdevel Archive on lore.kernel.org
help / color / mirror / Atom feed
* clean up utimes and use path based utimes in initrams
@ 2020-07-15 6:54 Christoph Hellwig
2020-07-15 6:54 ` [PATCH 1/4] fs: refactor do_utimes Christoph Hellwig
` (4 more replies)
0 siblings, 5 replies; 6+ messages in thread
From: Christoph Hellwig @ 2020-07-15 6:54 UTC (permalink / raw)
To: Al Viro, Linus Torvalds; +Cc: linux-fsdevel, linux-kernel
Hi Al and Linus,
here is the requested series to add a vfs_utimes and use that in
initramfs, plus assorted cleanups that makes this easier.
fs/utimes.c | 107 ++++++++++++++++++++++++++++-------------------------
include/linux/fs.h | 1
init/initramfs.c | 11 +++--
3 files changed, 65 insertions(+), 54 deletions(-)
^ permalink raw reply [flat|nested] 6+ messages in thread
* [PATCH 1/4] fs: refactor do_utimes
2020-07-15 6:54 clean up utimes and use path based utimes in initrams Christoph Hellwig
@ 2020-07-15 6:54 ` Christoph Hellwig
2020-07-15 6:54 ` [PATCH 2/4] fs: move timespec validation into utimes_common Christoph Hellwig
` (3 subsequent siblings)
4 siblings, 0 replies; 6+ messages in thread
From: Christoph Hellwig @ 2020-07-15 6:54 UTC (permalink / raw)
To: Al Viro, Linus Torvalds; +Cc: linux-fsdevel, linux-kernel
Split out one helper each for path vs fd based operations.
Signed-off-by: Christoph Hellwig <hch@lst.de>
---
fs/utimes.c | 100 ++++++++++++++++++++++++++++------------------------
1 file changed, 54 insertions(+), 46 deletions(-)
diff --git a/fs/utimes.c b/fs/utimes.c
index b7b927502d6e43..c667517b6eb110 100644
--- a/fs/utimes.c
+++ b/fs/utimes.c
@@ -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
@@ -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,
--
2.27.0
^ permalink raw reply [flat|nested] 6+ messages in thread
* [PATCH 2/4] fs: move timespec validation into utimes_common
2020-07-15 6:54 clean up utimes and use path based utimes in initrams Christoph Hellwig
2020-07-15 6:54 ` [PATCH 1/4] fs: refactor do_utimes Christoph Hellwig
@ 2020-07-15 6:54 ` Christoph Hellwig
2020-07-15 6:54 ` [PATCH 3/4] fs: expose utimes_common Christoph Hellwig
` (2 subsequent siblings)
4 siblings, 0 replies; 6+ messages in thread
From: Christoph Hellwig @ 2020-07-15 6:54 UTC (permalink / raw)
To: Al Viro, Linus Torvalds; +Cc: linux-fsdevel, linux-kernel
Consolidate the validation of the timespec from the two callers into
utimes_common. That means it is done a little later (e.g. after the
path lookup), but I can't find anything that requires a specific
order of processing the errors.
Signed-off-by: Christoph Hellwig <hch@lst.de>
---
fs/utimes.c | 17 ++++++++---------
1 file changed, 8 insertions(+), 9 deletions(-)
diff --git a/fs/utimes.c b/fs/utimes.c
index c667517b6eb110..441c7fb54053ca 100644
--- a/fs/utimes.c
+++ b/fs/utimes.c
@@ -27,9 +27,14 @@ static int utimes_common(const struct path *path, struct timespec64 *times)
if (error)
goto out;
- if (times && times[0].tv_nsec == UTIME_NOW &&
- times[1].tv_nsec == UTIME_NOW)
- times = NULL;
+ if (times) {
+ if (!nsec_valid(times[0].tv_nsec) ||
+ !nsec_valid(times[1].tv_nsec))
+ return -EINVAL;
+ if (times[0].tv_nsec == UTIME_NOW &&
+ times[1].tv_nsec == UTIME_NOW)
+ times = NULL;
+ }
newattrs.ia_valid = ATTR_CTIME | ATTR_MTIME | ATTR_ATIME;
if (times) {
@@ -76,9 +81,6 @@ static int do_utimes_path(int dfd, const char __user *filename,
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;
@@ -107,9 +109,6 @@ 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;
--
2.27.0
^ permalink raw reply [flat|nested] 6+ messages in thread
* [PATCH 3/4] fs: expose utimes_common
2020-07-15 6:54 clean up utimes and use path based utimes in initrams Christoph Hellwig
2020-07-15 6:54 ` [PATCH 1/4] fs: refactor do_utimes Christoph Hellwig
2020-07-15 6:54 ` [PATCH 2/4] fs: move timespec validation into utimes_common Christoph Hellwig
@ 2020-07-15 6:54 ` Christoph Hellwig
2020-07-15 6:54 ` [PATCH 4/4] initramfs: use vfs_utimes in do_copy Christoph Hellwig
2020-07-15 17:03 ` clean up utimes and use path based utimes in initrams Linus Torvalds
4 siblings, 0 replies; 6+ messages in thread
From: Christoph Hellwig @ 2020-07-15 6:54 UTC (permalink / raw)
To: Al Viro, Linus Torvalds; +Cc: linux-fsdevel, linux-kernel
Rename utimes_common to vfs_utimes and make it available outside of
utimes.c. This will be used by the initramfs unpacking code.
Signed-off-by: Christoph Hellwig <hch@lst.de>
---
fs/utimes.c | 6 +++---
include/linux/fs.h | 1 +
2 files changed, 4 insertions(+), 3 deletions(-)
diff --git a/fs/utimes.c b/fs/utimes.c
index 441c7fb54053ca..12dba0741e1a71 100644
--- a/fs/utimes.c
+++ b/fs/utimes.c
@@ -16,7 +16,7 @@ static bool nsec_valid(long nsec)
return nsec >= 0 && nsec <= 999999999;
}
-static int utimes_common(const struct path *path, struct timespec64 *times)
+int vfs_utimes(const struct path *path, struct timespec64 *times)
{
int error;
struct iattr newattrs;
@@ -94,7 +94,7 @@ static int do_utimes_path(int dfd, const char __user *filename,
if (error)
return error;
- error = utimes_common(&path, times);
+ error = vfs_utimes(&path, times);
path_put(&path);
if (retry_estale(error, lookup_flags)) {
lookup_flags |= LOOKUP_REVAL;
@@ -115,7 +115,7 @@ static int do_utimes_fd(int fd, struct timespec64 *times, int flags)
f = fdget(fd);
if (!f.file)
return -EBADF;
- error = utimes_common(&f.file->f_path, times);
+ error = vfs_utimes(&f.file->f_path, times);
fdput(f);
return error;
}
diff --git a/include/linux/fs.h b/include/linux/fs.h
index 635086726f2053..a1d2685a487868 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -1746,6 +1746,7 @@ int vfs_mkobj(struct dentry *, umode_t,
int vfs_fchown(struct file *file, uid_t user, gid_t group);
int vfs_fchmod(struct file *file, umode_t mode);
+int vfs_utimes(const struct path *path, struct timespec64 *times);
extern long vfs_ioctl(struct file *file, unsigned int cmd, unsigned long arg);
--
2.27.0
^ permalink raw reply [flat|nested] 6+ messages in thread
* [PATCH 4/4] initramfs: use vfs_utimes in do_copy
2020-07-15 6:54 clean up utimes and use path based utimes in initrams Christoph Hellwig
` (2 preceding siblings ...)
2020-07-15 6:54 ` [PATCH 3/4] fs: expose utimes_common Christoph Hellwig
@ 2020-07-15 6:54 ` Christoph Hellwig
2020-07-15 17:03 ` clean up utimes and use path based utimes in initrams Linus Torvalds
4 siblings, 0 replies; 6+ messages in thread
From: Christoph Hellwig @ 2020-07-15 6:54 UTC (permalink / raw)
To: Al Viro, Linus Torvalds; +Cc: linux-fsdevel, linux-kernel
Don't bother saving away the pathname and just use the new struct path
based utimes helper instead.
Signed-off-by: Christoph Hellwig <hch@lst.de>
---
init/initramfs.c | 11 +++++++----
1 file changed, 7 insertions(+), 4 deletions(-)
diff --git a/init/initramfs.c b/init/initramfs.c
index c335920e5ecc2d..3823d15e5d2619 100644
--- a/init/initramfs.c
+++ b/init/initramfs.c
@@ -201,7 +201,6 @@ static inline void __init eat(unsigned n)
byte_count -= n;
}
-static __initdata char *vcollected;
static __initdata char *collected;
static long remains __initdata;
static __initdata char *collect;
@@ -342,7 +341,6 @@ static int __init do_name(void)
vfs_fchmod(wfile, mode);
if (body_len)
vfs_truncate(&wfile->f_path, body_len);
- vcollected = kstrdup(collected, GFP_KERNEL);
state = CopyFile;
}
} else if (S_ISDIR(mode)) {
@@ -365,11 +363,16 @@ static int __init do_name(void)
static int __init do_copy(void)
{
if (byte_count >= body_len) {
+ struct timespec64 t[2] = { };
+
if (xwrite(wfile, victim, body_len) != body_len)
error("write error");
+
+ t[0].tv_sec = mtime;
+ t[1].tv_sec = mtime;
+ vfs_utimes(&wfile->f_path, t);
+
fput(wfile);
- do_utime(vcollected, mtime);
- kfree(vcollected);
eat(body_len);
state = SkipIt;
return 0;
--
2.27.0
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: clean up utimes and use path based utimes in initrams
2020-07-15 6:54 clean up utimes and use path based utimes in initrams Christoph Hellwig
` (3 preceding siblings ...)
2020-07-15 6:54 ` [PATCH 4/4] initramfs: use vfs_utimes in do_copy Christoph Hellwig
@ 2020-07-15 17:03 ` Linus Torvalds
4 siblings, 0 replies; 6+ messages in thread
From: Linus Torvalds @ 2020-07-15 17:03 UTC (permalink / raw)
To: Christoph Hellwig; +Cc: Al Viro, linux-fsdevel, Linux Kernel Mailing List
On Tue, Jul 14, 2020 at 11:54 PM Christoph Hellwig <hch@lst.de> wrote:
>
> here is the requested series to add a vfs_utimes and use that in
> initramfs, plus assorted cleanups that makes this easier.
Looks good to me, you can add my ack for all of them.
Linus
^ permalink raw reply [flat|nested] 6+ messages in thread
end of thread, other threads:[~2020-07-15 17:03 UTC | newest]
Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-07-15 6:54 clean up utimes and use path based utimes in initrams Christoph Hellwig
2020-07-15 6:54 ` [PATCH 1/4] fs: refactor do_utimes Christoph Hellwig
2020-07-15 6:54 ` [PATCH 2/4] fs: move timespec validation into utimes_common Christoph Hellwig
2020-07-15 6:54 ` [PATCH 3/4] fs: expose utimes_common Christoph Hellwig
2020-07-15 6:54 ` [PATCH 4/4] initramfs: use vfs_utimes in do_copy Christoph Hellwig
2020-07-15 17:03 ` clean up utimes and use path based utimes in initrams Linus Torvalds
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).