From 3d95de58f0334ffba30f7b81d88fbf5f2378f255 Mon Sep 17 00:00:00 2001 From: Sorgelig Date: Mon, 8 Nov 2021 02:13:42 +0800 Subject: [PATCH] Support for init loop device. --- drivers/block/loop.c | 7 ++++ init/do_mounts.c | 98 ++++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 101 insertions(+), 4 deletions(-) diff --git a/drivers/block/loop.c b/drivers/block/loop.c index 7bf4686af..b05b8aed3 100644 --- a/drivers/block/loop.c +++ b/drivers/block/loop.c @@ -133,6 +133,13 @@ static void loop_global_unlock(struct loop_device *lo, bool global) static int max_part; static int part_shift; +int loop_max_part(void) +{ + return max_part; +} + +EXPORT_SYMBOL(loop_max_part); + static int transfer_xor(struct loop_device *lo, int cmd, struct page *raw_page, unsigned raw_off, struct page *loop_page, unsigned loop_off, diff --git a/init/do_mounts.c b/init/do_mounts.c index 762b53497..ae2f2d571 100644 --- a/init/do_mounts.c +++ b/init/do_mounts.c @@ -26,9 +26,11 @@ #include #include +#include + #include "do_mounts.h" -int root_mountflags = MS_RDONLY | MS_SILENT; +int root_mountflags = MS_RDONLY | MS_SILENT | MS_NOATIME | MS_NODIRATIME; static char * __initdata root_device_name; static char __initdata saved_root_name[64]; static int root_wait; @@ -42,6 +44,14 @@ static int __init load_ramdisk(char *str) } __setup("load_ramdisk=", load_ramdisk); +static char * __initdata loop_name = 0; +static int __init set_loop_name(char *str) +{ + loop_name = str; + return 1; +} +__setup("loop=", set_loop_name); + static int __init readonly(char *str) { if (*str) @@ -564,6 +574,64 @@ static int __init mount_nodev_root(void) return err; } +static int __init m_open(const char *filename, int flags, int mode) +{ + int fd; + struct file *f = filp_open(filename, flags, mode); + if(IS_ERR(f)) + { + printk("Failed to open file (%s).\n", filename); + return -1; + } + + fd = get_unused_fd_flags(flags); + if(fd<0) + { + printk("Failed to get_unused_fd_flags.\n"); + return -1; + } + + fd_install(fd, f); + return fd; +} + +static int __init loop_setup(const char *file, const char *device) +{ + int file_fd = m_open(file, O_RDWR | O_LARGEFILE, 0); + int device_fd = -1; + + if(file_fd < 0) + { + printk("Failed to open backing file (%s).\n", file); + goto error; + } + + if((device_fd = m_open(device, O_RDWR | O_LARGEFILE, 0)) < 0) { + printk("Failed to open device (%s) %d.\n", device, device_fd); + goto error; + } + + if(sys_ioctl(device_fd, LOOP_SET_FD, (long)file_fd) < 0) { + printk("Failed to set fd.\n"); + goto error; + } + + sys_close(file_fd); + sys_close(device_fd); + return 0; + + error: + if(file_fd >= 0) { + sys_close(file_fd); + } + if(device_fd >= 0) { + sys_ioctl(device_fd, LOOP_CLR_FD, 0); + sys_close(device_fd); + } + return 1; +} + +extern int loop_max_part(void); void __init mount_root(void) { #ifdef CONFIG_ROOT_NFS @@ -587,10 +655,32 @@ void __init mount_root(void) #ifdef CONFIG_BLOCK { int err = create_dev("/dev/root", ROOT_DEV); + if (err < 0) pr_emerg("Failed to create /dev/root: %d\n", err); - if (err < 0) - pr_emerg("Failed to create /dev/root: %d\n", err); - mount_block_root("/dev/root", root_mountflags); + if(loop_name) + { + char lname[32]; + err = init_mkdir("/root2", 0777); + if (err) pr_emerg("Failed mkdir /root2: %d\n", err); + + err = init_mount("/dev/root", "/root2", "exfat", MS_DIRSYNC | MS_SYNCHRONOUS | MS_NOATIME | MS_NODIRATIME, ""); + if (err) pr_emerg("Failed to mount /dev/root as VFAT or exFAT: %d\n", err); + + err = create_dev("/dev/loop8", MKDEV(7, (loop_max_part()+1)*8)); + if (err < 0) pr_emerg("Failed to create /dev/loop8: %d\n", err); + + sprintf(lname, "/root2/%s", loop_name); + err = loop_setup(lname, "/dev/loop8"); + if (err) pr_emerg("Failed to loop_setup: %d\n", err); + + mount_block_root("/dev/loop8", root_mountflags); + err = init_mount("/root2", "/root/media/fat", "", MS_BIND, ""); + if (err) pr_emerg("Failed to bind-mount /dev/%s to /root/media/fat : %d\n", root_device_name, err); + } + else + { + mount_block_root("/dev/root", root_mountflags); + } } #endif }