Commit 4d936ec1 authored by Michael J. Evans's avatar Michael J. Evans Committed by Linus Torvalds

md: software Raid autodetect dev list not array

In current release kernels the md module (Software RAID) uses a static
array (dev_t[128]) to store partition/device info temporarily for
autostart.

I discovered this (and that the devices are added as disks/partitions are
discovered at boot) while I was debugging why only one of my MD arrays would
come up whole, while all the others were short a disk.

I eventually discovered that it was enumerating through all of 9 of my 11 hds
(2 had only 4 partitions apiece) while the other 9 have 15 partitions (I
wanted 64 per drive...).  The last partition of the 8th drive in my 9 drive
raid 5 sets wasn't added, thus making the final md array short both a parity
and data disk, and it was started later, elsewhere.

This patch replaces that static array with a list.

[akpm@linux-foundation.org: removed unused var]
Signed-off-by: default avatarMichael J. Evans <mjevans1983@gmail.com>
Cc: Neil Brown <neilb@suse.de>
Signed-off-by: default avatarAndrew Morton <akpm@linux-foundation.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
parent a686cd89
...@@ -5770,26 +5770,47 @@ static int __init md_init(void) ...@@ -5770,26 +5770,47 @@ static int __init md_init(void)
* Searches all registered partitions for autorun RAID arrays * Searches all registered partitions for autorun RAID arrays
* at boot time. * at boot time.
*/ */
static dev_t detected_devices[128];
static int dev_cnt; static LIST_HEAD(all_detected_devices);
struct detected_devices_node {
struct list_head list;
dev_t dev;
};
void md_autodetect_dev(dev_t dev) void md_autodetect_dev(dev_t dev)
{ {
if (dev_cnt >= 0 && dev_cnt < 127) struct detected_devices_node *node_detected_dev;
detected_devices[dev_cnt++] = dev;
node_detected_dev = kzalloc(sizeof(*node_detected_dev), GFP_KERNEL);
if (node_detected_dev) {
node_detected_dev->dev = dev;
list_add_tail(&node_detected_dev->list, &all_detected_devices);
} else {
printk(KERN_CRIT "md: md_autodetect_dev: kzalloc failed"
", skipping dev(%d,%d)\n", MAJOR(dev), MINOR(dev));
}
} }
static void autostart_arrays(int part) static void autostart_arrays(int part)
{ {
mdk_rdev_t *rdev; mdk_rdev_t *rdev;
int i; struct detected_devices_node *node_detected_dev;
dev_t dev;
int i_scanned, i_passed;
printk(KERN_INFO "md: Autodetecting RAID arrays.\n"); i_scanned = 0;
i_passed = 0;
for (i = 0; i < dev_cnt; i++) { printk(KERN_INFO "md: Autodetecting RAID arrays.\n");
dev_t dev = detected_devices[i];
while (!list_empty(&all_detected_devices) && i_scanned < INT_MAX) {
i_scanned++;
node_detected_dev = list_entry(all_detected_devices.next,
struct detected_devices_node, list);
list_del(&node_detected_dev->list);
dev = node_detected_dev->dev;
kfree(node_detected_dev);
rdev = md_import_device(dev,0, 90); rdev = md_import_device(dev,0, 90);
if (IS_ERR(rdev)) if (IS_ERR(rdev))
continue; continue;
...@@ -5799,8 +5820,11 @@ static void autostart_arrays(int part) ...@@ -5799,8 +5820,11 @@ static void autostart_arrays(int part)
continue; continue;
} }
list_add(&rdev->same_set, &pending_raid_disks); list_add(&rdev->same_set, &pending_raid_disks);
i_passed++;
} }
dev_cnt = 0;
printk(KERN_INFO "md: Scanned %d and added %d devices.\n",
i_scanned, i_passed);
autorun_devices(part); autorun_devices(part);
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment