--- zzzz-none-000/linux-3.10.107/init/do_mounts.c 2017-06-27 09:49:32.000000000 +0000 +++ scorpion-7490-727/linux-3.10.107/init/do_mounts.c 2021-02-04 17:41:59.000000000 +0000 @@ -26,6 +26,8 @@ #include #include #include +#include +#include #include #include @@ -100,13 +102,13 @@ /** * devt_from_partuuid - looks up the dev_t of a partition by its UUID - * @uuid: char array containing ascii UUID + * @uuid_str: char array containing ascii UUID * * The function will return the first partition which contains a matching * UUID value in its partition_meta_info struct. This does not search * by filesystem UUIDs. * - * If @uuid is followed by a "/PARTNROFF=%d", then the number will be + * If @uuid_str is followed by a "/PARTNROFF=%d", then the number will be * extracted and used as an offset from the partition identified by the UUID. * * Returns the matching dev_t on success or 0 on failure. @@ -180,7 +182,8 @@ /* * Convert a name into device number. We accept the following variants: * - * 1) device number in hexadecimal represents itself + * 1) device number in hexadecimal represents itself + * no leading 0x, for example b302. * 2) /dev/nfs represents Root_NFS (0xff) * 3) /dev/ represents the device number of disk * 4) /dev/ represents the device number @@ -195,6 +198,8 @@ * is a zero-filled hex representation of the 1-based partition number. * 7) PARTUUID=/PARTNROFF= to select a partition in relation to * a partition with a known unique id. + * 8) : major and minor number of the device separated by + * a colon. * * If name doesn't have fall into the categories above, we return (0,0). * block_class is used to check if something is a disk name. If the disk @@ -202,7 +207,7 @@ * bangs. */ -dev_t name_to_dev_t(char *name) +dev_t name_to_dev_t(const char *name) { char s[32]; char *p; @@ -220,9 +225,11 @@ #endif if (strncmp(name, "/dev/", 5) != 0) { - unsigned maj, min; + unsigned maj, min, offset; + char dummy; - if (sscanf(name, "%u:%u", &maj, &min) == 2) { + if ((sscanf(name, "%u:%u%c", &maj, &min, &dummy) == 2) || + (sscanf(name, "%u:%u:%u:%c", &maj, &min, &offset, &dummy) == 3)) { res = MKDEV(maj, min); if (maj != MAJOR(res) || min != MINOR(res)) goto fail; @@ -281,8 +288,11 @@ done: return res; } +EXPORT_SYMBOL_GPL(name_to_dev_t); -static int __init root_dev_setup(char *line) +/* this isn't static anymore, as we need to have this function available for + * mtdram1= param parsing in our mtd code -PHU*/ +int __init root_dev_setup(char *line) { strlcpy(saved_root_name, line, sizeof(saved_root_name)); return 1; @@ -390,8 +400,6 @@ case 0: goto out; case -EACCES: - flags |= MS_RDONLY; - goto retry; case -EINVAL: continue; } @@ -414,6 +422,10 @@ #endif panic("VFS: Unable to mount root fs on %s", b); } + if (!(flags & MS_RDONLY)) { + flags |= MS_RDONLY; + goto retry; + } printk("List of all partitions:\n"); printk_all_partitions(); @@ -428,7 +440,7 @@ out: put_page(page); } - + #ifdef CONFIG_ROOT_NFS #define NFSROOT_TIMEOUT_MIN 5 @@ -523,8 +535,13 @@ } #endif #ifdef CONFIG_BLOCK - create_dev("/dev/root", ROOT_DEV); - mount_block_root("/dev/root", root_mountflags); + { + int err = create_dev("/dev/root", ROOT_DEV); + + if (err < 0) + pr_emerg("Failed to create /dev/root: %d\n", err); + mount_block_root("/dev/root", root_mountflags); + } #endif } @@ -536,7 +553,7 @@ int is_floppy; if (root_delay) { - printk(KERN_INFO "Waiting %dsec before mounting root device...\n", + printk(KERN_INFO "Waiting %d sec before mounting root device...\n", root_delay); ssleep(root_delay); } @@ -568,12 +585,31 @@ goto out; /* wait for any asynchronous scanning to complete */ - if ((ROOT_DEV == 0) && root_wait) { + if ((ROOT_DEV == 0) && root_wait && saved_root_name[0]) { printk(KERN_INFO "Waiting for root device %s...\n", saved_root_name); while (driver_probe_done() != 0 || (ROOT_DEV = name_to_dev_t(saved_root_name)) == 0) msleep(100); + + async_synchronize_full(); + } else if (config_enabled(CONFIG_MTD_ROOTFS_ROOT_DEV) && + (ROOT_DEV == 0) && root_wait) { + pr_info(KERN_INFO "Waiting for root device ...\n"); + /* + * Though MMC devices get detected before kernel + * reaches here, GPT partition table parsing happens + * later. Since we assume the GPT partition "rootfs", + * as the device to mount the Root FS from, the + * "root=xxx" command line option might not be + * present resulting in 'saved_root_name' being NULL. + * Hence, don't try to do 'name_to_dev_t' on it. + * Eventually, ROOT_DEV will get updated by the GPT + * parsing code and we will break out of this loop. + */ + while (driver_probe_done() != 0 || ROOT_DEV == 0) + msleep(100); + async_synchronize_full(); } @@ -588,3 +624,50 @@ sys_mount(".", "/", NULL, MS_MOVE, NULL); sys_chroot("."); } + +static bool is_tmpfs; +static struct dentry *rootfs_mount(struct file_system_type *fs_type, + int flags, const char *dev_name, void *data) +{ + static unsigned long once; + void *fill = ramfs_fill_super; + + if (test_and_set_bit(0, &once)) + return ERR_PTR(-ENODEV); + + if (IS_ENABLED(CONFIG_TMPFS) && is_tmpfs) + fill = shmem_fill_super; + + return mount_nodev(fs_type, flags, data, fill); +} + +static struct file_system_type rootfs_fs_type = { + .name = "rootfs", + .mount = rootfs_mount, + .kill_sb = kill_litter_super, +}; + +int __init init_rootfs(void) +{ + int err = register_filesystem(&rootfs_fs_type); + + if (err) + return err; + +#if 0 + if (IS_ENABLED(CONFIG_TMPFS) && !saved_root_name[0] && + (!root_fs_names || strstr(root_fs_names, "tmpfs"))) { + err = shmem_init(); + is_tmpfs = true; + } else { + err = init_ramfs_fs(); + } +#else + err = init_ramfs_fs(); +#endif + + if (err) + unregister_filesystem(&rootfs_fs_type); + + return err; +}