^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) #include <linux/blkdev.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) #include <linux/init.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) #include <linux/mount.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) #include <linux/major.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) #include <linux/delay.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) #include <linux/init_syscalls.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) #include <linux/raid/detect.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #include <linux/raid/md_u.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include <linux/raid/md_p.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include "md.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) * When md (and any require personalities) are compiled into the kernel
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) * (not a module), arrays can be assembles are boot time using with AUTODETECT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) * where specially marked partitions are registered with md_autodetect_dev(),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) * and with MD_BOOT where devices to be collected are given on the boot line
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) * with md=.....
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) * The code for that is here.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) #ifdef CONFIG_MD_AUTODETECT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) static int __initdata raid_noautodetect;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) static int __initdata raid_noautodetect=1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) static int __initdata raid_autopart;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) static struct md_setup_args {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) int minor;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) int partitioned;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) int level;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) int chunk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) char *device_names;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) } md_setup_args[256] __initdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) static int md_setup_ents __initdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) * Parse the command-line parameters given our kernel, but do not
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) * actually try to invoke the MD device now; that is handled by
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) * md_setup_drive after the low-level disk drivers have initialised.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) * 27/11/1999: Fixed to work correctly with the 2.3 kernel (which
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) * assigns the task of parsing integer arguments to the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) * invoked program now). Added ability to initialise all
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) * the MD devices (by specifying multiple "md=" lines)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) * instead of just one. -- KTK
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) * 18May2000: Added support for persistent-superblock arrays:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) * md=n,0,factor,fault,device-list uses RAID0 for device n
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) * md=n,-1,factor,fault,device-list uses LINEAR for device n
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) * md=n,device-list reads a RAID superblock from the devices
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) * elements in device-list are read by name_to_kdev_t so can be
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) * a hex number or something like /dev/hda1 /dev/sdb
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) * 2001-06-03: Dave Cinege <dcinege@psychosis.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) * Shifted name_to_kdev_t() and related operations to md_set_drive()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) * for later execution. Rewrote section to make devfs compatible.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) static int __init md_setup(char *str)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) int minor, level, factor, fault, partitioned = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) char *pername = "";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) char *str1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) int ent;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) if (*str == 'd') {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) partitioned = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) str++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) if (get_option(&str, &minor) != 2) { /* MD Number */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) printk(KERN_WARNING "md: Too few arguments supplied to md=.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) str1 = str;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) for (ent=0 ; ent< md_setup_ents ; ent++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) if (md_setup_args[ent].minor == minor &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) md_setup_args[ent].partitioned == partitioned) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) printk(KERN_WARNING "md: md=%s%d, Specified more than once. "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) "Replacing previous definition.\n", partitioned?"d":"", minor);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) if (ent >= ARRAY_SIZE(md_setup_args)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) printk(KERN_WARNING "md: md=%s%d - too many md initialisations\n", partitioned?"d":"", minor);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) if (ent >= md_setup_ents)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) md_setup_ents++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) switch (get_option(&str, &level)) { /* RAID level */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) case 2: /* could be 0 or -1.. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) if (level == 0 || level == LEVEL_LINEAR) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) if (get_option(&str, &factor) != 2 || /* Chunk Size */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) get_option(&str, &fault) != 2) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) printk(KERN_WARNING "md: Too few arguments supplied to md=.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) md_setup_args[ent].level = level;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) md_setup_args[ent].chunk = 1 << (factor+12);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) if (level == LEVEL_LINEAR)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) pername = "linear";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) pername = "raid0";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) fallthrough;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) case 1: /* the first device is numeric */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) str = str1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) fallthrough;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) case 0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) md_setup_args[ent].level = LEVEL_NONE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) pername="super-block";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) printk(KERN_INFO "md: Will configure md%d (%s) from %s, below.\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) minor, pername, str);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) md_setup_args[ent].device_names = str;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) md_setup_args[ent].partitioned = partitioned;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) md_setup_args[ent].minor = minor;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) static void __init md_setup_drive(struct md_setup_args *args)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) char *devname = args->device_names;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) dev_t devices[MD_SB_DISKS + 1], mdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) struct mdu_array_info_s ainfo = { };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) struct block_device *bdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) struct mddev *mddev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) int err = 0, i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) char name[16];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) if (args->partitioned) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) mdev = MKDEV(mdp_major, args->minor << MdpMinorShift);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) sprintf(name, "md_d%d", args->minor);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) mdev = MKDEV(MD_MAJOR, args->minor);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) sprintf(name, "md%d", args->minor);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) for (i = 0; i < MD_SB_DISKS && devname != NULL; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) struct kstat stat;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) char *p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) char comp_name[64];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) dev_t dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) p = strchr(devname, ',');
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) if (p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) *p++ = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) dev = name_to_dev_t(devname);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) if (strncmp(devname, "/dev/", 5) == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) devname += 5;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) snprintf(comp_name, 63, "/dev/%s", devname);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) if (init_stat(comp_name, &stat, 0) == 0 && S_ISBLK(stat.mode))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) dev = new_decode_dev(stat.rdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) if (!dev) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) pr_warn("md: Unknown device name: %s\n", devname);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) devices[i] = dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) devname = p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) devices[i] = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) if (!i)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) pr_info("md: Loading %s: %s\n", name, args->device_names);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) bdev = blkdev_get_by_dev(mdev, FMODE_READ, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) if (IS_ERR(bdev)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) pr_err("md: open failed - cannot start array %s\n", name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) err = -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) if (WARN(bdev->bd_disk->fops != &md_fops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) "Opening block device %x resulted in non-md device\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) mdev))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) goto out_blkdev_put;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) mddev = bdev->bd_disk->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) err = mddev_lock(mddev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) if (err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) pr_err("md: failed to lock array %s\n", name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) goto out_blkdev_put;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) if (!list_empty(&mddev->disks) || mddev->raid_disks) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) pr_warn("md: Ignoring %s, already autodetected. (Use raid=noautodetect)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) goto out_unlock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) if (args->level != LEVEL_NONE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) /* non-persistent */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) ainfo.level = args->level;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) ainfo.md_minor = args->minor;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) ainfo.not_persistent = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) ainfo.state = (1 << MD_SB_CLEAN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) ainfo.chunk_size = args->chunk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) while (devices[ainfo.raid_disks])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) ainfo.raid_disks++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) err = md_set_array_info(mddev, &ainfo);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) for (i = 0; i <= MD_SB_DISKS && devices[i]; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) struct mdu_disk_info_s dinfo = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) .major = MAJOR(devices[i]),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) .minor = MINOR(devices[i]),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) if (args->level != LEVEL_NONE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) dinfo.number = i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) dinfo.raid_disk = i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) dinfo.state =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) (1 << MD_DISK_ACTIVE) | (1 << MD_DISK_SYNC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) md_add_new_disk(mddev, &dinfo);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) if (!err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) err = do_md_run(mddev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) pr_warn("md: starting %s failed\n", name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) out_unlock:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) mddev_unlock(mddev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) out_blkdev_put:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) blkdev_put(bdev, FMODE_READ);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) static int __init raid_setup(char *str)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) int len, pos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) len = strlen(str) + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) pos = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) while (pos < len) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) char *comma = strchr(str+pos, ',');
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) int wlen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) if (comma)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) wlen = (comma-str)-pos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) else wlen = (len-1)-pos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) if (!strncmp(str, "noautodetect", wlen))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) raid_noautodetect = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) if (!strncmp(str, "autodetect", wlen))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) raid_noautodetect = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) if (strncmp(str, "partitionable", wlen)==0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) raid_autopart = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) if (strncmp(str, "part", wlen)==0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) raid_autopart = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) pos += wlen+1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) __setup("raid=", raid_setup);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) __setup("md=", md_setup);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) static void __init autodetect_raid(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) * Since we don't want to detect and use half a raid array, we need to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) * wait for the known devices to complete their probing
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) printk(KERN_INFO "md: Waiting for all devices to be available before autodetect\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) printk(KERN_INFO "md: If you don't use raid, use raid=noautodetect\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) wait_for_device_probe();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) md_autostart_arrays(raid_autopart);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) void __init md_run_setup(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) int ent;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) if (raid_noautodetect)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) printk(KERN_INFO "md: Skipping autodetection of RAID arrays. (raid=autodetect will force)\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) autodetect_raid();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) for (ent = 0; ent < md_setup_ents; ent++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) md_setup_drive(&md_setup_args[ent]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) }