linux-raid.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* add file system helpers that take kernel pointers for the init code v4
@ 2020-07-28 16:33 Christoph Hellwig
  2020-07-28 16:33 ` [PATCH 01/23] fs: refactor do_mount Christoph Hellwig
                   ` (21 more replies)
  0 siblings, 22 replies; 35+ messages in thread
From: Christoph Hellwig @ 2020-07-28 16:33 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 and Linus,

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.  These helpers are in init/ and marked __init and thus will
be discarded after bootup.  A few also need to be duplicated in devtmpfs,
though unfortunately.

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 init_path

Gitweb:

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


Changes since v3:
 - rename fs/for_init.c to fs/init.c
 - document the purpose of the routines in fs/init.c with a comment
 - don't mark devtmpfs __init as that will cause it to get overwritten
   by initmem poisoning
 - add an init_dup helper to make Al more happy than with the version
   commit to the "decruft the early init / initrd / initramfs code v2"
   series

Changes since v2:
 - move to fs/for_init.c
 - reuse the init routines in devtmpfs after refactoring devtmpfsd
   (and thus the broken error handling in the previous version)
 - actually use kern_path in a place where user_path_at sneaked back in

Changes since v1:
 - avoid most core VFS changes
 - renamed the functions and move them to init/ and devtmpfs
 - drop a bunch of cleanups that can be submitted independently now


Diffstat:

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

* [PATCH 01/23] fs: refactor do_mount
  2020-07-28 16:33 add file system helpers that take kernel pointers for the init code v4 Christoph Hellwig
@ 2020-07-28 16:33 ` Christoph Hellwig
  2020-07-28 16:33 ` [PATCH 02/23] fs: refactor ksys_umount Christoph Hellwig
                   ` (20 subsequent siblings)
  21 siblings, 0 replies; 35+ messages in thread
From: Christoph Hellwig @ 2020-07-28 16:33 UTC (permalink / raw)
  To: Al Viro, Linus Torvalds
  Cc: Greg Kroah-Hartman, Rafael J. Wysocki, linux-kernel, linux-raid,
	linux-fsdevel, linux-api

Factor out a path_mount helper that takes a struct path * instead of the
actual file name.  This will allow to convert the init and devtmpfs code
to properly mount based on a kernel pointer instead of relying on the
implicit set_fs(KERNEL_DS) during early init.

Signed-off-by: Christoph Hellwig <hch@lst.de>
---
 fs/namespace.c | 67 ++++++++++++++++++++++++++------------------------
 1 file changed, 35 insertions(+), 32 deletions(-)

diff --git a/fs/namespace.c b/fs/namespace.c
index f30ed401cc6d7a..6f8234f74bed90 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;
 
 	/* 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,32 @@ 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;
 }
 
 static struct ucounts *inc_mnt_namespaces(struct user_namespace *ns)
-- 
2.27.0

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

* [PATCH 02/23] fs: refactor ksys_umount
  2020-07-28 16:33 add file system helpers that take kernel pointers for the init code v4 Christoph Hellwig
  2020-07-28 16:33 ` [PATCH 01/23] fs: refactor do_mount Christoph Hellwig
@ 2020-07-28 16:33 ` Christoph Hellwig
       [not found]   ` <20200728163416.556521-3-hch-jcswGhMUV9g@public.gmane.org>
  2020-07-28 16:33 ` [PATCH 03/23] fs: push the getname from do_rmdir into the callers Christoph Hellwig
                   ` (19 subsequent siblings)
  21 siblings, 1 reply; 35+ messages in thread
From: Christoph Hellwig @ 2020-07-28 16:33 UTC (permalink / raw)
  To: Al Viro, Linus Torvalds
  Cc: Greg Kroah-Hartman, Rafael J. Wysocki, linux-kernel, linux-raid,
	linux-fsdevel, linux-api

Factor out a path_umount helper that takes a struct path * instead of the
actual file name.  This will allow to convert the init and devtmpfs code
to properly mount based on a kernel pointer instead of relying on the
implicit set_fs(KERNEL_DS) during early init.

Signed-off-by: Christoph Hellwig <hch@lst.de>
---
 fs/namespace.c | 40 ++++++++++++++++++----------------------
 1 file changed, 18 insertions(+), 22 deletions(-)

diff --git a/fs/namespace.c b/fs/namespace.c
index 6f8234f74bed90..43834b59eff6c3 100644
--- a/fs/namespace.c
+++ b/fs/namespace.c
@@ -1706,36 +1706,19 @@ 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
- */
-
-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 +1731,25 @@ 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;
 }
 
+int ksys_umount(char __user *name, int flags)
+{
+	int lookup_flags = LOOKUP_MOUNTPOINT;
+	struct path path;
+	int ret;
+
+	if (!(flags & UMOUNT_NOFOLLOW))
+		lookup_flags |= LOOKUP_FOLLOW;
+	ret = user_path_at(AT_FDCWD, name, lookup_flags, &path);
+	if (ret)
+		return ret;
+	return path_umount(&path, flags);
+}
+
 SYSCALL_DEFINE2(umount, char __user *, name, int, flags)
 {
 	return ksys_umount(name, flags);
-- 
2.27.0

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

* [PATCH 03/23] fs: push the getname from do_rmdir into the callers
  2020-07-28 16:33 add file system helpers that take kernel pointers for the init code v4 Christoph Hellwig
  2020-07-28 16:33 ` [PATCH 01/23] fs: refactor do_mount Christoph Hellwig
  2020-07-28 16:33 ` [PATCH 02/23] fs: refactor ksys_umount Christoph Hellwig
@ 2020-07-28 16:33 ` Christoph Hellwig
  2020-07-28 16:33 ` [PATCH 05/23] init: initialize ramdisk_execute_command at compile time Christoph Hellwig
                   ` (18 subsequent siblings)
  21 siblings, 0 replies; 35+ messages in thread
From: Christoph Hellwig @ 2020-07-28 16:33 UTC (permalink / raw)
  To: Al Viro, Linus Torvalds
  Cc: Greg Kroah-Hartman, Rafael J. Wysocki, linux-kernel, linux-raid,
	linux-fsdevel, linux-api

This mirrors do_unlinkat and will make life a little easier for
the init code to reuse the whole function with a kernel filename.

Signed-off-by: Christoph Hellwig <hch@lst.de>
---
 fs/internal.h            |  2 +-
 fs/namei.c               | 10 ++++------
 include/linux/syscalls.h |  4 ++--
 3 files changed, 7 insertions(+), 9 deletions(-)

diff --git a/fs/internal.h b/fs/internal.h
index 9b863a7bd70892..e903d5aae139a2 100644
--- a/fs/internal.h
+++ b/fs/internal.h
@@ -65,7 +65,7 @@ extern int vfs_path_lookup(struct dentry *, struct vfsmount *,
 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_rmdir(int dfd, struct filename *name);
 long do_unlinkat(int dfd, struct filename *name);
 long do_symlinkat(const char __user *oldname, int newdfd,
 		  const char __user *newname);
diff --git a/fs/namei.c b/fs/namei.c
index 72d4219c93acb7..d75a6039ae3966 100644
--- a/fs/namei.c
+++ b/fs/namei.c
@@ -3720,17 +3720,16 @@ int vfs_rmdir(struct inode *dir, struct dentry *dentry)
 }
 EXPORT_SYMBOL(vfs_rmdir);
 
-long do_rmdir(int dfd, const char __user *pathname)
+long 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,
+	name = filename_parentat(dfd, name, lookup_flags,
 				&path, &last, &type);
 	if (IS_ERR(name))
 		return PTR_ERR(name);
@@ -3781,7 +3780,7 @@ long do_rmdir(int dfd, const char __user *pathname)
 
 SYSCALL_DEFINE1(rmdir, const char __user *, pathname)
 {
-	return do_rmdir(AT_FDCWD, pathname);
+	return do_rmdir(AT_FDCWD, getname(pathname));
 }
 
 /**
@@ -3926,8 +3925,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/syscalls.h b/include/linux/syscalls.h
index 5b0f1fca4cfb9d..e43816198e6001 100644
--- a/include/linux/syscalls.h
+++ b/include/linux/syscalls.h
@@ -1281,11 +1281,11 @@ 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);
+long do_rmdir(int dfd, struct filename *name);
 
 static inline long ksys_rmdir(const char __user *pathname)
 {
-	return do_rmdir(AT_FDCWD, pathname);
+	return do_rmdir(AT_FDCWD, getname(pathname));
 }
 
 extern long do_mkdirat(int dfd, const char __user *pathname, umode_t mode);
-- 
2.27.0

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

* [PATCH 04/23] devtmpfs: refactor devtmpfsd()
       [not found] ` <20200728163416.556521-1-hch-jcswGhMUV9g@public.gmane.org>
@ 2020-07-28 16:33   ` Christoph Hellwig
  2020-07-28 16:59     ` Greg Kroah-Hartman
  2020-07-28 16:33   ` [PATCH 06/23] init: mark console_on_rootfs as __init Christoph Hellwig
                     ` (2 subsequent siblings)
  3 siblings, 1 reply; 35+ messages in thread
From: Christoph Hellwig @ 2020-07-28 16:33 UTC (permalink / raw)
  To: Al Viro, Linus Torvalds
  Cc: Greg Kroah-Hartman, Rafael J. Wysocki,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	linux-raid-u79uwXL29TY76Z2rM5mHXA,
	linux-fsdevel-u79uwXL29TY76Z2rM5mHXA,
	linux-api-u79uwXL29TY76Z2rM5mHXA

Split the main worker loop into a separate function.  This allows
devtmpfsd_setup to be marked __init, which will allows us to call
__init routines for the setup work.  devtmpfѕ itself needs a __ref
marker for that to work, and a comment explaining why it works.

Signed-off-by: Christoph Hellwig <hch-jcswGhMUV9g@public.gmane.org>
---
 drivers/base/devtmpfs.c | 52 ++++++++++++++++++++++++-----------------
 1 file changed, 31 insertions(+), 21 deletions(-)

diff --git a/drivers/base/devtmpfs.c b/drivers/base/devtmpfs.c
index c9017e0584c003..d697634bc0d48c 100644
--- a/drivers/base/devtmpfs.c
+++ b/drivers/base/devtmpfs.c
@@ -378,7 +378,30 @@ static int handle(const char *name, umode_t mode, kuid_t uid, kgid_t gid,
 		return handle_remove(name, dev);
 }
 
-static int devtmpfs_setup(void *p)
+static void __noreturn devtmpfs_work_loop(void)
+{
+	while (1) {
+		spin_lock(&req_lock);
+		while (requests) {
+			struct req *req = requests;
+			requests = NULL;
+			spin_unlock(&req_lock);
+			while (req) {
+				struct req *next = req->next;
+				req->err = handle(req->name, req->mode,
+						  req->uid, req->gid, req->dev);
+				complete(&req->done);
+				req = next;
+			}
+			spin_lock(&req_lock);
+		}
+		__set_current_state(TASK_INTERRUPTIBLE);
+		spin_unlock(&req_lock);
+		schedule();
+	}
+}
+
+static int __init devtmpfs_setup(void *p)
 {
 	int err;
 
@@ -396,31 +419,18 @@ static int devtmpfs_setup(void *p)
 	return err;
 }
 
-static int devtmpfsd(void *p)
+/*
+ * The __ref is because devtmpfs_setup needs to be __init for the routines it
+ * calls.  That call is done while devtmpfs_init, which is marked __init,
+ * synchronously waits for it to complete.
+ */
+static int __ref devtmpfsd(void *p)
 {
 	int err = devtmpfs_setup(p);
 
 	if (err)
 		return err;
-	while (1) {
-		spin_lock(&req_lock);
-		while (requests) {
-			struct req *req = requests;
-			requests = NULL;
-			spin_unlock(&req_lock);
-			while (req) {
-				struct req *next = req->next;
-				req->err = handle(req->name, req->mode,
-						  req->uid, req->gid, req->dev);
-				complete(&req->done);
-				req = next;
-			}
-			spin_lock(&req_lock);
-		}
-		__set_current_state(TASK_INTERRUPTIBLE);
-		spin_unlock(&req_lock);
-		schedule();
-	}
+	devtmpfs_work_loop();
 	return 0;
 }
 
-- 
2.27.0

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

* [PATCH 05/23] init: initialize ramdisk_execute_command at compile time
  2020-07-28 16:33 add file system helpers that take kernel pointers for the init code v4 Christoph Hellwig
                   ` (2 preceding siblings ...)
  2020-07-28 16:33 ` [PATCH 03/23] fs: push the getname from do_rmdir into the callers Christoph Hellwig
@ 2020-07-28 16:33 ` Christoph Hellwig
  2020-07-28 16:34 ` [PATCH 08/23] init: add an init_mount helper Christoph Hellwig
                   ` (17 subsequent siblings)
  21 siblings, 0 replies; 35+ messages in thread
From: Christoph Hellwig @ 2020-07-28 16:33 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] 35+ messages in thread

* [PATCH 06/23] init: mark console_on_rootfs as __init
       [not found] ` <20200728163416.556521-1-hch-jcswGhMUV9g@public.gmane.org>
  2020-07-28 16:33   ` [PATCH 04/23] devtmpfs: refactor devtmpfsd() Christoph Hellwig
@ 2020-07-28 16:33   ` Christoph Hellwig
  2020-07-28 16:34   ` [PATCH 07/23] init: mark create_dev " Christoph Hellwig
  2020-07-28 16:34   ` [PATCH 22/23] init: add an init_utimes helper Christoph Hellwig
  3 siblings, 0 replies; 35+ messages in thread
From: Christoph Hellwig @ 2020-07-28 16:33 UTC (permalink / raw)
  To: Al Viro, Linus Torvalds
  Cc: Greg Kroah-Hartman, Rafael J. Wysocki,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	linux-raid-u79uwXL29TY76Z2rM5mHXA,
	linux-fsdevel-u79uwXL29TY76Z2rM5mHXA,
	linux-api-u79uwXL29TY76Z2rM5mHXA

This helper is only used for the early init code.

Signed-off-by: Christoph Hellwig <hch-jcswGhMUV9g@public.gmane.org>
---
 init/main.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/init/main.c b/init/main.c
index c2c9143db96795..47698427b15f62 100644
--- a/init/main.c
+++ b/init/main.c
@@ -1458,7 +1458,7 @@ static int __ref kernel_init(void *unused)
 }
 
 /* Open /dev/console, for stdin/stdout/stderr, this should never fail */
-void console_on_rootfs(void)
+void __init console_on_rootfs(void)
 {
 	struct file *file = filp_open("/dev/console", O_RDWR, 0);
 
-- 
2.27.0

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

* [PATCH 07/23] init: mark create_dev as __init
       [not found] ` <20200728163416.556521-1-hch-jcswGhMUV9g@public.gmane.org>
  2020-07-28 16:33   ` [PATCH 04/23] devtmpfs: refactor devtmpfsd() Christoph Hellwig
  2020-07-28 16:33   ` [PATCH 06/23] init: mark console_on_rootfs as __init Christoph Hellwig
@ 2020-07-28 16:34   ` Christoph Hellwig
  2020-07-28 16:34   ` [PATCH 22/23] init: add an init_utimes helper Christoph Hellwig
  3 siblings, 0 replies; 35+ messages in thread
From: Christoph Hellwig @ 2020-07-28 16:34 UTC (permalink / raw)
  To: Al Viro, Linus Torvalds
  Cc: Greg Kroah-Hartman, Rafael J. Wysocki,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	linux-raid-u79uwXL29TY76Z2rM5mHXA,
	linux-fsdevel-u79uwXL29TY76Z2rM5mHXA,
	linux-api-u79uwXL29TY76Z2rM5mHXA

This helper is only used for the early init code.

Signed-off-by: Christoph Hellwig <hch-jcswGhMUV9g@public.gmane.org>
---
 init/do_mounts.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/init/do_mounts.h b/init/do_mounts.h
index c855b3f0e06d19..021e2f60223e25 100644
--- a/init/do_mounts.h
+++ b/init/do_mounts.h
@@ -13,7 +13,7 @@ void  mount_block_root(char *name, int flags);
 void  mount_root(void);
 extern int root_mountflags;
 
-static inline int create_dev(char *name, dev_t dev)
+static inline __init int create_dev(char *name, dev_t dev)
 {
 	ksys_unlink(name);
 	return ksys_mknod(name, S_IFBLK|0600, new_encode_dev(dev));
-- 
2.27.0

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

* [PATCH 08/23] init: add an init_mount helper
  2020-07-28 16:33 add file system helpers that take kernel pointers for the init code v4 Christoph Hellwig
                   ` (3 preceding siblings ...)
  2020-07-28 16:33 ` [PATCH 05/23] init: initialize ramdisk_execute_command at compile time Christoph Hellwig
@ 2020-07-28 16:34 ` Christoph Hellwig
  2020-07-28 16:34 ` [PATCH 09/23] init: add an init_umount helper Christoph Hellwig
                   ` (16 subsequent siblings)
  21 siblings, 0 replies; 35+ messages in thread
From: Christoph Hellwig @ 2020-07-28 16:34 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       |  5 +++--
 fs/Makefile                   |  2 +-
 fs/init.c                     | 25 +++++++++++++++++++++++++
 fs/internal.h                 |  4 ++++
 fs/namespace.c                |  2 +-
 include/linux/init_syscalls.h |  4 ++++
 init/do_mounts.c              |  8 ++++----
 init/do_mounts.h              |  1 +
 init/do_mounts_initrd.c       |  6 +++---
 9 files changed, 46 insertions(+), 11 deletions(-)
 create mode 100644 fs/init.c
 create mode 100644 include/linux/init_syscalls.h

diff --git a/drivers/base/devtmpfs.c b/drivers/base/devtmpfs.c
index d697634bc0d48c..32af6cb987b428 100644
--- a/drivers/base/devtmpfs.c
+++ b/drivers/base/devtmpfs.c
@@ -25,6 +25,7 @@
 #include <linux/sched.h>
 #include <linux/slab.h>
 #include <linux/kthread.h>
+#include <linux/init_syscalls.h>
 #include <uapi/linux/mount.h>
 #include "base.h"
 
@@ -359,7 +360,7 @@ int __init devtmpfs_mount(void)
 	if (!thread)
 		return 0;
 
-	err = do_mount("devtmpfs", "dev", "devtmpfs", MS_SILENT, NULL);
+	err = init_mount("devtmpfs", "dev", "devtmpfs", MS_SILENT, NULL);
 	if (err)
 		printk(KERN_INFO "devtmpfs: error mounting %i\n", err);
 	else
@@ -408,7 +409,7 @@ static int __init devtmpfs_setup(void *p)
 	err = ksys_unshare(CLONE_NEWNS);
 	if (err)
 		goto out;
-	err = do_mount("devtmpfs", "/", "devtmpfs", MS_SILENT, NULL);
+	err = init_mount("devtmpfs", "/", "devtmpfs", MS_SILENT, NULL);
 	if (err)
 		goto out;
 	ksys_chdir("/.."); /* will traverse into overmounted root */
diff --git a/fs/Makefile b/fs/Makefile
index 2ce5112b02c867..1c7b0e3f6daa11 100644
--- a/fs/Makefile
+++ b/fs/Makefile
@@ -13,7 +13,7 @@ obj-y :=	open.o read_write.o file_table.o super.o \
 		seq_file.o xattr.o libfs.o fs-writeback.o \
 		pnode.o splice.o sync.o utimes.o d_path.o \
 		stack.o fs_struct.o statfs.o fs_pin.o nsfs.o \
-		fs_types.o fs_context.o fs_parser.o fsopen.o
+		fs_types.o fs_context.o fs_parser.o fsopen.o init.o
 
 ifeq ($(CONFIG_BLOCK),y)
 obj-y +=	buffer.o block_dev.o direct-io.o mpage.o
diff --git a/fs/init.c b/fs/init.c
new file mode 100644
index 00000000000000..c6eb724e1c7b22
--- /dev/null
+++ b/fs/init.c
@@ -0,0 +1,25 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Routines that mimic syscalls, but don't use the user address space or file
+ * descriptors.  Only for init/ and related early init code.
+ */
+#include <linux/init.h>
+#include <linux/mount.h>
+#include <linux/namei.h>
+#include <linux/fs.h>
+#include <linux/init_syscalls.h>
+#include "internal.h"
+
+int __init init_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;
+}
diff --git a/fs/internal.h b/fs/internal.h
index e903d5aae139a2..72ea0b6f7435a4 100644
--- a/fs/internal.h
+++ b/fs/internal.h
@@ -89,6 +89,10 @@ extern int __mnt_want_write_file(struct file *);
 extern void __mnt_drop_write_file(struct file *);
 
 extern void dissolve_on_fput(struct vfsmount *);
+
+int path_mount(const char *dev_name, struct path *path,
+		const char *type_page, unsigned long flags, void *data_page);
+
 /*
  * fs_struct.c
  */
diff --git a/fs/namespace.c b/fs/namespace.c
index 43834b59eff6c3..2c4d7592097485 100644
--- a/fs/namespace.c
+++ b/fs/namespace.c
@@ -3111,7 +3111,7 @@ char *copy_mount_string(const void __user *data)
  * Therefore, if this magic number is present, it carries no information
  * and must be discarded.
  */
-static int path_mount(const char *dev_name, struct path *path,
+int path_mount(const char *dev_name, struct path *path,
 		const char *type_page, unsigned long flags, void *data_page)
 {
 	unsigned int mnt_flags = 0, sb_flags;
diff --git a/include/linux/init_syscalls.h b/include/linux/init_syscalls.h
new file mode 100644
index 00000000000000..af9ea88a60e0bd
--- /dev/null
+++ b/include/linux/init_syscalls.h
@@ -0,0 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+
+int __init init_mount(const char *dev_name, const char *dir_name,
+		const char *type_page, unsigned long flags, void *data_page);
diff --git a/init/do_mounts.c b/init/do_mounts.c
index a7f22cf58c7efd..83db87b6e5d1e0 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 */
+		/* init_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. init_mount() will make sure it's terminated */
 		strncpy(data_page, data, PAGE_SIZE);
 	}
 
-	ret = do_mount(name, "/root", fs, flags, data_page);
+	ret = init_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);
+	init_mount(".", "/", NULL, MS_MOVE, NULL);
 	ksys_chroot(".");
 }
 
diff --git a/init/do_mounts.h b/init/do_mounts.h
index 021e2f60223e25..20e7fec8cb499e 100644
--- a/init/do_mounts.h
+++ b/init/do_mounts.h
@@ -8,6 +8,7 @@
 #include <linux/mount.h>
 #include <linux/major.h>
 #include <linux/root_dev.h>
+#include <linux/init_syscalls.h>
 
 void  mount_block_root(char *name, int flags);
 void  mount_root(void);
diff --git a/init/do_mounts_initrd.c b/init/do_mounts_initrd.c
index e08669187d63be..1f9336209ad9cc 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);
+	init_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);
+	init_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 = init_mount("/old", "/root/initrd", NULL, MS_MOVE, NULL);
 	if (!error)
 		printk("okay\n");
 	else {
-- 
2.27.0

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

* [PATCH 09/23] init: add an init_umount helper
  2020-07-28 16:33 add file system helpers that take kernel pointers for the init code v4 Christoph Hellwig
                   ` (4 preceding siblings ...)
  2020-07-28 16:34 ` [PATCH 08/23] init: add an init_mount helper Christoph Hellwig
@ 2020-07-28 16:34 ` Christoph Hellwig
  2020-07-28 16:34 ` [PATCH 10/23] init: add an init_unlink helper Christoph Hellwig
                   ` (15 subsequent siblings)
  21 siblings, 0 replies; 35+ messages in thread
From: Christoph Hellwig @ 2020-07-28 16:34 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, 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>
---
 fs/init.c                     | 14 ++++++++++++++
 fs/internal.h                 |  1 +
 fs/namespace.c                |  4 ++--
 include/linux/init_syscalls.h |  1 +
 include/linux/syscalls.h      |  1 -
 init/do_mounts_initrd.c       |  2 +-
 6 files changed, 19 insertions(+), 4 deletions(-)

diff --git a/fs/init.c b/fs/init.c
index c6eb724e1c7b22..9c8e31fdb048c8 100644
--- a/fs/init.c
+++ b/fs/init.c
@@ -23,3 +23,17 @@ int __init init_mount(const char *dev_name, const char *dir_name,
 	path_put(&path);
 	return ret;
 }
+
+int __init init_umount(const char *name, int flags)
+{
+	int lookup_flags = LOOKUP_MOUNTPOINT;
+	struct path path;
+	int ret;
+
+	if (!(flags & UMOUNT_NOFOLLOW))
+		lookup_flags |= LOOKUP_FOLLOW;
+	ret = kern_path(name, lookup_flags, &path);
+	if (ret)
+		return ret;
+	return path_umount(&path, flags);
+}
diff --git a/fs/internal.h b/fs/internal.h
index 72ea0b6f7435a4..491d1e63809b37 100644
--- a/fs/internal.h
+++ b/fs/internal.h
@@ -92,6 +92,7 @@ extern void dissolve_on_fput(struct vfsmount *);
 
 int path_mount(const char *dev_name, struct path *path,
 		const char *type_page, unsigned long flags, void *data_page);
+int path_umount(struct path *path, int flags);
 
 /*
  * fs_struct.c
diff --git a/fs/namespace.c b/fs/namespace.c
index 2c4d7592097485..a7301790abb211 100644
--- a/fs/namespace.c
+++ b/fs/namespace.c
@@ -1706,7 +1706,7 @@ static inline bool may_mandlock(void)
 }
 #endif
 
-static int path_umount(struct path *path, int flags)
+int path_umount(struct path *path, int flags)
 {
 	struct mount *mnt;
 	int retval;
@@ -1736,7 +1736,7 @@ static int path_umount(struct path *path, int flags)
 	return retval;
 }
 
-int ksys_umount(char __user *name, int flags)
+static int ksys_umount(char __user *name, int flags)
 {
 	int lookup_flags = LOOKUP_MOUNTPOINT;
 	struct path path;
diff --git a/include/linux/init_syscalls.h b/include/linux/init_syscalls.h
index af9ea88a60e0bd..a5a2e7f1991691 100644
--- a/include/linux/init_syscalls.h
+++ b/include/linux/init_syscalls.h
@@ -2,3 +2,4 @@
 
 int __init init_mount(const char *dev_name, const char *dir_name,
 		const char *type_page, unsigned long flags, void *data_page);
+int __init init_umount(const char *name, int flags);
diff --git a/include/linux/syscalls.h b/include/linux/syscalls.h
index e43816198e6001..1a4f5d8ee7044b 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 1f9336209ad9cc..6b020a06990251 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);
+		init_umount("/old", MNT_DETACH);
 	}
 }
 
-- 
2.27.0

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

* [PATCH 10/23] init: add an init_unlink helper
  2020-07-28 16:33 add file system helpers that take kernel pointers for the init code v4 Christoph Hellwig
                   ` (5 preceding siblings ...)
  2020-07-28 16:34 ` [PATCH 09/23] init: add an init_umount helper Christoph Hellwig
@ 2020-07-28 16:34 ` Christoph Hellwig
  2020-07-28 16:34 ` [PATCH 11/23] init: add an init_rmdir helper Christoph Hellwig
                   ` (14 subsequent siblings)
  21 siblings, 0 replies; 35+ messages in thread
From: Christoph Hellwig @ 2020-07-28 16:34 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 code over to it.  Remove the now unused ksys_unlink.

Signed-off-by: Christoph Hellwig <hch@lst.de>
---
 fs/init.c                     | 5 +++++
 include/linux/init_syscalls.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              | 3 ++-
 7 files changed, 12 insertions(+), 12 deletions(-)

diff --git a/fs/init.c b/fs/init.c
index 9c8e31fdb048c8..507ffbb5d146d6 100644
--- a/fs/init.c
+++ b/fs/init.c
@@ -37,3 +37,8 @@ int __init init_umount(const char *name, int flags)
 		return ret;
 	return path_umount(&path, flags);
 }
+
+int __init init_unlink(const char *pathname)
+{
+	return do_unlinkat(AT_FDCWD, getname_kernel(pathname));
+}
diff --git a/include/linux/init_syscalls.h b/include/linux/init_syscalls.h
index a5a2e7f1991691..00d597249549ee 100644
--- a/include/linux/init_syscalls.h
+++ b/include/linux/init_syscalls.h
@@ -3,3 +3,4 @@
 int __init init_mount(const char *dev_name, const char *dir_name,
 		const char *type_page, unsigned long flags, void *data_page);
 int __init init_umount(const char *name, int flags);
+int __init init_unlink(const char *pathname);
diff --git a/include/linux/syscalls.h b/include/linux/syscalls.h
index 1a4f5d8ee7044b..26f9738e5ab861 100644
--- a/include/linux/syscalls.h
+++ b/include/linux/syscalls.h
@@ -1273,13 +1273,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));
-}
-
 long do_rmdir(int dfd, struct filename *name);
 
 static inline long ksys_rmdir(const char __user *pathname)
diff --git a/init/do_mounts.h b/init/do_mounts.h
index 20e7fec8cb499e..104d8431725aeb 100644
--- a/init/do_mounts.h
+++ b/init/do_mounts.h
@@ -16,7 +16,7 @@ extern int root_mountflags;
 
 static inline __init int create_dev(char *name, dev_t dev)
 {
-	ksys_unlink(name);
+	init_unlink(name);
 	return ksys_mknod(name, S_IFBLK|0600, new_encode_dev(dev));
 }
 
diff --git a/init/do_mounts_initrd.c b/init/do_mounts_initrd.c
index 6b020a06990251..8b44dd017842a8 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");
+			init_unlink("/initrd.image");
 			handle_initrd();
 			return true;
 		}
 	}
-	ksys_unlink("/initrd.image");
+	init_unlink("/initrd.image");
 	return false;
 }
diff --git a/init/do_mounts_rd.c b/init/do_mounts_rd.c
index d4255c10432a8b..ac021ae6e6fa78 100644
--- a/init/do_mounts_rd.c
+++ b/init/do_mounts_rd.c
@@ -272,7 +272,7 @@ int __init rd_load_image(char *from)
 	fput(out_file);
 out:
 	kfree(buf);
-	ksys_unlink("/dev/ram");
+	init_unlink("/dev/ram");
 	return res;
 }
 
diff --git a/init/initramfs.c b/init/initramfs.c
index 584bc8fe88e77c..7e9db1cfa3c060 100644
--- a/init/initramfs.c
+++ b/init/initramfs.c
@@ -12,6 +12,7 @@
 #include <linux/file.h>
 #include <linux/memblock.h>
 #include <linux/namei.h>
+#include <linux/init_syscalls.h>
 
 static ssize_t __init xwrite(struct file *file, const char *p, size_t count,
 		loff_t *pos)
@@ -301,7 +302,7 @@ static void __init clean_path(char *path, umode_t fmode)
 		if (S_ISDIR(st.mode))
 			ksys_rmdir(path);
 		else
-			ksys_unlink(path);
+			init_unlink(path);
 	}
 }
 
-- 
2.27.0

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

* [PATCH 11/23] init: add an init_rmdir helper
  2020-07-28 16:33 add file system helpers that take kernel pointers for the init code v4 Christoph Hellwig
                   ` (6 preceding siblings ...)
  2020-07-28 16:34 ` [PATCH 10/23] init: add an init_unlink helper Christoph Hellwig
@ 2020-07-28 16:34 ` Christoph Hellwig
  2020-07-28 16:34 ` [PATCH 12/23] init: add an init_chdir helper Christoph Hellwig
                   ` (13 subsequent siblings)
  21 siblings, 0 replies; 35+ messages in thread
From: Christoph Hellwig @ 2020-07-28 16:34 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/init.c                     | 5 +++++
 include/linux/init_syscalls.h | 1 +
 include/linux/syscalls.h      | 7 -------
 init/initramfs.c              | 2 +-
 4 files changed, 7 insertions(+), 8 deletions(-)

diff --git a/fs/init.c b/fs/init.c
index 507ffbb5d146d6..eabd9ed2b51092 100644
--- a/fs/init.c
+++ b/fs/init.c
@@ -42,3 +42,8 @@ int __init init_unlink(const char *pathname)
 {
 	return do_unlinkat(AT_FDCWD, getname_kernel(pathname));
 }
+
+int __init init_rmdir(const char *pathname)
+{
+	return do_rmdir(AT_FDCWD, getname_kernel(pathname));
+}
diff --git a/include/linux/init_syscalls.h b/include/linux/init_syscalls.h
index 00d597249549ee..abf3af563c0b3a 100644
--- a/include/linux/init_syscalls.h
+++ b/include/linux/init_syscalls.h
@@ -4,3 +4,4 @@ int __init init_mount(const char *dev_name, const char *dir_name,
 		const char *type_page, unsigned long flags, void *data_page);
 int __init init_umount(const char *name, int flags);
 int __init init_unlink(const char *pathname);
+int __init init_rmdir(const char *pathname);
diff --git a/include/linux/syscalls.h b/include/linux/syscalls.h
index 26f9738e5ab861..a7b14258d245e2 100644
--- a/include/linux/syscalls.h
+++ b/include/linux/syscalls.h
@@ -1273,13 +1273,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.
  */
-long do_rmdir(int dfd, struct filename *name);
-
-static inline long ksys_rmdir(const char __user *pathname)
-{
-	return do_rmdir(AT_FDCWD, getname(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)
diff --git a/init/initramfs.c b/init/initramfs.c
index 7e9db1cfa3c060..fb7210731d9e5d 100644
--- a/init/initramfs.c
+++ b/init/initramfs.c
@@ -300,7 +300,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);
+			init_rmdir(path);
 		else
 			init_unlink(path);
 	}
-- 
2.27.0

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

* [PATCH 12/23] init: add an init_chdir helper
  2020-07-28 16:33 add file system helpers that take kernel pointers for the init code v4 Christoph Hellwig
                   ` (7 preceding siblings ...)
  2020-07-28 16:34 ` [PATCH 11/23] init: add an init_rmdir helper Christoph Hellwig
@ 2020-07-28 16:34 ` Christoph Hellwig
  2020-07-28 16:34 ` [PATCH 13/23] init: add an init_chroot helper Christoph Hellwig
                   ` (12 subsequent siblings)
  21 siblings, 0 replies; 35+ messages in thread
From: Christoph Hellwig @ 2020-07-28 16:34 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 chdir with a kernel space file name and switch
the early init code over to it.  Remove the now unused ksys_chdir.

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

diff --git a/drivers/base/devtmpfs.c b/drivers/base/devtmpfs.c
index 32af6cb987b428..e48aaba3166b5d 100644
--- a/drivers/base/devtmpfs.c
+++ b/drivers/base/devtmpfs.c
@@ -412,7 +412,7 @@ static int __init devtmpfs_setup(void *p)
 	err = init_mount("devtmpfs", "/", "devtmpfs", MS_SILENT, NULL);
 	if (err)
 		goto out;
-	ksys_chdir("/.."); /* will traverse into overmounted root */
+	init_chdir("/.."); /* will traverse into overmounted root */
 	ksys_chroot(".");
 out:
 	*(int *)p = err;
diff --git a/fs/init.c b/fs/init.c
index eabd9ed2b51092..64d4e12eba9339 100644
--- a/fs/init.c
+++ b/fs/init.c
@@ -7,6 +7,7 @@
 #include <linux/mount.h>
 #include <linux/namei.h>
 #include <linux/fs.h>
+#include <linux/fs_struct.h>
 #include <linux/init_syscalls.h>
 #include "internal.h"
 
@@ -38,6 +39,21 @@ int __init init_umount(const char *name, int flags)
 	return path_umount(&path, flags);
 }
 
+int __init init_chdir(const char *filename)
+{
+	struct path path;
+	int error;
+
+	error = kern_path(filename, LOOKUP_FOLLOW | LOOKUP_DIRECTORY, &path);
+	if (error)
+		return error;
+	error = inode_permission(path.dentry->d_inode, MAY_EXEC | MAY_CHDIR);
+	if (!error)
+		set_fs_pwd(current->fs, &path);
+	path_put(&path);
+	return error;
+}
+
 int __init init_unlink(const char *pathname)
 {
 	return do_unlinkat(AT_FDCWD, getname_kernel(pathname));
diff --git a/fs/open.c b/fs/open.c
index b316dd6a86a8b9..723e0ac898935e 100644
--- a/fs/open.c
+++ b/fs/open.c
@@ -482,7 +482,7 @@ SYSCALL_DEFINE2(access, const char __user *, filename, int, mode)
 	return do_faccessat(AT_FDCWD, filename, mode, 0);
 }
 
-int ksys_chdir(const char __user *filename)
+SYSCALL_DEFINE1(chdir, const char __user *, filename)
 {
 	struct path path;
 	int error;
@@ -508,11 +508,6 @@ int ksys_chdir(const char __user *filename)
 	return error;
 }
 
-SYSCALL_DEFINE1(chdir, const char __user *, filename)
-{
-	return ksys_chdir(filename);
-}
-
 SYSCALL_DEFINE1(fchdir, unsigned int, fd)
 {
 	struct fd f = fdget_raw(fd);
diff --git a/include/linux/init_syscalls.h b/include/linux/init_syscalls.h
index abf3af563c0b3a..1e845910ae56e9 100644
--- a/include/linux/init_syscalls.h
+++ b/include/linux/init_syscalls.h
@@ -3,5 +3,6 @@
 int __init init_mount(const char *dev_name, const char *dir_name,
 		const char *type_page, unsigned long flags, void *data_page);
 int __init init_umount(const char *name, int flags);
+int __init init_chdir(const char *filename);
 int __init init_unlink(const char *pathname);
 int __init init_rmdir(const char *pathname);
diff --git a/include/linux/syscalls.h b/include/linux/syscalls.h
index a7b14258d245e2..31fa67fb9894b3 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 83db87b6e5d1e0..a7581c6e85f268 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");
+	init_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 8b44dd017842a8..04627fd22a921f 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");
+	init_chdir("/root");
 	init_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");
+	init_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");
+		init_chdir("/old");
 		return;
 	}
 
-	ksys_chdir("/");
+	init_chdir("/");
 	ROOT_DEV = new_decode_dev(real_root_dev);
 	mount_root();
 
-- 
2.27.0

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

* [PATCH 13/23] init: add an init_chroot helper
  2020-07-28 16:33 add file system helpers that take kernel pointers for the init code v4 Christoph Hellwig
                   ` (8 preceding siblings ...)
  2020-07-28 16:34 ` [PATCH 12/23] init: add an init_chdir helper Christoph Hellwig
@ 2020-07-28 16:34 ` Christoph Hellwig
  2020-07-28 16:34 ` [PATCH 14/23] init: add an init_chown helper Christoph Hellwig
                   ` (11 subsequent siblings)
  21 siblings, 0 replies; 35+ messages in thread
From: Christoph Hellwig @ 2020-07-28 16:34 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 chroot with a kernel space file name and switch
the early init code over to it.  Remove the now unused ksys_chroot.

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

diff --git a/drivers/base/devtmpfs.c b/drivers/base/devtmpfs.c
index e48aaba3166b5d..eac184e6d65774 100644
--- a/drivers/base/devtmpfs.c
+++ b/drivers/base/devtmpfs.c
@@ -413,7 +413,7 @@ static int __init devtmpfs_setup(void *p)
 	if (err)
 		goto out;
 	init_chdir("/.."); /* will traverse into overmounted root */
-	ksys_chroot(".");
+	init_chroot(".");
 out:
 	*(int *)p = err;
 	complete(&setup_done);
diff --git a/fs/init.c b/fs/init.c
index 64d4e12eba9339..2c78f24814dde4 100644
--- a/fs/init.c
+++ b/fs/init.c
@@ -9,6 +9,7 @@
 #include <linux/fs.h>
 #include <linux/fs_struct.h>
 #include <linux/init_syscalls.h>
+#include <linux/security.h>
 #include "internal.h"
 
 int __init init_mount(const char *dev_name, const char *dir_name,
@@ -54,6 +55,29 @@ int __init init_chdir(const char *filename)
 	return error;
 }
 
+int __init init_chroot(const char *filename)
+{
+	struct path path;
+	int error;
+
+	error = kern_path(filename, LOOKUP_FOLLOW | LOOKUP_DIRECTORY, &path);
+	if (error)
+		return error;
+	error = inode_permission(path.dentry->d_inode, MAY_EXEC | MAY_CHDIR);
+	if (error)
+		goto dput_and_out;
+	error = -EPERM;
+	if (!ns_capable(current_user_ns(), CAP_SYS_CHROOT))
+		goto dput_and_out;
+	error = security_path_chroot(&path);
+	if (error)
+		goto dput_and_out;
+	set_fs_root(current->fs, &path);
+dput_and_out:
+	path_put(&path);
+	return error;
+}
+
 int __init init_unlink(const char *pathname)
 {
 	return do_unlinkat(AT_FDCWD, getname_kernel(pathname));
diff --git a/fs/open.c b/fs/open.c
index 723e0ac898935e..f62f4752bb436d 100644
--- a/fs/open.c
+++ b/fs/open.c
@@ -530,7 +530,7 @@ SYSCALL_DEFINE1(fchdir, unsigned int, fd)
 	return error;
 }
 
-int ksys_chroot(const char __user *filename)
+SYSCALL_DEFINE1(chroot, const char __user *, filename)
 {
 	struct path path;
 	int error;
@@ -563,11 +563,6 @@ int ksys_chroot(const char __user *filename)
 	return error;
 }
 
-SYSCALL_DEFINE1(chroot, const char __user *, filename)
-{
-	return ksys_chroot(filename);
-}
-
 static int chmod_common(const struct path *path, umode_t mode)
 {
 	struct inode *inode = path->dentry->d_inode;
diff --git a/include/linux/init_syscalls.h b/include/linux/init_syscalls.h
index 1e845910ae56e9..e07099a14b91db 100644
--- a/include/linux/init_syscalls.h
+++ b/include/linux/init_syscalls.h
@@ -4,5 +4,6 @@ int __init init_mount(const char *dev_name, const char *dir_name,
 		const char *type_page, unsigned long flags, void *data_page);
 int __init init_umount(const char *name, int flags);
 int __init init_chdir(const char *filename);
+int __init init_chroot(const char *filename);
 int __init init_unlink(const char *pathname);
 int __init init_rmdir(const char *pathname);
diff --git a/include/linux/syscalls.h b/include/linux/syscalls.h
index 31fa67fb9894b3..e89d62e944dc0e 100644
--- a/include/linux/syscalls.h
+++ b/include/linux/syscalls.h
@@ -1235,8 +1235,6 @@ asmlinkage long sys_ni_syscall(void);
  * Instead, use one of the functions which work equivalently, such as
  * 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 a7581c6e85f268..b5f9604d0c98a2 100644
--- a/init/do_mounts.c
+++ b/init/do_mounts.c
@@ -629,7 +629,7 @@ void __init prepare_namespace(void)
 out:
 	devtmpfs_mount();
 	init_mount(".", "/", NULL, MS_MOVE, NULL);
-	ksys_chroot(".");
+	init_chroot(".");
 }
 
 static bool is_tmpfs;
diff --git a/init/do_mounts_initrd.c b/init/do_mounts_initrd.c
index 04627fd22a921f..a6b447b191dbc8 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 */
 	init_chdir("/root");
 	init_mount(".", "/", NULL, MS_MOVE, NULL);
-	ksys_chroot(".");
+	init_chroot(".");
 	ksys_setsid();
 	return 0;
 }
@@ -101,7 +101,7 @@ static void __init handle_initrd(void)
 	/* move initrd to rootfs' /old */
 	init_mount("..", ".", NULL, MS_MOVE, NULL);
 	/* switch root and cwd back to / of rootfs */
-	ksys_chroot("..");
+	init_chroot("..");
 
 	if (new_decode_dev(real_root_dev) == Root_RAM0) {
 		init_chdir("/old");
-- 
2.27.0

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

* [PATCH 14/23] init: add an init_chown helper
  2020-07-28 16:33 add file system helpers that take kernel pointers for the init code v4 Christoph Hellwig
                   ` (9 preceding siblings ...)
  2020-07-28 16:34 ` [PATCH 13/23] init: add an init_chroot helper Christoph Hellwig
@ 2020-07-28 16:34 ` Christoph Hellwig
  2020-07-28 16:34 ` [PATCH 15/23] init: add an init_chmod helper Christoph Hellwig
                   ` (10 subsequent siblings)
  21 siblings, 0 replies; 35+ messages in thread
From: Christoph Hellwig @ 2020-07-28 16:34 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 file name and switch
the early init code over to it.

Signed-off-by: Christoph Hellwig <hch@lst.de>
---
 fs/init.c                     | 18 ++++++++++++++++++
 fs/internal.h                 |  2 +-
 fs/open.c                     |  2 +-
 include/linux/init_syscalls.h |  1 +
 init/initramfs.c              |  6 +++---
 5 files changed, 24 insertions(+), 5 deletions(-)

diff --git a/fs/init.c b/fs/init.c
index 2c78f24814dde4..edd0244655956e 100644
--- a/fs/init.c
+++ b/fs/init.c
@@ -78,6 +78,24 @@ int __init init_chroot(const char *filename)
 	return error;
 }
 
+int __init init_chown(const char *filename, uid_t user, gid_t group, int flags)
+{
+	int lookup_flags = (flags & AT_SYMLINK_NOFOLLOW) ? 0 : LOOKUP_FOLLOW;
+	struct path path;
+	int error;
+
+	error = kern_path(filename, lookup_flags, &path);
+	if (error)
+		return error;
+	error = mnt_want_write(path.mnt);
+	if (!error) {
+		error = chown_common(&path, user, group);
+		mnt_drop_write(path.mnt);
+	}
+	path_put(&path);
+	return error;
+}
+
 int __init init_unlink(const char *pathname)
 {
 	return do_unlinkat(AT_FDCWD, getname_kernel(pathname));
diff --git a/fs/internal.h b/fs/internal.h
index 491d1e63809b37..e81b9e23c3ea3f 100644
--- a/fs/internal.h
+++ b/fs/internal.h
@@ -134,7 +134,7 @@ 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);
-
+int chown_common(const struct path *path, uid_t user, gid_t group);
 extern int vfs_open(const struct path *, struct file *);
 
 /*
diff --git a/fs/open.c b/fs/open.c
index f62f4752bb436d..49960a1248f14b 100644
--- a/fs/open.c
+++ b/fs/open.c
@@ -639,7 +639,7 @@ SYSCALL_DEFINE2(chmod, const char __user *, filename, umode_t, mode)
 	return do_fchmodat(AT_FDCWD, filename, mode);
 }
 
-static int chown_common(const struct path *path, uid_t user, gid_t group)
+int chown_common(const struct path *path, uid_t user, gid_t group)
 {
 	struct inode *inode = path->dentry->d_inode;
 	struct inode *delegated_inode = NULL;
diff --git a/include/linux/init_syscalls.h b/include/linux/init_syscalls.h
index e07099a14b91db..0da59d76133e17 100644
--- a/include/linux/init_syscalls.h
+++ b/include/linux/init_syscalls.h
@@ -5,5 +5,6 @@ int __init init_mount(const char *dev_name, const char *dir_name,
 int __init init_umount(const char *name, int flags);
 int __init init_chdir(const char *filename);
 int __init init_chroot(const char *filename);
+int __init init_chown(const char *filename, uid_t user, gid_t group, int flags);
 int __init init_unlink(const char *pathname);
 int __init init_rmdir(const char *pathname);
diff --git a/init/initramfs.c b/init/initramfs.c
index fb7210731d9e5d..24a8dcc6734064 100644
--- a/init/initramfs.c
+++ b/init/initramfs.c
@@ -349,14 +349,14 @@ static int __init do_name(void)
 		}
 	} else if (S_ISDIR(mode)) {
 		ksys_mkdir(collected, mode);
-		ksys_chown(collected, uid, gid);
+		init_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);
+			init_chown(collected, uid, gid, 0);
 			ksys_chmod(collected, mode);
 			do_utime(collected, mtime);
 		}
@@ -394,7 +394,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);
+	init_chown(collected, uid, gid, AT_SYMLINK_NOFOLLOW);
 	do_utime(collected, mtime);
 	state = SkipIt;
 	next_state = Reset;
-- 
2.27.0

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

* [PATCH 15/23] init: add an init_chmod helper
  2020-07-28 16:33 add file system helpers that take kernel pointers for the init code v4 Christoph Hellwig
                   ` (10 preceding siblings ...)
  2020-07-28 16:34 ` [PATCH 14/23] init: add an init_chown helper Christoph Hellwig
@ 2020-07-28 16:34 ` Christoph Hellwig
  2020-07-28 16:34 ` [PATCH 16/23] init: add an init_eaccess helper Christoph Hellwig
                   ` (9 subsequent siblings)
  21 siblings, 0 replies; 35+ messages in thread
From: Christoph Hellwig @ 2020-07-28 16:34 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 chmod with a kernel space file name and switch
the early init code over to it.

Signed-off-by: Christoph Hellwig <hch@lst.de>
---
 fs/init.c                     | 13 +++++++++++++
 fs/internal.h                 |  2 +-
 fs/open.c                     |  4 ++--
 include/linux/init_syscalls.h |  1 +
 include/linux/syscalls.h      |  7 -------
 init/initramfs.c              |  4 ++--
 6 files changed, 19 insertions(+), 12 deletions(-)

diff --git a/fs/init.c b/fs/init.c
index edd0244655956e..a66032d128b618 100644
--- a/fs/init.c
+++ b/fs/init.c
@@ -96,6 +96,19 @@ int __init init_chown(const char *filename, uid_t user, gid_t group, int flags)
 	return error;
 }
 
+int __init init_chmod(const char *filename, umode_t mode)
+{
+	struct path path;
+	int error;
+
+	error = kern_path(filename, LOOKUP_FOLLOW, &path);
+	if (error)
+		return error;
+	error = chmod_common(&path, mode);
+	path_put(&path);
+	return error;
+}
+
 int __init init_unlink(const char *pathname)
 {
 	return do_unlinkat(AT_FDCWD, getname_kernel(pathname));
diff --git a/fs/internal.h b/fs/internal.h
index e81b9e23c3ea3f..6d82681c7d8372 100644
--- a/fs/internal.h
+++ b/fs/internal.h
@@ -131,7 +131,7 @@ 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);
+int chmod_common(const struct path *path, umode_t mode);
 int do_fchownat(int dfd, const char __user *filename, uid_t user, gid_t group,
 		int flag);
 int chown_common(const struct path *path, uid_t user, gid_t group);
diff --git a/fs/open.c b/fs/open.c
index 49960a1248f14b..7ba89eae46c560 100644
--- a/fs/open.c
+++ b/fs/open.c
@@ -563,7 +563,7 @@ SYSCALL_DEFINE1(chroot, const char __user *, filename)
 	return error;
 }
 
-static int chmod_common(const struct path *path, umode_t mode)
+int chmod_common(const struct path *path, umode_t mode)
 {
 	struct inode *inode = path->dentry->d_inode;
 	struct inode *delegated_inode = NULL;
@@ -610,7 +610,7 @@ 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, const char __user *filename, umode_t mode)
 {
 	struct path path;
 	int error;
diff --git a/include/linux/init_syscalls.h b/include/linux/init_syscalls.h
index 0da59d76133e17..2b1b4dc586825f 100644
--- a/include/linux/init_syscalls.h
+++ b/include/linux/init_syscalls.h
@@ -6,5 +6,6 @@ int __init init_umount(const char *name, int flags);
 int __init init_chdir(const char *filename);
 int __init init_chroot(const char *filename);
 int __init init_chown(const char *filename, uid_t user, gid_t group, int flags);
+int __init init_chmod(const char *filename, umode_t mode);
 int __init init_unlink(const char *pathname);
 int __init init_rmdir(const char *pathname);
diff --git a/include/linux/syscalls.h b/include/linux/syscalls.h
index e89d62e944dc0e..8b71fa321ca20c 100644
--- a/include/linux/syscalls.h
+++ b/include/linux/syscalls.h
@@ -1304,13 +1304,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);
-}
-
 long do_faccessat(int dfd, const char __user *filename, int mode, int flags);
 
 static inline long ksys_access(const char __user *filename, int mode)
diff --git a/init/initramfs.c b/init/initramfs.c
index 24a8dcc6734064..21a75f6ca893a9 100644
--- a/init/initramfs.c
+++ b/init/initramfs.c
@@ -350,14 +350,14 @@ static int __init do_name(void)
 	} else if (S_ISDIR(mode)) {
 		ksys_mkdir(collected, mode);
 		init_chown(collected, uid, gid, 0);
-		ksys_chmod(collected, mode);
+		init_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);
 			init_chown(collected, uid, gid, 0);
-			ksys_chmod(collected, mode);
+			init_chmod(collected, mode);
 			do_utime(collected, mtime);
 		}
 	}
-- 
2.27.0

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

* [PATCH 16/23] init: add an init_eaccess helper
  2020-07-28 16:33 add file system helpers that take kernel pointers for the init code v4 Christoph Hellwig
                   ` (11 preceding siblings ...)
  2020-07-28 16:34 ` [PATCH 15/23] init: add an init_chmod helper Christoph Hellwig
@ 2020-07-28 16:34 ` Christoph Hellwig
  2020-07-28 16:34 ` [PATCH 17/23] init: add an init_link helper Christoph Hellwig
                   ` (8 subsequent siblings)
  21 siblings, 0 replies; 35+ messages in thread
From: Christoph Hellwig @ 2020-07-28 16:34 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 check if a file exists based on kernel space file
name and switch the early init code over to it.  Note that this
theoretically changes behavior as it always is based on the effective
permissions.  But during early init that doesn't make a difference.

Signed-off-by: Christoph Hellwig <hch@lst.de>
---
 fs/init.c                     | 13 +++++++++++++
 fs/open.c                     |  2 +-
 include/linux/init_syscalls.h |  1 +
 include/linux/syscalls.h      |  7 -------
 init/main.c                   |  4 ++--
 5 files changed, 17 insertions(+), 10 deletions(-)

diff --git a/fs/init.c b/fs/init.c
index a66032d128b618..6d9af40d2897b1 100644
--- a/fs/init.c
+++ b/fs/init.c
@@ -109,6 +109,19 @@ int __init init_chmod(const char *filename, umode_t mode)
 	return error;
 }
 
+int __init init_eaccess(const char *filename)
+{
+	struct path path;
+	int error;
+
+	error = kern_path(filename, LOOKUP_FOLLOW, &path);
+	if (error)
+		return error;
+	error = inode_permission(d_inode(path.dentry), MAY_ACCESS);
+	path_put(&path);
+	return error;
+}
+
 int __init init_unlink(const char *pathname)
 {
 	return do_unlinkat(AT_FDCWD, getname_kernel(pathname));
diff --git a/fs/open.c b/fs/open.c
index 7ba89eae46c560..aafecd1f7ba1a5 100644
--- a/fs/open.c
+++ b/fs/open.c
@@ -394,7 +394,7 @@ 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 long do_faccessat(int dfd, const char __user *filename, int mode, int flags)
 {
 	struct path path;
 	struct inode *inode;
diff --git a/include/linux/init_syscalls.h b/include/linux/init_syscalls.h
index 2b1b4dc586825f..7031c0934bee9f 100644
--- a/include/linux/init_syscalls.h
+++ b/include/linux/init_syscalls.h
@@ -7,5 +7,6 @@ int __init init_chdir(const char *filename);
 int __init init_chroot(const char *filename);
 int __init init_chown(const char *filename, uid_t user, gid_t group, int flags);
 int __init init_chmod(const char *filename, umode_t mode);
+int __init init_eaccess(const char *filename);
 int __init init_unlink(const char *pathname);
 int __init init_rmdir(const char *pathname);
diff --git a/include/linux/syscalls.h b/include/linux/syscalls.h
index 8b71fa321ca20c..a2779638e41445 100644
--- a/include/linux/syscalls.h
+++ b/include/linux/syscalls.h
@@ -1304,13 +1304,6 @@ static inline long ksys_link(const char __user *oldname,
 	return do_linkat(AT_FDCWD, oldname, AT_FDCWD, newname, 0);
 }
 
-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 47698427b15f62..1c710d3e1d461a 100644
--- a/init/main.c
+++ b/init/main.c
@@ -96,6 +96,7 @@
 #include <linux/jump_label.h>
 #include <linux/mem_encrypt.h>
 #include <linux/kcsan.h>
+#include <linux/init_syscalls.h>
 
 #include <asm/io.h>
 #include <asm/bugs.h>
@@ -1514,8 +1515,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 (init_eaccess(ramdisk_execute_command) != 0) {
 		ramdisk_execute_command = NULL;
 		prepare_namespace();
 	}
-- 
2.27.0

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

* [PATCH 17/23] init: add an init_link helper
  2020-07-28 16:33 add file system helpers that take kernel pointers for the init code v4 Christoph Hellwig
                   ` (12 preceding siblings ...)
  2020-07-28 16:34 ` [PATCH 16/23] init: add an init_eaccess helper Christoph Hellwig
@ 2020-07-28 16:34 ` Christoph Hellwig
  2020-07-28 16:34 ` [PATCH 18/23] init: add an init_symlink helper Christoph Hellwig
                   ` (7 subsequent siblings)
  21 siblings, 0 replies; 35+ messages in thread
From: Christoph Hellwig @ 2020-07-28 16:34 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 link with a kernel space file name and switch
the early init code over to it.  Remove the now unused ksys_link.

Signed-off-by: Christoph Hellwig <hch@lst.de>
---
 fs/init.c                     | 33 +++++++++++++++++++++++++++++++++
 fs/internal.h                 |  3 +--
 fs/namei.c                    |  4 ++--
 include/linux/init_syscalls.h |  1 +
 include/linux/syscalls.h      |  9 ---------
 init/initramfs.c              |  2 +-
 6 files changed, 38 insertions(+), 14 deletions(-)

diff --git a/fs/init.c b/fs/init.c
index 6d9af40d2897b1..5db9d9f74868e1 100644
--- a/fs/init.c
+++ b/fs/init.c
@@ -122,6 +122,39 @@ int __init init_eaccess(const char *filename)
 	return error;
 }
 
+int __init init_link(const char *oldname, const char *newname)
+{
+	struct dentry *new_dentry;
+	struct path old_path, new_path;
+	int error;
+
+	error = kern_path(oldname, 0, &old_path);
+	if (error)
+		return error;
+
+	new_dentry = kern_path_create(AT_FDCWD, newname, &new_path, 0);
+	error = PTR_ERR(new_dentry);
+	if (IS_ERR(new_dentry))
+		goto out;
+
+	error = -EXDEV;
+	if (old_path.mnt != new_path.mnt)
+		goto out_dput;
+	error = may_linkat(&old_path);
+	if (unlikely(error))
+		goto out_dput;
+	error = security_path_link(old_path.dentry, &new_path, new_dentry);
+	if (error)
+		goto out_dput;
+	error = vfs_link(old_path.dentry, new_path.dentry->d_inode, new_dentry,
+			 NULL);
+out_dput:
+	done_path_create(&new_path, new_dentry);
+out:
+	path_put(&old_path);
+	return error;
+}
+
 int __init init_unlink(const char *pathname)
 {
 	return do_unlinkat(AT_FDCWD, getname_kernel(pathname));
diff --git a/fs/internal.h b/fs/internal.h
index 6d82681c7d8372..58451b033d2698 100644
--- a/fs/internal.h
+++ b/fs/internal.h
@@ -69,8 +69,7 @@ long do_rmdir(int dfd, struct filename *name);
 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);
+int may_linkat(struct path *link);
 
 /*
  * namespace.c
diff --git a/fs/namei.c b/fs/namei.c
index d75a6039ae3966..13de64c6be7640 100644
--- a/fs/namei.c
+++ b/fs/namei.c
@@ -1024,7 +1024,7 @@ static bool safe_hardlink_source(struct inode *inode)
  *
  * Returns 0 if successful, -ve on error.
  */
-static int may_linkat(struct path *link)
+int may_linkat(struct path *link)
 {
 	struct inode *inode = link->dentry->d_inode;
 
@@ -4086,7 +4086,7 @@ 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,
+static int do_linkat(int olddfd, const char __user *oldname, int newdfd,
 	      const char __user *newname, int flags)
 {
 	struct dentry *new_dentry;
diff --git a/include/linux/init_syscalls.h b/include/linux/init_syscalls.h
index 7031c0934bee9f..5ca15a5b55b7d7 100644
--- a/include/linux/init_syscalls.h
+++ b/include/linux/init_syscalls.h
@@ -8,5 +8,6 @@ int __init init_chroot(const char *filename);
 int __init init_chown(const char *filename, uid_t user, gid_t group, int flags);
 int __init init_chmod(const char *filename, umode_t mode);
 int __init init_eaccess(const char *filename);
+int __init init_link(const char *oldname, const char *newname);
 int __init init_unlink(const char *pathname);
 int __init init_rmdir(const char *pathname);
diff --git a/include/linux/syscalls.h b/include/linux/syscalls.h
index a2779638e41445..4b18b91ce46573 100644
--- a/include/linux/syscalls.h
+++ b/include/linux/syscalls.h
@@ -1295,15 +1295,6 @@ static inline long ksys_mknod(const char __user *filename, umode_t mode,
 	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);
-
-static inline long ksys_link(const char __user *oldname,
-			     const char __user *newname)
-{
-	return do_linkat(AT_FDCWD, oldname, AT_FDCWD, newname, 0);
-}
-
 extern int do_fchownat(int dfd, const char __user *filename, uid_t user,
 		       gid_t group, int flag);
 
diff --git a/init/initramfs.c b/init/initramfs.c
index 21a75f6ca893a9..a3d29318cc351d 100644
--- a/init/initramfs.c
+++ b/init/initramfs.c
@@ -312,7 +312,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 (init_link(old, collected) < 0) ? -1 : 1;
 		}
 	}
 	return 0;
-- 
2.27.0

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

* [PATCH 18/23] init: add an init_symlink helper
  2020-07-28 16:33 add file system helpers that take kernel pointers for the init code v4 Christoph Hellwig
                   ` (13 preceding siblings ...)
  2020-07-28 16:34 ` [PATCH 17/23] init: add an init_link helper Christoph Hellwig
@ 2020-07-28 16:34 ` Christoph Hellwig
  2020-07-28 16:34 ` [PATCH 19/23] init: add an init_mkdir helper Christoph Hellwig
                   ` (6 subsequent siblings)
  21 siblings, 0 replies; 35+ messages in thread
From: Christoph Hellwig @ 2020-07-28 16:34 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 symlink with a kernel space file name and switch
the early init code over to it.  Remove the now unused ksys_symlink.

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

diff --git a/fs/init.c b/fs/init.c
index 5db9d9f74868e1..09ef2b58d48caa 100644
--- a/fs/init.c
+++ b/fs/init.c
@@ -155,6 +155,22 @@ int __init init_link(const char *oldname, const char *newname)
 	return error;
 }
 
+int __init init_symlink(const char *oldname, const char *newname)
+{
+	struct dentry *dentry;
+	struct path path;
+	int error;
+
+	dentry = kern_path_create(AT_FDCWD, newname, &path, 0);
+	if (IS_ERR(dentry))
+		return PTR_ERR(dentry);
+	error = security_path_symlink(&path, dentry, oldname);
+	if (!error)
+		error = vfs_symlink(path.dentry->d_inode, dentry, oldname);
+	done_path_create(&path, dentry);
+	return error;
+}
+
 int __init init_unlink(const char *pathname)
 {
 	return do_unlinkat(AT_FDCWD, getname_kernel(pathname));
diff --git a/fs/internal.h b/fs/internal.h
index 58451b033d2698..40b50a222d7a22 100644
--- a/fs/internal.h
+++ b/fs/internal.h
@@ -67,8 +67,6 @@ long do_mknodat(int dfd, const char __user *filename, umode_t mode,
 long do_mkdirat(int dfd, const char __user *pathname, umode_t mode);
 long do_rmdir(int dfd, struct filename *name);
 long do_unlinkat(int dfd, struct filename *name);
-long do_symlinkat(const char __user *oldname, int newdfd,
-		  const char __user *newname);
 int may_linkat(struct path *link);
 
 /*
diff --git a/fs/namei.c b/fs/namei.c
index 13de64c6be7640..2f6fa53eb3da28 100644
--- a/fs/namei.c
+++ b/fs/namei.c
@@ -3955,7 +3955,7 @@ 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,
+static long do_symlinkat(const char __user *oldname, int newdfd,
 		  const char __user *newname)
 {
 	int error;
diff --git a/include/linux/init_syscalls.h b/include/linux/init_syscalls.h
index 5ca15a5b55b7d7..125f55ae3f80b8 100644
--- a/include/linux/init_syscalls.h
+++ b/include/linux/init_syscalls.h
@@ -9,5 +9,6 @@ int __init init_chown(const char *filename, uid_t user, gid_t group, int flags);
 int __init init_chmod(const char *filename, umode_t mode);
 int __init init_eaccess(const char *filename);
 int __init init_link(const char *oldname, const char *newname);
+int __init init_symlink(const char *oldname, const char *newname);
 int __init init_unlink(const char *pathname);
 int __init init_rmdir(const char *pathname);
diff --git a/include/linux/syscalls.h b/include/linux/syscalls.h
index 4b18b91ce46573..7cdc0d749a049f 100644
--- a/include/linux/syscalls.h
+++ b/include/linux/syscalls.h
@@ -1277,15 +1277,6 @@ 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);
-
-static inline long ksys_symlink(const char __user *oldname,
-				const char __user *newname)
-{
-	return do_symlinkat(oldname, AT_FDCWD, newname);
-}
-
 extern long do_mknodat(int dfd, const char __user *filename, umode_t mode,
 		       unsigned int dev);
 
diff --git a/init/initramfs.c b/init/initramfs.c
index a3d29318cc351d..b74d18657e7a17 100644
--- a/init/initramfs.c
+++ b/init/initramfs.c
@@ -393,7 +393,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);
+	init_symlink(collected + N_ALIGN(name_len), collected);
 	init_chown(collected, uid, gid, AT_SYMLINK_NOFOLLOW);
 	do_utime(collected, mtime);
 	state = SkipIt;
-- 
2.27.0

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

* [PATCH 19/23] init: add an init_mkdir helper
  2020-07-28 16:33 add file system helpers that take kernel pointers for the init code v4 Christoph Hellwig
                   ` (14 preceding siblings ...)
  2020-07-28 16:34 ` [PATCH 18/23] init: add an init_symlink helper Christoph Hellwig
@ 2020-07-28 16:34 ` Christoph Hellwig
  2020-07-28 16:34 ` [PATCH 20/23] init: add an init_mknod helper Christoph Hellwig
                   ` (5 subsequent siblings)
  21 siblings, 0 replies; 35+ messages in thread
From: Christoph Hellwig @ 2020-07-28 16:34 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 mkdir with a kernel space file name and switch
the early init code over to it.  Remove the now unused ksys_mkdir.

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

diff --git a/fs/init.c b/fs/init.c
index 09ef2b58d48caa..127033d0842601 100644
--- a/fs/init.c
+++ b/fs/init.c
@@ -176,6 +176,24 @@ int __init init_unlink(const char *pathname)
 	return do_unlinkat(AT_FDCWD, getname_kernel(pathname));
 }
 
+int __init init_mkdir(const char *pathname, umode_t mode)
+{
+	struct dentry *dentry;
+	struct path path;
+	int error;
+
+	dentry = kern_path_create(AT_FDCWD, pathname, &path, LOOKUP_DIRECTORY);
+	if (IS_ERR(dentry))
+		return PTR_ERR(dentry);
+	if (!IS_POSIXACL(path.dentry->d_inode))
+		mode &= ~current_umask();
+	error = security_path_mkdir(&path, dentry, mode);
+	if (!error)
+		error = vfs_mkdir(path.dentry->d_inode, dentry, mode);
+	done_path_create(&path, dentry);
+	return error;
+}
+
 int __init init_rmdir(const char *pathname)
 {
 	return do_rmdir(AT_FDCWD, getname_kernel(pathname));
diff --git a/fs/internal.h b/fs/internal.h
index 40b50a222d7a22..4741e591e923bf 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, struct filename *name);
 long do_unlinkat(int dfd, struct filename *name);
 int may_linkat(struct path *link);
diff --git a/fs/namei.c b/fs/namei.c
index 2f6fa53eb3da28..d6b25dd32f4d50 100644
--- a/fs/namei.c
+++ b/fs/namei.c
@@ -3645,7 +3645,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 long do_mkdirat(int dfd, const char __user *pathname, umode_t mode)
 {
 	struct dentry *dentry;
 	struct path path;
diff --git a/include/linux/init_syscalls.h b/include/linux/init_syscalls.h
index 125f55ae3f80b8..d808985231f8f8 100644
--- a/include/linux/init_syscalls.h
+++ b/include/linux/init_syscalls.h
@@ -11,4 +11,5 @@ int __init init_eaccess(const char *filename);
 int __init init_link(const char *oldname, const char *newname);
 int __init init_symlink(const char *oldname, const char *newname);
 int __init init_unlink(const char *pathname);
+int __init init_mkdir(const char *pathname, umode_t mode);
 int __init init_rmdir(const char *pathname);
diff --git a/include/linux/syscalls.h b/include/linux/syscalls.h
index 7cdc0d749a049f..5ef77a91382aa5 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_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_mknodat(int dfd, const char __user *filename, umode_t mode,
 		       unsigned int dev);
 
diff --git a/init/do_mounts_initrd.c b/init/do_mounts_initrd.c
index a6b447b191dbc8..3f5ac81913dde4 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);
+	init_mkdir("/old", 0700);
 	init_chdir("/old");
 
 	/*
diff --git a/init/initramfs.c b/init/initramfs.c
index b74d18657e7a17..23513e4419e052 100644
--- a/init/initramfs.c
+++ b/init/initramfs.c
@@ -348,7 +348,7 @@ static int __init do_name(void)
 			state = CopyFile;
 		}
 	} else if (S_ISDIR(mode)) {
-		ksys_mkdir(collected, mode);
+		init_mkdir(collected, mode);
 		init_chown(collected, uid, gid, 0);
 		init_chmod(collected, mode);
 		dir_add(collected, mtime);
diff --git a/init/noinitramfs.c b/init/noinitramfs.c
index fa9cdfa7101d3c..94cc4df74b11f2 100644
--- a/init/noinitramfs.c
+++ b/init/noinitramfs.c
@@ -9,6 +9,7 @@
 #include <linux/stat.h>
 #include <linux/kdev_t.h>
 #include <linux/syscalls.h>
+#include <linux/init_syscalls.h>
 
 /*
  * Create a simple rootfs that is similar to the default initramfs
@@ -17,7 +18,7 @@ static int __init default_rootfs(void)
 {
 	int err;
 
-	err = ksys_mkdir((const char __user __force *) "/dev", 0755);
+	err = init_mkdir("/dev", 0755);
 	if (err < 0)
 		goto out;
 
@@ -27,7 +28,7 @@ static int __init default_rootfs(void)
 	if (err < 0)
 		goto out;
 
-	err = ksys_mkdir((const char __user __force *) "/root", 0700);
+	err = init_mkdir("/root", 0700);
 	if (err < 0)
 		goto out;
 
-- 
2.27.0

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

* [PATCH 20/23] init: add an init_mknod helper
  2020-07-28 16:33 add file system helpers that take kernel pointers for the init code v4 Christoph Hellwig
                   ` (15 preceding siblings ...)
  2020-07-28 16:34 ` [PATCH 19/23] init: add an init_mkdir helper Christoph Hellwig
@ 2020-07-28 16:34 ` Christoph Hellwig
  2020-07-28 16:34 ` [PATCH 21/23] init: add an init_stat helper Christoph Hellwig
                   ` (4 subsequent siblings)
  21 siblings, 0 replies; 35+ messages in thread
From: Christoph Hellwig @ 2020-07-28 16:34 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 mknod with a kernel space file name and switch
the early init code over to it.  Remove the now unused ksys_mknod.

Signed-off-by: Christoph Hellwig <hch@lst.de>
---
 fs/init.c                     | 25 +++++++++++++++++++++++++
 fs/internal.h                 |  2 --
 fs/namei.c                    |  2 +-
 include/linux/init_syscalls.h |  1 +
 include/linux/syscalls.h      |  9 ---------
 init/do_mounts.h              |  2 +-
 init/initramfs.c              |  2 +-
 init/noinitramfs.c            |  3 +--
 8 files changed, 30 insertions(+), 16 deletions(-)

diff --git a/fs/init.c b/fs/init.c
index 127033d0842601..145fb31b7a5f2d 100644
--- a/fs/init.c
+++ b/fs/init.c
@@ -122,6 +122,31 @@ int __init init_eaccess(const char *filename)
 	return error;
 }
 
+int __init init_mknod(const char *filename, umode_t mode, unsigned int dev)
+{
+	struct dentry *dentry;
+	struct path path;
+	int error;
+
+	if (S_ISFIFO(mode) || S_ISSOCK(mode))
+		dev = 0;
+	else if (!(S_ISBLK(mode) || S_ISCHR(mode)))
+		return -EINVAL;
+
+	dentry = kern_path_create(AT_FDCWD, filename, &path, 0);
+	if (IS_ERR(dentry))
+		return PTR_ERR(dentry);
+
+	if (!IS_POSIXACL(path.dentry->d_inode))
+		mode &= ~current_umask();
+	error = security_path_mknod(&path, dentry, mode, dev);
+	if (!error)
+		error = vfs_mknod(path.dentry->d_inode, dentry, mode,
+				  new_decode_dev(dev));
+	done_path_create(&path, dentry);
+	return error;
+}
+
 int __init init_link(const char *oldname, const char *newname)
 {
 	struct dentry *new_dentry;
diff --git a/fs/internal.h b/fs/internal.h
index 4741e591e923bf..07e145b2f88c4a 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, struct filename *name);
 long do_unlinkat(int dfd, struct filename *name);
 int may_linkat(struct path *link);
diff --git a/fs/namei.c b/fs/namei.c
index d6b25dd32f4d50..fde8fe086c090d 100644
--- a/fs/namei.c
+++ b/fs/namei.c
@@ -3564,7 +3564,7 @@ static int may_mknod(umode_t mode)
 	}
 }
 
-long do_mknodat(int dfd, const char __user *filename, umode_t mode,
+static long do_mknodat(int dfd, const char __user *filename, umode_t mode,
 		unsigned int dev)
 {
 	struct dentry *dentry;
diff --git a/include/linux/init_syscalls.h b/include/linux/init_syscalls.h
index d808985231f8f8..fa1fe7a877795f 100644
--- a/include/linux/init_syscalls.h
+++ b/include/linux/init_syscalls.h
@@ -8,6 +8,7 @@ int __init init_chroot(const char *filename);
 int __init init_chown(const char *filename, uid_t user, gid_t group, int flags);
 int __init init_chmod(const char *filename, umode_t mode);
 int __init init_eaccess(const char *filename);
+int __init init_mknod(const char *filename, umode_t mode, unsigned int dev);
 int __init init_link(const char *oldname, const char *newname);
 int __init init_symlink(const char *oldname, const char *newname);
 int __init init_unlink(const char *pathname);
diff --git a/include/linux/syscalls.h b/include/linux/syscalls.h
index 5ef77a91382aa5..63046c5e9fc5d4 100644
--- a/include/linux/syscalls.h
+++ b/include/linux/syscalls.h
@@ -1270,15 +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_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_fchownat(int dfd, const char __user *filename, uid_t user,
 		       gid_t group, int flag);
 
diff --git a/init/do_mounts.h b/init/do_mounts.h
index 104d8431725aeb..7a29ac3e427bab 100644
--- a/init/do_mounts.h
+++ b/init/do_mounts.h
@@ -17,7 +17,7 @@ extern int root_mountflags;
 static inline __init int create_dev(char *name, dev_t dev)
 {
 	init_unlink(name);
-	return ksys_mknod(name, S_IFBLK|0600, new_encode_dev(dev));
+	return init_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 23513e4419e052..ad5800c2d8e206 100644
--- a/init/initramfs.c
+++ b/init/initramfs.c
@@ -355,7 +355,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);
+			init_mknod(collected, mode, rdev);
 			init_chown(collected, uid, gid, 0);
 			init_chmod(collected, mode);
 			do_utime(collected, mtime);
diff --git a/init/noinitramfs.c b/init/noinitramfs.c
index 94cc4df74b11f2..3d62b07f3bb9c3 100644
--- a/init/noinitramfs.c
+++ b/init/noinitramfs.c
@@ -22,8 +22,7 @@ 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,
+	err = init_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] 35+ messages in thread

* [PATCH 21/23] init: add an init_stat helper
  2020-07-28 16:33 add file system helpers that take kernel pointers for the init code v4 Christoph Hellwig
                   ` (16 preceding siblings ...)
  2020-07-28 16:34 ` [PATCH 20/23] init: add an init_mknod helper Christoph Hellwig
@ 2020-07-28 16:34 ` Christoph Hellwig
  2020-09-04 13:53   ` [PATCH] init: fix error check in clean_path() Barret Rhoden
       [not found] ` <20200728163416.556521-1-hch-jcswGhMUV9g@public.gmane.org>
                   ` (3 subsequent siblings)
  21 siblings, 1 reply; 35+ messages in thread
From: Christoph Hellwig @ 2020-07-28 16:34 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 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    |  3 ++-
 fs/init.c                     | 15 +++++++++++++++
 include/linux/init_syscalls.h |  1 +
 init/initramfs.c              |  3 ++-
 4 files changed, 20 insertions(+), 2 deletions(-)

diff --git a/drivers/md/md-autodetect.c b/drivers/md/md-autodetect.c
index 14b6e86814c061..6bbec89976a748 100644
--- a/drivers/md/md-autodetect.c
+++ b/drivers/md/md-autodetect.c
@@ -5,6 +5,7 @@
 #include <linux/mount.h>
 #include <linux/major.h>
 #include <linux/delay.h>
+#include <linux/init_syscalls.h>
 #include <linux/raid/detect.h>
 #include <linux/raid/md_u.h>
 #include <linux/raid/md_p.h>
@@ -151,7 +152,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 (init_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/init.c b/fs/init.c
index 145fb31b7a5f2d..51646ba38099e6 100644
--- a/fs/init.c
+++ b/fs/init.c
@@ -122,6 +122,21 @@ int __init init_eaccess(const char *filename)
 	return error;
 }
 
+int __init init_stat(const char *filename, struct kstat *stat, int flags)
+{
+	int lookup_flags = (flags & AT_SYMLINK_NOFOLLOW) ? 0 : LOOKUP_FOLLOW;
+	struct path path;
+	int error;
+
+	error = kern_path(filename, lookup_flags, &path);
+	if (error)
+		return error;
+	error = vfs_getattr(&path, stat, STATX_BASIC_STATS,
+			    flags | AT_NO_AUTOMOUNT);
+	path_put(&path);
+	return error;
+}
+
 int __init init_mknod(const char *filename, umode_t mode, unsigned int dev)
 {
 	struct dentry *dentry;
diff --git a/include/linux/init_syscalls.h b/include/linux/init_syscalls.h
index fa1fe7a877795f..b2fda50daca6c5 100644
--- a/include/linux/init_syscalls.h
+++ b/include/linux/init_syscalls.h
@@ -8,6 +8,7 @@ int __init init_chroot(const char *filename);
 int __init init_chown(const char *filename, uid_t user, gid_t group, int flags);
 int __init init_chmod(const char *filename, umode_t mode);
 int __init init_eaccess(const char *filename);
+int __init init_stat(const char *filename, struct kstat *stat, int flags);
 int __init init_mknod(const char *filename, umode_t mode, unsigned int dev);
 int __init init_link(const char *oldname, const char *newname);
 int __init init_symlink(const char *oldname, const char *newname);
diff --git a/init/initramfs.c b/init/initramfs.c
index ad5800c2d8e206..8f7e39f06547ff 100644
--- a/init/initramfs.c
+++ b/init/initramfs.c
@@ -298,7 +298,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 (init_stat(path, &st, AT_SYMLINK_NOFOLLOW) &&
+	    (st.mode ^ fmode) & S_IFMT) {
 		if (S_ISDIR(st.mode))
 			init_rmdir(path);
 		else
-- 
2.27.0

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

* [PATCH 22/23] init: add an init_utimes helper
       [not found] ` <20200728163416.556521-1-hch-jcswGhMUV9g@public.gmane.org>
                     ` (2 preceding siblings ...)
  2020-07-28 16:34   ` [PATCH 07/23] init: mark create_dev " Christoph Hellwig
@ 2020-07-28 16:34   ` Christoph Hellwig
  3 siblings, 0 replies; 35+ messages in thread
From: Christoph Hellwig @ 2020-07-28 16:34 UTC (permalink / raw)
  To: Al Viro, Linus Torvalds
  Cc: Greg Kroah-Hartman, Rafael J. Wysocki,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	linux-raid-u79uwXL29TY76Z2rM5mHXA,
	linux-fsdevel-u79uwXL29TY76Z2rM5mHXA,
	linux-api-u79uwXL29TY76Z2rM5mHXA

Add a simple helper to set timestamps with a kernel space file name and
switch the early init code over to it.

Signed-off-by: Christoph Hellwig <hch-jcswGhMUV9g@public.gmane.org>
---
 fs/init.c                     | 13 +++++++++++++
 include/linux/init_syscalls.h |  1 +
 init/initramfs.c              |  3 +--
 3 files changed, 15 insertions(+), 2 deletions(-)

diff --git a/fs/init.c b/fs/init.c
index 51646ba38099e6..db5c48a85644fa 100644
--- a/fs/init.c
+++ b/fs/init.c
@@ -238,3 +238,16 @@ int __init init_rmdir(const char *pathname)
 {
 	return do_rmdir(AT_FDCWD, getname_kernel(pathname));
 }
+
+int __init init_utimes(char *filename, struct timespec64 *ts)
+{
+	struct path path;
+	int error;
+
+	error = kern_path(filename, 0, &path);
+	if (error)
+		return error;
+	error = vfs_utimes(&path, ts);
+	path_put(&path);
+	return error;
+}
diff --git a/include/linux/init_syscalls.h b/include/linux/init_syscalls.h
index b2fda50daca6c5..3654b525ac0b17 100644
--- a/include/linux/init_syscalls.h
+++ b/include/linux/init_syscalls.h
@@ -15,3 +15,4 @@ int __init init_symlink(const char *oldname, const char *newname);
 int __init init_unlink(const char *pathname);
 int __init init_mkdir(const char *pathname, umode_t mode);
 int __init init_rmdir(const char *pathname);
+int __init init_utimes(char *filename, struct timespec64 *ts);
diff --git a/init/initramfs.c b/init/initramfs.c
index 8f7e39f06547ff..d5351737624edd 100644
--- a/init/initramfs.c
+++ b/init/initramfs.c
@@ -111,8 +111,7 @@ static long __init do_utime(char *filename, time64_t mtime)
 	t[0].tv_nsec = 0;
 	t[1].tv_sec = mtime;
 	t[1].tv_nsec = 0;
-
-	return do_utimes(AT_FDCWD, filename, t, AT_SYMLINK_NOFOLLOW);
+	return init_utimes(filename, t);
 }
 
 static __initdata LIST_HEAD(dir_list);
-- 
2.27.0

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

* [PATCH 23/23] init: add an init_dup helper
  2020-07-28 16:33 add file system helpers that take kernel pointers for the init code v4 Christoph Hellwig
                   ` (18 preceding siblings ...)
       [not found] ` <20200728163416.556521-1-hch-jcswGhMUV9g@public.gmane.org>
@ 2020-07-28 16:34 ` Christoph Hellwig
  2020-07-29 19:51 ` add file system helpers that take kernel pointers for the init code v4 Al Viro
  2020-08-03 14:56 ` Qian Cai
  21 siblings, 0 replies; 35+ messages in thread
From: Christoph Hellwig @ 2020-07-28 16:34 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 grab a reference to a file and install it at
the next available fd, and switch the early init code over to it.

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

diff --git a/fs/init.c b/fs/init.c
index db5c48a85644fa..730e05acda2392 100644
--- a/fs/init.c
+++ b/fs/init.c
@@ -8,6 +8,7 @@
 #include <linux/namei.h>
 #include <linux/fs.h>
 #include <linux/fs_struct.h>
+#include <linux/file.h>
 #include <linux/init_syscalls.h>
 #include <linux/security.h>
 #include "internal.h"
@@ -251,3 +252,14 @@ int __init init_utimes(char *filename, struct timespec64 *ts)
 	path_put(&path);
 	return error;
 }
+
+int __init init_dup(struct file *file)
+{
+	int fd;
+
+	fd = get_unused_fd_flags(0);
+	if (fd < 0)
+		return fd;
+	fd_install(get_unused_fd_flags(0), get_file(file));
+	return 0;
+}
diff --git a/include/linux/init_syscalls.h b/include/linux/init_syscalls.h
index 3654b525ac0b17..92045d18cbfc99 100644
--- a/include/linux/init_syscalls.h
+++ b/include/linux/init_syscalls.h
@@ -16,3 +16,4 @@ int __init init_unlink(const char *pathname);
 int __init init_mkdir(const char *pathname, umode_t mode);
 int __init init_rmdir(const char *pathname);
 int __init init_utimes(char *filename, struct timespec64 *ts);
+int __init init_dup(struct file *file);
diff --git a/init/main.c b/init/main.c
index 1c710d3e1d461a..089e21504b1fc1 100644
--- a/init/main.c
+++ b/init/main.c
@@ -1467,10 +1467,9 @@ void __init console_on_rootfs(void)
 		pr_err("Warning: unable to open an initial console.\n");
 		return;
 	}
-	get_file_rcu_many(file, 2);
-	fd_install(get_unused_fd_flags(0), file);
-	fd_install(get_unused_fd_flags(0), file);
-	fd_install(get_unused_fd_flags(0), file);
+	init_dup(file);
+	init_dup(file);
+	init_dup(file);
 }
 
 static noinline void __init kernel_init_freeable(void)
-- 
2.27.0

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

* Re: [PATCH 04/23] devtmpfs: refactor devtmpfsd()
  2020-07-28 16:33   ` [PATCH 04/23] devtmpfs: refactor devtmpfsd() Christoph Hellwig
@ 2020-07-28 16:59     ` Greg Kroah-Hartman
  0 siblings, 0 replies; 35+ messages in thread
From: Greg Kroah-Hartman @ 2020-07-28 16:59 UTC (permalink / raw)
  To: Christoph Hellwig
  Cc: Al Viro, Linus Torvalds, Rafael J. Wysocki, linux-kernel,
	linux-raid, linux-fsdevel, linux-api

On Tue, Jul 28, 2020 at 06:33:57PM +0200, Christoph Hellwig wrote:
> Split the main worker loop into a separate function.  This allows
> devtmpfsd_setup to be marked __init, which will allows us to call
> __init routines for the setup work.  devtmpfѕ itself needs a __ref
> marker for that to work, and a comment explaining why it works.
> 
> Signed-off-by: Christoph Hellwig <hch@lst.de>

Reviewed-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

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

* Re: add file system helpers that take kernel pointers for the init code v4
  2020-07-28 16:33 add file system helpers that take kernel pointers for the init code v4 Christoph Hellwig
                   ` (19 preceding siblings ...)
  2020-07-28 16:34 ` [PATCH 23/23] init: add an init_dup helper Christoph Hellwig
@ 2020-07-29 19:51 ` Al Viro
  2020-07-30  6:25   ` Christoph Hellwig
  2020-08-03 14:56 ` Qian Cai
  21 siblings, 1 reply; 35+ messages in thread
From: Al Viro @ 2020-07-29 19:51 UTC (permalink / raw)
  To: Christoph Hellwig
  Cc: Linus Torvalds, Greg Kroah-Hartman, Rafael J. Wysocki,
	linux-kernel, linux-raid, linux-fsdevel, linux-api

On Tue, Jul 28, 2020 at 06:33:53PM +0200, Christoph Hellwig wrote:
> Hi Al and Linus,
> 
> 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.  These helpers are in init/ and marked __init and thus will
> be discarded after bootup.  A few also need to be duplicated in devtmpfs,
> though unfortunately.
>
> The series sits on top of my previous
> 
>   "decruft the early init / initrd / initramfs code v2"

Could you fold the fixes in the parent branch to avoid the bisect hazards?
As it is, you have e.g. "initd: pass a non-f_pos offset to kernel_read/kernel_write"
that ought to go into "initrd: switch initrd loading to struct file based APIs"...

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

* Re: add file system helpers that take kernel pointers for the init code v4
  2020-07-29 19:51 ` add file system helpers that take kernel pointers for the init code v4 Al Viro
@ 2020-07-30  6:25   ` Christoph Hellwig
  2020-07-31  2:14     ` Al Viro
  0 siblings, 1 reply; 35+ messages in thread
From: Christoph Hellwig @ 2020-07-30  6:25 UTC (permalink / raw)
  To: Al Viro
  Cc: Christoph Hellwig, Linus Torvalds, Greg Kroah-Hartman,
	Rafael J. Wysocki, linux-kernel, linux-raid, linux-fsdevel,
	linux-api

On Wed, Jul 29, 2020 at 08:51:17PM +0100, Al Viro wrote:
> On Tue, Jul 28, 2020 at 06:33:53PM +0200, Christoph Hellwig wrote:
> > Hi Al and Linus,
> > 
> > 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.  These helpers are in init/ and marked __init and thus will
> > be discarded after bootup.  A few also need to be duplicated in devtmpfs,
> > though unfortunately.
> >
> > The series sits on top of my previous
> > 
> >   "decruft the early init / initrd / initramfs code v2"
> 
> Could you fold the fixes in the parent branch to avoid the bisect hazards?
> As it is, you have e.g. "initd: pass a non-f_pos offset to kernel_read/kernel_write"
> that ought to go into "initrd: switch initrd loading to struct file based APIs"...

I'm not a huge fan of rebasing after it has been out for a long time and
with pending other patches on top of it.  But at your request I've now
folded the fixes and force pushed it.

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

* Re: add file system helpers that take kernel pointers for the init code v4
  2020-07-30  6:25   ` Christoph Hellwig
@ 2020-07-31  2:14     ` Al Viro
       [not found]       ` <20200731021424.GG1236603-3bDd1+5oDREiFSDQTTA3OLVCufUGDwFn@public.gmane.org>
  0 siblings, 1 reply; 35+ messages in thread
From: Al Viro @ 2020-07-31  2:14 UTC (permalink / raw)
  To: Christoph Hellwig
  Cc: Linus Torvalds, Greg Kroah-Hartman, Rafael J. Wysocki,
	linux-kernel, linux-raid, linux-fsdevel, linux-api

On Thu, Jul 30, 2020 at 08:25:24AM +0200, Christoph Hellwig wrote:
> On Wed, Jul 29, 2020 at 08:51:17PM +0100, Al Viro wrote:
> > On Tue, Jul 28, 2020 at 06:33:53PM +0200, Christoph Hellwig wrote:
> > > Hi Al and Linus,
> > > 
> > > 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.  These helpers are in init/ and marked __init and thus will
> > > be discarded after bootup.  A few also need to be duplicated in devtmpfs,
> > > though unfortunately.
> > >
> > > The series sits on top of my previous
> > > 
> > >   "decruft the early init / initrd / initramfs code v2"
> > 
> > Could you fold the fixes in the parent branch to avoid the bisect hazards?
> > As it is, you have e.g. "initd: pass a non-f_pos offset to kernel_read/kernel_write"
> > that ought to go into "initrd: switch initrd loading to struct file based APIs"...
> 
> I'm not a huge fan of rebasing after it has been out for a long time and
> with pending other patches on top of it.  But at your request I've now
> folded the fixes and force pushed it.

Um...

Christoph Hellwig (28):
[snip]
      initramfs: switch initramfs unpacking to struct file based APIs
      initramfs: switch initramfs unpacking to struct file based APIs
[snip]

It's not a bisect hazard, of course, but if you don't fold those
together, you might at least want to give the second one a different
commit summary...  I hadn't been able to find an analogue of #init_path on
top of that either.

As it is, #init-user-pointers is fine (aside of that SNAFU with unfolded
pair of commits), and so's the contents of #init_path part following what
used to be #init-user-pointers, but it'll be an awful mess on merge in
the current shape.

I can sort it out myself, if you don't mind that; again, I'm OK with
the contents and I've no problem with doing reordering/folding.

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

* Re: add file system helpers that take kernel pointers for the init code v4
       [not found]       ` <20200731021424.GG1236603-3bDd1+5oDREiFSDQTTA3OLVCufUGDwFn@public.gmane.org>
@ 2020-07-31  6:33         ` Christoph Hellwig
  0 siblings, 0 replies; 35+ messages in thread
From: Christoph Hellwig @ 2020-07-31  6:33 UTC (permalink / raw)
  To: Al Viro
  Cc: Christoph Hellwig, Linus Torvalds, Greg Kroah-Hartman,
	Rafael J. Wysocki, linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	linux-raid-u79uwXL29TY76Z2rM5mHXA,
	linux-fsdevel-u79uwXL29TY76Z2rM5mHXA,
	linux-api-u79uwXL29TY76Z2rM5mHXA

On Fri, Jul 31, 2020 at 03:14:24AM +0100, Al Viro wrote:
> Christoph Hellwig (28):
> [snip]
>       initramfs: switch initramfs unpacking to struct file based APIs
>       initramfs: switch initramfs unpacking to struct file based APIs
> [snip]
> 
> It's not a bisect hazard, of course, but if you don't fold those
> together, you might at least want to give the second one a different
> commit summary...  I hadn't been able to find an analogue of #init_path on
> top of that either.
> 
> As it is, #init-user-pointers is fine (aside of that SNAFU with unfolded
> pair of commits), and so's the contents of #init_path part following what
> used to be #init-user-pointers, but it'll be an awful mess on merge in
> the current shape.
> 
> I can sort it out myself, if you don't mind that; again, I'm OK with
> the contents and I've no problem with doing reordering/folding.

I've fixed the folding issues in init-user-pointers and rebased init_path
on top of that.  Feel free to pull it.  I don't think it is worth
reposting.

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

* Re: add file system helpers that take kernel pointers for the init code v4
  2020-07-28 16:33 add file system helpers that take kernel pointers for the init code v4 Christoph Hellwig
                   ` (20 preceding siblings ...)
  2020-07-29 19:51 ` add file system helpers that take kernel pointers for the init code v4 Al Viro
@ 2020-08-03 14:56 ` Qian Cai
       [not found]   ` <20200803145622.GB4631-J5quhbR+WMc@public.gmane.org>
  21 siblings, 1 reply; 35+ messages in thread
From: Qian Cai @ 2020-08-03 14:56 UTC (permalink / raw)
  To: Christoph Hellwig
  Cc: Al Viro, Linus Torvalds, Greg Kroah-Hartman, Rafael J. Wysocki,
	linux-kernel, linux-raid, linux-fsdevel, linux-api, sfr,
	linux-next

On Tue, Jul 28, 2020 at 06:33:53PM +0200, Christoph Hellwig wrote:
> Hi Al and Linus,
> 
> 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.  These helpers are in init/ and marked __init and thus will
> be discarded after bootup.  A few also need to be duplicated in devtmpfs,
> though unfortunately.

Reverting this series from next-20200803 fixed the crash below on shutdown.

[ 7303.287890][    T1] systemd-shutdown[1]: All loop devices detached.
[ 7303.287930][    T1] systemd-shutdown[1]: Detaching DM devices.
[ 7303.441674][    T1] printk: shutdown: 9 output lines suppressed due to ratelimiting
[ 7303.443999][    T1] Kernel panic - not syncing: Attempted to kill init! exitcode=0x00000100
[ 7303.444027][    T1] CPU: 120 PID: 1 Comm: shutdown Not tainted 5.8.0-next-20200803 #2
[ 7303.444053][    T1] Call Trace:
[ 7303.444069][    T1] [c000000015d27b70] [c0000000006f3778] dump_stack+0xfc/0x174 (unreliable)
[ 7303.444103][    T1] [c000000015d27bc0] [c0000000000c9328] panic+0x214/0x4ac
[ 7303.444140][    T1] [c000000015d27c60] [c0000000000d4d28] do_exit+0xda8/0xee0
[ 7303.444178][    T1] [c000000015d27d60] [c0000000000d4f1c] do_group_exit+0x5c/0xd0
list_empty at include/linux/list.h:282
(inlined by) thread_group_empty at include/linux/sched/signal.h:671
(inlined by) do_group_exit at kernel/exit.c:888
[ 7303.444205][    T1] [c000000015d27da0] [c0000000000d4fac] sys_exit_group+0x1c/0x20
sys_exit_group at kernel/exit.c:914
[ 7303.444234][    T1] [c000000015d27dc0] [c00000000002c628] system_call_exception+0xf8/0x1d0
[ 7303.444262][    T1] [c000000015d27e20] [c00000000000d0a8] system_call_common+0xe8/0x218
[ 7304.936912][    T1] ---[ end Kernel panic - not syncing: Attempted to kill init! exitcode=0x00000100 ]---

> 
> 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 init_path
> 
> Gitweb:
> 
>     http://git.infradead.org/users/hch/misc.git/shortlog/refs/heads/init_path
> 
> 
> Changes since v3:
>  - rename fs/for_init.c to fs/init.c
>  - document the purpose of the routines in fs/init.c with a comment
>  - don't mark devtmpfs __init as that will cause it to get overwritten
>    by initmem poisoning
>  - add an init_dup helper to make Al more happy than with the version
>    commit to the "decruft the early init / initrd / initramfs code v2"
>    series
> 
> Changes since v2:
>  - move to fs/for_init.c
>  - reuse the init routines in devtmpfs after refactoring devtmpfsd
>    (and thus the broken error handling in the previous version)
>  - actually use kern_path in a place where user_path_at sneaked back in
> 
> Changes since v1:
>  - avoid most core VFS changes
>  - renamed the functions and move them to init/ and devtmpfs
>  - drop a bunch of cleanups that can be submitted independently now
> 
> 
> Diffstat:

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

* Re: add file system helpers that take kernel pointers for the init code v4
       [not found]   ` <20200803145622.GB4631-J5quhbR+WMc@public.gmane.org>
@ 2020-08-03 15:08     ` Christoph Hellwig
  0 siblings, 0 replies; 35+ messages in thread
From: Christoph Hellwig @ 2020-08-03 15:08 UTC (permalink / raw)
  To: Qian Cai
  Cc: Christoph Hellwig, Al Viro, Linus Torvalds, Greg Kroah-Hartman,
	Rafael J. Wysocki, linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	linux-raid-u79uwXL29TY76Z2rM5mHXA,
	linux-fsdevel-u79uwXL29TY76Z2rM5mHXA,
	linux-api-u79uwXL29TY76Z2rM5mHXA, sfr-3FnU+UHB4dNDw9hX6IcOSA,
	linux-next-u79uwXL29TY76Z2rM5mHXA

On Mon, Aug 03, 2020 at 10:56:23AM -0400, Qian Cai wrote:
> On Tue, Jul 28, 2020 at 06:33:53PM +0200, Christoph Hellwig wrote:
> > Hi Al and Linus,
> > 
> > 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.  These helpers are in init/ and marked __init and thus will
> > be discarded after bootup.  A few also need to be duplicated in devtmpfs,
> > though unfortunately.
> 
> Reverting this series from next-20200803 fixed the crash below on shutdown.

Please try this patch:

---
From 6448eebe2fe7189cedc5136ab3464517956922b7 Mon Sep 17 00:00:00 2001
From: Christoph Hellwig <hch-jcswGhMUV9g@public.gmane.org>
Date: Mon, 3 Aug 2020 15:56:18 +0200
Subject: init: fix init_dup

Don't allocate an unused fd for each call.  Also drop the extra
reference from filp_open after the init_dup calls while we're at it.

Fixes: 36e96b411649 ("init: add an init_dup helper")
Reported-by Stephen Rothwell <sfr-3FnU+UHB4dNDw9hX6IcOSA@public.gmane.org>
Signed-off-by: Christoph Hellwig <hch-jcswGhMUV9g@public.gmane.org>
---
 fs/init.c   | 2 +-
 init/main.c | 1 +
 2 files changed, 2 insertions(+), 1 deletion(-)

diff --git a/fs/init.c b/fs/init.c
index 730e05acda2392..e9c320a48cf157 100644
--- a/fs/init.c
+++ b/fs/init.c
@@ -260,6 +260,6 @@ int __init init_dup(struct file *file)
 	fd = get_unused_fd_flags(0);
 	if (fd < 0)
 		return fd;
-	fd_install(get_unused_fd_flags(0), get_file(file));
+	fd_install(fd, get_file(file));
 	return 0;
 }
diff --git a/init/main.c b/init/main.c
index 089e21504b1fc1..9dae9c4f806bb9 100644
--- a/init/main.c
+++ b/init/main.c
@@ -1470,6 +1470,7 @@ void __init console_on_rootfs(void)
 	init_dup(file);
 	init_dup(file);
 	init_dup(file);
+	fput(file);
 }
 
 static noinline void __init kernel_init_freeable(void)
-- 
2.27.0

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

* Re: [PATCH 02/23] fs: refactor ksys_umount
       [not found]   ` <20200728163416.556521-3-hch-jcswGhMUV9g@public.gmane.org>
@ 2020-08-06 14:44     ` Naresh Kamboju
  2020-08-17 13:44       ` Naresh Kamboju
  0 siblings, 1 reply; 35+ messages in thread
From: Naresh Kamboju @ 2020-08-06 14:44 UTC (permalink / raw)
  To: Christoph Hellwig
  Cc: Rafael J. Wysocki, Greg Kroah-Hartman, open list,
	lkft-triage-cunTk1MwBs8s++Sfvej+rw,
	linux-raid-u79uwXL29TY76Z2rM5mHXA, Al Viro,
	linux-api-u79uwXL29TY76Z2rM5mHXA,
	linux-fsdevel-u79uwXL29TY76Z2rM5mHXA, Linus Torvalds, LTP List

On Tue, 28 Jul 2020 at 22:04, Christoph Hellwig <hch-jcswGhMUV9g@public.gmane.org> wrote:
>
> Factor out a path_umount helper that takes a struct path * instead of the
> actual file name.  This will allow to convert the init and devtmpfs code
> to properly mount based on a kernel pointer instead of relying on the
> implicit set_fs(KERNEL_DS) during early init.
>
> Signed-off-by: Christoph Hellwig <hch-jcswGhMUV9g@public.gmane.org>
> ---
>  fs/namespace.c | 40 ++++++++++++++++++----------------------
>  1 file changed, 18 insertions(+), 22 deletions(-)
>
> diff --git a/fs/namespace.c b/fs/namespace.c
> index 6f8234f74bed90..43834b59eff6c3 100644
> --- a/fs/namespace.c
> +++ b/fs/namespace.c
> @@ -1706,36 +1706,19 @@ 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
> - */
> -
> -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 +1731,25 @@ 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;
>  }
>
> +int ksys_umount(char __user *name, int flags)
> +{
> +       int lookup_flags = LOOKUP_MOUNTPOINT;
> +       struct path path;
> +       int ret;
> +
> +       if (!(flags & UMOUNT_NOFOLLOW))
> +               lookup_flags |= LOOKUP_FOLLOW;
> +       ret = user_path_at(AT_FDCWD, name, lookup_flags, &path);
> +       if (ret)
> +               return ret;
> +       return path_umount(&path, flags);
> +}
> +
>  SYSCALL_DEFINE2(umount, char __user *, name, int, flags)
>  {
>         return ksys_umount(name, flags);

Regressions on linux next 20200803 tag kernel.
LTP syscalls test umount03 mount a path for testing and
umount failed and retired for 50 times and test exit with warning
and following test cases using that mount path failed.

LTP syscalls tests failed list,
    * umount03
    * umount2_01
    * umount2_02
    * umount2_03
    * utime06
    * copy_file_range01


Summary
------------------------------------------------------------------------

kernel: 5.8.0
git repo: https://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next.git
git branch: master
git describe: next-20200803
Test details: https://qa-reports.linaro.org/lkft/linux-next-oe/build/next-20200803
------------------------------------------------------------------------

test failed log:
tst_device.c:262: INFO: Using test device LTP_DEV='/dev/loop0'
tst_mkfs.c:90: INFO: Formatting /dev/loop0 with ext2 opts='' extra opts=''
mke2fs 1.43.8 (1-Jan-2018)
tst_test.c:1246: INFO: Timeout per run is 0h 15m 00s
[  870.449934] EXT4-fs (loop0): mounting ext2 file system using the
ext4 subsystem
[  870.454338] EXT4-fs (loop0): mounted filesystem without journal. Opts: (null)
[  870.456412] ext2 filesystem being mounted at
/tmp/ltp-YQrzWZNEEy/jVhqum/mntpoint supports timestamps until 2038
(0x7fffffff)
umount03.c:35: PASS: umount() fails as expected: EPERM (1)
tst_device.c:384: INFO: umount('mntpoint') failed with EBUSY, try  1...
tst_device.c:388: INFO: Likely gvfsd-trash is probing newly mounted
fs, kill it to speed up tests.
tst_device.c:384: INFO: umount('mntpoint') failed with EBUSY, try  2...
tst_device.c:384: INFO: umount('mntpoint') failed with EBUSY, try  3...
tst_device.c:384: INFO: umount('mntpoint') failed with EBUSY, try  4...
tst_device.c:384: INFO: umount('mntpoint') failed with EBUSY, try  5...
tst_device.c:384: INFO: umount('mntpoint') failed with EBUSY, try  6...
tst_device.c:384: INFO: umount('mntpoint') failed with EBUSY, try  7...
tst_device.c:384: INFO: umount('mntpoint') failed with EBUSY, try  8...
tst_device.c:384: INFO: umount('mntpoint') failed with EBUSY, try  9...
tst_device.c:384: INFO: umount('mntpoint') failed with EBUSY, try 10...
tst_device.c:384: INFO: umount('mntpoint') failed with EBUSY, try 11...
tst_device.c:384: INFO: umount('mntpoint') failed with EBUSY, try 12...
tst_device.c:384: INFO: umount('mntpoint') failed with EBUSY, try 13...
tst_device.c:384: INFO: umount('mntpoint') failed with EBUSY, try 14...
tst_device.c:384: INFO: umount('mntpoint') failed with EBUSY, try 15...
tst_device.c:384: INFO: umount('mntpoint') failed with EBUSY, try 16...
tst_device.c:384: INFO: umount('mntpoint') failed with EBUSY, try 17...
tst_device.c:384: INFO: umount('mntpoint') failed with EBUSY, try 18...
tst_device.c:384: INFO: umount('mntpoint') failed with EBUSY, try 19...
tst_device.c:384: INFO: umount('mntpoint') failed with EBUSY, try 20...
tst_device.c:384: INFO: umount('mntpoint') failed with EBUSY, try 21...
tst_device.c:384: INFO: umount('mntpoint') failed with EBUSY, try 22...
tst_device.c:384: INFO: umount('mntpoint') failed with EBUSY, try 23...
tst_device.c:384: INFO: umount('mntpoint') failed with EBUSY, try 24...
tst_device.c:384: INFO: umount('mntpoint') failed with EBUSY, try 25...
tst_device.c:384: INFO: umount('mntpoint') failed with EBUSY, try 26...
tst_device.c:384: INFO: umount('mntpoint') failed with EBUSY, try 27...
tst_device.c:384: INFO: umount('mntpoint') failed with EBUSY, try 28...
tst_device.c:384: INFO: umount('mntpoint') failed with EBUSY, try 29...
tst_device.c:384: INFO: umount('mntpoint') failed with EBUSY, try 30...
tst_device.c:384: INFO: umount('mntpoint') failed with EBUSY, try 31...
tst_device.c:384: INFO: umount('mntpoint') failed with EBUSY, try 32...
tst_device.c:384: INFO: umount('mntpoint') failed with EBUSY, try 33...
tst_device.c:384: INFO: umount('mntpoint') failed with EBUSY, try 34...
tst_device.c:384: INFO: umount('mntpoint') failed with EBUSY, try 35...
tst_device.c:384: INFO: umount('mntpoint') failed with EBUSY, try 36...
tst_device.c:384: INFO: umount('mntpoint') failed with EBUSY, try 37...
tst_device.c:384: INFO: umount('mntpoint') failed with EBUSY, try 38...
tst_device.c:384: INFO: umount('mntpoint') failed with EBUSY, try 39...
tst_device.c:384: INFO: umount('mntpoint') failed with EBUSY, try 40...
tst_device.c:384: INFO: umount('mntpoint') failed with EBUSY, try 41...
tst_device.c:384: INFO: umount('mntpoint') failed with EBUSY, try 42...
tst_device.c:384: INFO: umount('mntpoint') failed with EBUSY, try 43...
tst_device.c:384: INFO: umount('mntpoint') failed with EBUSY, try 44...
tst_device.c:384: INFO: umount('mntpoint') failed with EBUSY, try 45...
tst_device.c:384: INFO: umount('mntpoint') failed with EBUSY, try 46...
tst_device.c:384: INFO: umount('mntpoint') failed with EBUSY, try 47...
tst_device.c:384: INFO: umount('mntpoint') failed with EBUSY, try 48...
tst_device.c:384: INFO: umount('mntpoint') failed with EBUSY, try 49...
tst_device.c:384: INFO: umount('mntpoint') failed with EBUSY, try 50...
tst_device.c:394: WARN: Failed to umount('mntpoint') after 50 retries
tst_tmpdir.c:337: WARN: tst_rmdir: rmobj(/tmp/ltp-YQrzWZNEEy/jVhqum)
failed: remove(/tmp/ltp-YQrzWZNEEy/jVhqum/mntpoint) failed; errno=16:
EBUSY
Summary:
passed   1
failed   0
skipped  0
warnings 1

mke2fs 1.43.8 (1-Jan-2018)
/dev/loop0 is mounted; will not make a filesystem here!
umount2_01    0  TINFO  :  Using test device LTP_DEV='/dev/loop0'
umount2_01    0  TINFO  :  Formatting /dev/loop0 with ext2 opts='' extra opts=''
umount2_01    1  TBROK  :  tst_mkfs.c:103: umount2_01.c:81: mkfs.ext2
failed with 1
umount2_01    2  TBROK  :  tst_mkfs.c:103: Remaining cases broken
mke2fs 1.43.8 (1-Jan-2018)
/dev/loop0 is mounted; will not make a filesystem here!
umount2_02    0  TINFO  :  Using test device LTP_DEV='/dev/loop0'
umount2_02    0  TINFO  :  Formatting /dev/loop0 with ext2 opts='' extra opts=''
umount2_02    1  TBROK  :  tst_mkfs.c:103: umount2_02.c:121: mkfs.ext2
failed with 1
umount2_02    2  TBROK  :  tst_mkfs.c:103: Remaining cases broken
mke2fs 1.43.8 (1-Jan-2018)
/dev/loop0 is mounted; will not make a filesystem here!
umount2_03    0  TINFO  :  Using test device LTP_DEV='/dev/loop0'
umount2_03    0  TINFO  :  Formatting /dev/loop0 with ext2 opts='' extra opts=''
umount2_03    1  TBROK  :  tst_mkfs.c:103: umount2_03.c:101: mkfs.ext2
failed with 1
umount2_03    2  TBROK  :  tst_mkfs.c:103: Remaining cases broken

mke2fs 1.43.8 (1-Jan-2018)
/dev/loop0 is mounted; will not make a filesystem here!
utime06     0  TINFO  :  Using test device LTP_DEV='/dev/loop0'
utime06     0  TINFO  :  Formatting /dev/loop0 with ext2 opts='' extra opts=''
utime06     1  TBROK  :  tst_mkfs.c:103: utime06.c:122: mkfs.ext2 failed with 1
utime06     2  TBROK  :  tst_mkfs.c:103: Remaining cases broken

Steps to reproduce:
-------------------------
cd /opt/ltp
./runltp -s umount                 --> FAILS

Above command runs all umount tests.

Test case description,
Verify that umount(2) returns -1 and sets errno to EPERM if the user
is not the super-user.
Test case link,
https://github.com/linux-test-project/ltp/blob/master/testcases/kernel/syscalls/umount/umount03.c

full test log,
https://lkft.validation.linaro.org/scheduler/job/1642287

--
Linaro LKFT
https://lkft.linaro.org

-- 
Mailing list info: https://lists.linux.it/listinfo/ltp

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

* Re: [PATCH 02/23] fs: refactor ksys_umount
  2020-08-06 14:44     ` Naresh Kamboju
@ 2020-08-17 13:44       ` Naresh Kamboju
  0 siblings, 0 replies; 35+ messages in thread
From: Naresh Kamboju @ 2020-08-17 13:44 UTC (permalink / raw)
  To: Christoph Hellwig
  Cc: Al Viro, Linus Torvalds, Greg Kroah-Hartman, Rafael J. Wysocki,
	open list, linux-raid, linux-fsdevel, linux-api, Jan Stancek,
	chrubis, lkft-triage, LTP List

On Thu, 6 Aug 2020 at 20:14, Naresh Kamboju <naresh.kamboju@linaro.org> wrote:
>
> On Tue, 28 Jul 2020 at 22:04, Christoph Hellwig <hch@lst.de> wrote:
> >
> > Factor out a path_umount helper that takes a struct path * instead of the
> > actual file name.  This will allow to convert the init and devtmpfs code
> > to properly mount based on a kernel pointer instead of relying on the
> > implicit set_fs(KERNEL_DS) during early init.
> >
> > Signed-off-by: Christoph Hellwig <hch@lst.de>
> > ---
> >  fs/namespace.c | 40 ++++++++++++++++++----------------------
> >  1 file changed, 18 insertions(+), 22 deletions(-)
> >
> > diff --git a/fs/namespace.c b/fs/namespace.c
> > index 6f8234f74bed90..43834b59eff6c3 100644
> > --- a/fs/namespace.c
> > +++ b/fs/namespace.c

<trim>

>
> Regressions on linux next 20200803 tag kernel.
> LTP syscalls test umount03 mount a path for testing and
> umount failed and retired for 50 times and test exit with warning
> and following test cases using that mount path failed.
>
> LTP syscalls tests failed list,
>     * umount03
>     * umount2_01
>     * umount2_02
>     * umount2_03
>     * utime06
>     * copy_file_range01

The reported issue has been fixed in linux next 20200817 tag by
below patch.

fs: fix a struct path leak in path_umount
Make sure we also put the dentry and vfsmnt in the illegal flags and
!may_umount cases.
Fixes: 41525f56e256 ("fs: refactor ksys_umount")

- Naresh

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

* [PATCH] init: fix error check in clean_path()
  2020-07-28 16:34 ` [PATCH 21/23] init: add an init_stat helper Christoph Hellwig
@ 2020-09-04 13:53   ` Barret Rhoden
  2020-09-04 16:04     ` Christoph Hellwig
  0 siblings, 1 reply; 35+ messages in thread
From: Barret Rhoden @ 2020-09-04 13:53 UTC (permalink / raw)
  To: hch
  Cc: gregkh, linux-api, linux-fsdevel, linux-kernel, linux-raid,
	rafael, torvalds, viro, luto

init_stat() returns 0 on success, same as vfs_lstat().  When it replaced
vfs_lstat(), the '!' was dropped.

Fixes: 716308a5331b ("init: add an init_stat helper")
Signed-off-by: Barret Rhoden <brho@google.com>
---

Andy: this was broken in virtme.  "/init: source: not found"

 init/initramfs.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/init/initramfs.c b/init/initramfs.c
index e6dbfb767057..1f97c0328a7a 100644
--- a/init/initramfs.c
+++ b/init/initramfs.c
@@ -297,7 +297,7 @@ static void __init clean_path(char *path, umode_t fmode)
 {
 	struct kstat st;
 
-	if (init_stat(path, &st, AT_SYMLINK_NOFOLLOW) &&
+	if (!init_stat(path, &st, AT_SYMLINK_NOFOLLOW) &&
 	    (st.mode ^ fmode) & S_IFMT) {
 		if (S_ISDIR(st.mode))
 			init_rmdir(path);
-- 
2.28.0.526.ge36021eeef-goog


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

* Re: [PATCH] init: fix error check in clean_path()
  2020-09-04 13:53   ` [PATCH] init: fix error check in clean_path() Barret Rhoden
@ 2020-09-04 16:04     ` Christoph Hellwig
  0 siblings, 0 replies; 35+ messages in thread
From: Christoph Hellwig @ 2020-09-04 16:04 UTC (permalink / raw)
  To: Barret Rhoden
  Cc: hch, gregkh, linux-api, linux-fsdevel, linux-kernel, linux-raid,
	rafael, torvalds, viro, luto

On Fri, Sep 04, 2020 at 09:53:32AM -0400, Barret Rhoden wrote:
> init_stat() returns 0 on success, same as vfs_lstat().  When it replaced
> vfs_lstat(), the '!' was dropped.
> 
> Fixes: 716308a5331b ("init: add an init_stat helper")
> Signed-off-by: Barret Rhoden <brho@google.com>

Looks good,

Reviewed-by: Christoph Hellwig <hch@lst.de>

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

end of thread, other threads:[~2020-09-04 16:04 UTC | newest]

Thread overview: 35+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-07-28 16:33 add file system helpers that take kernel pointers for the init code v4 Christoph Hellwig
2020-07-28 16:33 ` [PATCH 01/23] fs: refactor do_mount Christoph Hellwig
2020-07-28 16:33 ` [PATCH 02/23] fs: refactor ksys_umount Christoph Hellwig
     [not found]   ` <20200728163416.556521-3-hch-jcswGhMUV9g@public.gmane.org>
2020-08-06 14:44     ` Naresh Kamboju
2020-08-17 13:44       ` Naresh Kamboju
2020-07-28 16:33 ` [PATCH 03/23] fs: push the getname from do_rmdir into the callers Christoph Hellwig
2020-07-28 16:33 ` [PATCH 05/23] init: initialize ramdisk_execute_command at compile time Christoph Hellwig
2020-07-28 16:34 ` [PATCH 08/23] init: add an init_mount helper Christoph Hellwig
2020-07-28 16:34 ` [PATCH 09/23] init: add an init_umount helper Christoph Hellwig
2020-07-28 16:34 ` [PATCH 10/23] init: add an init_unlink helper Christoph Hellwig
2020-07-28 16:34 ` [PATCH 11/23] init: add an init_rmdir helper Christoph Hellwig
2020-07-28 16:34 ` [PATCH 12/23] init: add an init_chdir helper Christoph Hellwig
2020-07-28 16:34 ` [PATCH 13/23] init: add an init_chroot helper Christoph Hellwig
2020-07-28 16:34 ` [PATCH 14/23] init: add an init_chown helper Christoph Hellwig
2020-07-28 16:34 ` [PATCH 15/23] init: add an init_chmod helper Christoph Hellwig
2020-07-28 16:34 ` [PATCH 16/23] init: add an init_eaccess helper Christoph Hellwig
2020-07-28 16:34 ` [PATCH 17/23] init: add an init_link helper Christoph Hellwig
2020-07-28 16:34 ` [PATCH 18/23] init: add an init_symlink helper Christoph Hellwig
2020-07-28 16:34 ` [PATCH 19/23] init: add an init_mkdir helper Christoph Hellwig
2020-07-28 16:34 ` [PATCH 20/23] init: add an init_mknod helper Christoph Hellwig
2020-07-28 16:34 ` [PATCH 21/23] init: add an init_stat helper Christoph Hellwig
2020-09-04 13:53   ` [PATCH] init: fix error check in clean_path() Barret Rhoden
2020-09-04 16:04     ` Christoph Hellwig
     [not found] ` <20200728163416.556521-1-hch-jcswGhMUV9g@public.gmane.org>
2020-07-28 16:33   ` [PATCH 04/23] devtmpfs: refactor devtmpfsd() Christoph Hellwig
2020-07-28 16:59     ` Greg Kroah-Hartman
2020-07-28 16:33   ` [PATCH 06/23] init: mark console_on_rootfs as __init Christoph Hellwig
2020-07-28 16:34   ` [PATCH 07/23] init: mark create_dev " Christoph Hellwig
2020-07-28 16:34   ` [PATCH 22/23] init: add an init_utimes helper Christoph Hellwig
2020-07-28 16:34 ` [PATCH 23/23] init: add an init_dup helper Christoph Hellwig
2020-07-29 19:51 ` add file system helpers that take kernel pointers for the init code v4 Al Viro
2020-07-30  6:25   ` Christoph Hellwig
2020-07-31  2:14     ` Al Viro
     [not found]       ` <20200731021424.GG1236603-3bDd1+5oDREiFSDQTTA3OLVCufUGDwFn@public.gmane.org>
2020-07-31  6:33         ` Christoph Hellwig
2020-08-03 14:56 ` Qian Cai
     [not found]   ` <20200803145622.GB4631-J5quhbR+WMc@public.gmane.org>
2020-08-03 15:08     ` 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).