linux-fsdevel.vger.kernel.org archive mirror
 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).