Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

3 Commits   0 Branches   0 Tags
^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) }