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: Michael J. Evans <mjevans1983@gmail.com>
Cc: Neil Brown <neilb@suse.de>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
This commit is contained in:
Michael J. Evans 2007-10-16 23:30:52 -07:00 committed by Linus Torvalds
parent a686cd898b
commit 4d936ec1fd

View File

@ -5770,26 +5770,47 @@ static int __init md_init(void)
* Searches all registered partitions for autorun RAID arrays
* 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)
{
if (dev_cnt >= 0 && dev_cnt < 127)
detected_devices[dev_cnt++] = dev;
struct detected_devices_node *node_detected_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)
{
mdk_rdev_t *rdev;
int i;
struct detected_devices_node *node_detected_dev;
dev_t dev;
int i_scanned, i_passed;
i_scanned = 0;
i_passed = 0;
printk(KERN_INFO "md: Autodetecting RAID arrays.\n");
for (i = 0; i < dev_cnt; i++) {
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);
if (IS_ERR(rdev))
continue;
@ -5799,8 +5820,11 @@ static void autostart_arrays(int part)
continue;
}
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);
}