From e7a3e8b2edf544ec28f689385c3adc2903f46ec0 Mon Sep 17 00:00:00 2001 From: Dominik Brodowski Date: Sun, 11 Mar 2018 11:34:41 +0100 Subject: fs: add ksys_write() helper; remove in-kernel calls to sys_write() Using this helper allows us to avoid the in-kernel calls to the sys_write() 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_write(). In the near future, the do_mounts / initramfs callers of ksys_write() should be converted to use filp_open() and vfs_write() instead. 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 Cc: linux-s390@vger.kernel.org Signed-off-by: Dominik Brodowski --- init/do_mounts_rd.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'init/do_mounts_rd.c') diff --git a/init/do_mounts_rd.c b/init/do_mounts_rd.c index 99e0b649fc0e..2d365c398ccc 100644 --- a/init/do_mounts_rd.c +++ b/init/do_mounts_rd.c @@ -270,7 +270,7 @@ int __init rd_load_image(char *from) printk("Loading disk #%d... ", disk); } sys_read(in_fd, buf, BLOCK_SIZE); - sys_write(out_fd, buf, BLOCK_SIZE); + ksys_write(out_fd, buf, BLOCK_SIZE); #if !defined(CONFIG_S390) if (!(i % 16)) { pr_cont("%c\b", rotator[rotate & 0x3]); @@ -317,7 +317,7 @@ static long __init compr_fill(void *buf, unsigned long len) static long __init compr_flush(void *window, unsigned long outcnt) { - long written = sys_write(crd_outfd, window, outcnt); + long written = ksys_write(crd_outfd, window, outcnt); if (written != outcnt) { if (decompress_error == 0) printk(KERN_ERR -- cgit v1.2.3 From 0f32ab8cfac478be053cb526ced8918ef6f4df47 Mon Sep 17 00:00:00 2001 From: Dominik Brodowski Date: Sun, 11 Mar 2018 11:34:47 +0100 Subject: fs: add ksys_unlink() wrapper; remove in-kernel calls to sys_unlink() Using this wrapper allows us to avoid the in-kernel calls to the sys_unlink() syscall. The ksys_ prefix denotes that this function is meant s a drop-in replacement for the syscall. In particular, it uses the same calling convention as sys_unlink(). In the near future, all callers of ksys_unlink() should be converted to call do_unlinkat() directly or, at least, to operate on regular kernel pointers. 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: Al Viro Cc: Andrew Morton Signed-off-by: Dominik Brodowski --- include/linux/syscalls.h | 11 +++++++++++ init/do_mounts.h | 2 +- init/do_mounts_initrd.c | 4 ++-- init/do_mounts_rd.c | 2 +- init/initramfs.c | 4 ++-- 5 files changed, 17 insertions(+), 6 deletions(-) (limited to 'init/do_mounts_rd.c') diff --git a/include/linux/syscalls.h b/include/linux/syscalls.h index 090645b48447..7cbfb41e666b 100644 --- a/include/linux/syscalls.h +++ b/include/linux/syscalls.h @@ -954,4 +954,15 @@ 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); +/* + * 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)); +} + #endif diff --git a/init/do_mounts.h b/init/do_mounts.h index 5b05c8f93f47..401f90ee1eeb 100644 --- a/init/do_mounts.h +++ b/init/do_mounts.h @@ -16,7 +16,7 @@ extern int root_mountflags; static inline int create_dev(char *name, dev_t dev) { - sys_unlink(name); + ksys_unlink(name); return sys_mknod(name, S_IFBLK|0600, new_encode_dev(dev)); } diff --git a/init/do_mounts_initrd.c b/init/do_mounts_initrd.c index 83f396d30b9a..e9e9e1c67d31 100644 --- a/init/do_mounts_initrd.c +++ b/init/do_mounts_initrd.c @@ -128,11 +128,11 @@ bool __init initrd_load(void) * mounted in the normal path. */ if (rd_load_image("/initrd.image") && ROOT_DEV != Root_RAM0) { - sys_unlink("/initrd.image"); + ksys_unlink("/initrd.image"); handle_initrd(); return true; } } - sys_unlink("/initrd.image"); + ksys_unlink("/initrd.image"); return false; } diff --git a/init/do_mounts_rd.c b/init/do_mounts_rd.c index 2d365c398ccc..5b69056f610a 100644 --- a/init/do_mounts_rd.c +++ b/init/do_mounts_rd.c @@ -288,7 +288,7 @@ noclose_input: sys_close(out_fd); out: kfree(buf); - sys_unlink("/dev/ram"); + ksys_unlink("/dev/ram"); return res; } diff --git a/init/initramfs.c b/init/initramfs.c index 6f972df15bf2..08eb551168a8 100644 --- a/init/initramfs.c +++ b/init/initramfs.c @@ -319,7 +319,7 @@ static void __init clean_path(char *path, umode_t fmode) if (S_ISDIR(st.mode)) sys_rmdir(path); else - sys_unlink(path); + ksys_unlink(path); } } @@ -591,7 +591,7 @@ static void __init clean_rootfs(void) if (S_ISDIR(st.mode)) sys_rmdir(dirp->d_name); else - sys_unlink(dirp->d_name); + ksys_unlink(dirp->d_name); } num -= dirp->d_reclen; -- cgit v1.2.3 From 2ca2a09d6215fd9621aa3e2db7cc9428a61f2911 Mon Sep 17 00:00:00 2001 From: Dominik Brodowski Date: Sun, 11 Mar 2018 11:34:55 +0100 Subject: fs: add ksys_close() wrapper; remove in-kernel calls to sys_close() Using the ksys_close() wrapper allows us to get rid of in-kernel calls to the sys_close() 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_close(), with one subtle difference: The few places which checked the return value did not care about the return value re-writing in sys_close(), so simply use a wrapper around __close_fd(). 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: Al Viro Cc: Andrew Morton Signed-off-by: Dominik Brodowski --- fs/autofs4/dev-ioctl.c | 2 +- fs/binfmt_misc.c | 2 +- fs/file.c | 1 + fs/open.c | 1 - include/linux/syscalls.h | 12 ++++++++++++ init/do_mounts.c | 4 ++-- init/do_mounts_initrd.c | 2 +- init/do_mounts_md.c | 8 ++++---- init/do_mounts_rd.c | 6 +++--- init/initramfs.c | 8 ++++---- 10 files changed, 29 insertions(+), 17 deletions(-) (limited to 'init/do_mounts_rd.c') diff --git a/fs/autofs4/dev-ioctl.c b/fs/autofs4/dev-ioctl.c index b7c816f39404..26f6b4f41ce6 100644 --- a/fs/autofs4/dev-ioctl.c +++ b/fs/autofs4/dev-ioctl.c @@ -310,7 +310,7 @@ static int autofs_dev_ioctl_closemount(struct file *fp, struct autofs_sb_info *sbi, struct autofs_dev_ioctl *param) { - return sys_close(param->ioctlfd); + return ksys_close(param->ioctlfd); } /* diff --git a/fs/binfmt_misc.c b/fs/binfmt_misc.c index a7c5a9861bef..a41b48f82a70 100644 --- a/fs/binfmt_misc.c +++ b/fs/binfmt_misc.c @@ -241,7 +241,7 @@ ret: return retval; error: if (fd_binary > 0) - sys_close(fd_binary); + ksys_close(fd_binary); bprm->interp_flags = 0; bprm->interp_data = 0; goto ret; diff --git a/fs/file.c b/fs/file.c index d304004f0b65..7ffd6e9d103d 100644 --- a/fs/file.c +++ b/fs/file.c @@ -638,6 +638,7 @@ out_unlock: spin_unlock(&files->file_lock); return -EBADF; } +EXPORT_SYMBOL(__close_fd); /* for ksys_close() */ void do_close_on_exec(struct files_struct *files) { diff --git a/fs/open.c b/fs/open.c index b3f3b2cd9f19..710102fc262b 100644 --- a/fs/open.c +++ b/fs/open.c @@ -1200,7 +1200,6 @@ SYSCALL_DEFINE1(close, unsigned int, fd) return retval; } -EXPORT_SYMBOL(sys_close); /* * This routine simulates a hangup on the tty, to arrange that users diff --git a/include/linux/syscalls.h b/include/linux/syscalls.h index 41023177c8ec..38805f3447ea 100644 --- a/include/linux/syscalls.h +++ b/include/linux/syscalls.h @@ -1045,4 +1045,16 @@ static inline long ksys_ftruncate(unsigned int fd, unsigned long length) return do_sys_ftruncate(fd, length, 1); } +extern int __close_fd(struct files_struct *files, unsigned int fd); + +/* + * In contrast to sys_close(), this stub does not check whether the syscall + * should or should not be restarted, but returns the raw error codes from + * __close_fd(). + */ +static inline int ksys_close(unsigned int fd) +{ + return __close_fd(current->files, fd); +} + #endif diff --git a/init/do_mounts.c b/init/do_mounts.c index 89f18985fa90..a28dd42d1f84 100644 --- a/init/do_mounts.c +++ b/init/do_mounts.c @@ -492,7 +492,7 @@ void __init change_floppy(char *fmt, ...) fd = sys_open("/dev/root", O_RDWR | O_NDELAY, 0); if (fd >= 0) { sys_ioctl(fd, FDEJECT, 0); - sys_close(fd); + ksys_close(fd); } printk(KERN_NOTICE "VFS: Insert %s and press ENTER\n", buf); fd = sys_open("/dev/console", O_RDWR, 0); @@ -503,7 +503,7 @@ void __init change_floppy(char *fmt, ...) sys_read(fd, &c, 1); termios.c_lflag |= ICANON; sys_ioctl(fd, TCSETSF, (long)&termios); - sys_close(fd); + ksys_close(fd); } } #endif diff --git a/init/do_mounts_initrd.c b/init/do_mounts_initrd.c index 99922d1ebfe6..6907c6dbc443 100644 --- a/init/do_mounts_initrd.c +++ b/init/do_mounts_initrd.c @@ -111,7 +111,7 @@ static void __init handle_initrd(void) error = fd; } else { error = sys_ioctl(fd, BLKFLSBUF, 0); - sys_close(fd); + ksys_close(fd); } printk(!error ? "okay\n" : "failed\n"); } diff --git a/init/do_mounts_md.c b/init/do_mounts_md.c index 3f733c760a8c..ebd4013d589e 100644 --- a/init/do_mounts_md.c +++ b/init/do_mounts_md.c @@ -191,7 +191,7 @@ static void __init md_setup_drive(void) printk(KERN_WARNING "md: Ignoring md=%d, already autodetected. (Use raid=noautodetect)\n", minor); - sys_close(fd); + ksys_close(fd); continue; } @@ -243,11 +243,11 @@ static void __init md_setup_drive(void) * boot a kernel with devfs compiled in from partitioned md * array without it */ - sys_close(fd); + ksys_close(fd); fd = sys_open(name, 0, 0); sys_ioctl(fd, BLKRRPART, 0); } - sys_close(fd); + ksys_close(fd); } } @@ -297,7 +297,7 @@ static void __init autodetect_raid(void) fd = sys_open("/dev/md0", 0, 0); if (fd >= 0) { sys_ioctl(fd, RAID_AUTORUN, raid_autopart); - sys_close(fd); + ksys_close(fd); } } diff --git a/init/do_mounts_rd.c b/init/do_mounts_rd.c index 5b69056f610a..f1aa341862d3 100644 --- a/init/do_mounts_rd.c +++ b/init/do_mounts_rd.c @@ -257,7 +257,7 @@ int __init rd_load_image(char *from) if (i && (i % devblocks == 0)) { printk("done disk #%d.\n", disk++); rotate = 0; - if (sys_close(in_fd)) { + if (ksys_close(in_fd)) { printk("Error closing the disk.\n"); goto noclose_input; } @@ -283,9 +283,9 @@ int __init rd_load_image(char *from) successful_load: res = 1; done: - sys_close(in_fd); + ksys_close(in_fd); noclose_input: - sys_close(out_fd); + ksys_close(out_fd); out: kfree(buf); ksys_unlink("/dev/ram"); diff --git a/init/initramfs.c b/init/initramfs.c index 0d3b001b0dc5..ce2bcad97cdf 100644 --- a/init/initramfs.c +++ b/init/initramfs.c @@ -373,7 +373,7 @@ static int __init do_copy(void) if (byte_count >= body_len) { if (xwrite(wfd, victim, body_len) != body_len) error("write error"); - sys_close(wfd); + ksys_close(wfd); do_utime(vcollected, mtime); kfree(vcollected); eat(body_len); @@ -574,7 +574,7 @@ static void __init clean_rootfs(void) buf = kzalloc(BUF_SIZE, GFP_KERNEL); WARN_ON(!buf); if (!buf) { - sys_close(fd); + ksys_close(fd); return; } @@ -602,7 +602,7 @@ static void __init clean_rootfs(void) num = sys_getdents64(fd, dirp, BUF_SIZE); } - sys_close(fd); + ksys_close(fd); kfree(buf); } #endif @@ -639,7 +639,7 @@ static int __init populate_rootfs(void) pr_err("/initrd.image: incomplete write (%zd != %ld)\n", written, initrd_end - initrd_start); - sys_close(fd); + ksys_close(fd); free_initrd(); } done: -- cgit v1.2.3 From bae217ea8c7e123ed3fb1064909a262924771bbb Mon Sep 17 00:00:00 2001 From: Dominik Brodowski Date: Sun, 11 Mar 2018 11:34:56 +0100 Subject: fs: add ksys_open() wrapper; remove in-kernel calls to sys_open() Using this wrapper allows us to avoid the in-kernel calls to the sys_open() 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_open(). 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: Al Viro Cc: Andrew Morton Signed-off-by: Dominik Brodowski --- fs/open.c | 2 +- include/linux/syscalls.h | 11 +++++++++++ init/do_mounts.c | 4 ++-- init/do_mounts_initrd.c | 4 ++-- init/do_mounts_md.c | 6 +++--- init/do_mounts_rd.c | 6 +++--- init/initramfs.c | 6 +++--- init/main.c | 2 +- 8 files changed, 26 insertions(+), 15 deletions(-) (limited to 'init/do_mounts_rd.c') diff --git a/fs/open.c b/fs/open.c index 710102fc262b..8a42a2961130 100644 --- a/fs/open.c +++ b/fs/open.c @@ -1151,7 +1151,7 @@ COMPAT_SYSCALL_DEFINE4(openat, int, dfd, const char __user *, filename, int, fla */ SYSCALL_DEFINE2(creat, const char __user *, pathname, umode_t, mode) { - return sys_open(pathname, O_CREAT | O_WRONLY | O_TRUNC, mode); + return ksys_open(pathname, O_CREAT | O_WRONLY | O_TRUNC, mode); } #endif diff --git a/include/linux/syscalls.h b/include/linux/syscalls.h index 38805f3447ea..f9df17dcec1c 100644 --- a/include/linux/syscalls.h +++ b/include/linux/syscalls.h @@ -1057,4 +1057,15 @@ static inline int ksys_close(unsigned int fd) return __close_fd(current->files, fd); } +extern long do_sys_open(int dfd, const char __user *filename, int flags, + umode_t mode); + +static inline long ksys_open(const char __user *filename, int flags, + umode_t mode) +{ + if (force_o_largefile()) + flags |= O_LARGEFILE; + return do_sys_open(AT_FDCWD, filename, flags, mode); +} + #endif diff --git a/init/do_mounts.c b/init/do_mounts.c index a28dd42d1f84..cc1103477071 100644 --- a/init/do_mounts.c +++ b/init/do_mounts.c @@ -489,13 +489,13 @@ void __init change_floppy(char *fmt, ...) va_start(args, fmt); vsprintf(buf, fmt, args); va_end(args); - fd = sys_open("/dev/root", O_RDWR | O_NDELAY, 0); + fd = ksys_open("/dev/root", O_RDWR | O_NDELAY, 0); if (fd >= 0) { sys_ioctl(fd, FDEJECT, 0); ksys_close(fd); } printk(KERN_NOTICE "VFS: Insert %s and press ENTER\n", buf); - fd = sys_open("/dev/console", O_RDWR, 0); + fd = ksys_open("/dev/console", O_RDWR, 0); if (fd >= 0) { sys_ioctl(fd, TCGETS, (long)&termios); termios.c_lflag &= ~ICANON; diff --git a/init/do_mounts_initrd.c b/init/do_mounts_initrd.c index 6907c6dbc443..cedca8fd2590 100644 --- a/init/do_mounts_initrd.c +++ b/init/do_mounts_initrd.c @@ -38,7 +38,7 @@ static int init_linuxrc(struct subprocess_info *info, struct cred *new) { sys_unshare(CLONE_FS | CLONE_FILES); /* stdin/stdout/stderr for /linuxrc */ - sys_open("/dev/console", O_RDWR, 0); + ksys_open("/dev/console", O_RDWR, 0); ksys_dup(0); ksys_dup(0); /* move initrd over / and chdir/chroot in initrd root */ @@ -99,7 +99,7 @@ static void __init handle_initrd(void) if (!error) printk("okay\n"); else { - int fd = sys_open("/dev/root.old", O_RDWR, 0); + int fd = ksys_open("/dev/root.old", O_RDWR, 0); if (error == -ENOENT) printk("/initrd does not exist. Ignored.\n"); else diff --git a/init/do_mounts_md.c b/init/do_mounts_md.c index ebd4013d589e..76dcfaada3ed 100644 --- a/init/do_mounts_md.c +++ b/init/do_mounts_md.c @@ -181,7 +181,7 @@ static void __init md_setup_drive(void) partitioned ? "_d" : "", minor, md_setup_args[ent].device_names); - fd = sys_open(name, 0, 0); + fd = ksys_open(name, 0, 0); if (fd < 0) { printk(KERN_ERR "md: open failed - cannot start " "array %s\n", name); @@ -244,7 +244,7 @@ static void __init md_setup_drive(void) * array without it */ ksys_close(fd); - fd = sys_open(name, 0, 0); + fd = ksys_open(name, 0, 0); sys_ioctl(fd, BLKRRPART, 0); } ksys_close(fd); @@ -294,7 +294,7 @@ static void __init autodetect_raid(void) wait_for_device_probe(); - fd = sys_open("/dev/md0", 0, 0); + fd = ksys_open("/dev/md0", 0, 0); if (fd >= 0) { sys_ioctl(fd, RAID_AUTORUN, raid_autopart); ksys_close(fd); diff --git a/init/do_mounts_rd.c b/init/do_mounts_rd.c index f1aa341862d3..a6706314baa7 100644 --- a/init/do_mounts_rd.c +++ b/init/do_mounts_rd.c @@ -196,11 +196,11 @@ int __init rd_load_image(char *from) char rotator[4] = { '|' , '/' , '-' , '\\' }; #endif - out_fd = sys_open("/dev/ram", O_RDWR, 0); + out_fd = ksys_open("/dev/ram", O_RDWR, 0); if (out_fd < 0) goto out; - in_fd = sys_open(from, O_RDONLY, 0); + in_fd = ksys_open(from, O_RDONLY, 0); if (in_fd < 0) goto noclose_input; @@ -262,7 +262,7 @@ int __init rd_load_image(char *from) goto noclose_input; } change_floppy("disk #%d", disk); - in_fd = sys_open(from, O_RDONLY, 0); + in_fd = ksys_open(from, O_RDONLY, 0); if (in_fd < 0) { printk("Error opening disk.\n"); goto noclose_input; diff --git a/init/initramfs.c b/init/initramfs.c index ce2bcad97cdf..5f2ff1d2370e 100644 --- a/init/initramfs.c +++ b/init/initramfs.c @@ -340,7 +340,7 @@ static int __init do_name(void) int openflags = O_WRONLY|O_CREAT; if (ml != 1) openflags |= O_TRUNC; - wfd = sys_open(collected, openflags, mode); + wfd = ksys_open(collected, openflags, mode); if (wfd >= 0) { ksys_fchown(wfd, uid, gid); @@ -567,7 +567,7 @@ static void __init clean_rootfs(void) struct linux_dirent64 *dirp; int num; - fd = sys_open("/", O_RDONLY, 0); + fd = ksys_open("/", O_RDONLY, 0); WARN_ON(fd < 0); if (fd < 0) return; @@ -629,7 +629,7 @@ static int __init populate_rootfs(void) } printk(KERN_INFO "rootfs image is not initramfs (%s)" "; looks like an initrd\n", err); - fd = sys_open("/initrd.image", + fd = ksys_open("/initrd.image", O_WRONLY|O_CREAT, 0700); if (fd >= 0) { ssize_t written = xwrite(fd, (char *)initrd_start, diff --git a/init/main.c b/init/main.c index d0ded4322c6b..e77951ae2c19 100644 --- a/init/main.c +++ b/init/main.c @@ -1074,7 +1074,7 @@ static noinline void __init kernel_init_freeable(void) do_basic_setup(); /* Open the /dev/console on the rootfs, this should never fail */ - if (sys_open((const char __user *) "/dev/console", O_RDWR, 0) < 0) + if (ksys_open((const char __user *) "/dev/console", O_RDWR, 0) < 0) pr_err("Warning: unable to open an initial console.\n"); (void) ksys_dup(0); -- cgit v1.2.3 From cbb60b924b9f3e4d7c67a1c9dcf981718f926e4e Mon Sep 17 00:00:00 2001 From: Dominik Brodowski Date: Tue, 13 Mar 2018 21:43:59 +0100 Subject: fs: add ksys_ioctl() helper; remove in-kernel calls to sys_ioctl() Using this helper allows us to avoid the in-kernel calls to the sys_ioctl() 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_ioctl(). After careful review, at least some of these calls could be converted to do_vfs_ioctl() in future. 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 Signed-off-by: Dominik Brodowski --- fs/ioctl.c | 7 ++++++- include/linux/syscalls.h | 1 + init/do_mounts.c | 8 ++++---- init/do_mounts_initrd.c | 2 +- init/do_mounts_md.c | 15 ++++++++------- init/do_mounts_rd.c | 4 ++-- 6 files changed, 22 insertions(+), 15 deletions(-) (limited to 'init/do_mounts_rd.c') diff --git a/fs/ioctl.c b/fs/ioctl.c index 5ace7efb0d04..4823431d1c9d 100644 --- a/fs/ioctl.c +++ b/fs/ioctl.c @@ -689,7 +689,7 @@ int do_vfs_ioctl(struct file *filp, unsigned int fd, unsigned int cmd, return error; } -SYSCALL_DEFINE3(ioctl, unsigned int, fd, unsigned int, cmd, unsigned long, arg) +int ksys_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg) { int error; struct fd f = fdget(fd); @@ -702,3 +702,8 @@ SYSCALL_DEFINE3(ioctl, unsigned int, fd, unsigned int, cmd, unsigned long, arg) fdput(f); return error; } + +SYSCALL_DEFINE3(ioctl, unsigned int, fd, unsigned int, cmd, unsigned long, arg) +{ + return ksys_ioctl(fd, cmd, arg); +} diff --git a/include/linux/syscalls.h b/include/linux/syscalls.h index c056aff6d7ad..5a959efd8fb7 100644 --- a/include/linux/syscalls.h +++ b/include/linux/syscalls.h @@ -957,6 +957,7 @@ int ksys_fchmod(unsigned int fd, umode_t mode); int ksys_fchown(unsigned int fd, uid_t user, gid_t group); int ksys_getdents64(unsigned int fd, struct linux_dirent64 __user *dirent, unsigned int count); +int ksys_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg); /* * The following kernel syscall equivalents are just wrappers to fs-internal diff --git a/init/do_mounts.c b/init/do_mounts.c index cc1103477071..b17e0095eb4e 100644 --- a/init/do_mounts.c +++ b/init/do_mounts.c @@ -491,18 +491,18 @@ void __init change_floppy(char *fmt, ...) va_end(args); fd = ksys_open("/dev/root", O_RDWR | O_NDELAY, 0); if (fd >= 0) { - sys_ioctl(fd, FDEJECT, 0); + ksys_ioctl(fd, FDEJECT, 0); ksys_close(fd); } printk(KERN_NOTICE "VFS: Insert %s and press ENTER\n", buf); fd = ksys_open("/dev/console", O_RDWR, 0); if (fd >= 0) { - sys_ioctl(fd, TCGETS, (long)&termios); + ksys_ioctl(fd, TCGETS, (long)&termios); termios.c_lflag &= ~ICANON; - sys_ioctl(fd, TCSETSF, (long)&termios); + ksys_ioctl(fd, TCSETSF, (long)&termios); sys_read(fd, &c, 1); termios.c_lflag |= ICANON; - sys_ioctl(fd, TCSETSF, (long)&termios); + ksys_ioctl(fd, TCSETSF, (long)&termios); ksys_close(fd); } } diff --git a/init/do_mounts_initrd.c b/init/do_mounts_initrd.c index cedca8fd2590..03ec0c1b7553 100644 --- a/init/do_mounts_initrd.c +++ b/init/do_mounts_initrd.c @@ -110,7 +110,7 @@ static void __init handle_initrd(void) if (fd < 0) { error = fd; } else { - error = sys_ioctl(fd, BLKFLSBUF, 0); + error = ksys_ioctl(fd, BLKFLSBUF, 0); ksys_close(fd); } printk(!error ? "okay\n" : "failed\n"); diff --git a/init/do_mounts_md.c b/init/do_mounts_md.c index 76dcfaada3ed..7d85d172bc7e 100644 --- a/init/do_mounts_md.c +++ b/init/do_mounts_md.c @@ -187,7 +187,7 @@ static void __init md_setup_drive(void) "array %s\n", name); continue; } - if (sys_ioctl(fd, SET_ARRAY_INFO, 0) == -EBUSY) { + if (ksys_ioctl(fd, SET_ARRAY_INFO, 0) == -EBUSY) { printk(KERN_WARNING "md: Ignoring md=%d, already autodetected. (Use raid=noautodetect)\n", minor); @@ -210,7 +210,7 @@ static void __init md_setup_drive(void) ainfo.state = (1 << MD_SB_CLEAN); ainfo.layout = 0; ainfo.chunk_size = md_setup_args[ent].chunk; - err = sys_ioctl(fd, SET_ARRAY_INFO, (long)&ainfo); + err = ksys_ioctl(fd, SET_ARRAY_INFO, (long)&ainfo); for (i = 0; !err && i <= MD_SB_DISKS; i++) { dev = devices[i]; if (!dev) @@ -220,7 +220,8 @@ static void __init md_setup_drive(void) dinfo.state = (1<= 0) { - sys_ioctl(fd, RAID_AUTORUN, raid_autopart); + ksys_ioctl(fd, RAID_AUTORUN, raid_autopart); ksys_close(fd); } } diff --git a/init/do_mounts_rd.c b/init/do_mounts_rd.c index a6706314baa7..4dafaed5736f 100644 --- a/init/do_mounts_rd.c +++ b/init/do_mounts_rd.c @@ -218,7 +218,7 @@ int __init rd_load_image(char *from) * NOTE NOTE: nblocks is not actually blocks but * the number of kibibytes of data to load into a ramdisk. */ - if (sys_ioctl(out_fd, BLKGETSIZE, (unsigned long)&rd_blocks) < 0) + if (ksys_ioctl(out_fd, BLKGETSIZE, (unsigned long)&rd_blocks) < 0) rd_blocks = 0; else rd_blocks >>= 1; @@ -232,7 +232,7 @@ int __init rd_load_image(char *from) /* * OK, time to copy in the data */ - if (sys_ioctl(in_fd, BLKGETSIZE, (unsigned long)&devblocks) < 0) + if (ksys_ioctl(in_fd, BLKGETSIZE, (unsigned long)&devblocks) < 0) devblocks = 0; else devblocks >>= 1; -- cgit v1.2.3 From 76847e4344350970e1c2e27c28b5abb3c588c5b3 Mon Sep 17 00:00:00 2001 From: Dominik Brodowski Date: Tue, 13 Mar 2018 21:51:17 +0100 Subject: fs: add ksys_lseek() helper; remove in-kernel calls to sys_lseek() Using this helper allows us to avoid the in-kernel calls to the sys_lseek() 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_lseek(). 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 Signed-off-by: Dominik Brodowski --- fs/read_write.c | 9 +++++++-- include/linux/syscalls.h | 1 + init/do_mounts_rd.c | 8 ++++---- 3 files changed, 12 insertions(+), 6 deletions(-) (limited to 'init/do_mounts_rd.c') diff --git a/fs/read_write.c b/fs/read_write.c index 8e8f0b4f52e2..b38b008a078e 100644 --- a/fs/read_write.c +++ b/fs/read_write.c @@ -301,7 +301,7 @@ loff_t vfs_llseek(struct file *file, loff_t offset, int whence) } EXPORT_SYMBOL(vfs_llseek); -SYSCALL_DEFINE3(lseek, unsigned int, fd, off_t, offset, unsigned int, whence) +off_t ksys_lseek(unsigned int fd, off_t offset, unsigned int whence) { off_t retval; struct fd f = fdget_pos(fd); @@ -319,10 +319,15 @@ SYSCALL_DEFINE3(lseek, unsigned int, fd, off_t, offset, unsigned int, whence) return retval; } +SYSCALL_DEFINE3(lseek, unsigned int, fd, off_t, offset, unsigned int, whence) +{ + return ksys_lseek(fd, offset, whence); +} + #ifdef CONFIG_COMPAT COMPAT_SYSCALL_DEFINE3(lseek, unsigned int, fd, compat_off_t, offset, unsigned int, whence) { - return sys_lseek(fd, offset, whence); + return ksys_lseek(fd, offset, whence); } #endif diff --git a/include/linux/syscalls.h b/include/linux/syscalls.h index 5a959efd8fb7..0f24e5334569 100644 --- a/include/linux/syscalls.h +++ b/include/linux/syscalls.h @@ -958,6 +958,7 @@ int ksys_fchown(unsigned int fd, uid_t user, gid_t group); int ksys_getdents64(unsigned int fd, struct linux_dirent64 __user *dirent, unsigned int count); int ksys_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg); +off_t ksys_lseek(unsigned int fd, off_t offset, unsigned int whence); /* * The following kernel syscall equivalents are just wrappers to fs-internal diff --git a/init/do_mounts_rd.c b/init/do_mounts_rd.c index 4dafaed5736f..13e54148c0e0 100644 --- a/init/do_mounts_rd.c +++ b/init/do_mounts_rd.c @@ -90,7 +90,7 @@ identify_ramdisk_image(int fd, int start_block, decompress_fn *decompressor) /* * Read block 0 to test for compressed kernel */ - sys_lseek(fd, start_block * BLOCK_SIZE, 0); + ksys_lseek(fd, start_block * BLOCK_SIZE, 0); sys_read(fd, buf, size); *decompressor = decompress_method(buf, size, &compress_name); @@ -136,7 +136,7 @@ identify_ramdisk_image(int fd, int start_block, decompress_fn *decompressor) /* * Read 512 bytes further to check if cramfs is padded */ - sys_lseek(fd, start_block * BLOCK_SIZE + 0x200, 0); + ksys_lseek(fd, start_block * BLOCK_SIZE + 0x200, 0); sys_read(fd, buf, size); if (cramfsb->magic == CRAMFS_MAGIC) { @@ -150,7 +150,7 @@ identify_ramdisk_image(int fd, int start_block, decompress_fn *decompressor) /* * Read block 1 to test for minix and ext2 superblock */ - sys_lseek(fd, (start_block+1) * BLOCK_SIZE, 0); + ksys_lseek(fd, (start_block+1) * BLOCK_SIZE, 0); sys_read(fd, buf, size); /* Try minix */ @@ -178,7 +178,7 @@ identify_ramdisk_image(int fd, int start_block, decompress_fn *decompressor) start_block); done: - sys_lseek(fd, start_block * BLOCK_SIZE, 0); + ksys_lseek(fd, start_block * BLOCK_SIZE, 0); kfree(buf); return nblocks; } -- cgit v1.2.3 From 3ce4a7bf66263748194b77ccefd284be963c6304 Mon Sep 17 00:00:00 2001 From: Dominik Brodowski Date: Tue, 13 Mar 2018 21:56:26 +0100 Subject: fs: add ksys_read() helper; remove in-kernel calls to sys_read() Using this helper allows us to avoid the in-kernel calls to the sys_read() 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_read(). 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 Signed-off-by: Dominik Brodowski --- arch/s390/kernel/compat_linux.c | 2 +- fs/read_write.c | 7 ++++++- include/linux/syscalls.h | 1 + init/do_mounts.c | 2 +- init/do_mounts_rd.c | 10 +++++----- 5 files changed, 14 insertions(+), 8 deletions(-) (limited to 'init/do_mounts_rd.c') diff --git a/arch/s390/kernel/compat_linux.c b/arch/s390/kernel/compat_linux.c index 9c5e975f71a6..af0469f204fd 100644 --- a/arch/s390/kernel/compat_linux.c +++ b/arch/s390/kernel/compat_linux.c @@ -460,7 +460,7 @@ COMPAT_SYSCALL_DEFINE3(s390_read, unsigned int, fd, char __user *, buf, compat_s if ((compat_ssize_t) count < 0) return -EINVAL; - return sys_read(fd, buf, count); + return ksys_read(fd, buf, count); } COMPAT_SYSCALL_DEFINE3(s390_write, unsigned int, fd, const char __user *, buf, compat_size_t, count) diff --git a/fs/read_write.c b/fs/read_write.c index b38b008a078e..fc441e1ac683 100644 --- a/fs/read_write.c +++ b/fs/read_write.c @@ -568,7 +568,7 @@ static inline void file_pos_write(struct file *file, loff_t pos) file->f_pos = pos; } -SYSCALL_DEFINE3(read, unsigned int, fd, char __user *, buf, size_t, count) +ssize_t ksys_read(unsigned int fd, char __user *buf, size_t count) { struct fd f = fdget_pos(fd); ssize_t ret = -EBADF; @@ -583,6 +583,11 @@ SYSCALL_DEFINE3(read, unsigned int, fd, char __user *, buf, size_t, count) return ret; } +SYSCALL_DEFINE3(read, unsigned int, fd, char __user *, buf, size_t, count) +{ + return ksys_read(fd, buf, count); +} + ssize_t ksys_write(unsigned int fd, const char __user *buf, size_t count) { struct fd f = fdget_pos(fd); diff --git a/include/linux/syscalls.h b/include/linux/syscalls.h index 0f24e5334569..3a2e90842ff8 100644 --- a/include/linux/syscalls.h +++ b/include/linux/syscalls.h @@ -959,6 +959,7 @@ int ksys_getdents64(unsigned int fd, struct linux_dirent64 __user *dirent, unsigned int count); int ksys_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg); off_t ksys_lseek(unsigned int fd, off_t offset, unsigned int whence); +ssize_t ksys_read(unsigned int fd, char __user *buf, size_t count); /* * The following kernel syscall equivalents are just wrappers to fs-internal diff --git a/init/do_mounts.c b/init/do_mounts.c index b17e0095eb4e..2c71dabe5626 100644 --- a/init/do_mounts.c +++ b/init/do_mounts.c @@ -500,7 +500,7 @@ void __init change_floppy(char *fmt, ...) ksys_ioctl(fd, TCGETS, (long)&termios); termios.c_lflag &= ~ICANON; ksys_ioctl(fd, TCSETSF, (long)&termios); - sys_read(fd, &c, 1); + ksys_read(fd, &c, 1); termios.c_lflag |= ICANON; ksys_ioctl(fd, TCSETSF, (long)&termios); ksys_close(fd); diff --git a/init/do_mounts_rd.c b/init/do_mounts_rd.c index 13e54148c0e0..12c159824c7b 100644 --- a/init/do_mounts_rd.c +++ b/init/do_mounts_rd.c @@ -91,7 +91,7 @@ identify_ramdisk_image(int fd, int start_block, decompress_fn *decompressor) * Read block 0 to test for compressed kernel */ ksys_lseek(fd, start_block * BLOCK_SIZE, 0); - sys_read(fd, buf, size); + ksys_read(fd, buf, size); *decompressor = decompress_method(buf, size, &compress_name); if (compress_name) { @@ -137,7 +137,7 @@ identify_ramdisk_image(int fd, int start_block, decompress_fn *decompressor) * Read 512 bytes further to check if cramfs is padded */ ksys_lseek(fd, start_block * BLOCK_SIZE + 0x200, 0); - sys_read(fd, buf, size); + ksys_read(fd, buf, size); if (cramfsb->magic == CRAMFS_MAGIC) { printk(KERN_NOTICE @@ -151,7 +151,7 @@ identify_ramdisk_image(int fd, int start_block, decompress_fn *decompressor) * Read block 1 to test for minix and ext2 superblock */ ksys_lseek(fd, (start_block+1) * BLOCK_SIZE, 0); - sys_read(fd, buf, size); + ksys_read(fd, buf, size); /* Try minix */ if (minixsb->s_magic == MINIX_SUPER_MAGIC || @@ -269,7 +269,7 @@ int __init rd_load_image(char *from) } printk("Loading disk #%d... ", disk); } - sys_read(in_fd, buf, BLOCK_SIZE); + ksys_read(in_fd, buf, BLOCK_SIZE); ksys_write(out_fd, buf, BLOCK_SIZE); #if !defined(CONFIG_S390) if (!(i % 16)) { @@ -307,7 +307,7 @@ static int crd_infd, crd_outfd; static long __init compr_fill(void *buf, unsigned long len) { - long r = sys_read(crd_infd, buf, len); + long r = ksys_read(crd_infd, buf, len); if (r < 0) printk(KERN_ERR "RAMDISK: error while reading compressed data"); else if (r == 0) -- cgit v1.2.3