diff options
author | Dominik Brodowski <linux@dominikbrodowski.net> | 2018-03-11 06:34:39 -0400 |
---|---|---|
committer | Dominik Brodowski <linux@dominikbrodowski.net> | 2018-04-02 14:15:48 -0400 |
commit | 312db1aa1dc7bff133d95c92efcc5e42b57cefa6 (patch) | |
tree | e62c8c554db9e30e7676d847fa75d189231895de | |
parent | ab0d1e85bfd0c25260f02cd3708d5abdfb5b5a9c (diff) |
fs: add ksys_mount() helper; remove in-kernel calls to sys_mount()
Using this helper allows us to avoid the in-kernel calls to the sys_mount()
syscall. The ksys_ prefix denotes that this function is meant as a drop-in
replacement for the syscall. In particular, it uses the same calling
convention as sys_mount().
In the near future, all callers of ksys_mount() should be converted to call
do_mount() directly.
This patch is part of a series which removes in-kernel calls to syscalls.
On this basis, the syscall entry path can be streamlined. For details, see
http://lkml.kernel.org/r/20180325162527.GA17492@light.dominikbrodowski.net
Cc: Alexander Viro <viro@zeniv.linux.org.uk>
Signed-off-by: Dominik Brodowski <linux@dominikbrodowski.net>
-rw-r--r-- | drivers/base/devtmpfs.c | 5 | ||||
-rw-r--r-- | fs/namespace.c | 10 | ||||
-rw-r--r-- | include/linux/syscalls.h | 3 | ||||
-rw-r--r-- | init/do_mounts.c | 4 | ||||
-rw-r--r-- | init/do_mounts_initrd.c | 6 |
5 files changed, 19 insertions, 9 deletions
diff --git a/drivers/base/devtmpfs.c b/drivers/base/devtmpfs.c index 50025d7959cb..4afb04686c8e 100644 --- a/drivers/base/devtmpfs.c +++ b/drivers/base/devtmpfs.c | |||
@@ -356,7 +356,8 @@ int devtmpfs_mount(const char *mntdir) | |||
356 | if (!thread) | 356 | if (!thread) |
357 | return 0; | 357 | return 0; |
358 | 358 | ||
359 | err = sys_mount("devtmpfs", (char *)mntdir, "devtmpfs", MS_SILENT, NULL); | 359 | err = ksys_mount("devtmpfs", (char *)mntdir, "devtmpfs", MS_SILENT, |
360 | NULL); | ||
360 | if (err) | 361 | if (err) |
361 | printk(KERN_INFO "devtmpfs: error mounting %i\n", err); | 362 | printk(KERN_INFO "devtmpfs: error mounting %i\n", err); |
362 | else | 363 | else |
@@ -382,7 +383,7 @@ static int devtmpfsd(void *p) | |||
382 | *err = sys_unshare(CLONE_NEWNS); | 383 | *err = sys_unshare(CLONE_NEWNS); |
383 | if (*err) | 384 | if (*err) |
384 | goto out; | 385 | goto out; |
385 | *err = sys_mount("devtmpfs", "/", "devtmpfs", MS_SILENT, options); | 386 | *err = ksys_mount("devtmpfs", "/", "devtmpfs", MS_SILENT, options); |
386 | if (*err) | 387 | if (*err) |
387 | goto out; | 388 | goto out; |
388 | sys_chdir("/.."); /* will traverse into overmounted root */ | 389 | sys_chdir("/.."); /* will traverse into overmounted root */ |
diff --git a/fs/namespace.c b/fs/namespace.c index 9d1374ab6e06..642b8b229944 100644 --- a/fs/namespace.c +++ b/fs/namespace.c | |||
@@ -3032,8 +3032,8 @@ struct dentry *mount_subtree(struct vfsmount *mnt, const char *name) | |||
3032 | } | 3032 | } |
3033 | EXPORT_SYMBOL(mount_subtree); | 3033 | EXPORT_SYMBOL(mount_subtree); |
3034 | 3034 | ||
3035 | SYSCALL_DEFINE5(mount, char __user *, dev_name, char __user *, dir_name, | 3035 | int ksys_mount(char __user *dev_name, char __user *dir_name, char __user *type, |
3036 | char __user *, type, unsigned long, flags, void __user *, data) | 3036 | unsigned long flags, void __user *data) |
3037 | { | 3037 | { |
3038 | int ret; | 3038 | int ret; |
3039 | char *kernel_type; | 3039 | char *kernel_type; |
@@ -3066,6 +3066,12 @@ out_type: | |||
3066 | return ret; | 3066 | return ret; |
3067 | } | 3067 | } |
3068 | 3068 | ||
3069 | SYSCALL_DEFINE5(mount, char __user *, dev_name, char __user *, dir_name, | ||
3070 | char __user *, type, unsigned long, flags, void __user *, data) | ||
3071 | { | ||
3072 | return ksys_mount(dev_name, dir_name, type, flags, data); | ||
3073 | } | ||
3074 | |||
3069 | /* | 3075 | /* |
3070 | * Return true if path is reachable from root | 3076 | * Return true if path is reachable from root |
3071 | * | 3077 | * |
diff --git a/include/linux/syscalls.h b/include/linux/syscalls.h index 6ab7ed71a8b6..3a9f9c534624 100644 --- a/include/linux/syscalls.h +++ b/include/linux/syscalls.h | |||
@@ -946,4 +946,7 @@ asmlinkage long sys_statx(int dfd, const char __user *path, unsigned flags, | |||
946 | * the ksys_xyzyyz() functions prototyped below. | 946 | * the ksys_xyzyyz() functions prototyped below. |
947 | */ | 947 | */ |
948 | 948 | ||
949 | int ksys_mount(char __user *dev_name, char __user *dir_name, char __user *type, | ||
950 | unsigned long flags, void __user *data); | ||
951 | |||
949 | #endif | 952 | #endif |
diff --git a/init/do_mounts.c b/init/do_mounts.c index 7cf4f6dafd5f..eb768de43d84 100644 --- a/init/do_mounts.c +++ b/init/do_mounts.c | |||
@@ -363,7 +363,7 @@ static void __init get_fs_names(char *page) | |||
363 | static int __init do_mount_root(char *name, char *fs, int flags, void *data) | 363 | static int __init do_mount_root(char *name, char *fs, int flags, void *data) |
364 | { | 364 | { |
365 | struct super_block *s; | 365 | struct super_block *s; |
366 | int err = sys_mount(name, "/root", fs, flags, data); | 366 | int err = ksys_mount(name, "/root", fs, flags, data); |
367 | if (err) | 367 | if (err) |
368 | return err; | 368 | return err; |
369 | 369 | ||
@@ -599,7 +599,7 @@ void __init prepare_namespace(void) | |||
599 | mount_root(); | 599 | mount_root(); |
600 | out: | 600 | out: |
601 | devtmpfs_mount("dev"); | 601 | devtmpfs_mount("dev"); |
602 | sys_mount(".", "/", NULL, MS_MOVE, NULL); | 602 | ksys_mount(".", "/", NULL, MS_MOVE, NULL); |
603 | sys_chroot("."); | 603 | sys_chroot("."); |
604 | } | 604 | } |
605 | 605 | ||
diff --git a/init/do_mounts_initrd.c b/init/do_mounts_initrd.c index 53d4f0f326e7..7868a6039fb4 100644 --- a/init/do_mounts_initrd.c +++ b/init/do_mounts_initrd.c | |||
@@ -43,7 +43,7 @@ static int init_linuxrc(struct subprocess_info *info, struct cred *new) | |||
43 | sys_dup(0); | 43 | sys_dup(0); |
44 | /* move initrd over / and chdir/chroot in initrd root */ | 44 | /* move initrd over / and chdir/chroot in initrd root */ |
45 | sys_chdir("/root"); | 45 | sys_chdir("/root"); |
46 | sys_mount(".", "/", NULL, MS_MOVE, NULL); | 46 | ksys_mount(".", "/", NULL, MS_MOVE, NULL); |
47 | sys_chroot("."); | 47 | sys_chroot("."); |
48 | sys_setsid(); | 48 | sys_setsid(); |
49 | return 0; | 49 | return 0; |
@@ -81,7 +81,7 @@ static void __init handle_initrd(void) | |||
81 | current->flags &= ~PF_FREEZER_SKIP; | 81 | current->flags &= ~PF_FREEZER_SKIP; |
82 | 82 | ||
83 | /* move initrd to rootfs' /old */ | 83 | /* move initrd to rootfs' /old */ |
84 | sys_mount("..", ".", NULL, MS_MOVE, NULL); | 84 | ksys_mount("..", ".", NULL, MS_MOVE, NULL); |
85 | /* switch root and cwd back to / of rootfs */ | 85 | /* switch root and cwd back to / of rootfs */ |
86 | sys_chroot(".."); | 86 | sys_chroot(".."); |
87 | 87 | ||
@@ -95,7 +95,7 @@ static void __init handle_initrd(void) | |||
95 | mount_root(); | 95 | mount_root(); |
96 | 96 | ||
97 | printk(KERN_NOTICE "Trying to move old root to /initrd ... "); | 97 | printk(KERN_NOTICE "Trying to move old root to /initrd ... "); |
98 | error = sys_mount("/old", "/root/initrd", NULL, MS_MOVE, NULL); | 98 | error = ksys_mount("/old", "/root/initrd", NULL, MS_MOVE, NULL); |
99 | if (!error) | 99 | if (!error) |
100 | printk("okay\n"); | 100 | printk("okay\n"); |
101 | else { | 101 | else { |