linux-api.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* add file system helpers that take kernel pointers for the init code
@ 2020-07-20 15:58 Christoph Hellwig
  2020-07-20 15:58 ` [PATCH 01/24] init: initialize ramdisk_execute_command at compile time Christoph Hellwig
                   ` (23 more replies)
  0 siblings, 24 replies; 28+ messages in thread
From: Christoph Hellwig @ 2020-07-20 15:58 UTC (permalink / raw)
  To: Al Viro, Linus Torvalds
  Cc: Greg Kroah-Hartman, Rafael J. Wysocki, linux-kernel, linux-raid,
	linux-fsdevel, linux-api

Hi Al,

currently a lot of the file system calls in the early in code (and the
devtmpfs kthread) rely on the implicit set_fs(KERNEL_DS) during boot.
This is one of the few last remaining places we need to deal with to kill
off set_fs entirely, so this series adds new helpers that take kernel
pointers.  That is mostly done by pushing the getname() call further up
the stack so that we can add variants using getname_kernel() without
duplicating code.

The series sits on top of my previous

  "decruft the early init / initrd / initramfs code v2"

series.


Git tree:

    git://git.infradead.org/users/hch/misc.git kern_path

Gitweb:

    http://git.infradead.org/users/hch/misc.git/shortlog/refs/heads/kern_path


Diffstat:
 drivers/base/devtmpfs.c    |    8 +-
 drivers/md/md-autodetect.c |    2 
 fs/coredump.c              |    2 
 fs/fs_parser.c             |    1 
 fs/internal.h              |   12 ---
 fs/namei.c                 |  166 +++++++++++++++++++++++++++++++--------------
 fs/namespace.c             |  134 +++++++++++++++++++++---------------
 fs/open.c                  |  149 ++++++++++++++++++++++++++++------------
 fs/stat.c                  |   92 ++++++++++++------------
 fs/utimes.c                |   19 +++--
 include/linux/fs.h         |   39 +++++-----
 include/linux/syscalls.h   |   82 ----------------------
 init/do_mounts.c           |   12 +--
 init/do_mounts.h           |    4 -
 init/do_mounts_initrd.c    |   26 +++----
 init/do_mounts_rd.c        |    2 
 init/initramfs.c           |   27 +++----
 init/main.c                |    9 --
 init/noinitramfs.c         |    9 +-
 kernel/uid16.c             |   15 ----
 20 files changed, 434 insertions(+), 376 deletions(-)

^ permalink raw reply	[flat|nested] 28+ messages in thread

* [PATCH 01/24] init: initialize ramdisk_execute_command at compile time
  2020-07-20 15:58 add file system helpers that take kernel pointers for the init code Christoph Hellwig
@ 2020-07-20 15:58 ` Christoph Hellwig
  2020-07-20 15:58 ` [PATCH 02/24] fs: add a do_kern_mount helper Christoph Hellwig
                   ` (22 subsequent siblings)
  23 siblings, 0 replies; 28+ messages in thread
From: Christoph Hellwig @ 2020-07-20 15:58 UTC (permalink / raw)
  To: Al Viro, Linus Torvalds
  Cc: Greg Kroah-Hartman, Rafael J. Wysocki, linux-kernel, linux-raid,
	linux-fsdevel, linux-api

Set ramdisk_execute_command to "/init" at compile time.  The command
line can still override it, but this saves a few instructions and
removes a NULL check.

Signed-off-by: Christoph Hellwig <hch@lst.de>
---
 init/main.c | 6 +-----
 1 file changed, 1 insertion(+), 5 deletions(-)

diff --git a/init/main.c b/init/main.c
index db0621dfbb0468..c2c9143db96795 100644
--- a/init/main.c
+++ b/init/main.c
@@ -154,7 +154,7 @@ static bool initargs_found;
 #endif
 
 static char *execute_command;
-static char *ramdisk_execute_command;
+static char *ramdisk_execute_command = "/init";
 
 /*
  * Used to generate warnings if static_key manipulation functions are used
@@ -1514,10 +1514,6 @@ static noinline void __init kernel_init_freeable(void)
 	 * check if there is an early userspace init.  If yes, let it do all
 	 * the work
 	 */
-
-	if (!ramdisk_execute_command)
-		ramdisk_execute_command = "/init";
-
 	if (ksys_access((const char __user *)
 			ramdisk_execute_command, 0) != 0) {
 		ramdisk_execute_command = NULL;
-- 
2.27.0


^ permalink raw reply related	[flat|nested] 28+ messages in thread

* [PATCH 02/24] fs: add a do_kern_mount helper
  2020-07-20 15:58 add file system helpers that take kernel pointers for the init code Christoph Hellwig
  2020-07-20 15:58 ` [PATCH 01/24] init: initialize ramdisk_execute_command at compile time Christoph Hellwig
@ 2020-07-20 15:58 ` Christoph Hellwig
  2020-07-20 15:58 ` [PATCH 03/24] fs: add a kern_umount helper Christoph Hellwig
                   ` (21 subsequent siblings)
  23 siblings, 0 replies; 28+ messages in thread
From: Christoph Hellwig @ 2020-07-20 15:58 UTC (permalink / raw)
  To: Al Viro, Linus Torvalds
  Cc: Greg Kroah-Hartman, Rafael J. Wysocki, linux-kernel, linux-raid,
	linux-fsdevel, linux-api

Like do_mount, but takes a kernel pointer for the destination path.
Switch over the mounts in the init code and devtmpfs to it, which
just happen to work due to the implicit set_fs(KERNEL_DS) during early
init right now.

Signed-off-by: Christoph Hellwig <hch@lst.de>
---
 drivers/base/devtmpfs.c |  4 +-
 fs/namespace.c          | 81 +++++++++++++++++++++++++----------------
 include/linux/fs.h      |  2 +
 init/do_mounts.c        |  8 ++--
 init/do_mounts_initrd.c |  6 +--
 5 files changed, 60 insertions(+), 41 deletions(-)

diff --git a/drivers/base/devtmpfs.c b/drivers/base/devtmpfs.c
index c9017e0584c003..03221ca708c91c 100644
--- a/drivers/base/devtmpfs.c
+++ b/drivers/base/devtmpfs.c
@@ -359,7 +359,7 @@ int __init devtmpfs_mount(void)
 	if (!thread)
 		return 0;
 
-	err = do_mount("devtmpfs", "dev", "devtmpfs", MS_SILENT, NULL);
+	err = do_kern_mount("devtmpfs", "dev", "devtmpfs", MS_SILENT, NULL);
 	if (err)
 		printk(KERN_INFO "devtmpfs: error mounting %i\n", err);
 	else
@@ -385,7 +385,7 @@ static int devtmpfs_setup(void *p)
 	err = ksys_unshare(CLONE_NEWNS);
 	if (err)
 		goto out;
-	err = do_mount("devtmpfs", "/", "devtmpfs", MS_SILENT, NULL);
+	err = do_kern_mount("devtmpfs", "/", "devtmpfs", MS_SILENT, NULL);
 	if (err)
 		goto out;
 	ksys_chdir("/.."); /* will traverse into overmounted root */
diff --git a/fs/namespace.c b/fs/namespace.c
index f30ed401cc6d7a..d208a389aac3c0 100644
--- a/fs/namespace.c
+++ b/fs/namespace.c
@@ -3115,12 +3115,11 @@ char *copy_mount_string(const void __user *data)
  * Therefore, if this magic number is present, it carries no information
  * and must be discarded.
  */
-long do_mount(const char *dev_name, const char __user *dir_name,
+static int path_mount(const char *dev_name, struct path *path,
 		const char *type_page, unsigned long flags, void *data_page)
 {
-	struct path path;
 	unsigned int mnt_flags = 0, sb_flags;
-	int retval = 0;
+	int ret = 0;
 
 	/* Discard magic */
 	if ((flags & MS_MGC_MSK) == MS_MGC_VAL)
@@ -3133,19 +3132,13 @@ long do_mount(const char *dev_name, const char __user *dir_name,
 	if (flags & MS_NOUSER)
 		return -EINVAL;
 
-	/* ... and get the mountpoint */
-	retval = user_path_at(AT_FDCWD, dir_name, LOOKUP_FOLLOW, &path);
-	if (retval)
-		return retval;
-
-	retval = security_sb_mount(dev_name, &path,
-				   type_page, flags, data_page);
-	if (!retval && !may_mount())
-		retval = -EPERM;
-	if (!retval && (flags & SB_MANDLOCK) && !may_mandlock())
-		retval = -EPERM;
-	if (retval)
-		goto dput_out;
+	ret = security_sb_mount(dev_name, path, type_page, flags, data_page);
+	if (ret)
+		return ret;
+	if (!may_mount())
+		return -EPERM;
+	if ((flags & SB_MANDLOCK) && !may_mandlock())
+		return -EPERM;
 
 	/* Default to relatime unless overriden */
 	if (!(flags & MS_NOATIME))
@@ -3172,7 +3165,7 @@ long do_mount(const char *dev_name, const char __user *dir_name,
 	    ((flags & (MS_NOATIME | MS_NODIRATIME | MS_RELATIME |
 		       MS_STRICTATIME)) == 0)) {
 		mnt_flags &= ~MNT_ATIME_MASK;
-		mnt_flags |= path.mnt->mnt_flags & MNT_ATIME_MASK;
+		mnt_flags |= path->mnt->mnt_flags & MNT_ATIME_MASK;
 	}
 
 	sb_flags = flags & (SB_RDONLY |
@@ -3185,22 +3178,46 @@ long do_mount(const char *dev_name, const char __user *dir_name,
 			    SB_I_VERSION);
 
 	if ((flags & (MS_REMOUNT | MS_BIND)) == (MS_REMOUNT | MS_BIND))
-		retval = do_reconfigure_mnt(&path, mnt_flags);
-	else if (flags & MS_REMOUNT)
-		retval = do_remount(&path, flags, sb_flags, mnt_flags,
-				    data_page);
-	else if (flags & MS_BIND)
-		retval = do_loopback(&path, dev_name, flags & MS_REC);
-	else if (flags & (MS_SHARED | MS_PRIVATE | MS_SLAVE | MS_UNBINDABLE))
-		retval = do_change_type(&path, flags);
-	else if (flags & MS_MOVE)
-		retval = do_move_mount_old(&path, dev_name);
-	else
-		retval = do_new_mount(&path, type_page, sb_flags, mnt_flags,
-				      dev_name, data_page);
-dput_out:
+		return do_reconfigure_mnt(path, mnt_flags);
+	if (flags & MS_REMOUNT)
+		return do_remount(path, flags, sb_flags, mnt_flags, data_page);
+	if (flags & MS_BIND)
+		return do_loopback(path, dev_name, flags & MS_REC);
+	if (flags & (MS_SHARED | MS_PRIVATE | MS_SLAVE | MS_UNBINDABLE))
+		return do_change_type(path, flags);
+	if (flags & MS_MOVE)
+		return do_move_mount_old(path, dev_name);
+
+	return do_new_mount(path, type_page, sb_flags, mnt_flags, dev_name,
+			    data_page);
+}
+
+long do_mount(const char *dev_name, const char __user *dir_name,
+		const char *type_page, unsigned long flags, void *data_page)
+{
+	struct path path;
+	int ret;
+
+	ret = user_path_at(AT_FDCWD, dir_name, LOOKUP_FOLLOW, &path);
+	if (ret)
+		return ret;
+	ret = path_mount(dev_name, &path, type_page, flags, data_page);
 	path_put(&path);
-	return retval;
+	return ret;
+}
+
+int do_kern_mount(const char *dev_name, const char *dir_name,
+		const char *type_page, unsigned long flags, void *data_page)
+{
+	struct path path;
+	int ret;
+
+	ret = kern_path(dir_name, LOOKUP_FOLLOW, &path);
+	if (ret)
+		return ret;
+	ret = path_mount(dev_name, &path, type_page, flags, data_page);
+	path_put(&path);
+	return ret;
 }
 
 static struct ucounts *inc_mnt_namespaces(struct user_namespace *ns)
diff --git a/include/linux/fs.h b/include/linux/fs.h
index a1d2685a487868..8f628f9868711d 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -2337,6 +2337,8 @@ extern int may_umount_tree(struct vfsmount *);
 extern int may_umount(struct vfsmount *);
 extern long do_mount(const char *, const char __user *,
 		     const char *, unsigned long, void *);
+int do_kern_mount(const char *dev_name, const char *dir_name,
+		const char *type_page, unsigned long flags, void *data_page);
 extern struct vfsmount *collect_mounts(const struct path *);
 extern void drop_collected_mounts(struct vfsmount *);
 extern int iterate_mounts(int (*)(struct vfsmount *, void *), void *,
diff --git a/init/do_mounts.c b/init/do_mounts.c
index 4f4ceb35805503..2fef92a8ed3c15 100644
--- a/init/do_mounts.c
+++ b/init/do_mounts.c
@@ -395,16 +395,16 @@ static int __init do_mount_root(const char *name, const char *fs,
 	int ret;
 
 	if (data) {
-		/* do_mount() requires a full page as fifth argument */
+		/* do_kern_mount() requires a full page as fifth argument */
 		p = alloc_page(GFP_KERNEL);
 		if (!p)
 			return -ENOMEM;
 		data_page = page_address(p);
-		/* zero-pad. do_mount() will make sure it's terminated */
+		/* zero-pad. do_kern_mount() will make sure it's terminated */
 		strncpy(data_page, data, PAGE_SIZE);
 	}
 
-	ret = do_mount(name, "/root", fs, flags, data_page);
+	ret = do_kern_mount(name, "/root", fs, flags, data_page);
 	if (ret)
 		goto out;
 
@@ -628,7 +628,7 @@ void __init prepare_namespace(void)
 	mount_root();
 out:
 	devtmpfs_mount();
-	do_mount(".", "/", NULL, MS_MOVE, NULL);
+	do_kern_mount(".", "/", NULL, MS_MOVE, NULL);
 	ksys_chroot(".");
 }
 
diff --git a/init/do_mounts_initrd.c b/init/do_mounts_initrd.c
index e08669187d63be..604ce78af9acfa 100644
--- a/init/do_mounts_initrd.c
+++ b/init/do_mounts_initrd.c
@@ -62,7 +62,7 @@ static int __init init_linuxrc(struct subprocess_info *info, struct cred *new)
 	console_on_rootfs();
 	/* move initrd over / and chdir/chroot in initrd root */
 	ksys_chdir("/root");
-	do_mount(".", "/", NULL, MS_MOVE, NULL);
+	do_kern_mount(".", "/", NULL, MS_MOVE, NULL);
 	ksys_chroot(".");
 	ksys_setsid();
 	return 0;
@@ -99,7 +99,7 @@ static void __init handle_initrd(void)
 	current->flags &= ~PF_FREEZER_SKIP;
 
 	/* move initrd to rootfs' /old */
-	do_mount("..", ".", NULL, MS_MOVE, NULL);
+	do_kern_mount("..", ".", NULL, MS_MOVE, NULL);
 	/* switch root and cwd back to / of rootfs */
 	ksys_chroot("..");
 
@@ -113,7 +113,7 @@ static void __init handle_initrd(void)
 	mount_root();
 
 	printk(KERN_NOTICE "Trying to move old root to /initrd ... ");
-	error = do_mount("/old", "/root/initrd", NULL, MS_MOVE, NULL);
+	error = do_kern_mount("/old", "/root/initrd", NULL, MS_MOVE, NULL);
 	if (!error)
 		printk("okay\n");
 	else {
-- 
2.27.0


^ permalink raw reply related	[flat|nested] 28+ messages in thread

* [PATCH 03/24] fs: add a kern_umount helper
  2020-07-20 15:58 add file system helpers that take kernel pointers for the init code Christoph Hellwig
  2020-07-20 15:58 ` [PATCH 01/24] init: initialize ramdisk_execute_command at compile time Christoph Hellwig
  2020-07-20 15:58 ` [PATCH 02/24] fs: add a do_kern_mount helper Christoph Hellwig
@ 2020-07-20 15:58 ` Christoph Hellwig
  2020-07-20 15:58 ` [PATCH 04/24] fs: move the putname from filename_create to the callers Christoph Hellwig
                   ` (20 subsequent siblings)
  23 siblings, 0 replies; 28+ messages in thread
From: Christoph Hellwig @ 2020-07-20 15:58 UTC (permalink / raw)
  To: Al Viro, Linus Torvalds
  Cc: Greg Kroah-Hartman, Rafael J. Wysocki, linux-kernel, linux-raid,
	linux-fsdevel, linux-api

Like ksys_umount, but takes a kernel pointer for the destination path.
Switch over the umount in the init code to it, which just happens to work
due to the implicit set_fs(KERNEL_DS) during early init right now.

Signed-off-by: Christoph Hellwig <hch@lst.de>
---
 fs/namespace.c           | 53 ++++++++++++++++++++++++----------------
 include/linux/fs.h       |  1 +
 include/linux/syscalls.h |  1 -
 init/do_mounts_initrd.c  |  2 +-
 4 files changed, 34 insertions(+), 23 deletions(-)

diff --git a/fs/namespace.c b/fs/namespace.c
index d208a389aac3c0..cfcee6a1bd5dd2 100644
--- a/fs/namespace.c
+++ b/fs/namespace.c
@@ -1706,36 +1706,26 @@ static inline bool may_mandlock(void)
 }
 #endif
 
-/*
- * Now umount can handle mount points as well as block devices.
- * This is important for filesystems which use unnamed block devices.
- *
- * We now support a flag for forced unmount like the other 'big iron'
- * unixes. Our API is identical to OSF/1 to avoid making a mess of AMD
- */
+static int umount_lookup_flags(int flags)
+{
+	if (flags & UMOUNT_NOFOLLOW)
+		return LOOKUP_MOUNTPOINT;
+	return LOOKUP_MOUNTPOINT | LOOKUP_FOLLOW;
+}
 
-int ksys_umount(char __user *name, int flags)
+static int path_umount(struct path *path, int flags)
 {
-	struct path path;
 	struct mount *mnt;
 	int retval;
-	int lookup_flags = LOOKUP_MOUNTPOINT;
 
 	if (flags & ~(MNT_FORCE | MNT_DETACH | MNT_EXPIRE | UMOUNT_NOFOLLOW))
 		return -EINVAL;
-
 	if (!may_mount())
 		return -EPERM;
 
-	if (!(flags & UMOUNT_NOFOLLOW))
-		lookup_flags |= LOOKUP_FOLLOW;
-
-	retval = user_path_at(AT_FDCWD, name, lookup_flags, &path);
-	if (retval)
-		goto out;
-	mnt = real_mount(path.mnt);
+	mnt = real_mount(path->mnt);
 	retval = -EINVAL;
-	if (path.dentry != path.mnt->mnt_root)
+	if (path->dentry != path->mnt->mnt_root)
 		goto dput_and_out;
 	if (!check_mnt(mnt))
 		goto dput_and_out;
@@ -1748,12 +1738,33 @@ int ksys_umount(char __user *name, int flags)
 	retval = do_umount(mnt, flags);
 dput_and_out:
 	/* we mustn't call path_put() as that would clear mnt_expiry_mark */
-	dput(path.dentry);
+	dput(path->dentry);
 	mntput_no_expire(mnt);
-out:
 	return retval;
 }
 
+static int ksys_umount(char __user *name, int flags)
+{
+	struct path path;
+	int ret;
+
+	ret = user_path_at(AT_FDCWD, name, umount_lookup_flags(flags), &path);
+	if (ret)
+		return ret;
+	return path_umount(&path, flags);
+}
+
+int __init kern_umount(char *name, int flags)
+{
+	struct path path;
+	int ret;
+
+	ret = kern_path(name, umount_lookup_flags(flags), &path);
+	if (ret)
+		return ret;
+	return path_umount(&path, flags);
+}
+
 SYSCALL_DEFINE2(umount, char __user *, name, int, flags)
 {
 	return ksys_umount(name, flags);
diff --git a/include/linux/fs.h b/include/linux/fs.h
index 8f628f9868711d..fbeadaa1a185fb 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -2339,6 +2339,7 @@ extern long do_mount(const char *, const char __user *,
 		     const char *, unsigned long, void *);
 int do_kern_mount(const char *dev_name, const char *dir_name,
 		const char *type_page, unsigned long flags, void *data_page);
+int __init kern_umount(char *name, int flags);
 extern struct vfsmount *collect_mounts(const struct path *);
 extern void drop_collected_mounts(struct vfsmount *);
 extern int iterate_mounts(int (*)(struct vfsmount *, void *), void *,
diff --git a/include/linux/syscalls.h b/include/linux/syscalls.h
index 5b0f1fca4cfb9d..3b1b8ebcda1d8c 100644
--- a/include/linux/syscalls.h
+++ b/include/linux/syscalls.h
@@ -1236,7 +1236,6 @@ asmlinkage long sys_ni_syscall(void);
  * the ksys_xyzyyz() functions prototyped below.
  */
 
-int ksys_umount(char __user *name, int flags);
 int ksys_chroot(const char __user *filename);
 ssize_t ksys_write(unsigned int fd, const char __user *buf, size_t count);
 int ksys_chdir(const char __user *filename);
diff --git a/init/do_mounts_initrd.c b/init/do_mounts_initrd.c
index 604ce78af9acfa..d3858620707893 100644
--- a/init/do_mounts_initrd.c
+++ b/init/do_mounts_initrd.c
@@ -122,7 +122,7 @@ static void __init handle_initrd(void)
 		else
 			printk("failed\n");
 		printk(KERN_NOTICE "Unmounting old root\n");
-		ksys_umount("/old", MNT_DETACH);
+		kern_umount("/old", MNT_DETACH);
 	}
 }
 
-- 
2.27.0


^ permalink raw reply related	[flat|nested] 28+ messages in thread

* [PATCH 04/24] fs: move the putname from filename_create to the callers
  2020-07-20 15:58 add file system helpers that take kernel pointers for the init code Christoph Hellwig
                   ` (2 preceding siblings ...)
  2020-07-20 15:58 ` [PATCH 03/24] fs: add a kern_umount helper Christoph Hellwig
@ 2020-07-20 15:58 ` Christoph Hellwig
  2020-07-20 18:05   ` Linus Torvalds
  2020-07-20 15:58 ` [PATCH 05/24] fs: move the putname from filename_lookup " Christoph Hellwig
                   ` (19 subsequent siblings)
  23 siblings, 1 reply; 28+ messages in thread
From: Christoph Hellwig @ 2020-07-20 15:58 UTC (permalink / raw)
  To: Al Viro, Linus Torvalds
  Cc: Greg Kroah-Hartman, Rafael J. Wysocki, linux-kernel, linux-raid,
	linux-fsdevel, linux-api

This allows reusing the struct filename for retries, and will also allow
pushing the getname up the stack for a few places to allower for better
handling of kernel space filenames.

Signed-off-by: Christoph Hellwig <hch@lst.de>
---
 fs/namei.c | 16 ++++++++++++----
 1 file changed, 12 insertions(+), 4 deletions(-)

diff --git a/fs/namei.c b/fs/namei.c
index 72d4219c93acb7..6ebe400c9736d2 100644
--- a/fs/namei.c
+++ b/fs/namei.c
@@ -3478,7 +3478,6 @@ static struct dentry *filename_create(int dfd, struct filename *name,
 		error = err2;
 		goto fail;
 	}
-	putname(name);
 	return dentry;
 fail:
 	dput(dentry);
@@ -3496,8 +3495,12 @@ static struct dentry *filename_create(int dfd, struct filename *name,
 struct dentry *kern_path_create(int dfd, const char *pathname,
 				struct path *path, unsigned int lookup_flags)
 {
-	return filename_create(dfd, getname_kernel(pathname),
-				path, lookup_flags);
+	struct filename *name = getname_kernel(pathname);
+	struct dentry *dentry = filename_create(dfd, name, path, lookup_flags);
+
+	if (!IS_ERR(dentry))
+		putname(name);
+	return dentry;
 }
 EXPORT_SYMBOL(kern_path_create);
 
@@ -3513,7 +3516,12 @@ EXPORT_SYMBOL(done_path_create);
 inline struct dentry *user_path_create(int dfd, const char __user *pathname,
 				struct path *path, unsigned int lookup_flags)
 {
-	return filename_create(dfd, getname(pathname), path, lookup_flags);
+	struct filename *name = getname(pathname);
+	struct dentry *dentry = filename_create(dfd, name, path, lookup_flags);
+
+	if (!IS_ERR(dentry))
+		putname(name);
+	return dentry;
 }
 EXPORT_SYMBOL(user_path_create);
 
-- 
2.27.0


^ permalink raw reply related	[flat|nested] 28+ messages in thread

* [PATCH 05/24] fs: move the putname from filename_lookup to the callers
  2020-07-20 15:58 add file system helpers that take kernel pointers for the init code Christoph Hellwig
                   ` (3 preceding siblings ...)
  2020-07-20 15:58 ` [PATCH 04/24] fs: move the putname from filename_create to the callers Christoph Hellwig
@ 2020-07-20 15:58 ` Christoph Hellwig
  2020-07-20 18:11   ` Al Viro
  2020-07-20 15:58 ` [PATCH 06/24] fs: add a kern_chdir helper Christoph Hellwig
                   ` (18 subsequent siblings)
  23 siblings, 1 reply; 28+ messages in thread
From: Christoph Hellwig @ 2020-07-20 15:58 UTC (permalink / raw)
  To: Al Viro, Linus Torvalds
  Cc: Greg Kroah-Hartman, Rafael J. Wysocki, linux-kernel, linux-raid,
	linux-fsdevel, linux-api

This allows reusing the struct filename for retries, and will also allow
pushing the getname up the stack for a few places to allower for better
handling of kernel space filenames.

Signed-off-by: Christoph Hellwig <hch@lst.de>
---
 fs/fs_parser.c |  1 +
 fs/namei.c     | 28 ++++++++++++++++++++--------
 2 files changed, 21 insertions(+), 8 deletions(-)

diff --git a/fs/fs_parser.c b/fs/fs_parser.c
index ab53e42a874aaa..58d5e53d74eeb7 100644
--- a/fs/fs_parser.c
+++ b/fs/fs_parser.c
@@ -171,6 +171,7 @@ int fs_lookup_param(struct fs_context *fc,
 		errorf(fc, "%s: Lookup failure for '%s'", param->key, f->name);
 		goto out;
 	}
+	putname(f);
 
 	if (want_bdev &&
 	    !S_ISBLK(d_backing_inode(_path->dentry)->i_mode)) {
diff --git a/fs/namei.c b/fs/namei.c
index 6ebe400c9736d2..6daffd59e97270 100644
--- a/fs/namei.c
+++ b/fs/namei.c
@@ -2372,8 +2372,9 @@ int filename_lookup(int dfd, struct filename *name, unsigned flags,
 	if (likely(!retval))
 		audit_inode(name, path->dentry,
 			    flags & LOOKUP_MOUNTPOINT ? AUDIT_INODE_NOEVAL : 0);
+	else
+		putname(name);
 	restore_nameidata();
-	putname(name);
 	return retval;
 }
 
@@ -2450,8 +2451,12 @@ struct dentry *kern_path_locked(const char *name, struct path *path)
 
 int kern_path(const char *name, unsigned int flags, struct path *path)
 {
-	return filename_lookup(AT_FDCWD, getname_kernel(name),
-			       flags, path, NULL);
+	struct filename *f = getname_kernel(name);
+	int ret = filename_lookup(AT_FDCWD, f, flags, path, NULL);
+
+	if (!ret)
+		putname(f);
+	return ret;
 }
 EXPORT_SYMBOL(kern_path);
 
@@ -2468,9 +2473,12 @@ int vfs_path_lookup(struct dentry *dentry, struct vfsmount *mnt,
 		    struct path *path)
 {
 	struct path root = {.mnt = mnt, .dentry = dentry};
-	/* the first argument of filename_lookup() is ignored with root */
-	return filename_lookup(AT_FDCWD, getname_kernel(name),
-			       flags , path, &root);
+	struct filename *f = getname_kernel(name);
+	int ret = filename_lookup(AT_FDCWD, f, flags, path, &root);
+
+	if (!ret)
+		putname(f);
+	return ret;
 }
 EXPORT_SYMBOL(vfs_path_lookup);
 
@@ -2643,8 +2651,12 @@ int path_pts(struct path *path)
 int user_path_at_empty(int dfd, const char __user *name, unsigned flags,
 		 struct path *path, int *empty)
 {
-	return filename_lookup(dfd, getname_flags(name, flags, empty),
-			       flags, path, NULL);
+	struct filename *f = getname_flags(name, flags, empty);
+	int ret = filename_lookup(dfd, f, flags, path, NULL);
+
+	if (!ret)
+		putname(f);
+	return ret;
 }
 EXPORT_SYMBOL(user_path_at_empty);
 
-- 
2.27.0


^ permalink raw reply related	[flat|nested] 28+ messages in thread

* [PATCH 06/24] fs: add a kern_chdir helper
  2020-07-20 15:58 add file system helpers that take kernel pointers for the init code Christoph Hellwig
                   ` (4 preceding siblings ...)
  2020-07-20 15:58 ` [PATCH 05/24] fs: move the putname from filename_lookup " Christoph Hellwig
@ 2020-07-20 15:58 ` Christoph Hellwig
  2020-07-20 18:17   ` Al Viro
  2020-07-20 15:58 ` [PATCH 07/24] fs: add a kern_chroot helper Christoph Hellwig
                   ` (17 subsequent siblings)
  23 siblings, 1 reply; 28+ messages in thread
From: Christoph Hellwig @ 2020-07-20 15:58 UTC (permalink / raw)
  To: Al Viro, Linus Torvalds
  Cc: Greg Kroah-Hartman, Rafael J. Wysocki, linux-kernel, linux-raid,
	linux-fsdevel, linux-api

Add a simple helper for a chdir with a kernelspace name and use it in the
early init code instead of relying on the implicit set_fs(KERNEL_DS)
there.  Remove the now unused ksys_chdir.

Signed-off-by: Christoph Hellwig <hch@lst.de>
---
 drivers/base/devtmpfs.c  |  2 +-
 fs/open.c                | 15 ++++++++++-----
 include/linux/fs.h       |  2 ++
 include/linux/syscalls.h |  1 -
 init/do_mounts.c         |  2 +-
 init/do_mounts_initrd.c  |  8 ++++----
 6 files changed, 18 insertions(+), 12 deletions(-)

diff --git a/drivers/base/devtmpfs.c b/drivers/base/devtmpfs.c
index 03221ca708c91c..2cedeb62706f18 100644
--- a/drivers/base/devtmpfs.c
+++ b/drivers/base/devtmpfs.c
@@ -388,7 +388,7 @@ static int devtmpfs_setup(void *p)
 	err = do_kern_mount("devtmpfs", "/", "devtmpfs", MS_SILENT, NULL);
 	if (err)
 		goto out;
-	ksys_chdir("/.."); /* will traverse into overmounted root */
+	kern_chdir("/.."); /* will traverse into overmounted root */
 	ksys_chroot(".");
 out:
 	*(int *)p = err;
diff --git a/fs/open.c b/fs/open.c
index b316dd6a86a8b9..3d62f4d2604739 100644
--- a/fs/open.c
+++ b/fs/open.c
@@ -482,15 +482,15 @@ SYSCALL_DEFINE2(access, const char __user *, filename, int, mode)
 	return do_faccessat(AT_FDCWD, filename, mode, 0);
 }
 
-int ksys_chdir(const char __user *filename)
+static int do_chdir(struct filename *name)
 {
 	struct path path;
 	int error;
 	unsigned int lookup_flags = LOOKUP_FOLLOW | LOOKUP_DIRECTORY;
 retry:
-	error = user_path_at(AT_FDCWD, filename, lookup_flags, &path);
+	error = filename_lookup(AT_FDCWD, name, lookup_flags, &path, NULL);
 	if (error)
-		goto out;
+		return error;
 
 	error = inode_permission(path.dentry->d_inode, MAY_EXEC | MAY_CHDIR);
 	if (error)
@@ -504,13 +504,18 @@ int ksys_chdir(const char __user *filename)
 		lookup_flags |= LOOKUP_REVAL;
 		goto retry;
 	}
-out:
+	putname(name);
 	return error;
 }
 
+int kern_chdir(const char *filename)
+{
+	return do_chdir(getname_kernel(filename));
+}
+
 SYSCALL_DEFINE1(chdir, const char __user *, filename)
 {
-	return ksys_chdir(filename);
+	return do_chdir(getname(filename));
 }
 
 SYSCALL_DEFINE1(fchdir, unsigned int, fd)
diff --git a/include/linux/fs.h b/include/linux/fs.h
index fbeadaa1a185fb..dccb37407e9bad 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -3671,4 +3671,6 @@ static inline int inode_drain_writes(struct inode *inode)
 	return filemap_write_and_wait(inode->i_mapping);
 }
 
+int kern_chdir(const char *filename);
+
 #endif /* _LINUX_FS_H */
diff --git a/include/linux/syscalls.h b/include/linux/syscalls.h
index 3b1b8ebcda1d8c..f2a181776b0409 100644
--- a/include/linux/syscalls.h
+++ b/include/linux/syscalls.h
@@ -1238,7 +1238,6 @@ asmlinkage long sys_ni_syscall(void);
 
 int ksys_chroot(const char __user *filename);
 ssize_t ksys_write(unsigned int fd, const char __user *buf, size_t count);
-int ksys_chdir(const char __user *filename);
 int ksys_fchown(unsigned int fd, uid_t user, gid_t group);
 ssize_t ksys_read(unsigned int fd, char __user *buf, size_t count);
 void ksys_sync(void);
diff --git a/init/do_mounts.c b/init/do_mounts.c
index 2fef92a8ed3c15..8c3fca8e2d3c6e 100644
--- a/init/do_mounts.c
+++ b/init/do_mounts.c
@@ -408,7 +408,7 @@ static int __init do_mount_root(const char *name, const char *fs,
 	if (ret)
 		goto out;
 
-	ksys_chdir("/root");
+	kern_chdir("/root");
 	s = current->fs->pwd.dentry->d_sb;
 	ROOT_DEV = s->s_dev;
 	printk(KERN_INFO
diff --git a/init/do_mounts_initrd.c b/init/do_mounts_initrd.c
index d3858620707893..522554d703b785 100644
--- a/init/do_mounts_initrd.c
+++ b/init/do_mounts_initrd.c
@@ -61,7 +61,7 @@ static int __init init_linuxrc(struct subprocess_info *info, struct cred *new)
 	ksys_unshare(CLONE_FS | CLONE_FILES);
 	console_on_rootfs();
 	/* move initrd over / and chdir/chroot in initrd root */
-	ksys_chdir("/root");
+	kern_chdir("/root");
 	do_kern_mount(".", "/", NULL, MS_MOVE, NULL);
 	ksys_chroot(".");
 	ksys_setsid();
@@ -82,7 +82,7 @@ static void __init handle_initrd(void)
 	/* mount initrd on rootfs' /root */
 	mount_block_root("/dev/root.old", root_mountflags & ~MS_RDONLY);
 	ksys_mkdir("/old", 0700);
-	ksys_chdir("/old");
+	kern_chdir("/old");
 
 	/*
 	 * In case that a resume from disk is carried out by linuxrc or one of
@@ -104,11 +104,11 @@ static void __init handle_initrd(void)
 	ksys_chroot("..");
 
 	if (new_decode_dev(real_root_dev) == Root_RAM0) {
-		ksys_chdir("/old");
+		kern_chdir("/old");
 		return;
 	}
 
-	ksys_chdir("/");
+	kern_chdir("/");
 	ROOT_DEV = new_decode_dev(real_root_dev);
 	mount_root();
 
-- 
2.27.0


^ permalink raw reply related	[flat|nested] 28+ messages in thread

* [PATCH 07/24] fs: add a kern_chroot helper
  2020-07-20 15:58 add file system helpers that take kernel pointers for the init code Christoph Hellwig
                   ` (5 preceding siblings ...)
  2020-07-20 15:58 ` [PATCH 06/24] fs: add a kern_chdir helper Christoph Hellwig
@ 2020-07-20 15:58 ` Christoph Hellwig
  2020-07-20 15:58 ` [PATCH 08/24] fs: add a kern_access helper Christoph Hellwig
                   ` (16 subsequent siblings)
  23 siblings, 0 replies; 28+ messages in thread
From: Christoph Hellwig @ 2020-07-20 15:58 UTC (permalink / raw)
  To: Al Viro, Linus Torvalds
  Cc: Greg Kroah-Hartman, Rafael J. Wysocki, linux-kernel, linux-raid,
	linux-fsdevel, linux-api

Add a simple helper for a chroot with a kernelspace name and use it in
the early init code instead of relying on the implicit set_fs(KERNEL_DS)
there.  Remove the now unused ksys_chroot.

Signed-off-by: Christoph Hellwig <hch@lst.de>
---
 drivers/base/devtmpfs.c  |  2 +-
 fs/open.c                | 15 ++++++++++-----
 include/linux/fs.h       |  1 +
 include/linux/syscalls.h |  1 -
 init/do_mounts.c         |  2 +-
 init/do_mounts_initrd.c  |  4 ++--
 6 files changed, 15 insertions(+), 10 deletions(-)

diff --git a/drivers/base/devtmpfs.c b/drivers/base/devtmpfs.c
index 2cedeb62706f18..a5126e7be34c8a 100644
--- a/drivers/base/devtmpfs.c
+++ b/drivers/base/devtmpfs.c
@@ -389,7 +389,7 @@ static int devtmpfs_setup(void *p)
 	if (err)
 		goto out;
 	kern_chdir("/.."); /* will traverse into overmounted root */
-	ksys_chroot(".");
+	kern_chroot(".");
 out:
 	*(int *)p = err;
 	complete(&setup_done);
diff --git a/fs/open.c b/fs/open.c
index 3d62f4d2604739..424db905da5f18 100644
--- a/fs/open.c
+++ b/fs/open.c
@@ -540,15 +540,15 @@ SYSCALL_DEFINE1(fchdir, unsigned int, fd)
 	return error;
 }
 
-int ksys_chroot(const char __user *filename)
+static int do_chroot(struct filename *name)
 {
 	struct path path;
 	int error;
 	unsigned int lookup_flags = LOOKUP_FOLLOW | LOOKUP_DIRECTORY;
 retry:
-	error = user_path_at(AT_FDCWD, filename, lookup_flags, &path);
+	error = filename_lookup(AT_FDCWD, name, lookup_flags, &path, NULL);
 	if (error)
-		goto out;
+		return error;
 
 	error = inode_permission(path.dentry->d_inode, MAY_EXEC | MAY_CHDIR);
 	if (error)
@@ -569,13 +569,18 @@ int ksys_chroot(const char __user *filename)
 		lookup_flags |= LOOKUP_REVAL;
 		goto retry;
 	}
-out:
+	putname(name);
 	return error;
 }
 
+int kern_chroot(const char *filename)
+{
+	return do_chroot(getname_kernel(filename));
+}
+
 SYSCALL_DEFINE1(chroot, const char __user *, filename)
 {
-	return ksys_chroot(filename);
+	return do_chroot(getname(filename));
 }
 
 static int chmod_common(const struct path *path, umode_t mode)
diff --git a/include/linux/fs.h b/include/linux/fs.h
index dccb37407e9bad..0205355bffb1bc 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -3672,5 +3672,6 @@ static inline int inode_drain_writes(struct inode *inode)
 }
 
 int kern_chdir(const char *filename);
+int kern_chroot(const char *filename);
 
 #endif /* _LINUX_FS_H */
diff --git a/include/linux/syscalls.h b/include/linux/syscalls.h
index f2a181776b0409..a3176d1a521467 100644
--- a/include/linux/syscalls.h
+++ b/include/linux/syscalls.h
@@ -1236,7 +1236,6 @@ asmlinkage long sys_ni_syscall(void);
  * the ksys_xyzyyz() functions prototyped below.
  */
 
-int ksys_chroot(const char __user *filename);
 ssize_t ksys_write(unsigned int fd, const char __user *buf, size_t count);
 int ksys_fchown(unsigned int fd, uid_t user, gid_t group);
 ssize_t ksys_read(unsigned int fd, char __user *buf, size_t count);
diff --git a/init/do_mounts.c b/init/do_mounts.c
index 8c3fca8e2d3c6e..31b8dedb189b57 100644
--- a/init/do_mounts.c
+++ b/init/do_mounts.c
@@ -629,7 +629,7 @@ void __init prepare_namespace(void)
 out:
 	devtmpfs_mount();
 	do_kern_mount(".", "/", NULL, MS_MOVE, NULL);
-	ksys_chroot(".");
+	kern_chroot(".");
 }
 
 static bool is_tmpfs;
diff --git a/init/do_mounts_initrd.c b/init/do_mounts_initrd.c
index 522554d703b785..1cbc9988d2e0ad 100644
--- a/init/do_mounts_initrd.c
+++ b/init/do_mounts_initrd.c
@@ -63,7 +63,7 @@ static int __init init_linuxrc(struct subprocess_info *info, struct cred *new)
 	/* move initrd over / and chdir/chroot in initrd root */
 	kern_chdir("/root");
 	do_kern_mount(".", "/", NULL, MS_MOVE, NULL);
-	ksys_chroot(".");
+	kern_chroot(".");
 	ksys_setsid();
 	return 0;
 }
@@ -101,7 +101,7 @@ static void __init handle_initrd(void)
 	/* move initrd to rootfs' /old */
 	do_kern_mount("..", ".", NULL, MS_MOVE, NULL);
 	/* switch root and cwd back to / of rootfs */
-	ksys_chroot("..");
+	kern_chroot("..");
 
 	if (new_decode_dev(real_root_dev) == Root_RAM0) {
 		kern_chdir("/old");
-- 
2.27.0


^ permalink raw reply related	[flat|nested] 28+ messages in thread

* [PATCH 08/24] fs: add a kern_access helper
  2020-07-20 15:58 add file system helpers that take kernel pointers for the init code Christoph Hellwig
                   ` (6 preceding siblings ...)
  2020-07-20 15:58 ` [PATCH 07/24] fs: add a kern_chroot helper Christoph Hellwig
@ 2020-07-20 15:58 ` Christoph Hellwig
  2020-07-20 15:58 ` [PATCH 09/24] fs: add a kern_chown helper Christoph Hellwig
                   ` (15 subsequent siblings)
  23 siblings, 0 replies; 28+ messages in thread
From: Christoph Hellwig @ 2020-07-20 15:58 UTC (permalink / raw)
  To: Al Viro, Linus Torvalds
  Cc: Greg Kroah-Hartman, Rafael J. Wysocki, linux-kernel, linux-raid,
	linux-fsdevel, linux-api

Add a simple helper for a access with a kernelspace name and use it in
the early init code instead of relying on the implicit set_fs(KERNEL_DS)
there.  Remove the now unused ksys_access.

Signed-off-by: Christoph Hellwig <hch@lst.de>
---
 fs/open.c                | 37 +++++++++++++++++++++++++------------
 include/linux/fs.h       |  1 +
 include/linux/syscalls.h |  7 -------
 init/main.c              |  3 +--
 4 files changed, 27 insertions(+), 21 deletions(-)

diff --git a/fs/open.c b/fs/open.c
index 424db905da5f18..2a9457a16b2be2 100644
--- a/fs/open.c
+++ b/fs/open.c
@@ -394,19 +394,19 @@ static const struct cred *access_override_creds(void)
 	return old_cred;
 }
 
-long do_faccessat(int dfd, const char __user *filename, int mode, int flags)
+static int do_faccessat(int dfd, struct filename *name, int mode, int flags)
 {
 	struct path path;
 	struct inode *inode;
-	int res;
+	int res = -EINVAL;
 	unsigned int lookup_flags = LOOKUP_FOLLOW;
 	const struct cred *old_cred = NULL;
 
 	if (mode & ~S_IRWXO)	/* where's F_OK, X_OK, W_OK, R_OK? */
-		return -EINVAL;
+		goto out_putname;
 
 	if (flags & ~(AT_EACCESS | AT_SYMLINK_NOFOLLOW | AT_EMPTY_PATH))
-		return -EINVAL;
+		goto out_putname;
 
 	if (flags & AT_SYMLINK_NOFOLLOW)
 		lookup_flags &= ~LOOKUP_FOLLOW;
@@ -414,15 +414,16 @@ long do_faccessat(int dfd, const char __user *filename, int mode, int flags)
 		lookup_flags |= LOOKUP_EMPTY;
 
 	if (!(flags & AT_EACCESS)) {
+		res = -ENOMEM;
 		old_cred = access_override_creds();
 		if (!old_cred)
-			return -ENOMEM;
+			goto out_putname;
 	}
 
 retry:
-	res = user_path_at(dfd, filename, lookup_flags, &path);
+	res = filename_lookup(dfd, name, lookup_flags, &path, NULL);
 	if (res)
-		goto out;
+		goto out_revert_creds;
 
 	inode = d_backing_inode(path.dentry);
 
@@ -459,27 +460,39 @@ long do_faccessat(int dfd, const char __user *filename, int mode, int flags)
 		lookup_flags |= LOOKUP_REVAL;
 		goto retry;
 	}
-out:
+	putname(name);
+out_revert_creds:
 	if (old_cred)
 		revert_creds(old_cred);
-
 	return res;
+out_putname:
+	if (!IS_ERR(name))
+		putname(name);
+	return res;
+}
+
+int __init kern_access(const char __user *filename, int mode)
+{
+	return do_faccessat(AT_FDCWD, getname_kernel(filename), mode, 0);
 }
 
 SYSCALL_DEFINE3(faccessat, int, dfd, const char __user *, filename, int, mode)
 {
-	return do_faccessat(dfd, filename, mode, 0);
+	return do_faccessat(dfd, getname(filename), mode, 0);
 }
 
 SYSCALL_DEFINE4(faccessat2, int, dfd, const char __user *, filename, int, mode,
 		int, flags)
 {
-	return do_faccessat(dfd, filename, mode, flags);
+	unsigned int lookup_flags = (flags & AT_EMPTY_PATH) ? LOOKUP_EMPTY : 0;
+	struct filename *name = getname_flags(filename, lookup_flags, NULL);
+
+	return do_faccessat(dfd, name, mode, flags);
 }
 
 SYSCALL_DEFINE2(access, const char __user *, filename, int, mode)
 {
-	return do_faccessat(AT_FDCWD, filename, mode, 0);
+	return do_faccessat(AT_FDCWD, getname(filename), mode, 0);
 }
 
 static int do_chdir(struct filename *name)
diff --git a/include/linux/fs.h b/include/linux/fs.h
index 0205355bffb1bc..0c7672d3f1172f 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -3673,5 +3673,6 @@ static inline int inode_drain_writes(struct inode *inode)
 
 int kern_chdir(const char *filename);
 int kern_chroot(const char *filename);
+int __init kern_access(const char *filename, int mode);
 
 #endif /* _LINUX_FS_H */
diff --git a/include/linux/syscalls.h b/include/linux/syscalls.h
index a3176d1a521467..b387e3700c68c5 100644
--- a/include/linux/syscalls.h
+++ b/include/linux/syscalls.h
@@ -1326,13 +1326,6 @@ static inline int ksys_chmod(const char __user *filename, umode_t mode)
 	return do_fchmodat(AT_FDCWD, filename, mode);
 }
 
-long do_faccessat(int dfd, const char __user *filename, int mode, int flags);
-
-static inline long ksys_access(const char __user *filename, int mode)
-{
-	return do_faccessat(AT_FDCWD, filename, mode, 0);
-}
-
 extern int do_fchownat(int dfd, const char __user *filename, uid_t user,
 		       gid_t group, int flag);
 
diff --git a/init/main.c b/init/main.c
index c2c9143db96795..880f195b61abe1 100644
--- a/init/main.c
+++ b/init/main.c
@@ -1514,8 +1514,7 @@ static noinline void __init kernel_init_freeable(void)
 	 * check if there is an early userspace init.  If yes, let it do all
 	 * the work
 	 */
-	if (ksys_access((const char __user *)
-			ramdisk_execute_command, 0) != 0) {
+	if (kern_access(ramdisk_execute_command, 0) != 0) {
 		ramdisk_execute_command = NULL;
 		prepare_namespace();
 	}
-- 
2.27.0


^ permalink raw reply related	[flat|nested] 28+ messages in thread

* [PATCH 09/24] fs: add a kern_chown helper
  2020-07-20 15:58 add file system helpers that take kernel pointers for the init code Christoph Hellwig
                   ` (7 preceding siblings ...)
  2020-07-20 15:58 ` [PATCH 08/24] fs: add a kern_access helper Christoph Hellwig
@ 2020-07-20 15:58 ` Christoph Hellwig
  2020-07-20 15:58 ` [PATCH 10/24] fs: move the uid16 (f)chown syscalls to fs/open.c Christoph Hellwig
                   ` (14 subsequent siblings)
  23 siblings, 0 replies; 28+ messages in thread
From: Christoph Hellwig @ 2020-07-20 15:58 UTC (permalink / raw)
  To: Al Viro, Linus Torvalds
  Cc: Greg Kroah-Hartman, Rafael J. Wysocki, linux-kernel, linux-raid,
	linux-fsdevel, linux-api

Add a simple helper to chown with a kernel space name and use it in the
early init code instead of relying on the implicit set_fs(KERNEL_DS)
there.  Remove ksys_chown after switching all users to call do_fchownat
directly.

Signed-off-by: Christoph Hellwig <hch@lst.de>
---
 fs/internal.h            |  2 --
 fs/open.c                | 31 +++++++++++++++++++++----------
 include/linux/fs.h       |  1 +
 include/linux/syscalls.h | 15 +--------------
 init/initramfs.c         |  6 +++---
 kernel/uid16.c           |  6 ++++--
 6 files changed, 30 insertions(+), 31 deletions(-)

diff --git a/fs/internal.h b/fs/internal.h
index 9b863a7bd70892..ad62729e7ae587 100644
--- a/fs/internal.h
+++ b/fs/internal.h
@@ -127,8 +127,6 @@ extern int build_open_flags(const struct open_how *how, struct open_flags *op);
 
 long do_sys_ftruncate(unsigned int fd, loff_t length, int small);
 int do_fchmodat(int dfd, const char __user *filename, umode_t mode);
-int do_fchownat(int dfd, const char __user *filename, uid_t user, gid_t group,
-		int flag);
 
 extern int vfs_open(const struct path *, struct file *);
 
diff --git a/fs/open.c b/fs/open.c
index 2a9457a16b2be2..7d7456070503f2 100644
--- a/fs/open.c
+++ b/fs/open.c
@@ -714,23 +714,23 @@ static int chown_common(const struct path *path, uid_t user, gid_t group)
 	return error;
 }
 
-int do_fchownat(int dfd, const char __user *filename, uid_t user, gid_t group,
+int do_fchownat(int dfd, struct filename *name, uid_t user, gid_t group,
 		int flag)
 {
 	struct path path;
-	int error = -EINVAL;
-	int lookup_flags;
+	int lookup_flags, error;
 
+	error = -EINVAL;
 	if ((flag & ~(AT_SYMLINK_NOFOLLOW | AT_EMPTY_PATH)) != 0)
-		goto out;
+		goto out_putname;
 
 	lookup_flags = (flag & AT_SYMLINK_NOFOLLOW) ? 0 : LOOKUP_FOLLOW;
 	if (flag & AT_EMPTY_PATH)
 		lookup_flags |= LOOKUP_EMPTY;
 retry:
-	error = user_path_at(dfd, filename, lookup_flags, &path);
+	error = filename_lookup(dfd, name, lookup_flags, &path, NULL);
 	if (error)
-		goto out;
+		return error;
 	error = mnt_want_write(path.mnt);
 	if (error)
 		goto out_release;
@@ -742,24 +742,35 @@ int do_fchownat(int dfd, const char __user *filename, uid_t user, gid_t group,
 		lookup_flags |= LOOKUP_REVAL;
 		goto retry;
 	}
-out:
+out_putname:
+	if (!IS_ERR(name))
+		putname(name);
 	return error;
 }
 
+int __init kern_chown(const char *filename, uid_t user, gid_t group, int flag)
+{
+	return do_fchownat(AT_FDCWD, getname_kernel(filename), user, group,
+			flag);
+}
+
 SYSCALL_DEFINE5(fchownat, int, dfd, const char __user *, filename, uid_t, user,
 		gid_t, group, int, flag)
 {
-	return do_fchownat(dfd, filename, user, group, flag);
+	int lookup_flags = (flag & AT_EMPTY_PATH) ? LOOKUP_EMPTY : 0;
+	struct filename *name = getname_flags(filename, lookup_flags, NULL);
+
+	return do_fchownat(dfd, name, user, group, flag);
 }
 
 SYSCALL_DEFINE3(chown, const char __user *, filename, uid_t, user, gid_t, group)
 {
-	return do_fchownat(AT_FDCWD, filename, user, group, 0);
+	return do_fchownat(AT_FDCWD, getname(filename), user, group, 0);
 }
 
 SYSCALL_DEFINE3(lchown, const char __user *, filename, uid_t, user, gid_t, group)
 {
-	return do_fchownat(AT_FDCWD, filename, user, group,
+	return do_fchownat(AT_FDCWD, getname(filename), user, group,
 			   AT_SYMLINK_NOFOLLOW);
 }
 
diff --git a/include/linux/fs.h b/include/linux/fs.h
index 0c7672d3f1172f..75d6ef7e1de52b 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -3674,5 +3674,6 @@ static inline int inode_drain_writes(struct inode *inode)
 int kern_chdir(const char *filename);
 int kern_chroot(const char *filename);
 int __init kern_access(const char *filename, int mode);
+int __init kern_chown(const char *filename, uid_t user, gid_t group, int flag);
 
 #endif /* _LINUX_FS_H */
diff --git a/include/linux/syscalls.h b/include/linux/syscalls.h
index b387e3700c68c5..42dd2715e07688 100644
--- a/include/linux/syscalls.h
+++ b/include/linux/syscalls.h
@@ -1326,22 +1326,9 @@ static inline int ksys_chmod(const char __user *filename, umode_t mode)
 	return do_fchmodat(AT_FDCWD, filename, mode);
 }
 
-extern int do_fchownat(int dfd, const char __user *filename, uid_t user,
+extern int do_fchownat(int dfd, struct filename *name, uid_t user,
 		       gid_t group, int flag);
 
-static inline long ksys_chown(const char __user *filename, uid_t user,
-			      gid_t group)
-{
-	return do_fchownat(AT_FDCWD, filename, user, group, 0);
-}
-
-static inline long ksys_lchown(const char __user *filename, uid_t user,
-			       gid_t group)
-{
-	return do_fchownat(AT_FDCWD, filename, user, group,
-			     AT_SYMLINK_NOFOLLOW);
-}
-
 extern long do_sys_ftruncate(unsigned int fd, loff_t length, int small);
 
 static inline long ksys_ftruncate(unsigned int fd, loff_t length)
diff --git a/init/initramfs.c b/init/initramfs.c
index 3823d15e5d2619..45e4ddb63caba1 100644
--- a/init/initramfs.c
+++ b/init/initramfs.c
@@ -345,14 +345,14 @@ static int __init do_name(void)
 		}
 	} else if (S_ISDIR(mode)) {
 		ksys_mkdir(collected, mode);
-		ksys_chown(collected, uid, gid);
+		kern_chown(collected, uid, gid, 0);
 		ksys_chmod(collected, mode);
 		dir_add(collected, mtime);
 	} else if (S_ISBLK(mode) || S_ISCHR(mode) ||
 		   S_ISFIFO(mode) || S_ISSOCK(mode)) {
 		if (maybe_link() == 0) {
 			ksys_mknod(collected, mode, rdev);
-			ksys_chown(collected, uid, gid);
+			kern_chown(collected, uid, gid, 0);
 			ksys_chmod(collected, mode);
 			do_utime(collected, mtime);
 		}
@@ -390,7 +390,7 @@ static int __init do_symlink(void)
 	collected[N_ALIGN(name_len) + body_len] = '\0';
 	clean_path(collected, 0);
 	ksys_symlink(collected + N_ALIGN(name_len), collected);
-	ksys_lchown(collected, uid, gid);
+	kern_chown(collected, uid, gid, AT_SYMLINK_NOFOLLOW);
 	do_utime(collected, mtime);
 	state = SkipIt;
 	next_state = Reset;
diff --git a/kernel/uid16.c b/kernel/uid16.c
index af6925d8599b9b..a332947e92d12e 100644
--- a/kernel/uid16.c
+++ b/kernel/uid16.c
@@ -22,12 +22,14 @@
 
 SYSCALL_DEFINE3(chown16, const char __user *, filename, old_uid_t, user, old_gid_t, group)
 {
-	return ksys_chown(filename, low2highuid(user), low2highgid(group));
+	return do_fchownat(AT_FDCWD, getname(filename), low2highuid(user),
+			low2highgid(group), 0);
 }
 
 SYSCALL_DEFINE3(lchown16, const char __user *, filename, old_uid_t, user, old_gid_t, group)
 {
-	return ksys_lchown(filename, low2highuid(user), low2highgid(group));
+	return do_fchownat(AT_FDCWD, getname(filename), low2highuid(user),
+			low2highgid(group), AT_SYMLINK_NOFOLLOW);
 }
 
 SYSCALL_DEFINE3(fchown16, unsigned int, fd, old_uid_t, user, old_gid_t, group)
-- 
2.27.0


^ permalink raw reply related	[flat|nested] 28+ messages in thread

* [PATCH 10/24] fs: move the uid16 (f)chown syscalls to fs/open.c
  2020-07-20 15:58 add file system helpers that take kernel pointers for the init code Christoph Hellwig
                   ` (8 preceding siblings ...)
  2020-07-20 15:58 ` [PATCH 09/24] fs: add a kern_chown helper Christoph Hellwig
@ 2020-07-20 15:58 ` Christoph Hellwig
  2020-07-20 15:58 ` [PATCH 11/24] fs: add a kern_chmod helper Christoph Hellwig
                   ` (13 subsequent siblings)
  23 siblings, 0 replies; 28+ messages in thread
From: Christoph Hellwig @ 2020-07-20 15:58 UTC (permalink / raw)
  To: Al Viro, Linus Torvalds
  Cc: Greg Kroah-Hartman, Rafael J. Wysocki, linux-kernel, linux-raid,
	linux-fsdevel, linux-api

This allows to keep the internal (f)chown helper private in open.c.

Signed-off-by: Christoph Hellwig <hch@lst.de>
---
 fs/open.c                | 25 ++++++++++++++++++++++---
 include/linux/syscalls.h |  4 ----
 kernel/uid16.c           | 17 -----------------
 3 files changed, 22 insertions(+), 24 deletions(-)

diff --git a/fs/open.c b/fs/open.c
index 7d7456070503f2..8157db254c8f8a 100644
--- a/fs/open.c
+++ b/fs/open.c
@@ -714,7 +714,7 @@ static int chown_common(const struct path *path, uid_t user, gid_t group)
 	return error;
 }
 
-int do_fchownat(int dfd, struct filename *name, uid_t user, gid_t group,
+static int do_fchownat(int dfd, struct filename *name, uid_t user, gid_t group,
 		int flag)
 {
 	struct path path;
@@ -787,7 +787,7 @@ int vfs_fchown(struct file *file, uid_t user, gid_t group)
 	return error;
 }
 
-int ksys_fchown(unsigned int fd, uid_t user, gid_t group)
+static int do_fchown(unsigned int fd, uid_t user, gid_t group)
 {
 	struct fd f = fdget(fd);
 	int error = -EBADF;
@@ -801,9 +801,28 @@ int ksys_fchown(unsigned int fd, uid_t user, gid_t group)
 
 SYSCALL_DEFINE3(fchown, unsigned int, fd, uid_t, user, gid_t, group)
 {
-	return ksys_fchown(fd, user, group);
+	return do_fchown(fd, user, group);
 }
 
+#ifdef CONFIG_UID16
+SYSCALL_DEFINE3(chown16, const char __user *, filename, old_uid_t, user, old_gid_t, group)
+{
+	return do_fchownat(AT_FDCWD, getname(filename), low2highuid(user),
+			low2highgid(group), 0);
+}
+
+SYSCALL_DEFINE3(lchown16, const char __user *, filename, old_uid_t, user, old_gid_t, group)
+{
+	return do_fchownat(AT_FDCWD, getname(filename), low2highuid(user),
+			low2highgid(group), AT_SYMLINK_NOFOLLOW);
+}
+
+SYSCALL_DEFINE3(fchown16, unsigned int, fd, old_uid_t, user, old_gid_t, group)
+{
+	return do_fchown(fd, low2highuid(user), low2highgid(group));
+}
+#endif /* CONFIG_UID16 */
+
 static int do_dentry_open(struct file *f,
 			  struct inode *inode,
 			  int (*open)(struct inode *, struct file *))
diff --git a/include/linux/syscalls.h b/include/linux/syscalls.h
index 42dd2715e07688..82346a68a73877 100644
--- a/include/linux/syscalls.h
+++ b/include/linux/syscalls.h
@@ -1237,7 +1237,6 @@ asmlinkage long sys_ni_syscall(void);
  */
 
 ssize_t ksys_write(unsigned int fd, const char __user *buf, size_t count);
-int ksys_fchown(unsigned int fd, uid_t user, gid_t group);
 ssize_t ksys_read(unsigned int fd, char __user *buf, size_t count);
 void ksys_sync(void);
 int ksys_unshare(unsigned long unshare_flags);
@@ -1326,9 +1325,6 @@ static inline int ksys_chmod(const char __user *filename, umode_t mode)
 	return do_fchmodat(AT_FDCWD, filename, mode);
 }
 
-extern int do_fchownat(int dfd, struct filename *name, uid_t user,
-		       gid_t group, int flag);
-
 extern long do_sys_ftruncate(unsigned int fd, loff_t length, int small);
 
 static inline long ksys_ftruncate(unsigned int fd, loff_t length)
diff --git a/kernel/uid16.c b/kernel/uid16.c
index a332947e92d12e..ec2a5634e99af6 100644
--- a/kernel/uid16.c
+++ b/kernel/uid16.c
@@ -20,23 +20,6 @@
 
 #include "uid16.h"
 
-SYSCALL_DEFINE3(chown16, const char __user *, filename, old_uid_t, user, old_gid_t, group)
-{
-	return do_fchownat(AT_FDCWD, getname(filename), low2highuid(user),
-			low2highgid(group), 0);
-}
-
-SYSCALL_DEFINE3(lchown16, const char __user *, filename, old_uid_t, user, old_gid_t, group)
-{
-	return do_fchownat(AT_FDCWD, getname(filename), low2highuid(user),
-			low2highgid(group), AT_SYMLINK_NOFOLLOW);
-}
-
-SYSCALL_DEFINE3(fchown16, unsigned int, fd, old_uid_t, user, old_gid_t, group)
-{
-	return ksys_fchown(fd, low2highuid(user), low2highgid(group));
-}
-
 SYSCALL_DEFINE2(setregid16, old_gid_t, rgid, old_gid_t, egid)
 {
 	return __sys_setregid(low2highgid(rgid), low2highgid(egid));
-- 
2.27.0


^ permalink raw reply related	[flat|nested] 28+ messages in thread

* [PATCH 11/24] fs: add a kern_chmod helper
  2020-07-20 15:58 add file system helpers that take kernel pointers for the init code Christoph Hellwig
                   ` (9 preceding siblings ...)
  2020-07-20 15:58 ` [PATCH 10/24] fs: move the uid16 (f)chown syscalls to fs/open.c Christoph Hellwig
@ 2020-07-20 15:58 ` Christoph Hellwig
  2020-07-20 15:58 ` [PATCH 12/24] fs: add a kern_utimes helper Christoph Hellwig
                   ` (12 subsequent siblings)
  23 siblings, 0 replies; 28+ messages in thread
From: Christoph Hellwig @ 2020-07-20 15:58 UTC (permalink / raw)
  To: Al Viro, Linus Torvalds
  Cc: Greg Kroah-Hartman, Rafael J. Wysocki, linux-kernel, linux-raid,
	linux-fsdevel, linux-api

Add a simple helper to chown with a kernel space name and use it in the
early init code instead of relying on the implicit set_fs(KERNEL_DS)
there.  Remove the now unused ksys_chmod.

Signed-off-by: Christoph Hellwig <hch@lst.de>
---
 fs/internal.h            |  1 -
 fs/open.c                | 28 +++++++++++++++++-----------
 include/linux/fs.h       |  1 +
 include/linux/syscalls.h |  7 -------
 init/initramfs.c         |  4 ++--
 5 files changed, 20 insertions(+), 21 deletions(-)

diff --git a/fs/internal.h b/fs/internal.h
index ad62729e7ae587..1e2b425f56ee9e 100644
--- a/fs/internal.h
+++ b/fs/internal.h
@@ -126,7 +126,6 @@ extern struct open_how build_open_how(int flags, umode_t mode);
 extern int build_open_flags(const struct open_how *how, struct open_flags *op);
 
 long do_sys_ftruncate(unsigned int fd, loff_t length, int small);
-int do_fchmodat(int dfd, const char __user *filename, umode_t mode);
 
 extern int vfs_open(const struct path *, struct file *);
 
diff --git a/fs/open.c b/fs/open.c
index 8157db254c8f8a..bb8ffc24c4b034 100644
--- a/fs/open.c
+++ b/fs/open.c
@@ -643,33 +643,39 @@ SYSCALL_DEFINE2(fchmod, unsigned int, fd, umode_t, mode)
 	return err;
 }
 
-int do_fchmodat(int dfd, const char __user *filename, umode_t mode)
+static int do_fchmodat(int dfd, struct filename *name, umode_t mode)
 {
 	struct path path;
 	int error;
 	unsigned int lookup_flags = LOOKUP_FOLLOW;
 retry:
-	error = user_path_at(dfd, filename, lookup_flags, &path);
-	if (!error) {
-		error = chmod_common(&path, mode);
-		path_put(&path);
-		if (retry_estale(error, lookup_flags)) {
-			lookup_flags |= LOOKUP_REVAL;
-			goto retry;
-		}
+	error = filename_lookup(dfd, name, lookup_flags, &path, NULL);
+	if (error)
+		return error;
+	error = chmod_common(&path, mode);
+	path_put(&path);
+	if (retry_estale(error, lookup_flags)) {
+		lookup_flags |= LOOKUP_REVAL;
+		goto retry;
 	}
+	putname(name);
 	return error;
 }
 
+int __init kern_chmod(const char *filename, umode_t mode)
+{
+	return do_fchmodat(AT_FDCWD, getname_kernel(filename), mode);
+}
+
 SYSCALL_DEFINE3(fchmodat, int, dfd, const char __user *, filename,
 		umode_t, mode)
 {
-	return do_fchmodat(dfd, filename, mode);
+	return do_fchmodat(dfd, getname(filename), mode);
 }
 
 SYSCALL_DEFINE2(chmod, const char __user *, filename, umode_t, mode)
 {
-	return do_fchmodat(AT_FDCWD, filename, mode);
+	return do_fchmodat(AT_FDCWD, getname(filename), mode);
 }
 
 static int chown_common(const struct path *path, uid_t user, gid_t group)
diff --git a/include/linux/fs.h b/include/linux/fs.h
index 75d6ef7e1de52b..ca034126cb0e4d 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -3675,5 +3675,6 @@ int kern_chdir(const char *filename);
 int kern_chroot(const char *filename);
 int __init kern_access(const char *filename, int mode);
 int __init kern_chown(const char *filename, uid_t user, gid_t group, int flag);
+int __init kern_chmod(const char *filename, umode_t mode);
 
 #endif /* _LINUX_FS_H */
diff --git a/include/linux/syscalls.h b/include/linux/syscalls.h
index 82346a68a73877..a2ece4cc8692f5 100644
--- a/include/linux/syscalls.h
+++ b/include/linux/syscalls.h
@@ -1318,13 +1318,6 @@ static inline long ksys_link(const char __user *oldname,
 	return do_linkat(AT_FDCWD, oldname, AT_FDCWD, newname, 0);
 }
 
-extern int do_fchmodat(int dfd, const char __user *filename, umode_t mode);
-
-static inline int ksys_chmod(const char __user *filename, umode_t mode)
-{
-	return do_fchmodat(AT_FDCWD, filename, mode);
-}
-
 extern long do_sys_ftruncate(unsigned int fd, loff_t length, int small);
 
 static inline long ksys_ftruncate(unsigned int fd, loff_t length)
diff --git a/init/initramfs.c b/init/initramfs.c
index 45e4ddb63caba1..2c2d4480d495e8 100644
--- a/init/initramfs.c
+++ b/init/initramfs.c
@@ -346,14 +346,14 @@ static int __init do_name(void)
 	} else if (S_ISDIR(mode)) {
 		ksys_mkdir(collected, mode);
 		kern_chown(collected, uid, gid, 0);
-		ksys_chmod(collected, mode);
+		kern_chmod(collected, mode);
 		dir_add(collected, mtime);
 	} else if (S_ISBLK(mode) || S_ISCHR(mode) ||
 		   S_ISFIFO(mode) || S_ISSOCK(mode)) {
 		if (maybe_link() == 0) {
 			ksys_mknod(collected, mode, rdev);
 			kern_chown(collected, uid, gid, 0);
-			ksys_chmod(collected, mode);
+			kern_chmod(collected, mode);
 			do_utime(collected, mtime);
 		}
 	}
-- 
2.27.0


^ permalink raw reply related	[flat|nested] 28+ messages in thread

* [PATCH 12/24] fs: add a kern_utimes helper
  2020-07-20 15:58 add file system helpers that take kernel pointers for the init code Christoph Hellwig
                   ` (10 preceding siblings ...)
  2020-07-20 15:58 ` [PATCH 11/24] fs: add a kern_chmod helper Christoph Hellwig
@ 2020-07-20 15:58 ` Christoph Hellwig
  2020-07-20 15:58 ` [PATCH 13/24] fs: add a kern_mkdir helper Christoph Hellwig
                   ` (11 subsequent siblings)
  23 siblings, 0 replies; 28+ messages in thread
From: Christoph Hellwig @ 2020-07-20 15:58 UTC (permalink / raw)
  To: Al Viro, Linus Torvalds
  Cc: Greg Kroah-Hartman, Rafael J. Wysocki, linux-kernel, linux-raid,
	linux-fsdevel, linux-api

Add a simple helper to set timestamps with a kernel space name and use it
in the early init code instead of relying on the implicit
set_fs(KERNEL_DS) there.

Signed-off-by: Christoph Hellwig <hch@lst.de>
---
 fs/utimes.c        | 19 ++++++++++++++-----
 include/linux/fs.h |  1 +
 init/initramfs.c   |  2 +-
 3 files changed, 16 insertions(+), 6 deletions(-)

diff --git a/fs/utimes.c b/fs/utimes.c
index fd3cc42262241f..f4d7f9a73e115a 100644
--- a/fs/utimes.c
+++ b/fs/utimes.c
@@ -7,6 +7,7 @@
 #include <linux/uaccess.h>
 #include <linux/compat.h>
 #include <asm/unistd.h>
+#include "internal.h"
 
 static bool nsec_valid(long nsec)
 {
@@ -75,14 +76,15 @@ int vfs_utimes(const struct path *path, struct timespec64 *times)
 	return error;
 }
 
-static int do_utimes_path(int dfd, const char __user *filename,
+static int do_utimes_path(int dfd, struct filename *name,
 		struct timespec64 *times, int flags)
 {
 	struct path path;
 	int lookup_flags = 0, error;
 
+	error = -EINVAL;
 	if (flags & ~(AT_SYMLINK_NOFOLLOW | AT_EMPTY_PATH))
-		return -EINVAL;
+		goto out_putname;
 
 	if (!(flags & AT_SYMLINK_NOFOLLOW))
 		lookup_flags |= LOOKUP_FOLLOW;
@@ -90,7 +92,7 @@ static int do_utimes_path(int dfd, const char __user *filename,
 		lookup_flags |= LOOKUP_EMPTY;
 
 retry:
-	error = user_path_at(dfd, filename, lookup_flags, &path);
+	error = filename_lookup(dfd, name, lookup_flags, &path, NULL);
 	if (error)
 		return error;
 
@@ -100,10 +102,17 @@ static int do_utimes_path(int dfd, const char __user *filename,
 		lookup_flags |= LOOKUP_REVAL;
 		goto retry;
 	}
-
+out_putname:
+	if (!IS_ERR(name))
+		putname(name);
 	return error;
 }
 
+int __init kern_utimes(const char *filename, struct timespec64 *tv, int flags)
+{
+	return do_utimes_path(AT_FDCWD, getname_kernel(filename), tv, flags);
+}
+
 static int do_utimes_fd(int fd, struct timespec64 *times, int flags)
 {
 	struct fd f;
@@ -140,7 +149,7 @@ long do_utimes(int dfd, const char __user *filename, struct timespec64 *times,
 {
 	if (filename == NULL && dfd != AT_FDCWD)
 		return do_utimes_fd(dfd, times, flags);
-	return do_utimes_path(dfd, filename, times, flags);
+	return do_utimes_path(dfd, getname(filename), times, flags);
 }
 
 SYSCALL_DEFINE4(utimensat, int, dfd, const char __user *, filename,
diff --git a/include/linux/fs.h b/include/linux/fs.h
index ca034126cb0e4d..7472ff0b7062d9 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -3676,5 +3676,6 @@ int kern_chroot(const char *filename);
 int __init kern_access(const char *filename, int mode);
 int __init kern_chown(const char *filename, uid_t user, gid_t group, int flag);
 int __init kern_chmod(const char *filename, umode_t mode);
+int __init kern_utimes(const char *filename, struct timespec64 *tv, int flags);
 
 #endif /* _LINUX_FS_H */
diff --git a/init/initramfs.c b/init/initramfs.c
index 2c2d4480d495e8..de850d4c6da200 100644
--- a/init/initramfs.c
+++ b/init/initramfs.c
@@ -110,7 +110,7 @@ static long __init do_utime(char *filename, time64_t mtime)
 	t[1].tv_sec = mtime;
 	t[1].tv_nsec = 0;
 
-	return do_utimes(AT_FDCWD, filename, t, AT_SYMLINK_NOFOLLOW);
+	return kern_utimes(filename, t, 0);
 }
 
 static __initdata LIST_HEAD(dir_list);
-- 
2.27.0


^ permalink raw reply related	[flat|nested] 28+ messages in thread

* [PATCH 13/24] fs: add a kern_mkdir helper
  2020-07-20 15:58 add file system helpers that take kernel pointers for the init code Christoph Hellwig
                   ` (11 preceding siblings ...)
  2020-07-20 15:58 ` [PATCH 12/24] fs: add a kern_utimes helper Christoph Hellwig
@ 2020-07-20 15:58 ` Christoph Hellwig
  2020-07-20 15:58 ` [PATCH 14/24] fs: add a kern_mknod helper Christoph Hellwig
                   ` (10 subsequent siblings)
  23 siblings, 0 replies; 28+ messages in thread
From: Christoph Hellwig @ 2020-07-20 15:58 UTC (permalink / raw)
  To: Al Viro, Linus Torvalds
  Cc: Greg Kroah-Hartman, Rafael J. Wysocki, linux-kernel, linux-raid,
	linux-fsdevel, linux-api

Add a simple helper perform a mkdir with a kernel space file name and use
it in the early init code instead of relying on the implicit
set_fs(KERNEL_DS) there.  To do so push the getname from do_mkdirat into the
callers.  Remove the now unused ksys_mkdir.

Signed-off-by: Christoph Hellwig <hch@lst.de>
---
 fs/internal.h            |  1 -
 fs/namei.c               | 14 ++++++++++----
 include/linux/fs.h       |  1 +
 include/linux/syscalls.h |  7 -------
 init/do_mounts_initrd.c  |  2 +-
 init/initramfs.c         |  2 +-
 init/noinitramfs.c       |  4 ++--
 7 files changed, 15 insertions(+), 16 deletions(-)

diff --git a/fs/internal.h b/fs/internal.h
index 1e2b425f56ee9e..722d33a66d9645 100644
--- a/fs/internal.h
+++ b/fs/internal.h
@@ -64,7 +64,6 @@ extern int vfs_path_lookup(struct dentry *, struct vfsmount *,
 			   const char *, unsigned int, struct path *);
 long do_mknodat(int dfd, const char __user *filename, umode_t mode,
 		unsigned int dev);
-long do_mkdirat(int dfd, const char __user *pathname, umode_t mode);
 long do_rmdir(int dfd, const char __user *pathname);
 long do_unlinkat(int dfd, struct filename *name);
 long do_symlinkat(const char __user *oldname, int newdfd,
diff --git a/fs/namei.c b/fs/namei.c
index 6daffd59e97270..3545623495d1f4 100644
--- a/fs/namei.c
+++ b/fs/namei.c
@@ -3665,7 +3665,7 @@ int vfs_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode)
 }
 EXPORT_SYMBOL(vfs_mkdir);
 
-long do_mkdirat(int dfd, const char __user *pathname, umode_t mode)
+static int do_mkdirat(int dfd, struct filename *name, umode_t mode)
 {
 	struct dentry *dentry;
 	struct path path;
@@ -3673,7 +3673,7 @@ long do_mkdirat(int dfd, const char __user *pathname, umode_t mode)
 	unsigned int lookup_flags = LOOKUP_DIRECTORY;
 
 retry:
-	dentry = user_path_create(dfd, pathname, &path, lookup_flags);
+	dentry = filename_create(dfd, name, &path, lookup_flags);
 	if (IS_ERR(dentry))
 		return PTR_ERR(dentry);
 
@@ -3687,17 +3687,23 @@ long do_mkdirat(int dfd, const char __user *pathname, umode_t mode)
 		lookup_flags |= LOOKUP_REVAL;
 		goto retry;
 	}
+	putname(name);
 	return error;
 }
 
+int kern_mkdir(const char *pathname, umode_t mode)
+{
+	return do_mkdirat(AT_FDCWD, getname_kernel(pathname), mode);
+}
+
 SYSCALL_DEFINE3(mkdirat, int, dfd, const char __user *, pathname, umode_t, mode)
 {
-	return do_mkdirat(dfd, pathname, mode);
+	return do_mkdirat(dfd, getname(pathname), mode);
 }
 
 SYSCALL_DEFINE2(mkdir, const char __user *, pathname, umode_t, mode)
 {
-	return do_mkdirat(AT_FDCWD, pathname, mode);
+	return do_mkdirat(AT_FDCWD, getname(pathname), mode);
 }
 
 int vfs_rmdir(struct inode *dir, struct dentry *dentry)
diff --git a/include/linux/fs.h b/include/linux/fs.h
index 7472ff0b7062d9..3bbeeadf2ddd98 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -3677,5 +3677,6 @@ int __init kern_access(const char *filename, int mode);
 int __init kern_chown(const char *filename, uid_t user, gid_t group, int flag);
 int __init kern_chmod(const char *filename, umode_t mode);
 int __init kern_utimes(const char *filename, struct timespec64 *tv, int flags);
+int kern_mkdir(const char *pathname, umode_t mode);
 
 #endif /* _LINUX_FS_H */
diff --git a/include/linux/syscalls.h b/include/linux/syscalls.h
index a2ece4cc8692f5..6aa1cd200425a4 100644
--- a/include/linux/syscalls.h
+++ b/include/linux/syscalls.h
@@ -1284,13 +1284,6 @@ static inline long ksys_rmdir(const char __user *pathname)
 	return do_rmdir(AT_FDCWD, pathname);
 }
 
-extern long do_mkdirat(int dfd, const char __user *pathname, umode_t mode);
-
-static inline long ksys_mkdir(const char __user *pathname, umode_t mode)
-{
-	return do_mkdirat(AT_FDCWD, pathname, mode);
-}
-
 extern long do_symlinkat(const char __user *oldname, int newdfd,
 			 const char __user *newname);
 
diff --git a/init/do_mounts_initrd.c b/init/do_mounts_initrd.c
index 1cbc9988d2e0ad..b9a749ebe85c2d 100644
--- a/init/do_mounts_initrd.c
+++ b/init/do_mounts_initrd.c
@@ -81,7 +81,7 @@ static void __init handle_initrd(void)
 	create_dev("/dev/root.old", Root_RAM0);
 	/* mount initrd on rootfs' /root */
 	mount_block_root("/dev/root.old", root_mountflags & ~MS_RDONLY);
-	ksys_mkdir("/old", 0700);
+	kern_mkdir("/old", 0700);
 	kern_chdir("/old");
 
 	/*
diff --git a/init/initramfs.c b/init/initramfs.c
index de850d4c6da200..40b97ca5fe8cde 100644
--- a/init/initramfs.c
+++ b/init/initramfs.c
@@ -344,7 +344,7 @@ static int __init do_name(void)
 			state = CopyFile;
 		}
 	} else if (S_ISDIR(mode)) {
-		ksys_mkdir(collected, mode);
+		kern_mkdir(collected, mode);
 		kern_chown(collected, uid, gid, 0);
 		kern_chmod(collected, mode);
 		dir_add(collected, mtime);
diff --git a/init/noinitramfs.c b/init/noinitramfs.c
index fa9cdfa7101d3c..89109c1d633adb 100644
--- a/init/noinitramfs.c
+++ b/init/noinitramfs.c
@@ -17,7 +17,7 @@ static int __init default_rootfs(void)
 {
 	int err;
 
-	err = ksys_mkdir((const char __user __force *) "/dev", 0755);
+	err = kern_mkdir("/dev", 0755);
 	if (err < 0)
 		goto out;
 
@@ -27,7 +27,7 @@ static int __init default_rootfs(void)
 	if (err < 0)
 		goto out;
 
-	err = ksys_mkdir((const char __user __force *) "/root", 0700);
+	err = kern_mkdir("/root", 0700);
 	if (err < 0)
 		goto out;
 
-- 
2.27.0


^ permalink raw reply related	[flat|nested] 28+ messages in thread

* [PATCH 14/24] fs: add a kern_mknod helper
  2020-07-20 15:58 add file system helpers that take kernel pointers for the init code Christoph Hellwig
                   ` (12 preceding siblings ...)
  2020-07-20 15:58 ` [PATCH 13/24] fs: add a kern_mkdir helper Christoph Hellwig
@ 2020-07-20 15:58 ` Christoph Hellwig
  2020-07-20 15:58 ` [PATCH 15/24] fs: add a kern_link helper Christoph Hellwig
                   ` (9 subsequent siblings)
  23 siblings, 0 replies; 28+ messages in thread
From: Christoph Hellwig @ 2020-07-20 15:58 UTC (permalink / raw)
  To: Al Viro, Linus Torvalds
  Cc: Greg Kroah-Hartman, Rafael J. Wysocki, linux-kernel, linux-raid,
	linux-fsdevel, linux-api

Add a simple helper perform a mknod with a kernel space file name and use
it in the early init code instead of relying on the implicit
set_fs(KERNEL_DS) there.  To do so push the getname from do_mknodat into the
callers.  Remove the now unused ksys_mknod.

Signed-off-by: Christoph Hellwig <hch@lst.de>
---
 fs/internal.h            |  2 --
 fs/namei.c               | 18 +++++++++++++-----
 include/linux/fs.h       |  1 +
 include/linux/syscalls.h |  9 ---------
 init/do_mounts.h         |  2 +-
 init/initramfs.c         |  2 +-
 init/noinitramfs.c       |  5 ++---
 7 files changed, 18 insertions(+), 21 deletions(-)

diff --git a/fs/internal.h b/fs/internal.h
index 722d33a66d9645..1e7a72bd183e63 100644
--- a/fs/internal.h
+++ b/fs/internal.h
@@ -62,8 +62,6 @@ extern int filename_lookup(int dfd, struct filename *name, unsigned flags,
 			   struct path *path, struct path *root);
 extern int vfs_path_lookup(struct dentry *, struct vfsmount *,
 			   const char *, unsigned int, struct path *);
-long do_mknodat(int dfd, const char __user *filename, umode_t mode,
-		unsigned int dev);
 long do_rmdir(int dfd, const char __user *pathname);
 long do_unlinkat(int dfd, struct filename *name);
 long do_symlinkat(const char __user *oldname, int newdfd,
diff --git a/fs/namei.c b/fs/namei.c
index 3545623495d1f4..de97edac21849d 100644
--- a/fs/namei.c
+++ b/fs/namei.c
@@ -3584,7 +3584,7 @@ static int may_mknod(umode_t mode)
 	}
 }
 
-long do_mknodat(int dfd, const char __user *filename, umode_t mode,
+static int do_mknodat(int dfd, struct filename *name, umode_t mode,
 		unsigned int dev)
 {
 	struct dentry *dentry;
@@ -3594,9 +3594,9 @@ long do_mknodat(int dfd, const char __user *filename, umode_t mode,
 
 	error = may_mknod(mode);
 	if (error)
-		return error;
+		goto out_putname;
 retry:
-	dentry = user_path_create(dfd, filename, &path, lookup_flags);
+	dentry = filename_create(dfd, name, &path, lookup_flags);
 	if (IS_ERR(dentry))
 		return PTR_ERR(dentry);
 
@@ -3625,18 +3625,26 @@ long do_mknodat(int dfd, const char __user *filename, umode_t mode,
 		lookup_flags |= LOOKUP_REVAL;
 		goto retry;
 	}
+out_putname:
+	if (!IS_ERR(name))
+		putname(name);
 	return error;
 }
 
+int kern_mknod(const char *filename, umode_t mode, unsigned int dev)
+{
+	return do_mknodat(AT_FDCWD, getname_kernel(filename), mode, dev);
+}
+
 SYSCALL_DEFINE4(mknodat, int, dfd, const char __user *, filename, umode_t, mode,
 		unsigned int, dev)
 {
-	return do_mknodat(dfd, filename, mode, dev);
+	return do_mknodat(dfd, getname(filename), mode, dev);
 }
 
 SYSCALL_DEFINE3(mknod, const char __user *, filename, umode_t, mode, unsigned, dev)
 {
-	return do_mknodat(AT_FDCWD, filename, mode, dev);
+	return do_mknodat(AT_FDCWD, getname(filename), mode, dev);
 }
 
 int vfs_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode)
diff --git a/include/linux/fs.h b/include/linux/fs.h
index 3bbeeadf2ddd98..846a21a9b3e14c 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -3678,5 +3678,6 @@ int __init kern_chown(const char *filename, uid_t user, gid_t group, int flag);
 int __init kern_chmod(const char *filename, umode_t mode);
 int __init kern_utimes(const char *filename, struct timespec64 *tv, int flags);
 int kern_mkdir(const char *pathname, umode_t mode);
+int kern_mknod(const char *filename, umode_t mode, unsigned int dev);
 
 #endif /* _LINUX_FS_H */
diff --git a/include/linux/syscalls.h b/include/linux/syscalls.h
index 6aa1cd200425a4..3dfcae351a077d 100644
--- a/include/linux/syscalls.h
+++ b/include/linux/syscalls.h
@@ -1293,15 +1293,6 @@ static inline long ksys_symlink(const char __user *oldname,
 	return do_symlinkat(oldname, AT_FDCWD, newname);
 }
 
-extern long do_mknodat(int dfd, const char __user *filename, umode_t mode,
-		       unsigned int dev);
-
-static inline long ksys_mknod(const char __user *filename, umode_t mode,
-			      unsigned int dev)
-{
-	return do_mknodat(AT_FDCWD, filename, mode, dev);
-}
-
 extern int do_linkat(int olddfd, const char __user *oldname, int newdfd,
 		     const char __user *newname, int flags);
 
diff --git a/init/do_mounts.h b/init/do_mounts.h
index c855b3f0e06d19..b9ec1d522f0ce1 100644
--- a/init/do_mounts.h
+++ b/init/do_mounts.h
@@ -16,7 +16,7 @@ extern int root_mountflags;
 static inline int create_dev(char *name, dev_t dev)
 {
 	ksys_unlink(name);
-	return ksys_mknod(name, S_IFBLK|0600, new_encode_dev(dev));
+	return kern_mknod(name, S_IFBLK|0600, new_encode_dev(dev));
 }
 
 #ifdef CONFIG_BLK_DEV_RAM
diff --git a/init/initramfs.c b/init/initramfs.c
index 40b97ca5fe8cde..f32226d0388100 100644
--- a/init/initramfs.c
+++ b/init/initramfs.c
@@ -351,7 +351,7 @@ static int __init do_name(void)
 	} else if (S_ISBLK(mode) || S_ISCHR(mode) ||
 		   S_ISFIFO(mode) || S_ISSOCK(mode)) {
 		if (maybe_link() == 0) {
-			ksys_mknod(collected, mode, rdev);
+			kern_mknod(collected, mode, rdev);
 			kern_chown(collected, uid, gid, 0);
 			kern_chmod(collected, mode);
 			do_utime(collected, mtime);
diff --git a/init/noinitramfs.c b/init/noinitramfs.c
index 89109c1d633adb..8048777874e4f1 100644
--- a/init/noinitramfs.c
+++ b/init/noinitramfs.c
@@ -21,9 +21,8 @@ static int __init default_rootfs(void)
 	if (err < 0)
 		goto out;
 
-	err = ksys_mknod((const char __user __force *) "/dev/console",
-			S_IFCHR | S_IRUSR | S_IWUSR,
-			new_encode_dev(MKDEV(5, 1)));
+	err = kern_mknod("/dev/console", S_IFCHR | S_IRUSR | S_IWUSR,
+			 new_encode_dev(MKDEV(5, 1)));
 	if (err < 0)
 		goto out;
 
-- 
2.27.0


^ permalink raw reply related	[flat|nested] 28+ messages in thread

* [PATCH 15/24] fs: add a kern_link helper
  2020-07-20 15:58 add file system helpers that take kernel pointers for the init code Christoph Hellwig
                   ` (13 preceding siblings ...)
  2020-07-20 15:58 ` [PATCH 14/24] fs: add a kern_mknod helper Christoph Hellwig
@ 2020-07-20 15:58 ` Christoph Hellwig
  2020-07-20 15:58 ` [PATCH 16/24] fs: add a kern_symlink helper Christoph Hellwig
                   ` (8 subsequent siblings)
  23 siblings, 0 replies; 28+ messages in thread
From: Christoph Hellwig @ 2020-07-20 15:58 UTC (permalink / raw)
  To: Al Viro, Linus Torvalds
  Cc: Greg Kroah-Hartman, Rafael J. Wysocki, linux-kernel, linux-raid,
	linux-fsdevel, linux-api

Add a simple helper perform a link with a kernel space file name and use
it in the early init code instead of relying on the implicit
set_fs(KERNEL_DS) there.  To do so push the getname from do_linkat into the
callers.  Remove the now unused ksys_link.

Signed-off-by: Christoph Hellwig <hch@lst.de>
---
 fs/internal.h            |  2 --
 fs/namei.c               | 39 +++++++++++++++++++++++++++++----------
 include/linux/fs.h       |  1 +
 include/linux/syscalls.h |  9 ---------
 init/initramfs.c         |  2 +-
 5 files changed, 31 insertions(+), 22 deletions(-)

diff --git a/fs/internal.h b/fs/internal.h
index 1e7a72bd183e63..f0869d5dc4dbfa 100644
--- a/fs/internal.h
+++ b/fs/internal.h
@@ -66,8 +66,6 @@ long do_rmdir(int dfd, const char __user *pathname);
 long do_unlinkat(int dfd, struct filename *name);
 long do_symlinkat(const char __user *oldname, int newdfd,
 		  const char __user *newname);
-int do_linkat(int olddfd, const char __user *oldname, int newdfd,
-	      const char __user *newname, int flags);
 
 /*
  * namespace.c
diff --git a/fs/namei.c b/fs/namei.c
index de97edac21849d..9d80a5bce1051a 100644
--- a/fs/namei.c
+++ b/fs/namei.c
@@ -4122,8 +4122,8 @@ 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, const char __user *oldname, int newdfd,
-	      const char __user *newname, int flags)
+static int do_linkat(int olddfd, struct filename *oldname, int newdfd,
+	      struct filename *newname, int flags)
 {
 	struct dentry *new_dentry;
 	struct path old_path, new_path;
@@ -4131,27 +4131,29 @@ int do_linkat(int olddfd, const char __user *oldname, int newdfd,
 	int how = 0;
 	int error;
 
+	error = -EINVAL;
 	if ((flags & ~(AT_SYMLINK_FOLLOW | AT_EMPTY_PATH)) != 0)
-		return -EINVAL;
+		goto out_put_both_names;
 	/*
 	 * 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) {
+		error = -ENOENT;
 		if (!capable(CAP_DAC_READ_SEARCH))
-			return -ENOENT;
+			goto out_put_both_names;
 		how = LOOKUP_EMPTY;
 	}
 
 	if (flags & AT_SYMLINK_FOLLOW)
 		how |= LOOKUP_FOLLOW;
 retry:
-	error = user_path_at(olddfd, oldname, how, &old_path);
+	error = filename_lookup(olddfd, oldname, how, &old_path, NULL);
 	if (error)
-		return error;
+		goto out_put_newname;
 
-	new_dentry = user_path_create(newdfd, newname, &new_path,
+	new_dentry = filename_create(newdfd, newname, &new_path,
 					(how & LOOKUP_REVAL));
 	error = PTR_ERR(new_dentry);
 	if (IS_ERR(new_dentry))
@@ -4181,21 +4183,38 @@ int do_linkat(int olddfd, const char __user *oldname, int newdfd,
 		how |= LOOKUP_REVAL;
 		goto retry;
 	}
+	putname(newname);
 out:
 	path_put(&old_path);
-
+	putname(oldname);
+	return error;
+out_put_both_names:
+	if (!IS_ERR(oldname))
+		putname(oldname);
+out_put_newname:
+	if (!IS_ERR(newname))
+		putname(newname);
 	return error;
 }
 
+int __init kern_link(const char *oldname, const char *newname)
+{
+	return do_linkat(AT_FDCWD, getname_kernel(oldname), AT_FDCWD,
+			 getname_kernel(newname), 0);
+}
+
 SYSCALL_DEFINE5(linkat, int, olddfd, const char __user *, oldname,
 		int, newdfd, const char __user *, newname, int, flags)
 {
-	return do_linkat(olddfd, oldname, newdfd, newname, flags);
+	int how = (flags & AT_EMPTY_PATH) ? LOOKUP_EMPTY : 0;
+
+	return do_linkat(olddfd, getname_flags(oldname, how, NULL), newdfd,
+			 getname(newname), flags);
 }
 
 SYSCALL_DEFINE2(link, const char __user *, oldname, const char __user *, newname)
 {
-	return do_linkat(AT_FDCWD, oldname, AT_FDCWD, newname, 0);
+	return do_linkat(AT_FDCWD, getname(oldname), AT_FDCWD, getname(newname), 0);
 }
 
 /**
diff --git a/include/linux/fs.h b/include/linux/fs.h
index 846a21a9b3e14c..fc3b09d473945f 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -3679,5 +3679,6 @@ int __init kern_chmod(const char *filename, umode_t mode);
 int __init kern_utimes(const char *filename, struct timespec64 *tv, int flags);
 int kern_mkdir(const char *pathname, umode_t mode);
 int kern_mknod(const char *filename, umode_t mode, unsigned int dev);
+int __init kern_link(const char *oldname, const char *newname);
 
 #endif /* _LINUX_FS_H */
diff --git a/include/linux/syscalls.h b/include/linux/syscalls.h
index 3dfcae351a077d..467cc4413874ed 100644
--- a/include/linux/syscalls.h
+++ b/include/linux/syscalls.h
@@ -1293,15 +1293,6 @@ static inline long ksys_symlink(const char __user *oldname,
 	return do_symlinkat(oldname, AT_FDCWD, newname);
 }
 
-extern int do_linkat(int olddfd, const char __user *oldname, int newdfd,
-		     const char __user *newname, int flags);
-
-static inline long ksys_link(const char __user *oldname,
-			     const char __user *newname)
-{
-	return do_linkat(AT_FDCWD, oldname, AT_FDCWD, newname, 0);
-}
-
 extern long do_sys_ftruncate(unsigned int fd, loff_t length, int small);
 
 static inline long ksys_ftruncate(unsigned int fd, loff_t length)
diff --git a/init/initramfs.c b/init/initramfs.c
index f32226d0388100..e484381c6c131b 100644
--- a/init/initramfs.c
+++ b/init/initramfs.c
@@ -310,7 +310,7 @@ static int __init maybe_link(void)
 		char *old = find_link(major, minor, ino, mode, collected);
 		if (old) {
 			clean_path(collected, 0);
-			return (ksys_link(old, collected) < 0) ? -1 : 1;
+			return (kern_link(old, collected) < 0) ? -1 : 1;
 		}
 	}
 	return 0;
-- 
2.27.0


^ permalink raw reply related	[flat|nested] 28+ messages in thread

* [PATCH 16/24] fs: add a kern_symlink helper
  2020-07-20 15:58 add file system helpers that take kernel pointers for the init code Christoph Hellwig
                   ` (14 preceding siblings ...)
  2020-07-20 15:58 ` [PATCH 15/24] fs: add a kern_link helper Christoph Hellwig
@ 2020-07-20 15:58 ` Christoph Hellwig
  2020-07-20 15:58 ` [PATCH 17/24] fs: add a kern_unlink helper Christoph Hellwig
                   ` (7 subsequent siblings)
  23 siblings, 0 replies; 28+ messages in thread
From: Christoph Hellwig @ 2020-07-20 15:58 UTC (permalink / raw)
  To: Al Viro, Linus Torvalds
  Cc: Greg Kroah-Hartman, Rafael J. Wysocki, linux-kernel, linux-raid,
	linux-fsdevel, linux-api

Add a simple helper perform a symlink with a kernel space file name and
use it in the early init code instead of relying on the implicit
set_fs(KERNEL_DS) there.  To do so push the getname from do_symlinkat
into the callers.  Remove the now unused ksys_symlink.

Signed-off-by: Christoph Hellwig <hch@lst.de>
---
 fs/internal.h            |  2 --
 fs/namei.c               | 27 ++++++++++++++++++---------
 include/linux/fs.h       |  1 +
 include/linux/syscalls.h |  9 ---------
 init/initramfs.c         |  2 +-
 5 files changed, 20 insertions(+), 21 deletions(-)

diff --git a/fs/internal.h b/fs/internal.h
index f0869d5dc4dbfa..46f727c0bd84e2 100644
--- a/fs/internal.h
+++ b/fs/internal.h
@@ -64,8 +64,6 @@ extern int vfs_path_lookup(struct dentry *, struct vfsmount *,
 			   const char *, unsigned int, struct path *);
 long do_rmdir(int dfd, const char __user *pathname);
 long do_unlinkat(int dfd, struct filename *name);
-long do_symlinkat(const char __user *oldname, int newdfd,
-		  const char __user *newname);
 
 /*
  * namespace.c
diff --git a/fs/namei.c b/fs/namei.c
index 9d80a5bce1051a..01e43676008644 100644
--- a/fs/namei.c
+++ b/fs/namei.c
@@ -3991,20 +3991,21 @@ int vfs_symlink(struct inode *dir, struct dentry *dentry, const char *oldname)
 }
 EXPORT_SYMBOL(vfs_symlink);
 
-long do_symlinkat(const char __user *oldname, int newdfd,
-		  const char __user *newname)
+static int do_symlinkat(struct filename *from, int newdfd,
+			struct filename *newname)
 {
 	int error;
-	struct filename *from;
 	struct dentry *dentry;
 	struct path path;
 	unsigned int lookup_flags = 0;
 
-	from = getname(oldname);
-	if (IS_ERR(from))
+	if (IS_ERR(from)) {
+		if (!IS_ERR(newname))
+			putname(newname);
 		return PTR_ERR(from);
+	}
 retry:
-	dentry = user_path_create(newdfd, newname, &path, lookup_flags);
+	dentry = filename_create(newdfd, newname, &path, lookup_flags);
 	error = PTR_ERR(dentry);
 	if (IS_ERR(dentry))
 		goto out_putname;
@@ -4017,20 +4018,28 @@ long do_symlinkat(const char __user *oldname, int newdfd,
 		lookup_flags |= LOOKUP_REVAL;
 		goto retry;
 	}
+	putname(newname);
 out_putname:
-	putname(from);
+	if (!IS_ERR(from))
+		putname(from);
 	return error;
 }
 
+int __init kern_symlink(const char *oldname, const char *newname)
+{
+	return do_symlinkat(getname_kernel(oldname), AT_FDCWD,
+			    getname_kernel(newname));
+}
+
 SYSCALL_DEFINE3(symlinkat, const char __user *, oldname,
 		int, newdfd, const char __user *, newname)
 {
-	return do_symlinkat(oldname, newdfd, newname);
+	return do_symlinkat(getname(oldname), newdfd, getname(newname));
 }
 
 SYSCALL_DEFINE2(symlink, const char __user *, oldname, const char __user *, newname)
 {
-	return do_symlinkat(oldname, AT_FDCWD, newname);
+	return do_symlinkat(getname(oldname), AT_FDCWD, getname(newname));
 }
 
 /**
diff --git a/include/linux/fs.h b/include/linux/fs.h
index fc3b09d473945f..7a7b3bf1b8aa53 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -3680,5 +3680,6 @@ int __init kern_utimes(const char *filename, struct timespec64 *tv, int flags);
 int kern_mkdir(const char *pathname, umode_t mode);
 int kern_mknod(const char *filename, umode_t mode, unsigned int dev);
 int __init kern_link(const char *oldname, const char *newname);
+int __init kern_symlink(const char *oldname, const char *newname);
 
 #endif /* _LINUX_FS_H */
diff --git a/include/linux/syscalls.h b/include/linux/syscalls.h
index 467cc4413874ed..474d5d165048c8 100644
--- a/include/linux/syscalls.h
+++ b/include/linux/syscalls.h
@@ -1284,15 +1284,6 @@ static inline long ksys_rmdir(const char __user *pathname)
 	return do_rmdir(AT_FDCWD, pathname);
 }
 
-extern long do_symlinkat(const char __user *oldname, int newdfd,
-			 const char __user *newname);
-
-static inline long ksys_symlink(const char __user *oldname,
-				const char __user *newname)
-{
-	return do_symlinkat(oldname, AT_FDCWD, newname);
-}
-
 extern long do_sys_ftruncate(unsigned int fd, loff_t length, int small);
 
 static inline long ksys_ftruncate(unsigned int fd, loff_t length)
diff --git a/init/initramfs.c b/init/initramfs.c
index e484381c6c131b..4efd78427996da 100644
--- a/init/initramfs.c
+++ b/init/initramfs.c
@@ -389,7 +389,7 @@ static int __init do_symlink(void)
 {
 	collected[N_ALIGN(name_len) + body_len] = '\0';
 	clean_path(collected, 0);
-	ksys_symlink(collected + N_ALIGN(name_len), collected);
+	kern_symlink(collected + N_ALIGN(name_len), collected);
 	kern_chown(collected, uid, gid, AT_SYMLINK_NOFOLLOW);
 	do_utime(collected, mtime);
 	state = SkipIt;
-- 
2.27.0


^ permalink raw reply related	[flat|nested] 28+ messages in thread

* [PATCH 17/24] fs: add a kern_unlink helper
  2020-07-20 15:58 add file system helpers that take kernel pointers for the init code Christoph Hellwig
                   ` (15 preceding siblings ...)
  2020-07-20 15:58 ` [PATCH 16/24] fs: add a kern_symlink helper Christoph Hellwig
@ 2020-07-20 15:58 ` Christoph Hellwig
  2020-07-20 15:58 ` [PATCH 18/24] fs: add a kern_rmdir helper Christoph Hellwig
                   ` (6 subsequent siblings)
  23 siblings, 0 replies; 28+ messages in thread
From: Christoph Hellwig @ 2020-07-20 15:58 UTC (permalink / raw)
  To: Al Viro, Linus Torvalds
  Cc: Greg Kroah-Hartman, Rafael J. Wysocki, linux-kernel, linux-raid,
	linux-fsdevel, linux-api

Add a simple helper to unlink with a kernel space file name and switch
the early init and coredump code over to it.  Remove the now unused
ksys_unlink.

Signed-off-by: Christoph Hellwig <hch@lst.de>
---
 fs/coredump.c            | 2 +-
 fs/internal.h            | 1 -
 fs/namei.c               | 7 ++++++-
 include/linux/fs.h       | 1 +
 include/linux/syscalls.h | 7 -------
 init/do_mounts.h         | 2 +-
 init/do_mounts_initrd.c  | 4 ++--
 init/do_mounts_rd.c      | 2 +-
 init/initramfs.c         | 2 +-
 9 files changed, 13 insertions(+), 15 deletions(-)

diff --git a/fs/coredump.c b/fs/coredump.c
index 7237f07ff6bed2..fc82170e78c71d 100644
--- a/fs/coredump.c
+++ b/fs/coredump.c
@@ -719,7 +719,7 @@ void do_coredump(const kernel_siginfo_t *siginfo)
 			 * If it doesn't exist, that's fine. If there's some
 			 * other problem, we'll catch it at the filp_open().
 			 */
-			do_unlinkat(AT_FDCWD, getname_kernel(cn.corename));
+			kern_unlink(cn.corename);
 		}
 
 		/*
diff --git a/fs/internal.h b/fs/internal.h
index 46f727c0bd84e2..62e17871f16316 100644
--- a/fs/internal.h
+++ b/fs/internal.h
@@ -63,7 +63,6 @@ extern int filename_lookup(int dfd, struct filename *name, unsigned flags,
 extern int vfs_path_lookup(struct dentry *, struct vfsmount *,
 			   const char *, unsigned int, struct path *);
 long do_rmdir(int dfd, const char __user *pathname);
-long do_unlinkat(int dfd, struct filename *name);
 
 /*
  * namespace.c
diff --git a/fs/namei.c b/fs/namei.c
index 01e43676008644..3cbaca386d3189 100644
--- a/fs/namei.c
+++ b/fs/namei.c
@@ -3883,7 +3883,7 @@ EXPORT_SYMBOL(vfs_unlink);
  * writeout happening, and we don't want to prevent access to the directory
  * while waiting on the I/O.
  */
-long do_unlinkat(int dfd, struct filename *name)
+static int do_unlinkat(int dfd, struct filename *name)
 {
 	int error;
 	struct dentry *dentry;
@@ -3954,6 +3954,11 @@ long do_unlinkat(int dfd, struct filename *name)
 	goto exit2;
 }
 
+int kern_unlink(const char *pathname)
+{
+	return do_unlinkat(AT_FDCWD, getname_kernel(pathname));
+}
+
 SYSCALL_DEFINE3(unlinkat, int, dfd, const char __user *, pathname, int, flag)
 {
 	if ((flag & ~AT_REMOVEDIR) != 0)
diff --git a/include/linux/fs.h b/include/linux/fs.h
index 7a7b3bf1b8aa53..306e58ff54f69f 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -3681,5 +3681,6 @@ int kern_mkdir(const char *pathname, umode_t mode);
 int kern_mknod(const char *filename, umode_t mode, unsigned int dev);
 int __init kern_link(const char *oldname, const char *newname);
 int __init kern_symlink(const char *oldname, const char *newname);
+int kern_unlink(const char *pathname);
 
 #endif /* _LINUX_FS_H */
diff --git a/include/linux/syscalls.h b/include/linux/syscalls.h
index 474d5d165048c8..483431765ac823 100644
--- a/include/linux/syscalls.h
+++ b/include/linux/syscalls.h
@@ -1270,13 +1270,6 @@ int compat_ksys_ipc(u32 call, int first, int second,
  * The following kernel syscall equivalents are just wrappers to fs-internal
  * functions. Therefore, provide stubs to be inlined at the callsites.
  */
-extern long do_unlinkat(int dfd, struct filename *name);
-
-static inline long ksys_unlink(const char __user *pathname)
-{
-	return do_unlinkat(AT_FDCWD, getname(pathname));
-}
-
 extern long do_rmdir(int dfd, const char __user *pathname);
 
 static inline long ksys_rmdir(const char __user *pathname)
diff --git a/init/do_mounts.h b/init/do_mounts.h
index b9ec1d522f0ce1..0b3c72ee6670b2 100644
--- a/init/do_mounts.h
+++ b/init/do_mounts.h
@@ -15,7 +15,7 @@ extern int root_mountflags;
 
 static inline int create_dev(char *name, dev_t dev)
 {
-	ksys_unlink(name);
+	kern_unlink(name);
 	return kern_mknod(name, S_IFBLK|0600, new_encode_dev(dev));
 }
 
diff --git a/init/do_mounts_initrd.c b/init/do_mounts_initrd.c
index b9a749ebe85c2d..1b74a0a5c38f8b 100644
--- a/init/do_mounts_initrd.c
+++ b/init/do_mounts_initrd.c
@@ -137,11 +137,11 @@ bool __init initrd_load(void)
 		 * mounted in the normal path.
 		 */
 		if (rd_load_image("/initrd.image") && ROOT_DEV != Root_RAM0) {
-			ksys_unlink("/initrd.image");
+			kern_unlink("/initrd.image");
 			handle_initrd();
 			return true;
 		}
 	}
-	ksys_unlink("/initrd.image");
+	kern_unlink("/initrd.image");
 	return false;
 }
diff --git a/init/do_mounts_rd.c b/init/do_mounts_rd.c
index 7b64390c075043..1737f1d2ee9fd7 100644
--- a/init/do_mounts_rd.c
+++ b/init/do_mounts_rd.c
@@ -271,7 +271,7 @@ int __init rd_load_image(char *from)
 	fput(out_file);
 out:
 	kfree(buf);
-	ksys_unlink("/dev/ram");
+	kern_unlink("/dev/ram");
 	return res;
 }
 
diff --git a/init/initramfs.c b/init/initramfs.c
index 4efd78427996da..86d3750a47499d 100644
--- a/init/initramfs.c
+++ b/init/initramfs.c
@@ -300,7 +300,7 @@ static void __init clean_path(char *path, umode_t fmode)
 		if (S_ISDIR(st.mode))
 			ksys_rmdir(path);
 		else
-			ksys_unlink(path);
+			kern_unlink(path);
 	}
 }
 
-- 
2.27.0


^ permalink raw reply related	[flat|nested] 28+ messages in thread

* [PATCH 18/24] fs: add a kern_rmdir helper
  2020-07-20 15:58 add file system helpers that take kernel pointers for the init code Christoph Hellwig
                   ` (16 preceding siblings ...)
  2020-07-20 15:58 ` [PATCH 17/24] fs: add a kern_unlink helper Christoph Hellwig
@ 2020-07-20 15:58 ` Christoph Hellwig
  2020-07-20 15:58 ` [PATCH 19/24] fs: remove vfs_statx_fd Christoph Hellwig
                   ` (5 subsequent siblings)
  23 siblings, 0 replies; 28+ messages in thread
From: Christoph Hellwig @ 2020-07-20 15:58 UTC (permalink / raw)
  To: Al Viro, Linus Torvalds
  Cc: Greg Kroah-Hartman, Rafael J. Wysocki, linux-kernel, linux-raid,
	linux-fsdevel, linux-api

Add a simple helper to rmdir with a kernel space file name and switch
the early init code over to it.  Remove the now unused ksys_rmdir.

Signed-off-by: Christoph Hellwig <hch@lst.de>
---
 fs/internal.h            |  1 -
 fs/namei.c               | 17 ++++++++++-------
 include/linux/fs.h       |  1 +
 include/linux/syscalls.h |  7 -------
 init/initramfs.c         |  2 +-
 5 files changed, 12 insertions(+), 16 deletions(-)

diff --git a/fs/internal.h b/fs/internal.h
index 62e17871f16316..11b5b99c8dc689 100644
--- a/fs/internal.h
+++ b/fs/internal.h
@@ -62,7 +62,6 @@ extern int filename_lookup(int dfd, struct filename *name, unsigned flags,
 			   struct path *path, struct path *root);
 extern int vfs_path_lookup(struct dentry *, struct vfsmount *,
 			   const char *, unsigned int, struct path *);
-long do_rmdir(int dfd, const char __user *pathname);
 
 /*
  * namespace.c
diff --git a/fs/namei.c b/fs/namei.c
index 3cbaca386d3189..3de1476885a18a 100644
--- a/fs/namei.c
+++ b/fs/namei.c
@@ -3754,18 +3754,16 @@ int vfs_rmdir(struct inode *dir, struct dentry *dentry)
 }
 EXPORT_SYMBOL(vfs_rmdir);
 
-long do_rmdir(int dfd, const char __user *pathname)
+static int do_rmdir(int dfd, struct filename *name)
 {
 	int error = 0;
-	struct filename *name;
 	struct dentry *dentry;
 	struct path path;
 	struct qstr last;
 	int type;
 	unsigned int lookup_flags = 0;
 retry:
-	name = filename_parentat(dfd, getname(pathname), lookup_flags,
-				&path, &last, &type);
+	name = filename_parentat(dfd, name, lookup_flags, &path, &last, &type);
 	if (IS_ERR(name))
 		return PTR_ERR(name);
 
@@ -3805,17 +3803,22 @@ long do_rmdir(int dfd, const char __user *pathname)
 	mnt_drop_write(path.mnt);
 exit1:
 	path_put(&path);
-	putname(name);
 	if (retry_estale(error, lookup_flags)) {
 		lookup_flags |= LOOKUP_REVAL;
 		goto retry;
 	}
+	putname(name);
 	return error;
 }
 
+int __init kern_rmdir(const char *pathname)
+{
+	return do_rmdir(AT_FDCWD, getname_kernel(pathname));
+}
+
 SYSCALL_DEFINE1(rmdir, const char __user *, pathname)
 {
-	return do_rmdir(AT_FDCWD, pathname);
+	return do_rmdir(AT_FDCWD, getname(pathname));
 }
 
 /**
@@ -3965,7 +3968,7 @@ SYSCALL_DEFINE3(unlinkat, int, dfd, const char __user *, pathname, int, flag)
 		return -EINVAL;
 
 	if (flag & AT_REMOVEDIR)
-		return do_rmdir(dfd, pathname);
+		return do_rmdir(dfd, getname(pathname));
 
 	return do_unlinkat(dfd, getname(pathname));
 }
diff --git a/include/linux/fs.h b/include/linux/fs.h
index 306e58ff54f69f..6100b9f92cee8b 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -3682,5 +3682,6 @@ int kern_mknod(const char *filename, umode_t mode, unsigned int dev);
 int __init kern_link(const char *oldname, const char *newname);
 int __init kern_symlink(const char *oldname, const char *newname);
 int kern_unlink(const char *pathname);
+int __init kern_rmdir(const char *pathname);
 
 #endif /* _LINUX_FS_H */
diff --git a/include/linux/syscalls.h b/include/linux/syscalls.h
index 483431765ac823..56c1fb4fadd666 100644
--- a/include/linux/syscalls.h
+++ b/include/linux/syscalls.h
@@ -1270,13 +1270,6 @@ int compat_ksys_ipc(u32 call, int first, int second,
  * The following kernel syscall equivalents are just wrappers to fs-internal
  * functions. Therefore, provide stubs to be inlined at the callsites.
  */
-extern long do_rmdir(int dfd, const char __user *pathname);
-
-static inline long ksys_rmdir(const char __user *pathname)
-{
-	return do_rmdir(AT_FDCWD, pathname);
-}
-
 extern long do_sys_ftruncate(unsigned int fd, loff_t length, int small);
 
 static inline long ksys_ftruncate(unsigned int fd, loff_t length)
diff --git a/init/initramfs.c b/init/initramfs.c
index 86d3750a47499d..d72594298133a7 100644
--- a/init/initramfs.c
+++ b/init/initramfs.c
@@ -298,7 +298,7 @@ static void __init clean_path(char *path, umode_t fmode)
 
 	if (!vfs_lstat(path, &st) && (st.mode ^ fmode) & S_IFMT) {
 		if (S_ISDIR(st.mode))
-			ksys_rmdir(path);
+			kern_rmdir(path);
 		else
 			kern_unlink(path);
 	}
-- 
2.27.0


^ permalink raw reply related	[flat|nested] 28+ messages in thread

* [PATCH 19/24] fs: remove vfs_statx_fd
  2020-07-20 15:58 add file system helpers that take kernel pointers for the init code Christoph Hellwig
                   ` (17 preceding siblings ...)
  2020-07-20 15:58 ` [PATCH 18/24] fs: add a kern_rmdir helper Christoph Hellwig
@ 2020-07-20 15:58 ` Christoph Hellwig
  2020-07-20 15:58 ` [PATCH 20/24] fs: implement vfs_stat and vfs_lstat in terms of vfs_fstatat Christoph Hellwig
                   ` (4 subsequent siblings)
  23 siblings, 0 replies; 28+ messages in thread
From: Christoph Hellwig @ 2020-07-20 15:58 UTC (permalink / raw)
  To: Al Viro, Linus Torvalds
  Cc: Greg Kroah-Hartman, Rafael J. Wysocki, linux-kernel, linux-raid,
	linux-fsdevel, linux-api

vfs_statx_fd is only used to implement vfs_fstat.  Remove vfs_statx_fd
and just implement vfs_fstat directly.

Signed-off-by: Christoph Hellwig <hch@lst.de>
---
 fs/stat.c          | 22 +++++++---------------
 include/linux/fs.h |  7 +------
 2 files changed, 8 insertions(+), 21 deletions(-)

diff --git a/fs/stat.c b/fs/stat.c
index 44f8ad346db4ca..2683a051ce07fa 100644
--- a/fs/stat.c
+++ b/fs/stat.c
@@ -126,35 +126,27 @@ int vfs_getattr(const struct path *path, struct kstat *stat,
 EXPORT_SYMBOL(vfs_getattr);
 
 /**
- * vfs_statx_fd - Get the enhanced basic attributes by file descriptor
+ * vfs_fstat - Get the basic attributes by file descriptor
  * @fd: The file descriptor referring to the file of interest
  * @stat: The result structure to fill in.
- * @request_mask: STATX_xxx flags indicating what the caller wants
- * @query_flags: Query mode (KSTAT_QUERY_FLAGS)
  *
  * This function is a wrapper around vfs_getattr().  The main difference is
  * that it uses a file descriptor to determine the file location.
  *
  * 0 will be returned on success, and a -ve error code if unsuccessful.
  */
-int vfs_statx_fd(unsigned int fd, struct kstat *stat,
-		 u32 request_mask, unsigned int query_flags)
+int vfs_fstat(int fd, struct kstat *stat)
 {
 	struct fd f;
-	int error = -EBADF;
-
-	if (query_flags & ~KSTAT_QUERY_FLAGS)
-		return -EINVAL;
+	int error;
 
 	f = fdget_raw(fd);
-	if (f.file) {
-		error = vfs_getattr(&f.file->f_path, stat,
-				    request_mask, query_flags);
-		fdput(f);
-	}
+	if (!f.file)
+		return -EBADF;
+	error = vfs_getattr(&f.file->f_path, stat, STATX_BASIC_STATS, 0);
+	fdput(f);
 	return error;
 }
-EXPORT_SYMBOL(vfs_statx_fd);
 
 static inline unsigned vfs_stat_set_lookup_flags(unsigned *lookup_flags,
 						 int flags)
diff --git a/include/linux/fs.h b/include/linux/fs.h
index 6100b9f92cee8b..0169d3efa844d0 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -3297,7 +3297,7 @@ extern const struct inode_operations simple_symlink_inode_operations;
 extern int iterate_dir(struct file *, struct dir_context *);
 
 extern int vfs_statx(int, const char __user *, int, struct kstat *, u32);
-extern int vfs_statx_fd(unsigned int, struct kstat *, u32, unsigned int);
+int vfs_fstat(int fd, struct kstat *stat);
 
 static inline int vfs_stat(const char __user *filename, struct kstat *stat)
 {
@@ -3315,11 +3315,6 @@ static inline int vfs_fstatat(int dfd, const char __user *filename,
 	return vfs_statx(dfd, filename, flags | AT_NO_AUTOMOUNT,
 			 stat, STATX_BASIC_STATS);
 }
-static inline int vfs_fstat(int fd, struct kstat *stat)
-{
-	return vfs_statx_fd(fd, stat, STATX_BASIC_STATS, 0);
-}
-
 
 extern const char *vfs_get_link(struct dentry *, struct delayed_call *);
 extern int vfs_readlink(struct dentry *, char __user *, int);
-- 
2.27.0


^ permalink raw reply related	[flat|nested] 28+ messages in thread

* [PATCH 20/24] fs: implement vfs_stat and vfs_lstat in terms of vfs_fstatat
  2020-07-20 15:58 add file system helpers that take kernel pointers for the init code Christoph Hellwig
                   ` (18 preceding siblings ...)
  2020-07-20 15:58 ` [PATCH 19/24] fs: remove vfs_statx_fd Christoph Hellwig
@ 2020-07-20 15:58 ` Christoph Hellwig
  2020-07-20 15:58 ` [PATCH 21/24] fs: move vfs_fstatat out of line Christoph Hellwig
                   ` (3 subsequent siblings)
  23 siblings, 0 replies; 28+ messages in thread
From: Christoph Hellwig @ 2020-07-20 15:58 UTC (permalink / raw)
  To: Al Viro, Linus Torvalds
  Cc: Greg Kroah-Hartman, Rafael J. Wysocki, linux-kernel, linux-raid,
	linux-fsdevel, linux-api

Go through vfs_fstatat instead of duplicating the *stat to statx mapping
three times.

Signed-off-by: Christoph Hellwig <hch@lst.de>
---
 include/linux/fs.h | 16 +++++++---------
 1 file changed, 7 insertions(+), 9 deletions(-)

diff --git a/include/linux/fs.h b/include/linux/fs.h
index 0169d3efa844d0..4d9d33c62fa2e5 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -3299,21 +3299,19 @@ extern int iterate_dir(struct file *, struct dir_context *);
 extern int vfs_statx(int, const char __user *, int, struct kstat *, u32);
 int vfs_fstat(int fd, struct kstat *stat);
 
-static inline int vfs_stat(const char __user *filename, struct kstat *stat)
+static inline int vfs_fstatat(int dfd, const char __user *filename,
+			      struct kstat *stat, int flags)
 {
-	return vfs_statx(AT_FDCWD, filename, AT_NO_AUTOMOUNT,
+	return vfs_statx(dfd, filename, flags | AT_NO_AUTOMOUNT,
 			 stat, STATX_BASIC_STATS);
 }
-static inline int vfs_lstat(const char __user *name, struct kstat *stat)
+static inline int vfs_stat(const char __user *filename, struct kstat *stat)
 {
-	return vfs_statx(AT_FDCWD, name, AT_SYMLINK_NOFOLLOW | AT_NO_AUTOMOUNT,
-			 stat, STATX_BASIC_STATS);
+	return vfs_fstatat(AT_FDCWD, filename, stat, 0);
 }
-static inline int vfs_fstatat(int dfd, const char __user *filename,
-			      struct kstat *stat, int flags)
+static inline int vfs_lstat(const char __user *name, struct kstat *stat)
 {
-	return vfs_statx(dfd, filename, flags | AT_NO_AUTOMOUNT,
-			 stat, STATX_BASIC_STATS);
+	return vfs_fstatat(AT_FDCWD, name, stat, AT_SYMLINK_NOFOLLOW);
 }
 
 extern const char *vfs_get_link(struct dentry *, struct delayed_call *);
-- 
2.27.0


^ permalink raw reply related	[flat|nested] 28+ messages in thread

* [PATCH 21/24] fs: move vfs_fstatat out of line
  2020-07-20 15:58 add file system helpers that take kernel pointers for the init code Christoph Hellwig
                   ` (19 preceding siblings ...)
  2020-07-20 15:58 ` [PATCH 20/24] fs: implement vfs_stat and vfs_lstat in terms of vfs_fstatat Christoph Hellwig
@ 2020-07-20 15:58 ` Christoph Hellwig
  2020-07-20 15:59 ` [PATCH 22/24] fs: remove vfs_stat_set_lookup_flags Christoph Hellwig
                   ` (2 subsequent siblings)
  23 siblings, 0 replies; 28+ messages in thread
From: Christoph Hellwig @ 2020-07-20 15:58 UTC (permalink / raw)
  To: Al Viro, Linus Torvalds
  Cc: Greg Kroah-Hartman, Rafael J. Wysocki, linux-kernel, linux-raid,
	linux-fsdevel, linux-api

This allows to keep vfs_statx static in fs/stat.c to prepare for the following
changes.

Signed-off-by: Christoph Hellwig <hch@lst.de>
---
 fs/stat.c          | 9 +++++++--
 include/linux/fs.h | 9 ++-------
 2 files changed, 9 insertions(+), 9 deletions(-)

diff --git a/fs/stat.c b/fs/stat.c
index 2683a051ce07fa..ddf0176d4dbcd7 100644
--- a/fs/stat.c
+++ b/fs/stat.c
@@ -181,7 +181,7 @@ static inline unsigned vfs_stat_set_lookup_flags(unsigned *lookup_flags,
  *
  * 0 will be returned on success, and a -ve error code if unsuccessful.
  */
-int vfs_statx(int dfd, const char __user *filename, int flags,
+static int vfs_statx(int dfd, const char __user *filename, int flags,
 	      struct kstat *stat, u32 request_mask)
 {
 	struct path path;
@@ -209,8 +209,13 @@ int vfs_statx(int dfd, const char __user *filename, int flags,
 out:
 	return error;
 }
-EXPORT_SYMBOL(vfs_statx);
 
+int vfs_fstatat(int dfd, const char __user *filename,
+			      struct kstat *stat, int flags)
+{
+	return vfs_statx(dfd, filename, flags | AT_NO_AUTOMOUNT,
+			 stat, STATX_BASIC_STATS);
+}
 
 #ifdef __ARCH_WANT_OLD_STAT
 
diff --git a/include/linux/fs.h b/include/linux/fs.h
index 4d9d33c62fa2e5..0e0cd6a988bb38 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -3296,15 +3296,10 @@ extern const struct inode_operations simple_symlink_inode_operations;
 
 extern int iterate_dir(struct file *, struct dir_context *);
 
-extern int vfs_statx(int, const char __user *, int, struct kstat *, u32);
+int vfs_fstatat(int dfd, const char __user *filename, struct kstat *stat,
+		int flags);
 int vfs_fstat(int fd, struct kstat *stat);
 
-static inline int vfs_fstatat(int dfd, const char __user *filename,
-			      struct kstat *stat, int flags)
-{
-	return vfs_statx(dfd, filename, flags | AT_NO_AUTOMOUNT,
-			 stat, STATX_BASIC_STATS);
-}
 static inline int vfs_stat(const char __user *filename, struct kstat *stat)
 {
 	return vfs_fstatat(AT_FDCWD, filename, stat, 0);
-- 
2.27.0


^ permalink raw reply related	[flat|nested] 28+ messages in thread

* [PATCH 22/24] fs: remove vfs_stat_set_lookup_flags
  2020-07-20 15:58 add file system helpers that take kernel pointers for the init code Christoph Hellwig
                   ` (20 preceding siblings ...)
  2020-07-20 15:58 ` [PATCH 21/24] fs: move vfs_fstatat out of line Christoph Hellwig
@ 2020-07-20 15:59 ` Christoph Hellwig
  2020-07-20 15:59 ` [PATCH 23/24] fs: remove KSTAT_QUERY_FLAGS Christoph Hellwig
  2020-07-20 15:59 ` [PATCH 24/24] fs: add a kern_stat helper Christoph Hellwig
  23 siblings, 0 replies; 28+ messages in thread
From: Christoph Hellwig @ 2020-07-20 15:59 UTC (permalink / raw)
  To: Al Viro, Linus Torvalds
  Cc: Greg Kroah-Hartman, Rafael J. Wysocki, linux-kernel, linux-raid,
	linux-fsdevel, linux-api

The function really obsfucates checking for valid flags and setting the
lookup flags.  The fact that it returns -EINVAL through and unsigned
return value, which is then used as boolean really doesn't help either.

Signed-off-by: Christoph Hellwig <hch@lst.de>
---
 fs/stat.c | 33 ++++++++++++---------------------
 1 file changed, 12 insertions(+), 21 deletions(-)

diff --git a/fs/stat.c b/fs/stat.c
index ddf0176d4dbcd7..8acc4b14ac24c9 100644
--- a/fs/stat.c
+++ b/fs/stat.c
@@ -148,24 +148,6 @@ int vfs_fstat(int fd, struct kstat *stat)
 	return error;
 }
 
-static inline unsigned vfs_stat_set_lookup_flags(unsigned *lookup_flags,
-						 int flags)
-{
-	if ((flags & ~(AT_SYMLINK_NOFOLLOW | AT_NO_AUTOMOUNT |
-		       AT_EMPTY_PATH | KSTAT_QUERY_FLAGS)) != 0)
-		return -EINVAL;
-
-	*lookup_flags = LOOKUP_FOLLOW | LOOKUP_AUTOMOUNT;
-	if (flags & AT_SYMLINK_NOFOLLOW)
-		*lookup_flags &= ~LOOKUP_FOLLOW;
-	if (flags & AT_NO_AUTOMOUNT)
-		*lookup_flags &= ~LOOKUP_AUTOMOUNT;
-	if (flags & AT_EMPTY_PATH)
-		*lookup_flags |= LOOKUP_EMPTY;
-
-	return 0;
-}
-
 /**
  * vfs_statx - Get basic and extra attributes by filename
  * @dfd: A file descriptor representing the base dir for a relative filename
@@ -185,11 +167,20 @@ static int vfs_statx(int dfd, const char __user *filename, int flags,
 	      struct kstat *stat, u32 request_mask)
 {
 	struct path path;
-	int error = -EINVAL;
-	unsigned lookup_flags;
+	unsigned lookup_flags = 0;
+	int error;
 
-	if (vfs_stat_set_lookup_flags(&lookup_flags, flags))
+	if (flags & ~(AT_SYMLINK_NOFOLLOW | AT_NO_AUTOMOUNT | AT_EMPTY_PATH |
+		      KSTAT_QUERY_FLAGS))
 		return -EINVAL;
+
+	if (!(flags & AT_SYMLINK_NOFOLLOW))
+		lookup_flags |= LOOKUP_FOLLOW;
+	if (!(flags & AT_NO_AUTOMOUNT))
+		lookup_flags |= LOOKUP_AUTOMOUNT;
+	if (flags & AT_EMPTY_PATH)
+		lookup_flags |= LOOKUP_EMPTY;
+
 retry:
 	error = user_path_at(dfd, filename, lookup_flags, &path);
 	if (error)
-- 
2.27.0


^ permalink raw reply related	[flat|nested] 28+ messages in thread

* [PATCH 23/24] fs: remove KSTAT_QUERY_FLAGS
  2020-07-20 15:58 add file system helpers that take kernel pointers for the init code Christoph Hellwig
                   ` (21 preceding siblings ...)
  2020-07-20 15:59 ` [PATCH 22/24] fs: remove vfs_stat_set_lookup_flags Christoph Hellwig
@ 2020-07-20 15:59 ` Christoph Hellwig
  2020-07-20 15:59 ` [PATCH 24/24] fs: add a kern_stat helper Christoph Hellwig
  23 siblings, 0 replies; 28+ messages in thread
From: Christoph Hellwig @ 2020-07-20 15:59 UTC (permalink / raw)
  To: Al Viro, Linus Torvalds
  Cc: Greg Kroah-Hartman, Rafael J. Wysocki, linux-kernel, linux-raid,
	linux-fsdevel, linux-api

KSTAT_QUERY_FLAGS expands to AT_STATX_SYNC_TYPE, which itself already
is a mask.  Remove the double name, especially given that the prefix
is a little confusing vs the normal AT_* flags.

Signed-off-by: Christoph Hellwig <hch@lst.de>
---
 fs/stat.c | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/fs/stat.c b/fs/stat.c
index 8acc4b14ac24c9..dacecdda2e7967 100644
--- a/fs/stat.c
+++ b/fs/stat.c
@@ -56,7 +56,7 @@ EXPORT_SYMBOL(generic_fillattr);
  * @path: file to get attributes from
  * @stat: structure to return attributes in
  * @request_mask: STATX_xxx flags indicating what the caller wants
- * @query_flags: Query mode (KSTAT_QUERY_FLAGS)
+ * @query_flags: Query mode (AT_STATX_SYNC_TYPE)
  *
  * Get attributes without calling security_inode_getattr.
  *
@@ -71,7 +71,7 @@ int vfs_getattr_nosec(const struct path *path, struct kstat *stat,
 
 	memset(stat, 0, sizeof(*stat));
 	stat->result_mask |= STATX_BASIC_STATS;
-	query_flags &= KSTAT_QUERY_FLAGS;
+	query_flags &= AT_STATX_SYNC_TYPE;
 
 	/* allow the fs to override these if it really wants to */
 	/* SB_NOATIME means filesystem supplies dummy atime value */
@@ -97,7 +97,7 @@ EXPORT_SYMBOL(vfs_getattr_nosec);
  * @path: The file of interest
  * @stat: Where to return the statistics
  * @request_mask: STATX_xxx flags indicating what the caller wants
- * @query_flags: Query mode (KSTAT_QUERY_FLAGS)
+ * @query_flags: Query mode (AT_STATX_SYNC_TYPE)
  *
  * Ask the filesystem for a file's attributes.  The caller must indicate in
  * request_mask and query_flags to indicate what they want.
@@ -171,7 +171,7 @@ static int vfs_statx(int dfd, const char __user *filename, int flags,
 	int error;
 
 	if (flags & ~(AT_SYMLINK_NOFOLLOW | AT_NO_AUTOMOUNT | AT_EMPTY_PATH |
-		      KSTAT_QUERY_FLAGS))
+		      AT_STATX_SYNC_TYPE))
 		return -EINVAL;
 
 	if (!(flags & AT_SYMLINK_NOFOLLOW))
-- 
2.27.0


^ permalink raw reply related	[flat|nested] 28+ messages in thread

* [PATCH 24/24] fs: add a kern_stat helper
  2020-07-20 15:58 add file system helpers that take kernel pointers for the init code Christoph Hellwig
                   ` (22 preceding siblings ...)
  2020-07-20 15:59 ` [PATCH 23/24] fs: remove KSTAT_QUERY_FLAGS Christoph Hellwig
@ 2020-07-20 15:59 ` Christoph Hellwig
  23 siblings, 0 replies; 28+ messages in thread
From: Christoph Hellwig @ 2020-07-20 15:59 UTC (permalink / raw)
  To: Al Viro, Linus Torvalds
  Cc: Greg Kroah-Hartman, Rafael J. Wysocki, linux-kernel, linux-raid,
	linux-fsdevel, linux-api

Add a simple helper to stat/lstat with a kernel space file name and
switch the early init code over to it.

Signed-off-by: Christoph Hellwig <hch@lst.de>
---
 drivers/md/md-autodetect.c |  2 +-
 fs/stat.c                  | 32 ++++++++++++++++++++++----------
 include/linux/fs.h         |  1 +
 init/initramfs.c           |  3 ++-
 4 files changed, 26 insertions(+), 12 deletions(-)

diff --git a/drivers/md/md-autodetect.c b/drivers/md/md-autodetect.c
index 14b6e86814c061..5bd52ec05ed821 100644
--- a/drivers/md/md-autodetect.c
+++ b/drivers/md/md-autodetect.c
@@ -151,7 +151,7 @@ static void __init md_setup_drive(struct md_setup_args *args)
 		if (strncmp(devname, "/dev/", 5) == 0)
 			devname += 5;
 		snprintf(comp_name, 63, "/dev/%s", devname);
-		if (vfs_stat(comp_name, &stat) == 0 && S_ISBLK(stat.mode))
+		if (kern_stat(comp_name, &stat, 0) == 0 && S_ISBLK(stat.mode))
 			dev = new_decode_dev(stat.rdev);
 		if (!dev) {
 			pr_warn("md: Unknown device name: %s\n", devname);
diff --git a/fs/stat.c b/fs/stat.c
index dacecdda2e7967..3c976b92db00ca 100644
--- a/fs/stat.c
+++ b/fs/stat.c
@@ -151,7 +151,7 @@ int vfs_fstat(int fd, struct kstat *stat)
 /**
  * vfs_statx - Get basic and extra attributes by filename
  * @dfd: A file descriptor representing the base dir for a relative filename
- * @filename: The name of the file of interest
+ * @name: The name of the file of interest
  * @flags: Flags to control the query
  * @stat: The result structure to fill in.
  * @request_mask: STATX_xxx flags indicating what the caller wants
@@ -163,16 +163,16 @@ int vfs_fstat(int fd, struct kstat *stat)
  *
  * 0 will be returned on success, and a -ve error code if unsuccessful.
  */
-static int vfs_statx(int dfd, const char __user *filename, int flags,
+static int vfs_statx(int dfd, struct filename *name, int flags,
 	      struct kstat *stat, u32 request_mask)
 {
 	struct path path;
 	unsigned lookup_flags = 0;
-	int error;
+	int error = -EINVAL;
 
 	if (flags & ~(AT_SYMLINK_NOFOLLOW | AT_NO_AUTOMOUNT | AT_EMPTY_PATH |
 		      AT_STATX_SYNC_TYPE))
-		return -EINVAL;
+		goto out_putname;
 
 	if (!(flags & AT_SYMLINK_NOFOLLOW))
 		lookup_flags |= LOOKUP_FOLLOW;
@@ -182,9 +182,9 @@ static int vfs_statx(int dfd, const char __user *filename, int flags,
 		lookup_flags |= LOOKUP_EMPTY;
 
 retry:
-	error = user_path_at(dfd, filename, lookup_flags, &path);
+	error = filename_lookup(dfd, name, lookup_flags, &path, NULL);
 	if (error)
-		goto out;
+		return error;
 
 	error = vfs_getattr(&path, stat, request_mask, flags);
 	stat->mnt_id = real_mount(path.mnt)->mnt_id;
@@ -197,15 +197,25 @@ static int vfs_statx(int dfd, const char __user *filename, int flags,
 		lookup_flags |= LOOKUP_REVAL;
 		goto retry;
 	}
-out:
+out_putname:
+	if (!IS_ERR(name))
+		putname(name);
 	return error;
 }
 
+int __init kern_stat(const char *filename, struct kstat *stat, int flags)
+{
+	return vfs_statx(AT_FDCWD, getname_kernel(filename),
+			 flags | AT_NO_AUTOMOUNT, stat, STATX_BASIC_STATS);
+}
+
 int vfs_fstatat(int dfd, const char __user *filename,
 			      struct kstat *stat, int flags)
 {
-	return vfs_statx(dfd, filename, flags | AT_NO_AUTOMOUNT,
-			 stat, STATX_BASIC_STATS);
+	int lookup_flags = (flags & AT_EMPTY_PATH) ? LOOKUP_EMPTY : 0;
+
+	return vfs_statx(dfd, getname_flags(filename, lookup_flags, NULL),
+			 flags | AT_NO_AUTOMOUNT, stat, STATX_BASIC_STATS);
 }
 
 #ifdef __ARCH_WANT_OLD_STAT
@@ -569,6 +579,7 @@ cp_statx(const struct kstat *stat, struct statx __user *buffer)
 int do_statx(int dfd, const char __user *filename, unsigned flags,
 	     unsigned int mask, struct statx __user *buffer)
 {
+	int lookup_flags = (flags & AT_EMPTY_PATH) ? LOOKUP_EMPTY : 0;
 	struct kstat stat;
 	int error;
 
@@ -577,7 +588,8 @@ int do_statx(int dfd, const char __user *filename, unsigned flags,
 	if ((flags & AT_STATX_SYNC_TYPE) == AT_STATX_SYNC_TYPE)
 		return -EINVAL;
 
-	error = vfs_statx(dfd, filename, flags, &stat, mask);
+	error = vfs_statx(dfd, getname_flags(filename, lookup_flags, NULL),
+			  flags, &stat, mask);
 	if (error)
 		return error;
 
diff --git a/include/linux/fs.h b/include/linux/fs.h
index 0e0cd6a988bb38..d1f8edb39cf969 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -3671,5 +3671,6 @@ int __init kern_link(const char *oldname, const char *newname);
 int __init kern_symlink(const char *oldname, const char *newname);
 int kern_unlink(const char *pathname);
 int __init kern_rmdir(const char *pathname);
+int __init kern_stat(const char *filename, struct kstat *stat, int flags);
 
 #endif /* _LINUX_FS_H */
diff --git a/init/initramfs.c b/init/initramfs.c
index d72594298133a7..6c605f23900fa1 100644
--- a/init/initramfs.c
+++ b/init/initramfs.c
@@ -296,7 +296,8 @@ static void __init clean_path(char *path, umode_t fmode)
 {
 	struct kstat st;
 
-	if (!vfs_lstat(path, &st) && (st.mode ^ fmode) & S_IFMT) {
+	if (kern_stat(path, &st, AT_SYMLINK_NOFOLLOW) &&
+	    (st.mode ^ fmode) & S_IFMT) {
 		if (S_ISDIR(st.mode))
 			kern_rmdir(path);
 		else
-- 
2.27.0


^ permalink raw reply related	[flat|nested] 28+ messages in thread

* Re: [PATCH 04/24] fs: move the putname from filename_create to the callers
  2020-07-20 15:58 ` [PATCH 04/24] fs: move the putname from filename_create to the callers Christoph Hellwig
@ 2020-07-20 18:05   ` Linus Torvalds
  0 siblings, 0 replies; 28+ messages in thread
From: Linus Torvalds @ 2020-07-20 18:05 UTC (permalink / raw)
  To: Christoph Hellwig
  Cc: Al Viro, Greg Kroah-Hartman, Rafael J. Wysocki,
	Linux Kernel Mailing List, linux-raid, linux-fsdevel, Linux API

On Mon, Jul 20, 2020 at 8:59 AM Christoph Hellwig <hch@lst.de> wrote:
>
> This allows reusing the struct filename for retries, and will also allow
> pushing the getname up the stack for a few places to allower for better
> handling of kernel space filenames.

I find this _very_ confusing.

Now the rule is that filename_create() does the putname() if it fails,
but not if it succeeds.

That's just all kinds of messed up.

It was already slightly confusing how "getname()" was paired with
"putname()", and how you didn't need to check for errors, but at least
it was easy to explain: "filename_create() will  check errors and use
the name we got".

That slightly confusing calling convention made the code much more
compact, and nobody involved needed to do error checks on the name
etc.

Now that "slightly confusing" convention has gone from "slightly" to
"outright", and the whole advantage of the interface has completely
gone away, because now you not only need to do the putname() in the
caller, you need to do it _conditionally_.

So please don't do this.

The other patches also all make it *really* hard to follow when
putname() is done - because depending on the context, you have to do
it when returning an error, or when an error was not returned.

I really think this is a huge mistake. Don't do it this way. NAK NAK NAK.

Please instead of making this all completely messy and completely
impossible to follow the rule about exactly who does "putname()" and
under what conditions, just leave the slight duplication in place.

Duplicating simple helper routines is *good*. Complex and
hard-to-understand and non-intuitive rules are *bad*.

You're adding badness.

                 Linus

^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: [PATCH 05/24] fs: move the putname from filename_lookup to the callers
  2020-07-20 15:58 ` [PATCH 05/24] fs: move the putname from filename_lookup " Christoph Hellwig
@ 2020-07-20 18:11   ` Al Viro
  0 siblings, 0 replies; 28+ messages in thread
From: Al Viro @ 2020-07-20 18:11 UTC (permalink / raw)
  To: Christoph Hellwig
  Cc: Linus Torvalds, Greg Kroah-Hartman, Rafael J. Wysocki,
	linux-kernel, linux-raid, linux-fsdevel, linux-api

On Mon, Jul 20, 2020 at 05:58:43PM +0200, Christoph Hellwig wrote:
> This allows reusing the struct filename for retries, and will also allow
> pushing the getname up the stack for a few places to allower for better
> handling of kernel space filenames.

You are complicating the callers for no good reason.  NAK.  The same goes
for the previous patch in the series.

Keep the cleanup rules simple.  Sure, I understand wanting to avoid
special rules for early bootstrap, but that's a corner case; don't
make fs/namei.c harder to follow.

^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: [PATCH 06/24] fs: add a kern_chdir helper
  2020-07-20 15:58 ` [PATCH 06/24] fs: add a kern_chdir helper Christoph Hellwig
@ 2020-07-20 18:17   ` Al Viro
  0 siblings, 0 replies; 28+ messages in thread
From: Al Viro @ 2020-07-20 18:17 UTC (permalink / raw)
  To: Christoph Hellwig
  Cc: Linus Torvalds, Greg Kroah-Hartman, Rafael J. Wysocki,
	linux-kernel, linux-raid, linux-fsdevel, linux-api

On Mon, Jul 20, 2020 at 05:58:44PM +0200, Christoph Hellwig wrote:
> Add a simple helper for a chdir with a kernelspace name and use it in the
> early init code instead of relying on the implicit set_fs(KERNEL_DS)
> there.  Remove the now unused ksys_chdir.

FWIW, my problem with that is that you are making it first-class primitive.
And I don't see any valid use for it - existing one is really "we have
a userland process that would be making syscalls if we only could have it
done right; the only reason we can't is that the infrastructure to build
the binary would be hell to maintain in the tree".  It's *NOT* "kernel
code that has a valid reason to get the syscall functionality".

^ permalink raw reply	[flat|nested] 28+ messages in thread

end of thread, other threads:[~2020-07-20 18:17 UTC | newest]

Thread overview: 28+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-07-20 15:58 add file system helpers that take kernel pointers for the init code Christoph Hellwig
2020-07-20 15:58 ` [PATCH 01/24] init: initialize ramdisk_execute_command at compile time Christoph Hellwig
2020-07-20 15:58 ` [PATCH 02/24] fs: add a do_kern_mount helper Christoph Hellwig
2020-07-20 15:58 ` [PATCH 03/24] fs: add a kern_umount helper Christoph Hellwig
2020-07-20 15:58 ` [PATCH 04/24] fs: move the putname from filename_create to the callers Christoph Hellwig
2020-07-20 18:05   ` Linus Torvalds
2020-07-20 15:58 ` [PATCH 05/24] fs: move the putname from filename_lookup " Christoph Hellwig
2020-07-20 18:11   ` Al Viro
2020-07-20 15:58 ` [PATCH 06/24] fs: add a kern_chdir helper Christoph Hellwig
2020-07-20 18:17   ` Al Viro
2020-07-20 15:58 ` [PATCH 07/24] fs: add a kern_chroot helper Christoph Hellwig
2020-07-20 15:58 ` [PATCH 08/24] fs: add a kern_access helper Christoph Hellwig
2020-07-20 15:58 ` [PATCH 09/24] fs: add a kern_chown helper Christoph Hellwig
2020-07-20 15:58 ` [PATCH 10/24] fs: move the uid16 (f)chown syscalls to fs/open.c Christoph Hellwig
2020-07-20 15:58 ` [PATCH 11/24] fs: add a kern_chmod helper Christoph Hellwig
2020-07-20 15:58 ` [PATCH 12/24] fs: add a kern_utimes helper Christoph Hellwig
2020-07-20 15:58 ` [PATCH 13/24] fs: add a kern_mkdir helper Christoph Hellwig
2020-07-20 15:58 ` [PATCH 14/24] fs: add a kern_mknod helper Christoph Hellwig
2020-07-20 15:58 ` [PATCH 15/24] fs: add a kern_link helper Christoph Hellwig
2020-07-20 15:58 ` [PATCH 16/24] fs: add a kern_symlink helper Christoph Hellwig
2020-07-20 15:58 ` [PATCH 17/24] fs: add a kern_unlink helper Christoph Hellwig
2020-07-20 15:58 ` [PATCH 18/24] fs: add a kern_rmdir helper Christoph Hellwig
2020-07-20 15:58 ` [PATCH 19/24] fs: remove vfs_statx_fd Christoph Hellwig
2020-07-20 15:58 ` [PATCH 20/24] fs: implement vfs_stat and vfs_lstat in terms of vfs_fstatat Christoph Hellwig
2020-07-20 15:58 ` [PATCH 21/24] fs: move vfs_fstatat out of line Christoph Hellwig
2020-07-20 15:59 ` [PATCH 22/24] fs: remove vfs_stat_set_lookup_flags Christoph Hellwig
2020-07-20 15:59 ` [PATCH 23/24] fs: remove KSTAT_QUERY_FLAGS Christoph Hellwig
2020-07-20 15:59 ` [PATCH 24/24] fs: add a kern_stat helper Christoph Hellwig

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).