LCOV - code coverage report
Current view: top level - init - do_mounts.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 7 218 3.2 %
Date: 2023-03-27 20:00:47 Functions: 3 24 12.5 %

          Line data    Source code
       1             : // SPDX-License-Identifier: GPL-2.0-only
       2             : #include <linux/module.h>
       3             : #include <linux/sched.h>
       4             : #include <linux/ctype.h>
       5             : #include <linux/fd.h>
       6             : #include <linux/tty.h>
       7             : #include <linux/suspend.h>
       8             : #include <linux/root_dev.h>
       9             : #include <linux/security.h>
      10             : #include <linux/delay.h>
      11             : #include <linux/mount.h>
      12             : #include <linux/device.h>
      13             : #include <linux/init.h>
      14             : #include <linux/fs.h>
      15             : #include <linux/initrd.h>
      16             : #include <linux/async.h>
      17             : #include <linux/fs_struct.h>
      18             : #include <linux/slab.h>
      19             : #include <linux/ramfs.h>
      20             : #include <linux/shmem_fs.h>
      21             : 
      22             : #include <linux/nfs_fs.h>
      23             : #include <linux/nfs_fs_sb.h>
      24             : #include <linux/nfs_mount.h>
      25             : #include <linux/raid/detect.h>
      26             : #include <uapi/linux/mount.h>
      27             : 
      28             : #include "do_mounts.h"
      29             : 
      30             : int root_mountflags = MS_RDONLY | MS_SILENT;
      31             : static char * __initdata root_device_name;
      32             : static char __initdata saved_root_name[64];
      33             : static int root_wait;
      34             : 
      35             : dev_t ROOT_DEV;
      36             : 
      37           0 : static int __init load_ramdisk(char *str)
      38             : {
      39           0 :         pr_warn("ignoring the deprecated load_ramdisk= option\n");
      40           0 :         return 1;
      41             : }
      42             : __setup("load_ramdisk=", load_ramdisk);
      43             : 
      44           0 : static int __init readonly(char *str)
      45             : {
      46           0 :         if (*str)
      47             :                 return 0;
      48           0 :         root_mountflags |= MS_RDONLY;
      49           0 :         return 1;
      50             : }
      51             : 
      52           0 : static int __init readwrite(char *str)
      53             : {
      54           0 :         if (*str)
      55             :                 return 0;
      56           0 :         root_mountflags &= ~MS_RDONLY;
      57           0 :         return 1;
      58             : }
      59             : 
      60             : __setup("ro", readonly);
      61             : __setup("rw", readwrite);
      62             : 
      63             : #ifdef CONFIG_BLOCK
      64             : struct uuidcmp {
      65             :         const char *uuid;
      66             :         int len;
      67             : };
      68             : 
      69             : /**
      70             :  * match_dev_by_uuid - callback for finding a partition using its uuid
      71             :  * @dev:        device passed in by the caller
      72             :  * @data:       opaque pointer to the desired struct uuidcmp to match
      73             :  *
      74             :  * Returns 1 if the device matches, and 0 otherwise.
      75             :  */
      76           0 : static int match_dev_by_uuid(struct device *dev, const void *data)
      77             : {
      78           0 :         struct block_device *bdev = dev_to_bdev(dev);
      79           0 :         const struct uuidcmp *cmp = data;
      80             : 
      81           0 :         if (!bdev->bd_meta_info ||
      82           0 :             strncasecmp(cmp->uuid, bdev->bd_meta_info->uuid, cmp->len))
      83             :                 return 0;
      84             :         return 1;
      85             : }
      86             : 
      87             : /**
      88             :  * devt_from_partuuid - looks up the dev_t of a partition by its UUID
      89             :  * @uuid_str:   char array containing ascii UUID
      90             :  *
      91             :  * The function will return the first partition which contains a matching
      92             :  * UUID value in its partition_meta_info struct.  This does not search
      93             :  * by filesystem UUIDs.
      94             :  *
      95             :  * If @uuid_str is followed by a "/PARTNROFF=%d", then the number will be
      96             :  * extracted and used as an offset from the partition identified by the UUID.
      97             :  *
      98             :  * Returns the matching dev_t on success or 0 on failure.
      99             :  */
     100           0 : static dev_t devt_from_partuuid(const char *uuid_str)
     101             : {
     102             :         struct uuidcmp cmp;
     103           0 :         struct device *dev = NULL;
     104           0 :         dev_t devt = 0;
     105           0 :         int offset = 0;
     106             :         char *slash;
     107             : 
     108           0 :         cmp.uuid = uuid_str;
     109             : 
     110           0 :         slash = strchr(uuid_str, '/');
     111             :         /* Check for optional partition number offset attributes. */
     112           0 :         if (slash) {
     113           0 :                 char c = 0;
     114             : 
     115             :                 /* Explicitly fail on poor PARTUUID syntax. */
     116           0 :                 if (sscanf(slash + 1, "PARTNROFF=%d%c", &offset, &c) != 1)
     117             :                         goto clear_root_wait;
     118           0 :                 cmp.len = slash - uuid_str;
     119             :         } else {
     120           0 :                 cmp.len = strlen(uuid_str);
     121             :         }
     122             : 
     123           0 :         if (!cmp.len)
     124             :                 goto clear_root_wait;
     125             : 
     126           0 :         dev = class_find_device(&block_class, NULL, &cmp, &match_dev_by_uuid);
     127           0 :         if (!dev)
     128             :                 return 0;
     129             : 
     130           0 :         if (offset) {
     131             :                 /*
     132             :                  * Attempt to find the requested partition by adding an offset
     133             :                  * to the partition number found by UUID.
     134             :                  */
     135           0 :                 devt = part_devt(dev_to_disk(dev),
     136           0 :                                  dev_to_bdev(dev)->bd_partno + offset);
     137             :         } else {
     138           0 :                 devt = dev->devt;
     139             :         }
     140             : 
     141           0 :         put_device(dev);
     142           0 :         return devt;
     143             : 
     144             : clear_root_wait:
     145           0 :         pr_err("VFS: PARTUUID= is invalid.\n"
     146             :                "Expected PARTUUID=<valid-uuid-id>[/PARTNROFF=%%d]\n");
     147           0 :         if (root_wait)
     148           0 :                 pr_err("Disabling rootwait; root= is invalid.\n");
     149           0 :         root_wait = 0;
     150           0 :         return 0;
     151             : }
     152             : 
     153             : /**
     154             :  * match_dev_by_label - callback for finding a partition using its label
     155             :  * @dev:        device passed in by the caller
     156             :  * @data:       opaque pointer to the label to match
     157             :  *
     158             :  * Returns 1 if the device matches, and 0 otherwise.
     159             :  */
     160           0 : static int match_dev_by_label(struct device *dev, const void *data)
     161             : {
     162           0 :         struct block_device *bdev = dev_to_bdev(dev);
     163           0 :         const char *label = data;
     164             : 
     165           0 :         if (!bdev->bd_meta_info || strcmp(label, bdev->bd_meta_info->volname))
     166             :                 return 0;
     167             :         return 1;
     168             : }
     169             : 
     170           0 : static dev_t devt_from_partlabel(const char *label)
     171             : {
     172             :         struct device *dev;
     173           0 :         dev_t devt = 0;
     174             : 
     175           0 :         dev = class_find_device(&block_class, NULL, label, &match_dev_by_label);
     176           0 :         if (dev) {
     177           0 :                 devt = dev->devt;
     178           0 :                 put_device(dev);
     179             :         }
     180             : 
     181           0 :         return devt;
     182             : }
     183             : 
     184           0 : static dev_t devt_from_devname(const char *name)
     185             : {
     186           0 :         dev_t devt = 0;
     187             :         int part;
     188             :         char s[32];
     189             :         char *p;
     190             : 
     191           0 :         if (strlen(name) > 31)
     192             :                 return 0;
     193           0 :         strcpy(s, name);
     194           0 :         for (p = s; *p; p++) {
     195           0 :                 if (*p == '/')
     196           0 :                         *p = '!';
     197             :         }
     198             : 
     199           0 :         devt = blk_lookup_devt(s, 0);
     200           0 :         if (devt)
     201             :                 return devt;
     202             : 
     203             :         /*
     204             :          * Try non-existent, but valid partition, which may only exist after
     205             :          * opening the device, like partitioned md devices.
     206             :          */
     207           0 :         while (p > s && isdigit(p[-1]))
     208           0 :                 p--;
     209           0 :         if (p == s || !*p || *p == '0')
     210             :                 return 0;
     211             : 
     212             :         /* try disk name without <part number> */
     213           0 :         part = simple_strtoul(p, NULL, 10);
     214           0 :         *p = '\0';
     215           0 :         devt = blk_lookup_devt(s, part);
     216           0 :         if (devt)
     217             :                 return devt;
     218             : 
     219             :         /* try disk name without p<part number> */
     220           0 :         if (p < s + 2 || !isdigit(p[-2]) || p[-1] != 'p')
     221             :                 return 0;
     222           0 :         p[-1] = '\0';
     223           0 :         return blk_lookup_devt(s, part);
     224             : }
     225             : #endif /* CONFIG_BLOCK */
     226             : 
     227           0 : static dev_t devt_from_devnum(const char *name)
     228             : {
     229             :         unsigned maj, min, offset;
     230           0 :         dev_t devt = 0;
     231             :         char *p, dummy;
     232             : 
     233           0 :         if (sscanf(name, "%u:%u%c", &maj, &min, &dummy) == 2 ||
     234           0 :             sscanf(name, "%u:%u:%u:%c", &maj, &min, &offset, &dummy) == 3) {
     235           0 :                 devt = MKDEV(maj, min);
     236           0 :                 if (maj != MAJOR(devt) || min != MINOR(devt))
     237             :                         return 0;
     238             :         } else {
     239           0 :                 devt = new_decode_dev(simple_strtoul(name, &p, 16));
     240           0 :                 if (*p)
     241             :                         return 0;
     242             :         }
     243             : 
     244             :         return devt;
     245             : }
     246             : 
     247             : /*
     248             :  *      Convert a name into device number.  We accept the following variants:
     249             :  *
     250             :  *      1) <hex_major><hex_minor> device number in hexadecimal represents itself
     251             :  *         no leading 0x, for example b302.
     252             :  *      2) /dev/nfs represents Root_NFS (0xff)
     253             :  *      3) /dev/<disk_name> represents the device number of disk
     254             :  *      4) /dev/<disk_name><decimal> represents the device number
     255             :  *         of partition - device number of disk plus the partition number
     256             :  *      5) /dev/<disk_name>p<decimal> - same as the above, that form is
     257             :  *         used when disk name of partitioned disk ends on a digit.
     258             :  *      6) PARTUUID=00112233-4455-6677-8899-AABBCCDDEEFF representing the
     259             :  *         unique id of a partition if the partition table provides it.
     260             :  *         The UUID may be either an EFI/GPT UUID, or refer to an MSDOS
     261             :  *         partition using the format SSSSSSSS-PP, where SSSSSSSS is a zero-
     262             :  *         filled hex representation of the 32-bit "NT disk signature", and PP
     263             :  *         is a zero-filled hex representation of the 1-based partition number.
     264             :  *      7) PARTUUID=<UUID>/PARTNROFF=<int> to select a partition in relation to
     265             :  *         a partition with a known unique id.
     266             :  *      8) <major>:<minor> major and minor number of the device separated by
     267             :  *         a colon.
     268             :  *      9) PARTLABEL=<name> with name being the GPT partition label.
     269             :  *         MSDOS partitions do not support labels!
     270             :  *      10) /dev/cifs represents Root_CIFS (0xfe)
     271             :  *
     272             :  *      If name doesn't have fall into the categories above, we return (0,0).
     273             :  *      block_class is used to check if something is a disk name. If the disk
     274             :  *      name contains slashes, the device name has them replaced with
     275             :  *      bangs.
     276             :  */
     277           0 : dev_t name_to_dev_t(const char *name)
     278             : {
     279           0 :         if (strcmp(name, "/dev/nfs") == 0)
     280             :                 return Root_NFS;
     281           0 :         if (strcmp(name, "/dev/cifs") == 0)
     282             :                 return Root_CIFS;
     283           0 :         if (strcmp(name, "/dev/ram") == 0)
     284             :                 return Root_RAM0;
     285             : #ifdef CONFIG_BLOCK
     286           0 :         if (strncmp(name, "PARTUUID=", 9) == 0)
     287           0 :                 return devt_from_partuuid(name + 9);
     288           0 :         if (strncmp(name, "PARTLABEL=", 10) == 0)
     289           0 :                 return devt_from_partlabel(name + 10);
     290           0 :         if (strncmp(name, "/dev/", 5) == 0)
     291           0 :                 return devt_from_devname(name + 5);
     292             : #endif
     293           0 :         return devt_from_devnum(name);
     294             : }
     295             : EXPORT_SYMBOL_GPL(name_to_dev_t);
     296             : 
     297           1 : static int __init root_dev_setup(char *line)
     298             : {
     299           1 :         strscpy(saved_root_name, line, sizeof(saved_root_name));
     300           1 :         return 1;
     301             : }
     302             : 
     303             : __setup("root=", root_dev_setup);
     304             : 
     305           0 : static int __init rootwait_setup(char *str)
     306             : {
     307           0 :         if (*str)
     308             :                 return 0;
     309           0 :         root_wait = 1;
     310           0 :         return 1;
     311             : }
     312             : 
     313             : __setup("rootwait", rootwait_setup);
     314             : 
     315             : static char * __initdata root_mount_data;
     316           0 : static int __init root_data_setup(char *str)
     317             : {
     318           0 :         root_mount_data = str;
     319           0 :         return 1;
     320             : }
     321             : 
     322             : static char * __initdata root_fs_names;
     323           0 : static int __init fs_names_setup(char *str)
     324             : {
     325           0 :         root_fs_names = str;
     326           0 :         return 1;
     327             : }
     328             : 
     329             : static unsigned int __initdata root_delay;
     330           0 : static int __init root_delay_setup(char *str)
     331             : {
     332           0 :         root_delay = simple_strtoul(str, NULL, 0);
     333           0 :         return 1;
     334             : }
     335             : 
     336             : __setup("rootflags=", root_data_setup);
     337             : __setup("rootfstype=", fs_names_setup);
     338             : __setup("rootdelay=", root_delay_setup);
     339             : 
     340             : /* This can return zero length strings. Caller should check */
     341           0 : static int __init split_fs_names(char *page, size_t size, char *names)
     342             : {
     343           0 :         int count = 1;
     344           0 :         char *p = page;
     345             : 
     346           0 :         strscpy(p, root_fs_names, size);
     347           0 :         while (*p++) {
     348           0 :                 if (p[-1] == ',') {
     349           0 :                         p[-1] = '\0';
     350           0 :                         count++;
     351             :                 }
     352             :         }
     353             : 
     354           0 :         return count;
     355             : }
     356             : 
     357           0 : static int __init do_mount_root(const char *name, const char *fs,
     358             :                                  const int flags, const void *data)
     359             : {
     360             :         struct super_block *s;
     361           0 :         struct page *p = NULL;
     362           0 :         char *data_page = NULL;
     363             :         int ret;
     364             : 
     365           0 :         if (data) {
     366             :                 /* init_mount() requires a full page as fifth argument */
     367           0 :                 p = alloc_page(GFP_KERNEL);
     368           0 :                 if (!p)
     369             :                         return -ENOMEM;
     370           0 :                 data_page = page_address(p);
     371             :                 /* zero-pad. init_mount() will make sure it's terminated */
     372           0 :                 strncpy(data_page, data, PAGE_SIZE);
     373             :         }
     374             : 
     375           0 :         ret = init_mount(name, "/root", fs, flags, data_page);
     376           0 :         if (ret)
     377             :                 goto out;
     378             : 
     379           0 :         init_chdir("/root");
     380           0 :         s = current->fs->pwd.dentry->d_sb;
     381           0 :         ROOT_DEV = s->s_dev;
     382           0 :         printk(KERN_INFO
     383             :                "VFS: Mounted root (%s filesystem)%s on device %u:%u.\n",
     384             :                s->s_type->name,
     385             :                sb_rdonly(s) ? " readonly" : "",
     386             :                MAJOR(ROOT_DEV), MINOR(ROOT_DEV));
     387             : 
     388             : out:
     389           0 :         if (p)
     390           0 :                 put_page(p);
     391             :         return ret;
     392             : }
     393             : 
     394           0 : void __init mount_block_root(char *name, int flags)
     395             : {
     396           0 :         struct page *page = alloc_page(GFP_KERNEL);
     397           0 :         char *fs_names = page_address(page);
     398             :         char *p;
     399             :         char b[BDEVNAME_SIZE];
     400             :         int num_fs, i;
     401             : 
     402           0 :         scnprintf(b, BDEVNAME_SIZE, "unknown-block(%u,%u)",
     403           0 :                   MAJOR(ROOT_DEV), MINOR(ROOT_DEV));
     404           0 :         if (root_fs_names)
     405           0 :                 num_fs = split_fs_names(fs_names, PAGE_SIZE, root_fs_names);
     406             :         else
     407           0 :                 num_fs = list_bdev_fs_names(fs_names, PAGE_SIZE);
     408             : retry:
     409           0 :         for (i = 0, p = fs_names; i < num_fs; i++, p += strlen(p)+1) {
     410             :                 int err;
     411             : 
     412           0 :                 if (!*p)
     413           0 :                         continue;
     414           0 :                 err = do_mount_root(name, p, flags, root_mount_data);
     415           0 :                 switch (err) {
     416             :                         case 0:
     417             :                                 goto out;
     418             :                         case -EACCES:
     419             :                         case -EINVAL:
     420           0 :                                 continue;
     421             :                 }
     422             :                 /*
     423             :                  * Allow the user to distinguish between failed sys_open
     424             :                  * and bad superblock on root device.
     425             :                  * and give them a list of the available devices
     426             :                  */
     427           0 :                 printk("VFS: Cannot open root device \"%s\" or %s: error %d\n",
     428             :                                 root_device_name, b, err);
     429           0 :                 printk("Please append a correct \"root=\" boot option; here are the available partitions:\n");
     430             : 
     431           0 :                 printk_all_partitions();
     432           0 :                 panic("VFS: Unable to mount root fs on %s", b);
     433             :         }
     434           0 :         if (!(flags & SB_RDONLY)) {
     435           0 :                 flags |= SB_RDONLY;
     436           0 :                 goto retry;
     437             :         }
     438             : 
     439           0 :         printk("List of all partitions:\n");
     440           0 :         printk_all_partitions();
     441           0 :         printk("No filesystem could mount root, tried: ");
     442           0 :         for (i = 0, p = fs_names; i < num_fs; i++, p += strlen(p)+1)
     443           0 :                 printk(" %s", p);
     444           0 :         printk("\n");
     445           0 :         panic("VFS: Unable to mount root fs on %s", b);
     446             : out:
     447           0 :         put_page(page);
     448           0 : }
     449             :  
     450             : #ifdef CONFIG_ROOT_NFS
     451             : 
     452             : #define NFSROOT_TIMEOUT_MIN     5
     453             : #define NFSROOT_TIMEOUT_MAX     30
     454             : #define NFSROOT_RETRY_MAX       5
     455             : 
     456             : static int __init mount_nfs_root(void)
     457             : {
     458             :         char *root_dev, *root_data;
     459             :         unsigned int timeout;
     460             :         int try, err;
     461             : 
     462             :         err = nfs_root_data(&root_dev, &root_data);
     463             :         if (err != 0)
     464             :                 return 0;
     465             : 
     466             :         /*
     467             :          * The server or network may not be ready, so try several
     468             :          * times.  Stop after a few tries in case the client wants
     469             :          * to fall back to other boot methods.
     470             :          */
     471             :         timeout = NFSROOT_TIMEOUT_MIN;
     472             :         for (try = 1; ; try++) {
     473             :                 err = do_mount_root(root_dev, "nfs",
     474             :                                         root_mountflags, root_data);
     475             :                 if (err == 0)
     476             :                         return 1;
     477             :                 if (try > NFSROOT_RETRY_MAX)
     478             :                         break;
     479             : 
     480             :                 /* Wait, in case the server refused us immediately */
     481             :                 ssleep(timeout);
     482             :                 timeout <<= 1;
     483             :                 if (timeout > NFSROOT_TIMEOUT_MAX)
     484             :                         timeout = NFSROOT_TIMEOUT_MAX;
     485             :         }
     486             :         return 0;
     487             : }
     488             : #endif
     489             : 
     490             : #ifdef CONFIG_CIFS_ROOT
     491             : 
     492             : extern int cifs_root_data(char **dev, char **opts);
     493             : 
     494             : #define CIFSROOT_TIMEOUT_MIN    5
     495             : #define CIFSROOT_TIMEOUT_MAX    30
     496             : #define CIFSROOT_RETRY_MAX      5
     497             : 
     498             : static int __init mount_cifs_root(void)
     499             : {
     500             :         char *root_dev, *root_data;
     501             :         unsigned int timeout;
     502             :         int try, err;
     503             : 
     504             :         err = cifs_root_data(&root_dev, &root_data);
     505             :         if (err != 0)
     506             :                 return 0;
     507             : 
     508             :         timeout = CIFSROOT_TIMEOUT_MIN;
     509             :         for (try = 1; ; try++) {
     510             :                 err = do_mount_root(root_dev, "cifs", root_mountflags,
     511             :                                     root_data);
     512             :                 if (err == 0)
     513             :                         return 1;
     514             :                 if (try > CIFSROOT_RETRY_MAX)
     515             :                         break;
     516             : 
     517             :                 ssleep(timeout);
     518             :                 timeout <<= 1;
     519             :                 if (timeout > CIFSROOT_TIMEOUT_MAX)
     520             :                         timeout = CIFSROOT_TIMEOUT_MAX;
     521             :         }
     522             :         return 0;
     523             : }
     524             : #endif
     525             : 
     526           0 : static bool __init fs_is_nodev(char *fstype)
     527             : {
     528           0 :         struct file_system_type *fs = get_fs_type(fstype);
     529           0 :         bool ret = false;
     530             : 
     531           0 :         if (fs) {
     532           0 :                 ret = !(fs->fs_flags & FS_REQUIRES_DEV);
     533           0 :                 put_filesystem(fs);
     534             :         }
     535             : 
     536           0 :         return ret;
     537             : }
     538             : 
     539           0 : static int __init mount_nodev_root(void)
     540             : {
     541             :         char *fs_names, *fstype;
     542           0 :         int err = -EINVAL;
     543             :         int num_fs, i;
     544             : 
     545           0 :         fs_names = (void *)__get_free_page(GFP_KERNEL);
     546           0 :         if (!fs_names)
     547             :                 return -EINVAL;
     548           0 :         num_fs = split_fs_names(fs_names, PAGE_SIZE, root_fs_names);
     549             : 
     550           0 :         for (i = 0, fstype = fs_names; i < num_fs;
     551           0 :              i++, fstype += strlen(fstype) + 1) {
     552           0 :                 if (!*fstype)
     553           0 :                         continue;
     554           0 :                 if (!fs_is_nodev(fstype))
     555           0 :                         continue;
     556           0 :                 err = do_mount_root(root_device_name, fstype, root_mountflags,
     557             :                                     root_mount_data);
     558           0 :                 if (!err)
     559             :                         break;
     560             :         }
     561             : 
     562           0 :         free_page((unsigned long)fs_names);
     563           0 :         return err;
     564             : }
     565             : 
     566           0 : void __init mount_root(void)
     567             : {
     568             : #ifdef CONFIG_ROOT_NFS
     569             :         if (ROOT_DEV == Root_NFS) {
     570             :                 if (!mount_nfs_root())
     571             :                         printk(KERN_ERR "VFS: Unable to mount root fs via NFS.\n");
     572             :                 return;
     573             :         }
     574             : #endif
     575             : #ifdef CONFIG_CIFS_ROOT
     576             :         if (ROOT_DEV == Root_CIFS) {
     577             :                 if (!mount_cifs_root())
     578             :                         printk(KERN_ERR "VFS: Unable to mount root fs via SMB.\n");
     579             :                 return;
     580             :         }
     581             : #endif
     582           0 :         if (ROOT_DEV == 0 && root_device_name && root_fs_names) {
     583           0 :                 if (mount_nodev_root() == 0)
     584             :                         return;
     585             :         }
     586             : #ifdef CONFIG_BLOCK
     587             :         {
     588           0 :                 int err = create_dev("/dev/root", ROOT_DEV);
     589             : 
     590           0 :                 if (err < 0)
     591           0 :                         pr_emerg("Failed to create /dev/root: %d\n", err);
     592           0 :                 mount_block_root("/dev/root", root_mountflags);
     593             :         }
     594             : #endif
     595             : }
     596             : 
     597             : /*
     598             :  * Prepare the namespace - decide what/where to mount, load ramdisks, etc.
     599             :  */
     600           0 : void __init prepare_namespace(void)
     601             : {
     602           0 :         if (root_delay) {
     603           0 :                 printk(KERN_INFO "Waiting %d sec before mounting root device...\n",
     604             :                        root_delay);
     605           0 :                 ssleep(root_delay);
     606             :         }
     607             : 
     608             :         /*
     609             :          * wait for the known devices to complete their probing
     610             :          *
     611             :          * Note: this is a potential source of long boot delays.
     612             :          * For example, it is not atypical to wait 5 seconds here
     613             :          * for the touchpad of a laptop to initialize.
     614             :          */
     615           0 :         wait_for_device_probe();
     616             : 
     617             :         md_run_setup();
     618             : 
     619           0 :         if (saved_root_name[0]) {
     620           0 :                 root_device_name = saved_root_name;
     621           0 :                 if (!strncmp(root_device_name, "mtd", 3) ||
     622           0 :                     !strncmp(root_device_name, "ubi", 3)) {
     623           0 :                         mount_block_root(root_device_name, root_mountflags);
     624           0 :                         goto out;
     625             :                 }
     626           0 :                 ROOT_DEV = name_to_dev_t(root_device_name);
     627           0 :                 if (strncmp(root_device_name, "/dev/", 5) == 0)
     628           0 :                         root_device_name += 5;
     629             :         }
     630             : 
     631             :         if (initrd_load())
     632             :                 goto out;
     633             : 
     634             :         /* wait for any asynchronous scanning to complete */
     635           0 :         if ((ROOT_DEV == 0) && root_wait) {
     636           0 :                 printk(KERN_INFO "Waiting for root device %s...\n",
     637             :                         saved_root_name);
     638           0 :                 while (driver_probe_done() != 0 ||
     639           0 :                         (ROOT_DEV = name_to_dev_t(saved_root_name)) == 0)
     640           0 :                         msleep(5);
     641           0 :                 async_synchronize_full();
     642             :         }
     643             : 
     644           0 :         mount_root();
     645             : out:
     646             :         devtmpfs_mount();
     647           0 :         init_mount(".", "/", NULL, MS_MOVE, NULL);
     648           0 :         init_chroot(".");
     649           0 : }
     650             : 
     651             : static bool is_tmpfs;
     652           1 : static int rootfs_init_fs_context(struct fs_context *fc)
     653             : {
     654             :         if (IS_ENABLED(CONFIG_TMPFS) && is_tmpfs)
     655             :                 return shmem_init_fs_context(fc);
     656             : 
     657           1 :         return ramfs_init_fs_context(fc);
     658             : }
     659             : 
     660             : struct file_system_type rootfs_fs_type = {
     661             :         .name           = "rootfs",
     662             :         .init_fs_context = rootfs_init_fs_context,
     663             :         .kill_sb        = kill_litter_super,
     664             : };
     665             : 
     666           1 : void __init init_rootfs(void)
     667             : {
     668             :         if (IS_ENABLED(CONFIG_TMPFS) && !saved_root_name[0] &&
     669             :                 (!root_fs_names || strstr(root_fs_names, "tmpfs")))
     670             :                 is_tmpfs = true;
     671           1 : }

Generated by: LCOV version 1.14