hc
2024-05-11 297b60346df8beafee954a0fd7c2d64f33f3b9bc
kernel/init/do_mounts.c
....@@ -1,3 +1,4 @@
1
+// SPDX-License-Identifier: GPL-2.0-only
12 #include <linux/module.h>
23 #include <linux/sched.h>
34 #include <linux/ctype.h>
....@@ -22,10 +23,10 @@
2223 #include <linux/nfs_fs.h>
2324 #include <linux/nfs_fs_sb.h>
2425 #include <linux/nfs_mount.h>
26
+#include <linux/raid/detect.h>
27
+#include <uapi/linux/mount.h>
2528
2629 #include "do_mounts.h"
27
-
28
-int __initdata rd_doload; /* 1 = load RAM disk, 0 = don't load */
2930
3031 int root_mountflags = MS_RDONLY | MS_SILENT;
3132 static char * __initdata root_device_name;
....@@ -36,7 +37,7 @@
3637
3738 static int __init load_ramdisk(char *str)
3839 {
39
- rd_doload = simple_strtol(str,NULL,0) & 3;
40
+ pr_warn("ignoring the deprecated load_ramdisk= option\n");
4041 return 1;
4142 }
4243 __setup("load_ramdisk=", load_ramdisk);
....@@ -167,6 +168,24 @@
167168 }
168169 return res;
169170 }
171
+
172
+/**
173
+ * match_dev_by_label - callback for finding a partition using its label
174
+ * @dev: device passed in by the caller
175
+ * @data: opaque pointer to the label to match
176
+ *
177
+ * Returns 1 if the device matches, and 0 otherwise.
178
+ */
179
+static int match_dev_by_label(struct device *dev, const void *data)
180
+{
181
+ const char *label = data;
182
+ struct hd_struct *part = dev_to_part(dev);
183
+
184
+ if (part->info && !strcmp(label, part->info->volname))
185
+ return 1;
186
+
187
+ return 0;
188
+}
170189 #endif
171190
172191 /*
....@@ -190,6 +209,9 @@
190209 * a partition with a known unique id.
191210 * 8) <major>:<minor> major and minor number of the device separated by
192211 * a colon.
212
+ * 9) PARTLABEL=<name> with name being the GPT partition label.
213
+ * MSDOS partitions do not support labels!
214
+ * 10) /dev/cifs represents Root_CIFS (0xfe)
193215 *
194216 * If name doesn't have fall into the categories above, we return (0,0).
195217 * block_class is used to check if something is a disk name. If the disk
....@@ -210,6 +232,17 @@
210232 res = devt_from_partuuid(name);
211233 if (!res)
212234 goto fail;
235
+ goto done;
236
+ } else if (strncmp(name, "PARTLABEL=", 10) == 0) {
237
+ struct device *dev;
238
+
239
+ dev = class_find_device(&block_class, NULL, name + 10,
240
+ &match_dev_by_label);
241
+ if (!dev)
242
+ goto fail;
243
+
244
+ res = dev->devt;
245
+ put_device(dev);
213246 goto done;
214247 }
215248 #endif
....@@ -234,6 +267,9 @@
234267 name += 5;
235268 res = Root_NFS;
236269 if (strcmp(name, "nfs") == 0)
270
+ goto done;
271
+ res = Root_CIFS;
272
+ if (strcmp(name, "cifs") == 0)
237273 goto done;
238274 res = Root_RAM0;
239275 if (strcmp(name, "ram") == 0)
....@@ -350,14 +386,29 @@
350386 *s = '\0';
351387 }
352388
353
-static int __init do_mount_root(char *name, char *fs, int flags, void *data)
389
+static int __init do_mount_root(const char *name, const char *fs,
390
+ const int flags, const void *data)
354391 {
355392 struct super_block *s;
356
- int err = ksys_mount(name, "/root", fs, flags, data);
357
- if (err)
358
- return err;
393
+ struct page *p = NULL;
394
+ char *data_page = NULL;
395
+ int ret;
359396
360
- ksys_chdir("/root");
397
+ if (data) {
398
+ /* init_mount() requires a full page as fifth argument */
399
+ p = alloc_page(GFP_KERNEL);
400
+ if (!p)
401
+ return -ENOMEM;
402
+ data_page = page_address(p);
403
+ /* zero-pad. init_mount() will make sure it's terminated */
404
+ strncpy(data_page, data, PAGE_SIZE);
405
+ }
406
+
407
+ ret = init_mount(name, "/root", fs, flags, data_page);
408
+ if (ret)
409
+ goto out;
410
+
411
+ init_chdir("/root");
361412 s = current->fs->pwd.dentry->d_sb;
362413 ROOT_DEV = s->s_dev;
363414 printk(KERN_INFO
....@@ -365,7 +416,11 @@
365416 s->s_type->name,
366417 sb_rdonly(s) ? " readonly" : "",
367418 MAJOR(ROOT_DEV), MINOR(ROOT_DEV));
368
- return 0;
419
+
420
+out:
421
+ if (p)
422
+ put_page(p);
423
+ return ret;
369424 }
370425
371426 void __init mount_block_root(char *name, int flags)
....@@ -373,12 +428,10 @@
373428 struct page *page = alloc_page(GFP_KERNEL);
374429 char *fs_names = page_address(page);
375430 char *p;
376
-#ifdef CONFIG_BLOCK
377431 char b[BDEVNAME_SIZE];
378
-#else
379
- const char *b = name;
380
-#endif
381432
433
+ scnprintf(b, BDEVNAME_SIZE, "unknown-block(%u,%u)",
434
+ MAJOR(ROOT_DEV), MINOR(ROOT_DEV));
382435 get_fs_names(fs_names);
383436 retry:
384437 for (p = fs_names; *p; p += strlen(p)+1) {
....@@ -395,9 +448,6 @@
395448 * and bad superblock on root device.
396449 * and give them a list of the available devices
397450 */
398
-#ifdef CONFIG_BLOCK
399
- __bdevname(ROOT_DEV, b);
400
-#endif
401451 printk("VFS: Cannot open root device \"%s\" or %s: error %d\n",
402452 root_device_name, b, err);
403453 printk("Please append a correct \"root=\" boot option; here are the available partitions:\n");
....@@ -420,9 +470,6 @@
420470 for (p = fs_names; *p; p += strlen(p)+1)
421471 printk(" %s", p);
422472 printk("\n");
423
-#ifdef CONFIG_BLOCK
424
- __bdevname(ROOT_DEV, b);
425
-#endif
426473 panic("VFS: Unable to mount root fs on %s", b);
427474 out:
428475 put_page(page);
....@@ -468,33 +515,39 @@
468515 }
469516 #endif
470517
471
-#if defined(CONFIG_BLK_DEV_RAM) || defined(CONFIG_BLK_DEV_FD)
472
-void __init change_floppy(char *fmt, ...)
518
+#ifdef CONFIG_CIFS_ROOT
519
+
520
+extern int cifs_root_data(char **dev, char **opts);
521
+
522
+#define CIFSROOT_TIMEOUT_MIN 5
523
+#define CIFSROOT_TIMEOUT_MAX 30
524
+#define CIFSROOT_RETRY_MAX 5
525
+
526
+static int __init mount_cifs_root(void)
473527 {
474
- struct termios termios;
475
- char buf[80];
476
- char c;
477
- int fd;
478
- va_list args;
479
- va_start(args, fmt);
480
- vsprintf(buf, fmt, args);
481
- va_end(args);
482
- fd = ksys_open("/dev/root", O_RDWR | O_NDELAY, 0);
483
- if (fd >= 0) {
484
- ksys_ioctl(fd, FDEJECT, 0);
485
- ksys_close(fd);
528
+ char *root_dev, *root_data;
529
+ unsigned int timeout;
530
+ int try, err;
531
+
532
+ err = cifs_root_data(&root_dev, &root_data);
533
+ if (err != 0)
534
+ return 0;
535
+
536
+ timeout = CIFSROOT_TIMEOUT_MIN;
537
+ for (try = 1; ; try++) {
538
+ err = do_mount_root(root_dev, "cifs", root_mountflags,
539
+ root_data);
540
+ if (err == 0)
541
+ return 1;
542
+ if (try > CIFSROOT_RETRY_MAX)
543
+ break;
544
+
545
+ ssleep(timeout);
546
+ timeout <<= 1;
547
+ if (timeout > CIFSROOT_TIMEOUT_MAX)
548
+ timeout = CIFSROOT_TIMEOUT_MAX;
486549 }
487
- printk(KERN_NOTICE "VFS: Insert %s and press ENTER\n", buf);
488
- fd = ksys_open("/dev/console", O_RDWR, 0);
489
- if (fd >= 0) {
490
- ksys_ioctl(fd, TCGETS, (long)&termios);
491
- termios.c_lflag &= ~ICANON;
492
- ksys_ioctl(fd, TCSETSF, (long)&termios);
493
- ksys_read(fd, &c, 1);
494
- termios.c_lflag |= ICANON;
495
- ksys_ioctl(fd, TCSETSF, (long)&termios);
496
- ksys_close(fd);
497
- }
550
+ return 0;
498551 }
499552 #endif
500553
....@@ -502,23 +555,16 @@
502555 {
503556 #ifdef CONFIG_ROOT_NFS
504557 if (ROOT_DEV == Root_NFS) {
505
- if (mount_nfs_root())
506
- return;
507
-
508
- printk(KERN_ERR "VFS: Unable to mount root fs via NFS, trying floppy.\n");
509
- ROOT_DEV = Root_FD0;
558
+ if (!mount_nfs_root())
559
+ printk(KERN_ERR "VFS: Unable to mount root fs via NFS.\n");
560
+ return;
510561 }
511562 #endif
512
-#ifdef CONFIG_BLK_DEV_FD
513
- if (MAJOR(ROOT_DEV) == FLOPPY_MAJOR) {
514
- /* rd_doload is 2 for a dual initrd/ramload setup */
515
- if (rd_doload==2) {
516
- if (rd_load_disk(1)) {
517
- ROOT_DEV = Root_RAM1;
518
- root_device_name = NULL;
519
- }
520
- } else
521
- change_floppy("root floppy");
563
+#ifdef CONFIG_CIFS_ROOT
564
+ if (ROOT_DEV == Root_CIFS) {
565
+ if (!mount_cifs_root())
566
+ printk(KERN_ERR "VFS: Unable to mount root fs via SMB.\n");
567
+ return;
522568 }
523569 #endif
524570 #ifdef CONFIG_BLOCK
....@@ -537,8 +583,6 @@
537583 */
538584 void __init prepare_namespace(void)
539585 {
540
- int is_floppy;
541
-
542586 if (root_delay) {
543587 printk(KERN_INFO "Waiting %d sec before mounting root device...\n",
544588 root_delay);
....@@ -581,57 +625,31 @@
581625 async_synchronize_full();
582626 }
583627
584
- is_floppy = MAJOR(ROOT_DEV) == FLOPPY_MAJOR;
585
-
586
- if (is_floppy && rd_doload && rd_load_disk(0))
587
- ROOT_DEV = Root_RAM0;
588
-
589628 mount_root();
590629 out:
591
- devtmpfs_mount("dev");
592
- ksys_mount(".", "/", NULL, MS_MOVE, NULL);
593
- ksys_chroot(".");
630
+ devtmpfs_mount();
631
+ init_mount(".", "/", NULL, MS_MOVE, NULL);
632
+ init_chroot(".");
594633 }
595634
596635 static bool is_tmpfs;
597
-static struct dentry *rootfs_mount(struct file_system_type *fs_type,
598
- int flags, const char *dev_name, void *data)
636
+static int rootfs_init_fs_context(struct fs_context *fc)
599637 {
600
- static unsigned long once;
601
- void *fill = ramfs_fill_super;
602
-
603
- if (test_and_set_bit(0, &once))
604
- return ERR_PTR(-ENODEV);
605
-
606638 if (IS_ENABLED(CONFIG_TMPFS) && is_tmpfs)
607
- fill = shmem_fill_super;
639
+ return shmem_init_fs_context(fc);
608640
609
- return mount_nodev(fs_type, flags, data, fill);
641
+ return ramfs_init_fs_context(fc);
610642 }
611643
612
-static struct file_system_type rootfs_fs_type = {
644
+struct file_system_type rootfs_fs_type = {
613645 .name = "rootfs",
614
- .mount = rootfs_mount,
646
+ .init_fs_context = rootfs_init_fs_context,
615647 .kill_sb = kill_litter_super,
616648 };
617649
618
-int __init init_rootfs(void)
650
+void __init init_rootfs(void)
619651 {
620
- int err = register_filesystem(&rootfs_fs_type);
621
-
622
- if (err)
623
- return err;
624
-
625652 if (IS_ENABLED(CONFIG_TMPFS) && !saved_root_name[0] &&
626
- (!root_fs_names || strstr(root_fs_names, "tmpfs"))) {
627
- err = shmem_init();
653
+ (!root_fs_names || strstr(root_fs_names, "tmpfs")))
628654 is_tmpfs = true;
629
- } else {
630
- err = init_ramfs_fs();
631
- }
632
-
633
- if (err)
634
- unregister_filesystem(&rootfs_fs_type);
635
-
636
- return err;
637655 }