Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0
0002 #include <linux/kernel.h>
0003 #include <linux/blkdev.h>
0004 #include <linux/init.h>
0005 #include <linux/mount.h>
0006 #include <linux/major.h>
0007 #include <linux/delay.h>
0008 #include <linux/init_syscalls.h>
0009 #include <linux/raid/detect.h>
0010 #include <linux/raid/md_u.h>
0011 #include <linux/raid/md_p.h>
0012 #include "md.h"
0013 
0014 /*
0015  * When md (and any require personalities) are compiled into the kernel
0016  * (not a module), arrays can be assembles are boot time using with AUTODETECT
0017  * where specially marked partitions are registered with md_autodetect_dev(),
0018  * and with MD_BOOT where devices to be collected are given on the boot line
0019  * with md=.....
0020  * The code for that is here.
0021  */
0022 
0023 #ifdef CONFIG_MD_AUTODETECT
0024 static int __initdata raid_noautodetect;
0025 #else
0026 static int __initdata raid_noautodetect=1;
0027 #endif
0028 static int __initdata raid_autopart;
0029 
0030 static struct md_setup_args {
0031     int minor;
0032     int partitioned;
0033     int level;
0034     int chunk;
0035     char *device_names;
0036 } md_setup_args[256] __initdata;
0037 
0038 static int md_setup_ents __initdata;
0039 
0040 /*
0041  * Parse the command-line parameters given our kernel, but do not
0042  * actually try to invoke the MD device now; that is handled by
0043  * md_setup_drive after the low-level disk drivers have initialised.
0044  *
0045  * 27/11/1999: Fixed to work correctly with the 2.3 kernel (which
0046  *             assigns the task of parsing integer arguments to the
0047  *             invoked program now).  Added ability to initialise all
0048  *             the MD devices (by specifying multiple "md=" lines)
0049  *             instead of just one.  -- KTK
0050  * 18May2000: Added support for persistent-superblock arrays:
0051  *             md=n,0,factor,fault,device-list   uses RAID0 for device n
0052  *             md=n,-1,factor,fault,device-list  uses LINEAR for device n
0053  *             md=n,device-list      reads a RAID superblock from the devices
0054  *             elements in device-list are read by name_to_kdev_t so can be
0055  *             a hex number or something like /dev/hda1 /dev/sdb
0056  * 2001-06-03: Dave Cinege <dcinege@psychosis.com>
0057  *      Shifted name_to_kdev_t() and related operations to md_set_drive()
0058  *      for later execution. Rewrote section to make devfs compatible.
0059  */
0060 static int __init md_setup(char *str)
0061 {
0062     int minor, level, factor, fault, partitioned = 0;
0063     char *pername = "";
0064     char *str1;
0065     int ent;
0066 
0067     if (*str == 'd') {
0068         partitioned = 1;
0069         str++;
0070     }
0071     if (get_option(&str, &minor) != 2) {    /* MD Number */
0072         printk(KERN_WARNING "md: Too few arguments supplied to md=.\n");
0073         return 0;
0074     }
0075     str1 = str;
0076     for (ent=0 ; ent< md_setup_ents ; ent++)
0077         if (md_setup_args[ent].minor == minor &&
0078             md_setup_args[ent].partitioned == partitioned) {
0079             printk(KERN_WARNING "md: md=%s%d, Specified more than once. "
0080                    "Replacing previous definition.\n", partitioned?"d":"", minor);
0081             break;
0082         }
0083     if (ent >= ARRAY_SIZE(md_setup_args)) {
0084         printk(KERN_WARNING "md: md=%s%d - too many md initialisations\n", partitioned?"d":"", minor);
0085         return 0;
0086     }
0087     if (ent >= md_setup_ents)
0088         md_setup_ents++;
0089     switch (get_option(&str, &level)) { /* RAID level */
0090     case 2: /* could be 0 or -1.. */
0091         if (level == 0 || level == LEVEL_LINEAR) {
0092             if (get_option(&str, &factor) != 2 ||   /* Chunk Size */
0093                     get_option(&str, &fault) != 2) {
0094                 printk(KERN_WARNING "md: Too few arguments supplied to md=.\n");
0095                 return 0;
0096             }
0097             md_setup_args[ent].level = level;
0098             md_setup_args[ent].chunk = 1 << (factor+12);
0099             if (level ==  LEVEL_LINEAR)
0100                 pername = "linear";
0101             else
0102                 pername = "raid0";
0103             break;
0104         }
0105         fallthrough;
0106     case 1: /* the first device is numeric */
0107         str = str1;
0108         fallthrough;
0109     case 0:
0110         md_setup_args[ent].level = LEVEL_NONE;
0111         pername="super-block";
0112     }
0113 
0114     printk(KERN_INFO "md: Will configure md%d (%s) from %s, below.\n",
0115         minor, pername, str);
0116     md_setup_args[ent].device_names = str;
0117     md_setup_args[ent].partitioned = partitioned;
0118     md_setup_args[ent].minor = minor;
0119 
0120     return 1;
0121 }
0122 
0123 static void __init md_setup_drive(struct md_setup_args *args)
0124 {
0125     char *devname = args->device_names;
0126     dev_t devices[MD_SB_DISKS + 1], mdev;
0127     struct mdu_array_info_s ainfo = { };
0128     struct mddev *mddev;
0129     int err = 0, i;
0130     char name[16];
0131 
0132     if (args->partitioned) {
0133         mdev = MKDEV(mdp_major, args->minor << MdpMinorShift);
0134         sprintf(name, "md_d%d", args->minor);
0135     } else {
0136         mdev = MKDEV(MD_MAJOR, args->minor);
0137         sprintf(name, "md%d", args->minor);
0138     }
0139 
0140     for (i = 0; i < MD_SB_DISKS && devname != NULL; i++) {
0141         struct kstat stat;
0142         char *p;
0143         char comp_name[64];
0144         dev_t dev;
0145 
0146         p = strchr(devname, ',');
0147         if (p)
0148             *p++ = 0;
0149 
0150         dev = name_to_dev_t(devname);
0151         if (strncmp(devname, "/dev/", 5) == 0)
0152             devname += 5;
0153         snprintf(comp_name, 63, "/dev/%s", devname);
0154         if (init_stat(comp_name, &stat, 0) == 0 && S_ISBLK(stat.mode))
0155             dev = new_decode_dev(stat.rdev);
0156         if (!dev) {
0157             pr_warn("md: Unknown device name: %s\n", devname);
0158             break;
0159         }
0160 
0161         devices[i] = dev;
0162         devname = p;
0163     }
0164     devices[i] = 0;
0165 
0166     if (!i)
0167         return;
0168 
0169     pr_info("md: Loading %s: %s\n", name, args->device_names);
0170 
0171     mddev = md_alloc(mdev, name);
0172     if (IS_ERR(mddev)) {
0173         pr_err("md: md_alloc failed - cannot start array %s\n", name);
0174         return;
0175     }
0176 
0177     err = mddev_lock(mddev);
0178     if (err) {
0179         pr_err("md: failed to lock array %s\n", name);
0180         goto out_mddev_put;
0181     }
0182 
0183     if (!list_empty(&mddev->disks) || mddev->raid_disks) {
0184         pr_warn("md: Ignoring %s, already autodetected. (Use raid=noautodetect)\n",
0185                name);
0186         goto out_unlock;
0187     }
0188 
0189     if (args->level != LEVEL_NONE) {
0190         /* non-persistent */
0191         ainfo.level = args->level;
0192         ainfo.md_minor = args->minor;
0193         ainfo.not_persistent = 1;
0194         ainfo.state = (1 << MD_SB_CLEAN);
0195         ainfo.chunk_size = args->chunk;
0196         while (devices[ainfo.raid_disks])
0197             ainfo.raid_disks++;
0198     }
0199 
0200     err = md_set_array_info(mddev, &ainfo);
0201 
0202     for (i = 0; i <= MD_SB_DISKS && devices[i]; i++) {
0203         struct mdu_disk_info_s dinfo = {
0204             .major  = MAJOR(devices[i]),
0205             .minor  = MINOR(devices[i]),
0206         };
0207 
0208         if (args->level != LEVEL_NONE) {
0209             dinfo.number = i;
0210             dinfo.raid_disk = i;
0211             dinfo.state =
0212                 (1 << MD_DISK_ACTIVE) | (1 << MD_DISK_SYNC);
0213         }
0214 
0215         md_add_new_disk(mddev, &dinfo);
0216     }
0217 
0218     if (!err)
0219         err = do_md_run(mddev);
0220     if (err)
0221         pr_warn("md: starting %s failed\n", name);
0222 out_unlock:
0223     mddev_unlock(mddev);
0224 out_mddev_put:
0225     mddev_put(mddev);
0226 }
0227 
0228 static int __init raid_setup(char *str)
0229 {
0230     int len, pos;
0231 
0232     len = strlen(str) + 1;
0233     pos = 0;
0234 
0235     while (pos < len) {
0236         char *comma = strchr(str+pos, ',');
0237         int wlen;
0238         if (comma)
0239             wlen = (comma-str)-pos;
0240         else    wlen = (len-1)-pos;
0241 
0242         if (!strncmp(str, "noautodetect", wlen))
0243             raid_noautodetect = 1;
0244         if (!strncmp(str, "autodetect", wlen))
0245             raid_noautodetect = 0;
0246         if (strncmp(str, "partitionable", wlen)==0)
0247             raid_autopart = 1;
0248         if (strncmp(str, "part", wlen)==0)
0249             raid_autopart = 1;
0250         pos += wlen+1;
0251     }
0252     return 1;
0253 }
0254 
0255 __setup("raid=", raid_setup);
0256 __setup("md=", md_setup);
0257 
0258 static void __init autodetect_raid(void)
0259 {
0260     /*
0261      * Since we don't want to detect and use half a raid array, we need to
0262      * wait for the known devices to complete their probing
0263      */
0264     printk(KERN_INFO "md: Waiting for all devices to be available before autodetect\n");
0265     printk(KERN_INFO "md: If you don't use raid, use raid=noautodetect\n");
0266 
0267     wait_for_device_probe();
0268     md_autostart_arrays(raid_autopart);
0269 }
0270 
0271 void __init md_run_setup(void)
0272 {
0273     int ent;
0274 
0275     if (raid_noautodetect)
0276         printk(KERN_INFO "md: Skipping autodetection of RAID arrays. (raid=autodetect will force)\n");
0277     else
0278         autodetect_raid();
0279 
0280     for (ent = 0; ent < md_setup_ents; ent++)
0281         md_setup_drive(&md_setup_args[ent]);
0282 }