]> git.neil.brown.name Git - history.git/commitdiff
[PATCH] md: allow assembling of partitioned arrays at boot time.
authorAndrew Morton <akpm@osdl.org>
Sat, 13 Mar 2004 11:26:28 +0000 (03:26 -0800)
committerLen Brown <len.brown@intel.com>
Sat, 13 Mar 2004 11:26:28 +0000 (03:26 -0800)
From: NeilBrown <neilb@cse.unsw.edu.au>

kernel parameters:

   raid=partitionable
     will make all auto-detected md arrays partitionable

   md=d....
     will assemble an array as a partitionable array.

drivers/md/md.c
init/do_mounts_md.c

index 874b29ccd65094795d1cf7635cf7a7e56cc3c1de..0ba39812e726fdb36533d50865a449b7499bd898 100644 (file)
@@ -57,7 +57,7 @@
 
 
 #ifndef MODULE
-static void autostart_arrays (void);
+static void autostart_arrays (int part);
 #endif
 
 static mdk_personality_t *pers[MAX_PERSONALITY];
@@ -1447,7 +1447,7 @@ abort:
        return 1;
 }
 
-static int mdp_major = 0;
+int mdp_major = 0;
 
 static struct kobject *md_probe(dev_t dev, int *part, void *data)
 {
@@ -1792,7 +1792,7 @@ static void autorun_array(mddev_t *mddev)
  *
  * If "unit" is allocated, then bump its reference count
  */
-static void autorun_devices(void)
+static void autorun_devices(int part)
 {
        struct list_head candidates;
        struct list_head *tmp;
@@ -1825,7 +1825,12 @@ static void autorun_devices(void)
                               bdevname(rdev0->bdev, b), rdev0->preferred_minor);
                        break;
                }
-               dev = MKDEV(MD_MAJOR, rdev0->preferred_minor);
+               if (part)
+                       dev = MKDEV(mdp_major,
+                                   rdev0->preferred_minor << MdpMinorShift);
+               else
+                       dev = MKDEV(MD_MAJOR, rdev0->preferred_minor);
+
                md_probe(dev, NULL, NULL);
                mddev = mddev_find(dev);
                if (!mddev) {
@@ -1922,7 +1927,7 @@ static int autostart_array(dev_t startdev)
        /*
         * possibly return codes
         */
-       autorun_devices();
+       autorun_devices(0);
        return 0;
 
 }
@@ -2407,7 +2412,7 @@ static int md_ioctl(struct inode *inode, struct file *file,
 #ifndef MODULE
                case RAID_AUTORUN:
                        err = 0;
-                       autostart_arrays();
+                       autostart_arrays(arg);
                        goto done;
 #endif
                default:;
@@ -3577,7 +3582,7 @@ void md_autodetect_dev(dev_t dev)
 }
 
 
-static void autostart_arrays(void)
+static void autostart_arrays(int part)
 {
        char b[BDEVNAME_SIZE];
        mdk_rdev_t *rdev;
@@ -3602,7 +3607,7 @@ static void autostart_arrays(void)
        }
        dev_cnt = 0;
 
-       autorun_devices();
+       autorun_devices(part);
 }
 
 #endif
index a2b7fe08a418cb60fc525f1c8f33882d5937515e..1b960c88cb58a17a40ad5ce8a0ce51ba575bfc4f 100644 (file)
  * The code for that is here.
  */
 
-static int __initdata raid_noautodetect;
+static int __initdata raid_noautodetect, raid_autopart;
 
 static struct {
-       char device_set [MAX_MD_DEVS];
-       int pers[MAX_MD_DEVS];
-       int chunk[MAX_MD_DEVS];
-       char *device_names[MAX_MD_DEVS];
-} md_setup_args __initdata;
+       int minor;
+       int partitioned;
+       int pers;
+       int chunk;
+       char *device_names;
+} md_setup_args[MAX_MD_DEVS] __initdata;
 
+static int md_setup_ents __initdata;
+
+extern int mdp_major;
 /*
  * Parse the command-line parameters given our kernel, but do not
  * actually try to invoke the MD device now; that is handled by
@@ -43,21 +47,37 @@ static struct {
  */
 static int __init md_setup(char *str)
 {
-       int minor, level, factor, fault, pers;
+       int minor, level, factor, fault, pers, partitioned = 0;
        char *pername = "";
-       char *str1 = str;
+       char *str1;
+       int ent;
 
+       if (*str == 'd') {
+               partitioned = 1;
+               str++;
+       }
        if (get_option(&str, &minor) != 2) {    /* MD Number */
                printk(KERN_WARNING "md: Too few arguments supplied to md=.\n");
                return 0;
        }
+       str1 = str;
        if (minor >= MAX_MD_DEVS) {
                printk(KERN_WARNING "md: md=%d, Minor device number too high.\n", minor);
                return 0;
-       } else if (md_setup_args.device_names[minor]) {
-               printk(KERN_WARNING "md: md=%d, Specified more than once. "
-                      "Replacing previous definition.\n", minor);
        }
+       for (ent=0 ; ent< md_setup_ents ; ent++)
+               if (md_setup_args[ent].minor == minor &&
+                   md_setup_args[ent].partitioned == partitioned) {
+                       printk(KERN_WARNING "md: md=%s%d, Specified more than once. "
+                              "Replacing previous definition.\n", partitioned?"d":"", minor);
+                       break;
+               }
+       if (ent >= MAX_MD_DEVS) {
+               printk(KERN_WARNING "md: md=%s%d - too many md initialisations\n", partitioned?"d":"", minor);
+               return 0;
+       }
+       if (ent >= md_setup_ents)
+               md_setup_ents++;
        switch (get_option(&str, &level)) {     /* RAID Personality */
        case 2: /* could be 0 or -1.. */
                if (level == 0 || level == LEVEL_LINEAR) {
@@ -66,24 +86,16 @@ static int __init md_setup(char *str)
                                printk(KERN_WARNING "md: Too few arguments supplied to md=.\n");
                                return 0;
                        }
-                       md_setup_args.pers[minor] = level;
-                       md_setup_args.chunk[minor] = 1 << (factor+12);
-                       switch(level) {
-                       case LEVEL_LINEAR:
+                       md_setup_args[ent].pers = level;
+                       md_setup_args[ent].chunk = 1 << (factor+12);
+                       if (level ==  LEVEL_LINEAR) {
                                pers = LINEAR;
                                pername = "linear";
-                               break;
-                       case 0:
+                       } else {
                                pers = RAID0;
                                pername = "raid0";
-                               break;
-                       default:
-                               printk(KERN_WARNING
-                                      "md: The kernel has not been configured for raid%d support!\n",
-                                      level);
-                               return 0;
                        }
-                       md_setup_args.pers[minor] = pers;
+                       md_setup_args[ent].pers = pers;
                        break;
                }
                /* FALL THROUGH */
@@ -91,36 +103,45 @@ static int __init md_setup(char *str)
                str = str1;
                /* FALL THROUGH */
        case 0:
-               md_setup_args.pers[minor] = 0;
+               md_setup_args[ent].pers = 0;
                pername="super-block";
        }
 
        printk(KERN_INFO "md: Will configure md%d (%s) from %s, below.\n",
                minor, pername, str);
-       md_setup_args.device_names[minor] = str;
+       md_setup_args[ent].device_names = str;
+       md_setup_args[ent].partitioned = partitioned;
+       md_setup_args[ent].minor = minor;
 
        return 1;
 }
 
+#define MdpMinorShift 6
+
 static void __init md_setup_drive(void)
 {
-       int minor, i;
+       int minor, i, ent, partitioned;
        dev_t dev;
        dev_t devices[MD_SB_DISKS+1];
 
-       for (minor = 0; minor < MAX_MD_DEVS; minor++) {
+       for (ent = 0; ent < md_setup_ents ; ent++) {
                int fd;
                int err = 0;
                char *devname;
                mdu_disk_info_t dinfo;
                char name[16], devfs_name[16];
 
-               if (!(devname = md_setup_args.device_names[minor]))
-                       continue;
-               
-               sprintf(name, "/dev/md%d", minor);
-               sprintf(devfs_name, "/dev/md/%d", minor);
-               create_dev(name, MKDEV(MD_MAJOR, minor), devfs_name);
+               minor = md_setup_args[ent].minor;
+               partitioned = md_setup_args[ent].partitioned;
+               devname = md_setup_args[ent].device_names;
+
+               sprintf(name, "/dev/md%s%d", partitioned?"_d":"", minor);
+               sprintf(devfs_name, "/dev/md/%s%d", partitioned?"d":"", minor);
+               if (partitioned)
+                       dev = MKDEV(mdp_major, minor << MdpMinorShift);
+               else
+                       dev = MKDEV(MD_MAJOR, minor);
+               create_dev(name, dev, devfs_name);
                for (i = 0; i < MD_SB_DISKS && devname != 0; i++) {
                        char *p;
                        char comp_name[64];
@@ -143,20 +164,22 @@ static void __init md_setup_drive(void)
                        }
 
                        devices[i] = dev;
-                       md_setup_args.device_set[minor] = 1;
 
                        devname = p;
                }
                devices[i] = 0;
 
-               if (!md_setup_args.device_set[minor])
+               if (!i)
                        continue;
 
-               printk(KERN_INFO "md: Loading md%d: %s\n", minor, md_setup_args.device_names[minor]);
+               printk(KERN_INFO "md: Loading md%s%d: %s\n",
+                       partitioned ? "_d" : "", minor,
+                       md_setup_args[ent].device_names);
 
                fd = sys_open(name, 0, 0);
                if (fd < 0) {
-                       printk(KERN_ERR "md: open failed - cannot start array %d\n", minor);
+                       printk(KERN_ERR "md: open failed - cannot start "
+                                       "array %s\n", name);
                        continue;
                }
                if (sys_ioctl(fd, SET_ARRAY_INFO, 0) == -EBUSY) {
@@ -167,10 +190,10 @@ static void __init md_setup_drive(void)
                        continue;
                }
 
-               if (md_setup_args.pers[minor]) {
+               if (md_setup_args[ent].pers) {
                        /* non-persistent */
                        mdu_array_info_t ainfo;
-                       ainfo.level = pers_to_level(md_setup_args.pers[minor]);
+                       ainfo.level = pers_to_level(md_setup_args[ent].pers);
                        ainfo.size = 0;
                        ainfo.nr_disks =0;
                        ainfo.raid_disks =0;
@@ -181,7 +204,7 @@ static void __init md_setup_drive(void)
 
                        ainfo.state = (1 << MD_SB_CLEAN);
                        ainfo.layout = 0;
-                       ainfo.chunk_size = md_setup_args.chunk[minor];
+                       ainfo.chunk_size = md_setup_args[ent].chunk;
                        err = sys_ioctl(fd, SET_ARRAY_INFO, (long)&ainfo);
                        for (i = 0; !err && i <= MD_SB_DISKS; i++) {
                                dev = devices[i];
@@ -229,6 +252,10 @@ static int __init raid_setup(char *str)
 
                if (!strncmp(str, "noautodetect", wlen))
                        raid_noautodetect = 1;
+               if (strncmp(str, "partitionable", wlen)==0)
+                       raid_autopart = 1;
+               if (strncmp(str, "part", wlen)==0)
+                       raid_autopart = 1;
                pos += wlen+1;
        }
        return 1;
@@ -245,7 +272,7 @@ void __init md_run_setup(void)
        else {
                int fd = sys_open("/dev/md0", 0, 0);
                if (fd >= 0) {
-                       sys_ioctl(fd, RAID_AUTORUN, 0);
+                       sys_ioctl(fd, RAID_AUTORUN, raid_autopart);
                        sys_close(fd);
                }
        }