fs: add ksys_close() wrapper; remove in-kernel calls to sys_close()
authorDominik Brodowski <linux@dominikbrodowski.net>
Sun, 11 Mar 2018 10:34:55 +0000 (11:34 +0100)
committerDominik Brodowski <linux@dominikbrodowski.net>
Mon, 2 Apr 2018 18:16:00 +0000 (20:16 +0200)
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 <viro@zeniv.linux.org.uk>
Cc: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Dominik Brodowski <linux@dominikbrodowski.net>
fs/autofs4/dev-ioctl.c
fs/binfmt_misc.c
fs/file.c
fs/open.c
include/linux/syscalls.h
init/do_mounts.c
init/do_mounts_initrd.c
init/do_mounts_md.c
init/do_mounts_rd.c
init/initramfs.c

index b7c816f3940402f21002cb6e6cbc391b35cb32b9..26f6b4f41ce6b3c686a81e10bd15fc31a960ed1f 100644 (file)
@@ -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);
 }
 
 /*
index a7c5a9861bef5a73b8f7377dfa9e045427b915c7..a41b48f82a70c7baab0a76df25e17c1a6f9712ee 100644 (file)
@@ -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;
index d304004f0b652772928cf931158c7953b3346542..7ffd6e9d103d6470cbc2ea0b1618ea2f2cb028c2 100644 (file)
--- 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)
 {
index b3f3b2cd9f1993c25e8ea24ae026936f74e74524..710102fc262b4f61f98988aa10f0d04889a2b56d 100644 (file)
--- 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
index 41023177c8ecf30c45b02475ed54f3a267cefbcf..38805f3447ea83c92fe58df34ad0461c0169ad29 100644 (file)
@@ -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
index 89f18985fa908478ed96e8869bb1cbadbed315f5..a28dd42d1f84c53b6b725e755a0de83922dddcc3 100644 (file)
@@ -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
index 99922d1ebfe6ad7f558288977ea3034eab5ab31b..6907c6dbc44340b6dca9118a84f49aca2f1ca5ad 100644 (file)
@@ -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");
        }
index 3f733c760a8c556fb3a95a741490e56a088899d6..ebd4013d589e4d2189e72b2caa5f2bfd493b7c6e 100644 (file)
@@ -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);
        }
 }
 
index 5b69056f610aca4a126b92430bdf456f14f2f559..f1aa341862d3460dc2ee467cd4f3002be1a60843 100644 (file)
@@ -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");
index 0d3b001b0dc534a9345e0af490845818ab5c4af1..ce2bcad97cdf90a7ed96d6e6f4cf9d0d80b54fb0 100644 (file)
@@ -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: