From 881627f353754dd05a8f3e1c1941f0dbbf47a170 Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Sat, 6 Jun 2020 10:49:35 +0200 Subject: init: remove the bstat helper The only caller of the bstat function becomes cleaner and simpler when open coding the function. Signed-off-by: Christoph Hellwig Reviewed-by: NeilBrown Acked-by: Song Liu Acked-by: Linus Torvalds --- init/do_mounts.h | 10 ---------- init/do_mounts_md.c | 8 ++++---- 2 files changed, 4 insertions(+), 14 deletions(-) (limited to 'init') diff --git a/init/do_mounts.h b/init/do_mounts.h index 0bb0806de4ce..7513d1c14d13 100644 --- a/init/do_mounts.h +++ b/init/do_mounts.h @@ -20,16 +20,6 @@ static inline int create_dev(char *name, dev_t dev) return ksys_mknod(name, S_IFBLK|0600, new_encode_dev(dev)); } -static inline u32 bstat(char *name) -{ - struct kstat stat; - if (vfs_stat(name, &stat) != 0) - return 0; - if (!S_ISBLK(stat.mode)) - return 0; - return stat.rdev; -} - #ifdef CONFIG_BLK_DEV_RAM int __init rd_load_disk(int n); diff --git a/init/do_mounts_md.c b/init/do_mounts_md.c index b84031528dd4..359363e85ccd 100644 --- a/init/do_mounts_md.c +++ b/init/do_mounts_md.c @@ -138,9 +138,9 @@ static void __init md_setup_drive(void) dev = MKDEV(MD_MAJOR, minor); create_dev(name, dev); for (i = 0; i < MD_SB_DISKS && devname != NULL; i++) { + struct kstat stat; char *p; char comp_name[64]; - u32 rdev; p = strchr(devname, ','); if (p) @@ -150,9 +150,9 @@ static void __init md_setup_drive(void) if (strncmp(devname, "/dev/", 5) == 0) devname += 5; snprintf(comp_name, 63, "/dev/%s", devname); - rdev = bstat(comp_name); - if (rdev) - dev = new_decode_dev(rdev); + if (vfs_stat(comp_name, &stat) == 0 && + S_ISBLK(stat.mode)) + dev = new_decode_dev(stat.rdev); if (!dev) { printk(KERN_WARNING "md: Unknown device name: %s\n", devname); break; -- cgit v1.2.3 From 4f5b246b37e024955c0fcca0c7f5952089052d1d Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Sun, 7 Jun 2020 16:18:59 +0200 Subject: md: move the early init autodetect code to drivers/md/ Just like the NFS and CIFS root code this better lives with the driver it is tightly integrated with. Signed-off-by: Christoph Hellwig Acked-by: Song Liu Acked-by: Linus Torvalds --- init/Makefile | 1 - init/do_mounts.c | 1 + init/do_mounts.h | 10 -- init/do_mounts_md.c | 304 ---------------------------------------------------- 4 files changed, 1 insertion(+), 315 deletions(-) delete mode 100644 init/do_mounts_md.c (limited to 'init') diff --git a/init/Makefile b/init/Makefile index 57499b1ff471..6bc37f64b361 100644 --- a/init/Makefile +++ b/init/Makefile @@ -18,7 +18,6 @@ obj-y += init_task.o mounts-y := do_mounts.o mounts-$(CONFIG_BLK_DEV_RAM) += do_mounts_rd.o mounts-$(CONFIG_BLK_DEV_INITRD) += do_mounts_initrd.o -mounts-$(CONFIG_BLK_DEV_MD) += do_mounts_md.o # dependencies on generated files need to be listed explicitly $(obj)/version.o: include/generated/compile.h diff --git a/init/do_mounts.c b/init/do_mounts.c index 29d326b6c29d..1a4dfa17fb28 100644 --- a/init/do_mounts.c +++ b/init/do_mounts.c @@ -23,6 +23,7 @@ #include #include #include +#include #include #include "do_mounts.h" diff --git a/init/do_mounts.h b/init/do_mounts.h index 7513d1c14d13..50d6c8941e15 100644 --- a/init/do_mounts.h +++ b/init/do_mounts.h @@ -41,13 +41,3 @@ bool __init initrd_load(void); static inline bool initrd_load(void) { return false; } #endif - -#ifdef CONFIG_BLK_DEV_MD - -void md_run_setup(void); - -#else - -static inline void md_run_setup(void) {} - -#endif diff --git a/init/do_mounts_md.c b/init/do_mounts_md.c deleted file mode 100644 index 359363e85ccd..000000000000 --- a/init/do_mounts_md.c +++ /dev/null @@ -1,304 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -#include -#include -#include - -#include "do_mounts.h" - -/* - * When md (and any require personalities) are compiled into the kernel - * (not a module), arrays can be assembles are boot time using with AUTODETECT - * where specially marked partitions are registered with md_autodetect_dev(), - * and with MD_BOOT where devices to be collected are given on the boot line - * with md=..... - * The code for that is here. - */ - -#ifdef CONFIG_MD_AUTODETECT -static int __initdata raid_noautodetect; -#else -static int __initdata raid_noautodetect=1; -#endif -static int __initdata raid_autopart; - -static struct { - int minor; - int partitioned; - int level; - int chunk; - char *device_names; -} md_setup_args[256] __initdata; - -static int md_setup_ents __initdata; - -/* - * Parse the command-line parameters given our kernel, but do not - * actually try to invoke the MD device now; that is handled by - * md_setup_drive after the low-level disk drivers have initialised. - * - * 27/11/1999: Fixed to work correctly with the 2.3 kernel (which - * assigns the task of parsing integer arguments to the - * invoked program now). Added ability to initialise all - * the MD devices (by specifying multiple "md=" lines) - * instead of just one. -- KTK - * 18May2000: Added support for persistent-superblock arrays: - * md=n,0,factor,fault,device-list uses RAID0 for device n - * md=n,-1,factor,fault,device-list uses LINEAR for device n - * md=n,device-list reads a RAID superblock from the devices - * elements in device-list are read by name_to_kdev_t so can be - * a hex number or something like /dev/hda1 /dev/sdb - * 2001-06-03: Dave Cinege - * Shifted name_to_kdev_t() and related operations to md_set_drive() - * for later execution. Rewrote section to make devfs compatible. - */ -static int __init md_setup(char *str) -{ - int minor, level, factor, fault, partitioned = 0; - char *pername = ""; - char *str1; - int ent; - - if (*str == 'd') { - partitioned = 1; - str++; - } - if (get_option(&str, &minor) != 2) { /* MD Number */ - printk(KERN_WARNING "md: Too few arguments supplied to md=.\n"); - return 0; - } - str1 = str; - for (ent=0 ; ent< md_setup_ents ; ent++) - if (md_setup_args[ent].minor == minor && - md_setup_args[ent].partitioned == partitioned) { - printk(KERN_WARNING "md: md=%s%d, Specified more than once. " - "Replacing previous definition.\n", partitioned?"d":"", minor); - break; - } - if (ent >= ARRAY_SIZE(md_setup_args)) { - printk(KERN_WARNING "md: md=%s%d - too many md initialisations\n", partitioned?"d":"", minor); - return 0; - } - if (ent >= md_setup_ents) - md_setup_ents++; - switch (get_option(&str, &level)) { /* RAID level */ - case 2: /* could be 0 or -1.. */ - if (level == 0 || level == LEVEL_LINEAR) { - if (get_option(&str, &factor) != 2 || /* Chunk Size */ - get_option(&str, &fault) != 2) { - printk(KERN_WARNING "md: Too few arguments supplied to md=.\n"); - return 0; - } - md_setup_args[ent].level = level; - md_setup_args[ent].chunk = 1 << (factor+12); - if (level == LEVEL_LINEAR) - pername = "linear"; - else - pername = "raid0"; - break; - } - /* FALL THROUGH */ - case 1: /* the first device is numeric */ - str = str1; - /* FALL THROUGH */ - case 0: - md_setup_args[ent].level = LEVEL_NONE; - pername="super-block"; - } - - printk(KERN_INFO "md: Will configure md%d (%s) from %s, below.\n", - minor, pername, str); - md_setup_args[ent].device_names = str; - md_setup_args[ent].partitioned = partitioned; - md_setup_args[ent].minor = minor; - - return 1; -} - -static void __init md_setup_drive(void) -{ - int minor, i, ent, partitioned; - dev_t dev; - dev_t devices[MD_SB_DISKS+1]; - - for (ent = 0; ent < md_setup_ents ; ent++) { - int fd; - int err = 0; - char *devname; - mdu_disk_info_t dinfo; - char name[16]; - - minor = md_setup_args[ent].minor; - partitioned = md_setup_args[ent].partitioned; - devname = md_setup_args[ent].device_names; - - sprintf(name, "/dev/md%s%d", partitioned?"_d":"", minor); - if (partitioned) - dev = MKDEV(mdp_major, minor << MdpMinorShift); - else - dev = MKDEV(MD_MAJOR, minor); - create_dev(name, dev); - for (i = 0; i < MD_SB_DISKS && devname != NULL; i++) { - struct kstat stat; - char *p; - char comp_name[64]; - - p = strchr(devname, ','); - if (p) - *p++ = 0; - - dev = name_to_dev_t(devname); - 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)) - dev = new_decode_dev(stat.rdev); - if (!dev) { - printk(KERN_WARNING "md: Unknown device name: %s\n", devname); - break; - } - - devices[i] = dev; - - devname = p; - } - devices[i] = 0; - - if (!i) - continue; - - printk(KERN_INFO "md: Loading md%s%d: %s\n", - partitioned ? "_d" : "", minor, - md_setup_args[ent].device_names); - - fd = ksys_open(name, 0, 0); - if (fd < 0) { - printk(KERN_ERR "md: open failed - cannot start " - "array %s\n", name); - continue; - } - if (ksys_ioctl(fd, SET_ARRAY_INFO, 0) == -EBUSY) { - printk(KERN_WARNING - "md: Ignoring md=%d, already autodetected. (Use raid=noautodetect)\n", - minor); - ksys_close(fd); - continue; - } - - if (md_setup_args[ent].level != LEVEL_NONE) { - /* non-persistent */ - mdu_array_info_t ainfo; - ainfo.level = md_setup_args[ent].level; - ainfo.size = 0; - ainfo.nr_disks =0; - ainfo.raid_disks =0; - while (devices[ainfo.raid_disks]) - ainfo.raid_disks++; - ainfo.md_minor =minor; - ainfo.not_persistent = 1; - - ainfo.state = (1 << MD_SB_CLEAN); - ainfo.layout = 0; - ainfo.chunk_size = md_setup_args[ent].chunk; - err = ksys_ioctl(fd, SET_ARRAY_INFO, (long)&ainfo); - for (i = 0; !err && i <= MD_SB_DISKS; i++) { - dev = devices[i]; - if (!dev) - break; - dinfo.number = i; - dinfo.raid_disk = i; - dinfo.state = (1<= 0) { - ksys_ioctl(fd, RAID_AUTORUN, raid_autopart); - ksys_close(fd); - } -} - -void __init md_run_setup(void) -{ - create_dev("/dev/md0", MKDEV(MD_MAJOR, 0)); - - if (raid_noautodetect) - printk(KERN_INFO "md: Skipping autodetection of RAID arrays. (raid=autodetect will force)\n"); - else - autodetect_raid(); - md_setup_drive(); -} -- cgit v1.2.3 From c8376994c86c4eb02b9a1032cd3a8d44c911d671 Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Thu, 4 Jun 2020 10:23:14 +0200 Subject: initrd: remove support for multiple floppies Remove the special handling for multiple floppies in the initrd code. No one should be using floppies for booting these days. (famous last words..) Includes a spelling fix from Colin Ian King . Signed-off-by: Christoph Hellwig Acked-by: Linus Torvalds --- init/do_mounts.c | 69 ++++++----------------------------------------------- init/do_mounts.h | 1 - init/do_mounts_rd.c | 20 ++++------------ 3 files changed, 12 insertions(+), 78 deletions(-) (limited to 'init') diff --git a/init/do_mounts.c b/init/do_mounts.c index 1a4dfa17fb28..a7f22cf58c7e 100644 --- a/init/do_mounts.c +++ b/init/do_mounts.c @@ -28,8 +28,6 @@ #include "do_mounts.h" -int __initdata rd_doload; /* 1 = load RAM disk, 0 = don't load */ - int root_mountflags = MS_RDONLY | MS_SILENT; static char * __initdata root_device_name; static char __initdata saved_root_name[64]; @@ -39,7 +37,7 @@ dev_t ROOT_DEV; static int __init load_ramdisk(char *str) { - rd_doload = simple_strtol(str,NULL,0) & 3; + pr_warn("ignoring the deprecated load_ramdisk= option\n"); return 1; } __setup("load_ramdisk=", load_ramdisk); @@ -553,66 +551,20 @@ static int __init mount_cifs_root(void) } #endif -#if defined(CONFIG_BLK_DEV_RAM) || defined(CONFIG_BLK_DEV_FD) -void __init change_floppy(char *fmt, ...) -{ - struct termios termios; - char buf[80]; - char c; - int fd; - va_list args; - va_start(args, fmt); - vsprintf(buf, fmt, args); - va_end(args); - fd = ksys_open("/dev/root", O_RDWR | O_NDELAY, 0); - if (fd >= 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) { - ksys_ioctl(fd, TCGETS, (long)&termios); - termios.c_lflag &= ~ICANON; - ksys_ioctl(fd, TCSETSF, (long)&termios); - ksys_read(fd, &c, 1); - termios.c_lflag |= ICANON; - ksys_ioctl(fd, TCSETSF, (long)&termios); - ksys_close(fd); - } -} -#endif - void __init mount_root(void) { #ifdef CONFIG_ROOT_NFS if (ROOT_DEV == Root_NFS) { - if (mount_nfs_root()) - return; - - printk(KERN_ERR "VFS: Unable to mount root fs via NFS, trying floppy.\n"); - ROOT_DEV = Root_FD0; + if (!mount_nfs_root()) + printk(KERN_ERR "VFS: Unable to mount root fs via NFS.\n"); + return; } #endif #ifdef CONFIG_CIFS_ROOT if (ROOT_DEV == Root_CIFS) { - if (mount_cifs_root()) - return; - - printk(KERN_ERR "VFS: Unable to mount root fs via SMB, trying floppy.\n"); - ROOT_DEV = Root_FD0; - } -#endif -#ifdef CONFIG_BLK_DEV_FD - if (MAJOR(ROOT_DEV) == FLOPPY_MAJOR) { - /* rd_doload is 2 for a dual initrd/ramload setup */ - if (rd_doload==2) { - if (rd_load_disk(1)) { - ROOT_DEV = Root_RAM1; - root_device_name = NULL; - } - } else - change_floppy("root floppy"); + if (!mount_cifs_root()) + printk(KERN_ERR "VFS: Unable to mount root fs via SMB.\n"); + return; } #endif #ifdef CONFIG_BLOCK @@ -631,8 +583,6 @@ void __init mount_root(void) */ void __init prepare_namespace(void) { - int is_floppy; - if (root_delay) { printk(KERN_INFO "Waiting %d sec before mounting root device...\n", root_delay); @@ -675,11 +625,6 @@ void __init prepare_namespace(void) async_synchronize_full(); } - is_floppy = MAJOR(ROOT_DEV) == FLOPPY_MAJOR; - - if (is_floppy && rd_doload && rd_load_disk(0)) - ROOT_DEV = Root_RAM0; - mount_root(); out: devtmpfs_mount(); diff --git a/init/do_mounts.h b/init/do_mounts.h index 50d6c8941e15..c855b3f0e06d 100644 --- a/init/do_mounts.h +++ b/init/do_mounts.h @@ -9,7 +9,6 @@ #include #include -void change_floppy(char *fmt, ...); void mount_block_root(char *name, int flags); void mount_root(void); extern int root_mountflags; diff --git a/init/do_mounts_rd.c b/init/do_mounts_rd.c index 32fb049d18f9..0a5c3ebee61d 100644 --- a/init/do_mounts_rd.c +++ b/init/do_mounts_rd.c @@ -15,11 +15,9 @@ #include -int __initdata rd_prompt = 1;/* 1 = prompt for RAM disk, 0 = don't prompt */ - static int __init prompt_ramdisk(char *str) { - rd_prompt = simple_strtol(str,NULL,0) & 1; + pr_warn("ignoring the deprecated prompt_ramdisk= option\n"); return 1; } __setup("prompt_ramdisk=", prompt_ramdisk); @@ -178,7 +176,7 @@ int __init rd_load_image(char *from) int res = 0; int in_fd, out_fd; unsigned long rd_blocks, devblocks; - int nblocks, i, disk; + int nblocks, i; char *buf = NULL; unsigned short rotate = 0; decompress_fn decompressor = NULL; @@ -243,21 +241,15 @@ int __init rd_load_image(char *from) printk(KERN_NOTICE "RAMDISK: Loading %dKiB [%ld disk%s] into ram disk... ", nblocks, ((nblocks-1)/devblocks)+1, nblocks>devblocks ? "s" : ""); - for (i = 0, disk = 1; i < nblocks; i++) { + for (i = 0; i < nblocks; i++) { if (i && (i % devblocks == 0)) { - pr_cont("done disk #%d.\n", disk++); + pr_cont("done disk #1.\n"); rotate = 0; if (ksys_close(in_fd)) { printk("Error closing the disk.\n"); goto noclose_input; } - change_floppy("disk #%d", disk); - in_fd = ksys_open(from, O_RDONLY, 0); - if (in_fd < 0) { - printk("Error opening disk.\n"); - goto noclose_input; - } - printk("Loading disk #%d... ", disk); + break; } ksys_read(in_fd, buf, BLOCK_SIZE); ksys_write(out_fd, buf, BLOCK_SIZE); @@ -284,8 +276,6 @@ out: int __init rd_load_disk(int n) { - if (rd_prompt) - change_floppy("root floppy disk to be loaded into RAM disk"); create_dev("/dev/root", ROOT_DEV); create_dev("/dev/ram", MKDEV(RAMDISK_MAJOR, n)); return rd_load_image("/dev/root"); -- cgit v1.2.3 From 899ac10cc0bdaaee3b908e390bf94d2f1ba5d512 Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Sun, 7 Jun 2020 17:40:30 +0200 Subject: initrd: remove the BLKFLSBUF call in handle_initrd BLKFLSBUF used to be overloaded for the ramdisk driver to free the whole ramdisk, which was completely different behavior compared to all other drivers. But this magic overload got removed in commit ff26956875c2 ("brd: remove support for BLKFLSBUF"), so this call is entirely pointless now. Signed-off-by: Christoph Hellwig Acked-by: Linus Torvalds --- init/do_mounts_initrd.c | 9 --------- 1 file changed, 9 deletions(-) (limited to 'init') diff --git a/init/do_mounts_initrd.c b/init/do_mounts_initrd.c index d72beda824aa..e4f88e9e1c08 100644 --- a/init/do_mounts_initrd.c +++ b/init/do_mounts_initrd.c @@ -115,21 +115,12 @@ static void __init handle_initrd(void) if (!error) printk("okay\n"); else { - int fd = ksys_open("/dev/root.old", O_RDWR, 0); if (error == -ENOENT) printk("/initrd does not exist. Ignored.\n"); else printk("failed\n"); printk(KERN_NOTICE "Unmounting old root\n"); ksys_umount("/old", MNT_DETACH); - printk(KERN_NOTICE "Trying to free ramdisk memory ... "); - if (fd < 0) { - error = fd; - } else { - error = ksys_ioctl(fd, BLKFLSBUF, 0); - ksys_close(fd); - } - printk(!error ? "okay\n" : "failed\n"); } } -- cgit v1.2.3 From bef173299613404f55b11180d9a865861637f31d Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Sat, 6 Jun 2020 14:49:58 +0200 Subject: initrd: switch initrd loading to struct file based APIs There is no good reason to mess with file descriptors from in-kernel code, switch the initrd loading to struct file based read and writes instead. Also Pass an explicit offset instead of ->f_pos, and to make that easier, use file scope file structs and offsets everywhere except for identify_ramdisk_image instead of the current strange mix. Signed-off-by: Christoph Hellwig Acked-by: Linus Torvalds --- init/do_mounts_rd.c | 79 ++++++++++++++++++++++++++--------------------------- 1 file changed, 39 insertions(+), 40 deletions(-) (limited to 'init') diff --git a/init/do_mounts_rd.c b/init/do_mounts_rd.c index 0a5c3ebee61d..d4255c10432a 100644 --- a/init/do_mounts_rd.c +++ b/init/do_mounts_rd.c @@ -14,6 +14,8 @@ #include +static struct file *in_file, *out_file; +static loff_t in_pos, out_pos; static int __init prompt_ramdisk(char *str) { @@ -31,7 +33,7 @@ static int __init ramdisk_start_setup(char *str) } __setup("ramdisk_start=", ramdisk_start_setup); -static int __init crd_load(int in_fd, int out_fd, decompress_fn deco); +static int __init crd_load(decompress_fn deco); /* * This routine tries to find a RAM disk image to load, and returns the @@ -53,7 +55,8 @@ static int __init crd_load(int in_fd, int out_fd, decompress_fn deco); * lz4 */ static int __init -identify_ramdisk_image(int fd, int start_block, decompress_fn *decompressor) +identify_ramdisk_image(struct file *file, loff_t pos, + decompress_fn *decompressor) { const int size = 512; struct minix_super_block *minixsb; @@ -64,6 +67,7 @@ identify_ramdisk_image(int fd, int start_block, decompress_fn *decompressor) unsigned char *buf; const char *compress_name; unsigned long n; + int start_block = rd_image_start; buf = kmalloc(size, GFP_KERNEL); if (!buf) @@ -78,8 +82,8 @@ 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); - ksys_read(fd, buf, size); + pos = start_block * BLOCK_SIZE; + kernel_read(file, buf, size, &pos); *decompressor = decompress_method(buf, size, &compress_name); if (compress_name) { @@ -124,8 +128,8 @@ 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); - ksys_read(fd, buf, size); + pos = start_block * BLOCK_SIZE + 0x200; + kernel_read(file, buf, size, &pos); if (cramfsb->magic == CRAMFS_MAGIC) { printk(KERN_NOTICE @@ -138,8 +142,8 @@ 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); - ksys_read(fd, buf, size); + pos = (start_block + 1) * BLOCK_SIZE; + kernel_read(file, buf, size, &pos); /* Try minix */ if (minixsb->s_magic == MINIX_SUPER_MAGIC || @@ -166,15 +170,22 @@ identify_ramdisk_image(int fd, int start_block, decompress_fn *decompressor) start_block); done: - ksys_lseek(fd, start_block * BLOCK_SIZE, 0); kfree(buf); return nblocks; } +static unsigned long nr_blocks(struct file *file) +{ + struct inode *inode = file->f_mapping->host; + + if (!S_ISBLK(inode->i_mode)) + return 0; + return i_size_read(inode) >> 10; +} + int __init rd_load_image(char *from) { int res = 0; - int in_fd, out_fd; unsigned long rd_blocks, devblocks; int nblocks, i; char *buf = NULL; @@ -184,20 +195,21 @@ int __init rd_load_image(char *from) char rotator[4] = { '|' , '/' , '-' , '\\' }; #endif - out_fd = ksys_open("/dev/ram", O_RDWR, 0); - if (out_fd < 0) + out_file = filp_open("/dev/ram", O_RDWR, 0); + if (IS_ERR(out_file)) goto out; - in_fd = ksys_open(from, O_RDONLY, 0); - if (in_fd < 0) + in_file = filp_open(from, O_RDONLY, 0); + if (IS_ERR(in_file)) goto noclose_input; - nblocks = identify_ramdisk_image(in_fd, rd_image_start, &decompressor); + in_pos = rd_image_start * BLOCK_SIZE; + nblocks = identify_ramdisk_image(in_file, in_pos, &decompressor); if (nblocks < 0) goto done; if (nblocks == 0) { - if (crd_load(in_fd, out_fd, decompressor) == 0) + if (crd_load(decompressor) == 0) goto successful_load; goto done; } @@ -206,11 +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 (ksys_ioctl(out_fd, BLKGETSIZE, (unsigned long)&rd_blocks) < 0) - rd_blocks = 0; - else - rd_blocks >>= 1; - + rd_blocks = nr_blocks(out_file); if (nblocks > rd_blocks) { printk("RAMDISK: image too big! (%dKiB/%ldKiB)\n", nblocks, rd_blocks); @@ -220,13 +228,10 @@ int __init rd_load_image(char *from) /* * OK, time to copy in the data */ - if (ksys_ioctl(in_fd, BLKGETSIZE, (unsigned long)&devblocks) < 0) - devblocks = 0; - else - devblocks >>= 1; - if (strcmp(from, "/initrd.image") == 0) devblocks = nblocks; + else + devblocks = nr_blocks(in_file); if (devblocks == 0) { printk(KERN_ERR "RAMDISK: could not determine device size\n"); @@ -245,14 +250,11 @@ int __init rd_load_image(char *from) if (i && (i % devblocks == 0)) { pr_cont("done disk #1.\n"); rotate = 0; - if (ksys_close(in_fd)) { - printk("Error closing the disk.\n"); - goto noclose_input; - } + fput(in_file); break; } - ksys_read(in_fd, buf, BLOCK_SIZE); - ksys_write(out_fd, buf, BLOCK_SIZE); + kernel_read(in_file, buf, BLOCK_SIZE, &in_pos); + kernel_write(out_file, buf, BLOCK_SIZE, &out_pos); #if !defined(CONFIG_S390) if (!(i % 16)) { pr_cont("%c\b", rotator[rotate & 0x3]); @@ -265,9 +267,9 @@ int __init rd_load_image(char *from) successful_load: res = 1; done: - ksys_close(in_fd); + fput(in_file); noclose_input: - ksys_close(out_fd); + fput(out_file); out: kfree(buf); ksys_unlink("/dev/ram"); @@ -283,11 +285,10 @@ int __init rd_load_disk(int n) static int exit_code; static int decompress_error; -static int crd_infd, crd_outfd; static long __init compr_fill(void *buf, unsigned long len) { - long r = ksys_read(crd_infd, buf, len); + long r = kernel_read(in_file, buf, len, &in_pos); if (r < 0) printk(KERN_ERR "RAMDISK: error while reading compressed data"); else if (r == 0) @@ -297,7 +298,7 @@ static long __init compr_fill(void *buf, unsigned long len) static long __init compr_flush(void *window, unsigned long outcnt) { - long written = ksys_write(crd_outfd, window, outcnt); + long written = kernel_write(out_file, window, outcnt, &out_pos); if (written != outcnt) { if (decompress_error == 0) printk(KERN_ERR @@ -316,11 +317,9 @@ static void __init error(char *x) decompress_error = 1; } -static int __init crd_load(int in_fd, int out_fd, decompress_fn deco) +static int __init crd_load(decompress_fn deco) { int result; - crd_infd = in_fd; - crd_outfd = out_fd; if (!deco) { pr_emerg("Invalid ramdisk decompression routine. " -- cgit v1.2.3 From f0ea68f1390ca11aae9e08a042c6dba5bc48eea2 Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Sat, 6 Jun 2020 15:54:39 +0200 Subject: initrd: mark init_linuxrc as __init Signed-off-by: Christoph Hellwig Acked-by: Linus Torvalds --- init/do_mounts_initrd.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'init') diff --git a/init/do_mounts_initrd.c b/init/do_mounts_initrd.c index e4f88e9e1c08..57ad5b2da8f5 100644 --- a/init/do_mounts_initrd.c +++ b/init/do_mounts_initrd.c @@ -56,7 +56,7 @@ static int __init early_initrd(char *p) } early_param("initrd", early_initrd); -static int init_linuxrc(struct subprocess_info *info, struct cred *new) +static int __init init_linuxrc(struct subprocess_info *info, struct cred *new) { ksys_unshare(CLONE_FS | CLONE_FILES); console_on_rootfs(); -- cgit v1.2.3 From 9acc17baf1fd6369cf969b1130bcf8c4b616ecfb Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Wed, 8 Jul 2020 18:18:54 +0200 Subject: initrd: mark initrd support as deprecated The classic initial ramdisk has been replaced by the much more flexible and efficient initramfs a long time. Warn about it being removed soon. Includes a spelling fix from Colin Ian King . Signed-off-by: Christoph Hellwig Acked-by: Linus Torvalds --- init/do_mounts_initrd.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'init') diff --git a/init/do_mounts_initrd.c b/init/do_mounts_initrd.c index 57ad5b2da8f5..e08669187d63 100644 --- a/init/do_mounts_initrd.c +++ b/init/do_mounts_initrd.c @@ -75,6 +75,8 @@ static void __init handle_initrd(void) extern char *envp_init[]; int error; + pr_warn("using deprecated initrd support, will be removed in 2021.\n"); + real_root_dev = new_encode_dev(ROOT_DEV); create_dev("/dev/root.old", Root_RAM0); /* mount initrd on rootfs' /root */ -- cgit v1.2.3 From 9ab6b718491b1a3c3eeb52f32a428dc0cbf5bb80 Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Sat, 6 Jun 2020 13:51:52 +0200 Subject: initramfs: remove the populate_initrd_image and clean_rootfs stubs If initrd support is not enable just print the warning directly instead of hiding the fact that we just failed behind two stub functions. Signed-off-by: Christoph Hellwig Acked-by: Linus Torvalds --- init/initramfs.c | 15 ++++----------- 1 file changed, 4 insertions(+), 11 deletions(-) (limited to 'init') diff --git a/init/initramfs.c b/init/initramfs.c index 7a38012e1af7..d10404625c31 100644 --- a/init/initramfs.c +++ b/init/initramfs.c @@ -618,13 +618,7 @@ static void __init clean_rootfs(void) ksys_close(fd); kfree(buf); } -#else -static inline void clean_rootfs(void) -{ -} -#endif /* CONFIG_BLK_DEV_RAM */ -#ifdef CONFIG_BLK_DEV_RAM static void __init populate_initrd_image(char *err) { ssize_t written; @@ -644,11 +638,6 @@ static void __init populate_initrd_image(char *err) written, initrd_end - initrd_start); ksys_close(fd); } -#else -static void __init populate_initrd_image(char *err) -{ - printk(KERN_EMERG "Initramfs unpacking failed: %s\n", err); -} #endif /* CONFIG_BLK_DEV_RAM */ static int __init populate_rootfs(void) @@ -668,8 +657,12 @@ static int __init populate_rootfs(void) err = unpack_to_rootfs((char *)initrd_start, initrd_end - initrd_start); if (err) { +#ifdef CONFIG_BLK_DEV_RAM clean_rootfs(); populate_initrd_image(err); +#else + printk(KERN_EMERG "Initramfs unpacking failed: %s\n", err); +#endif } done: -- cgit v1.2.3 From b2a74d5f9d446ae33a381ed7ba5f283f09bed726 Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Sat, 6 Jun 2020 13:59:54 +0200 Subject: initramfs: remove clean_rootfs There is no point in trying to clean up after unpacking the initramfs failed, as it should never get past the magic number check. In addition the current code only removes file that are direct children of the root entry, which wasn't complete anyway Fixes: df52092f3c97 ("fastboot: remove duplicate unpack_to_rootfs()") Reported-by: Marek Szyprowski Signed-off-by: Christoph Hellwig --- init/initramfs.c | 49 +------------------------------------------------ 1 file changed, 1 insertion(+), 48 deletions(-) (limited to 'init') diff --git a/init/initramfs.c b/init/initramfs.c index d10404625c31..1bc977ebfe31 100644 --- a/init/initramfs.c +++ b/init/initramfs.c @@ -11,6 +11,7 @@ #include #include #include +#include static ssize_t __init xwrite(int fd, const char *p, size_t count) { @@ -572,53 +573,6 @@ static inline bool kexec_free_initrd(void) #endif /* CONFIG_KEXEC_CORE */ #ifdef CONFIG_BLK_DEV_RAM -#define BUF_SIZE 1024 -static void __init clean_rootfs(void) -{ - int fd; - void *buf; - struct linux_dirent64 *dirp; - int num; - - fd = ksys_open("/", O_RDONLY, 0); - WARN_ON(fd < 0); - if (fd < 0) - return; - buf = kzalloc(BUF_SIZE, GFP_KERNEL); - WARN_ON(!buf); - if (!buf) { - ksys_close(fd); - return; - } - - dirp = buf; - num = ksys_getdents64(fd, dirp, BUF_SIZE); - while (num > 0) { - while (num > 0) { - struct kstat st; - int ret; - - ret = vfs_lstat(dirp->d_name, &st); - WARN_ON_ONCE(ret); - if (!ret) { - if (S_ISDIR(st.mode)) - ksys_rmdir(dirp->d_name); - else - ksys_unlink(dirp->d_name); - } - - num -= dirp->d_reclen; - dirp = (void *)dirp + dirp->d_reclen; - } - dirp = buf; - memset(buf, 0, BUF_SIZE); - num = ksys_getdents64(fd, dirp, BUF_SIZE); - } - - ksys_close(fd); - kfree(buf); -} - static void __init populate_initrd_image(char *err) { ssize_t written; @@ -658,7 +612,6 @@ static int __init populate_rootfs(void) err = unpack_to_rootfs((char *)initrd_start, initrd_end - initrd_start); if (err) { #ifdef CONFIG_BLK_DEV_RAM - clean_rootfs(); populate_initrd_image(err); #else printk(KERN_EMERG "Initramfs unpacking failed: %s\n", err); -- cgit v1.2.3 From bf6419e4d5440c6d414a320506c5488857a5b001 Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Tue, 14 Jul 2020 08:56:19 +0200 Subject: initramfs: switch initramfs unpacking to struct file based APIs There is no good reason to mess with file descriptors from in-kernel code, switch the initramfs unpacking to struct file based write instead. Signed-off-by: Christoph Hellwig Acked-by: Linus Torvalds --- init/initramfs.c | 47 ++++++++++++++++++++++++++--------------------- 1 file changed, 26 insertions(+), 21 deletions(-) (limited to 'init') diff --git a/init/initramfs.c b/init/initramfs.c index 1bc977ebfe31..35c26668d463 100644 --- a/init/initramfs.c +++ b/init/initramfs.c @@ -13,13 +13,14 @@ #include #include -static ssize_t __init xwrite(int fd, const char *p, size_t count) +static ssize_t __init xwrite(struct file *file, const char *p, size_t count, + loff_t *pos) { ssize_t out = 0; /* sys_write only can write MAX_RW_COUNT aka 2G-4K bytes at most */ while (count) { - ssize_t rv = ksys_write(fd, p, count); + ssize_t rv = kernel_write(file, p, count, pos); if (rv < 0) { if (rv == -EINTR || rv == -EAGAIN) @@ -317,7 +318,8 @@ static int __init maybe_link(void) return 0; } -static __initdata int wfd; +static __initdata struct file *wfile; +static __initdata loff_t wfile_pos; static int __init do_name(void) { @@ -334,16 +336,17 @@ static int __init do_name(void) int openflags = O_WRONLY|O_CREAT; if (ml != 1) openflags |= O_TRUNC; - wfd = ksys_open(collected, openflags, mode); - - if (wfd >= 0) { - ksys_fchown(wfd, uid, gid); - ksys_fchmod(wfd, mode); - if (body_len) - ksys_ftruncate(wfd, body_len); - vcollected = kstrdup(collected, GFP_KERNEL); - state = CopyFile; - } + wfile = filp_open(collected, openflags, mode); + if (IS_ERR(wfile)) + return 0; + wfile_pos = 0; + + vfs_fchown(wfile, uid, gid); + vfs_fchmod(wfile, mode); + if (body_len) + vfs_truncate(&wfile->f_path, body_len); + vcollected = kstrdup(collected, GFP_KERNEL); + state = CopyFile; } } else if (S_ISDIR(mode)) { ksys_mkdir(collected, mode); @@ -365,16 +368,16 @@ static int __init do_name(void) static int __init do_copy(void) { if (byte_count >= body_len) { - if (xwrite(wfd, victim, body_len) != body_len) + if (xwrite(wfile, victim, body_len, &wfile_pos) != body_len) error("write error"); - ksys_close(wfd); + fput(wfile); do_utime(vcollected, mtime); kfree(vcollected); eat(body_len); state = SkipIt; return 0; } else { - if (xwrite(wfd, victim, byte_count) != byte_count) + if (xwrite(wfile, victim, byte_count, &wfile_pos) != byte_count) error("write error"); body_len -= byte_count; eat(byte_count); @@ -576,21 +579,23 @@ static inline bool kexec_free_initrd(void) static void __init populate_initrd_image(char *err) { ssize_t written; - int fd; + struct file *file; + loff_t pos = 0; unpack_to_rootfs(__initramfs_start, __initramfs_size); printk(KERN_INFO "rootfs image is not initramfs (%s); looks like an initrd\n", err); - fd = ksys_open("/initrd.image", O_WRONLY | O_CREAT, 0700); - if (fd < 0) + file = filp_open("/initrd.image", O_WRONLY | O_CREAT, 0700); + if (IS_ERR(file)) return; - written = xwrite(fd, (char *)initrd_start, initrd_end - initrd_start); + written = xwrite(file, (char *)initrd_start, initrd_end - initrd_start, + &pos); if (written != initrd_end - initrd_start) pr_err("/initrd.image: incomplete write (%zd != %ld)\n", written, initrd_end - initrd_start); - ksys_close(fd); + fput(file); } #endif /* CONFIG_BLK_DEV_RAM */ -- cgit v1.2.3 From 8f740636d9049a3f9665a0ec87a00822ec1120b4 Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Sun, 7 Jun 2020 17:44:28 +0200 Subject: init: open code setting up stdin/stdout/stderr Don't rely on the implicit set_fs(KERNEL_DS) for ksys_open to work, but instead open a struct file for /dev/console and then install it as FD 0/1/2 manually. Signed-off-by: Christoph Hellwig Acked-by: Linus Torvalds --- init/main.c | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) (limited to 'init') diff --git a/init/main.c b/init/main.c index 0ead83e86b5a..db0621dfbb04 100644 --- a/init/main.c +++ b/init/main.c @@ -1457,15 +1457,19 @@ static int __ref kernel_init(void *unused) "See Linux Documentation/admin-guide/init.rst for guidance."); } +/* Open /dev/console, for stdin/stdout/stderr, this should never fail */ void console_on_rootfs(void) { - /* Open the /dev/console as stdin, this should never fail */ - if (ksys_open((const char __user *) "/dev/console", O_RDWR, 0) < 0) - pr_err("Warning: unable to open an initial console.\n"); + struct file *file = filp_open("/dev/console", O_RDWR, 0); - /* create stdout/stderr */ - (void) ksys_dup(0); - (void) ksys_dup(0); + if (IS_ERR(file)) { + 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); } static noinline void __init kernel_init_freeable(void) -- cgit v1.2.3 From 38b082236e77d403fed23ac2d30d570598744ec3 Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Thu, 30 Jul 2020 08:19:00 +0200 Subject: initramfs: use vfs_utimes in do_copy Don't bother saving away the pathname and just use the new struct path based utimes helper instead. Signed-off-by: Christoph Hellwig Acked-by: Linus Torvalds --- init/initramfs.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) (limited to 'init') diff --git a/init/initramfs.c b/init/initramfs.c index 35c26668d463..9820fca4d4e3 100644 --- a/init/initramfs.c +++ b/init/initramfs.c @@ -202,7 +202,6 @@ static inline void __init eat(unsigned n) byte_count -= n; } -static __initdata char *vcollected; static __initdata char *collected; static long remains __initdata; static __initdata char *collect; @@ -345,7 +344,6 @@ static int __init do_name(void) vfs_fchmod(wfile, mode); if (body_len) vfs_truncate(&wfile->f_path, body_len); - vcollected = kstrdup(collected, GFP_KERNEL); state = CopyFile; } } else if (S_ISDIR(mode)) { @@ -368,11 +366,15 @@ static int __init do_name(void) static int __init do_copy(void) { if (byte_count >= body_len) { + struct timespec64 t[2] = { }; if (xwrite(wfile, victim, body_len, &wfile_pos) != body_len) error("write error"); + + t[0].tv_sec = mtime; + t[1].tv_sec = mtime; + vfs_utimes(&wfile->f_path, t); + fput(wfile); - do_utime(vcollected, mtime); - kfree(vcollected); eat(body_len); state = SkipIt; return 0; -- cgit v1.2.3 From 916db733deca5dc1e14ea8e3acfc121600a9f462 Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Sun, 7 Jun 2020 09:06:29 +0200 Subject: init: initialize ramdisk_execute_command at compile time 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 --- init/main.c | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) (limited to 'init') diff --git a/init/main.c b/init/main.c index db0621dfbb04..c2c9143db967 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; -- cgit v1.2.3 From a94b5214487b626a148c6aab86809fbeb8fcd6b1 Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Tue, 28 Jul 2020 18:23:21 +0200 Subject: init: mark console_on_rootfs as __init This helper is only used for the early init code. Signed-off-by: Christoph Hellwig --- init/main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'init') diff --git a/init/main.c b/init/main.c index c2c9143db967..47698427b15f 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); -- cgit v1.2.3 From 09cbcec07b578c04ab4ab0e31940c20126f79c4b Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Tue, 21 Jul 2020 12:20:16 +0200 Subject: init: mark create_dev as __init This helper is only used for the early init code. Signed-off-by: Christoph Hellwig --- init/do_mounts.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'init') diff --git a/init/do_mounts.h b/init/do_mounts.h index c855b3f0e06d..021e2f60223e 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)); -- cgit v1.2.3 From c60166f04283ffba7b88b45d824bbfb2bfccee24 Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Tue, 21 Jul 2020 11:12:08 +0200 Subject: init: add an init_mount helper 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 --- init/do_mounts.c | 8 ++++---- init/do_mounts.h | 1 + init/do_mounts_initrd.c | 6 +++--- 3 files changed, 8 insertions(+), 7 deletions(-) (limited to 'init') diff --git a/init/do_mounts.c b/init/do_mounts.c index a7f22cf58c7e..83db87b6e5d1 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 021e2f60223e..20e7fec8cb49 100644 --- a/init/do_mounts.h +++ b/init/do_mounts.h @@ -8,6 +8,7 @@ #include #include #include +#include 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 e08669187d63..1f9336209ad9 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 { -- cgit v1.2.3 From 09267defa36aaff6ff829bd2fc8b043ec151cc3e Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Thu, 23 Jul 2020 08:23:08 +0200 Subject: init: add an init_umount helper 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 --- init/do_mounts_initrd.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'init') diff --git a/init/do_mounts_initrd.c b/init/do_mounts_initrd.c index 1f9336209ad9..6b020a069902 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); } } -- cgit v1.2.3 From 8fb9f73e5a539ab3aa4785f30fb52c65fa98600c Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Thu, 23 Jul 2020 08:23:40 +0200 Subject: init: add an init_unlink helper 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 --- init/do_mounts.h | 2 +- init/do_mounts_initrd.c | 4 ++-- init/do_mounts_rd.c | 2 +- init/initramfs.c | 3 ++- 4 files changed, 6 insertions(+), 5 deletions(-) (limited to 'init') diff --git a/init/do_mounts.h b/init/do_mounts.h index 20e7fec8cb49..104d8431725a 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 6b020a069902..8b44dd017842 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 d4255c10432a..ac021ae6e6fa 100644 --- a/init/do_mounts_rd.c +++ b/init/do_mounts_rd.c @@ -272,7 +272,7 @@ noclose_input: 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 9820fca4d4e3..eb58cee6dadb 100644 --- a/init/initramfs.c +++ b/init/initramfs.c @@ -12,6 +12,7 @@ #include #include #include +#include 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); } } -- cgit v1.2.3 From 20cce026c3e0972017b9cb4a7cccfb8cacf187d5 Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Wed, 22 Jul 2020 11:11:45 +0200 Subject: init: add an init_rmdir helper 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 --- init/initramfs.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'init') diff --git a/init/initramfs.c b/init/initramfs.c index eb58cee6dadb..1a9159bf452f 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); } -- cgit v1.2.3 From db63f1e315384590b979f8f74abd1b5363b69894 Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Wed, 22 Jul 2020 11:25:21 +0200 Subject: init: add an init_chdir helper 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 --- init/do_mounts.c | 2 +- init/do_mounts_initrd.c | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) (limited to 'init') diff --git a/init/do_mounts.c b/init/do_mounts.c index 83db87b6e5d1..a7581c6e85f2 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 8b44dd017842..04627fd22a92 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(); -- cgit v1.2.3 From 4b7ca5014cbef51cdb99fd644eae4f3773747a05 Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Wed, 22 Jul 2020 11:26:13 +0200 Subject: init: add an init_chroot helper 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 --- init/do_mounts.c | 2 +- init/do_mounts_initrd.c | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) (limited to 'init') diff --git a/init/do_mounts.c b/init/do_mounts.c index a7581c6e85f2..b5f9604d0c98 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 04627fd22a92..a6b447b191db 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"); -- cgit v1.2.3 From b873498f99c77e7b5be3aa5ffe9ca67437232fe0 Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Wed, 22 Jul 2020 11:13:26 +0200 Subject: init: add an init_chown helper 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 --- init/initramfs.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'init') diff --git a/init/initramfs.c b/init/initramfs.c index 1a9159bf452f..358dcd93cb9d 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); } @@ -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); - ksys_lchown(collected, uid, gid); + init_chown(collected, uid, gid, AT_SYMLINK_NOFOLLOW); do_utime(collected, mtime); state = SkipIt; next_state = Reset; -- cgit v1.2.3 From 1097742efc643ffc667c5c6684635b2663145a7d Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Wed, 22 Jul 2020 11:41:02 +0200 Subject: init: add an init_chmod helper 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 --- init/initramfs.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'init') diff --git a/init/initramfs.c b/init/initramfs.c index 358dcd93cb9d..efa9fb70038d 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); } } -- cgit v1.2.3 From eb9d7d390e51108b4c6a9a7993ed9be92548c8f7 Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Wed, 22 Jul 2020 11:14:02 +0200 Subject: init: add an init_eaccess helper 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 --- init/main.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'init') diff --git a/init/main.c b/init/main.c index 47698427b15f..1c710d3e1d46 100644 --- a/init/main.c +++ b/init/main.c @@ -96,6 +96,7 @@ #include #include #include +#include #include #include @@ -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(); } -- cgit v1.2.3 From 812931d693da58cc24d2bb8dec01c2b4a7f4668f Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Wed, 22 Jul 2020 11:14:19 +0200 Subject: init: add an init_link helper 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 --- init/initramfs.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'init') diff --git a/init/initramfs.c b/init/initramfs.c index efa9fb70038d..516a66900d7a 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; -- cgit v1.2.3 From cd3acb6a79349f346714ab3d26d203a0c6ca5ab0 Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Wed, 22 Jul 2020 11:14:36 +0200 Subject: init: add an init_symlink helper 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 --- init/initramfs.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'init') diff --git a/init/initramfs.c b/init/initramfs.c index 516a66900d7a..c91fc9a51d2a 100644 --- a/init/initramfs.c +++ b/init/initramfs.c @@ -392,7 +392,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; -- cgit v1.2.3 From 83ff98c3e9cd2b82b4289e185f2ce7d635a9cbd3 Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Wed, 22 Jul 2020 11:14:59 +0200 Subject: init: add an init_mkdir helper 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 --- init/do_mounts_initrd.c | 2 +- init/initramfs.c | 2 +- init/noinitramfs.c | 5 +++-- 3 files changed, 5 insertions(+), 4 deletions(-) (limited to 'init') diff --git a/init/do_mounts_initrd.c b/init/do_mounts_initrd.c index a6b447b191db..3f5ac81913dd 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 c91fc9a51d2a..0489eb65b3b8 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 fa9cdfa7101d..94cc4df74b11 100644 --- a/init/noinitramfs.c +++ b/init/noinitramfs.c @@ -9,6 +9,7 @@ #include #include #include +#include /* * 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; -- cgit v1.2.3 From 5fee64fcde0770c41e926ff981022eaa512d8980 Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Wed, 22 Jul 2020 11:41:20 +0200 Subject: init: add an init_mknod helper 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 --- init/do_mounts.h | 2 +- init/initramfs.c | 2 +- init/noinitramfs.c | 3 +-- 3 files changed, 3 insertions(+), 4 deletions(-) (limited to 'init') diff --git a/init/do_mounts.h b/init/do_mounts.h index 104d8431725a..7a29ac3e427b 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 0489eb65b3b8..425addaf7c69 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 94cc4df74b11..3d62b07f3bb9 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; -- cgit v1.2.3 From 716308a5331bf907b819f9db8dc942b19568f925 Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Wed, 22 Jul 2020 11:15:40 +0200 Subject: init: add an init_stat helper 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 --- init/initramfs.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'init') diff --git a/init/initramfs.c b/init/initramfs.c index 425addaf7c69..744e111baba4 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 -- cgit v1.2.3 From 235e57935bf328c4cce371ffc4dd1d8fab4885cd Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Tue, 21 Jul 2020 16:05:31 +0200 Subject: init: add an init_utimes helper 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 --- init/initramfs.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'init') diff --git a/init/initramfs.c b/init/initramfs.c index 744e111baba4..e6dbfb767057 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); -- cgit v1.2.3 From f073531070d24bbb82cb2658952d949f4851024b Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Tue, 28 Jul 2020 17:49:47 +0200 Subject: init: add an init_dup helper 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 Signed-off-by: Al Viro --- init/main.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'init') diff --git a/init/main.c b/init/main.c index 1c710d3e1d46..9dae9c4f806b 100644 --- a/init/main.c +++ b/init/main.c @@ -1467,10 +1467,10 @@ 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); + fput(file); } static noinline void __init kernel_init_freeable(void) -- cgit v1.2.3