summaryrefslogtreecommitdiffstats
path: root/drivers/block/md.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/block/md.c')
-rw-r--r--drivers/block/md.c116
1 files changed, 65 insertions, 51 deletions
diff --git a/drivers/block/md.c b/drivers/block/md.c
index 087b5aee1..de977bdf0 100644
--- a/drivers/block/md.c
+++ b/drivers/block/md.c
@@ -2080,10 +2080,10 @@ void md_setup_drive(void) md__init;
*/
#ifdef CONFIG_AUTODETECT_RAID
static int detected_devices[128] md__initdata;
-static int dev_cnt md__initdata=0;
-void md__init md_autodetect_dev(kdev_t dev)
+static int dev_cnt=0;
+void md_autodetect_dev(kdev_t dev)
{
- if (dev_cnt < 127)
+ if (dev_cnt >= 0 && dev_cnt < 127)
detected_devices[dev_cnt++] = dev;
}
#endif
@@ -2094,36 +2094,39 @@ void md__init md_run_setup(void)
mdk_rdev_t *rdev;
int i;
- if (raid_setup_args.noautodetect) {
+ if (raid_setup_args.noautodetect)
printk(KERN_INFO "skipping autodetection of RAID arrays\n");
- return;
- }
- printk(KERN_INFO "autodetecting RAID arrays\n");
+ else {
- for (i=0; i<dev_cnt; i++) {
- kdev_t dev = detected_devices[i];
+ printk(KERN_INFO "autodetecting RAID arrays\n");
- if (md_import_device(dev,1)) {
- printk(KERN_ALERT "could not import %s!\n",
- partition_name(dev));
- continue;
- }
- /*
- * Sanity checks:
- */
- rdev = find_rdev_all(dev);
- if (!rdev) {
- MD_BUG();
- continue;
- }
- if (rdev->faulty) {
- MD_BUG();
- continue;
+ for (i=0; i<dev_cnt; i++) {
+ kdev_t dev = detected_devices[i];
+
+ if (md_import_device(dev,1)) {
+ printk(KERN_ALERT "could not import %s!\n",
+ partition_name(dev));
+ continue;
+ }
+ /*
+ * Sanity checks:
+ */
+ rdev = find_rdev_all(dev);
+ if (!rdev) {
+ MD_BUG();
+ continue;
+ }
+ if (rdev->faulty) {
+ MD_BUG();
+ continue;
+ }
+ md_list_add(&rdev->pending, &pending_raid_disks);
}
- md_list_add(&rdev->pending, &pending_raid_disks);
+
+ autorun_devices();
}
- autorun_devices();
+ dev_cnt = -1; /* make sure further calls to md_autodetect_dev are ignored */
#endif
#ifdef CONFIG_MD_BOOT
md_setup_drive();
@@ -2731,11 +2734,9 @@ static int md_ioctl (struct inode *inode, struct file *file,
goto done_unlock;
case STOP_ARRAY:
- err = do_md_stop (mddev, 0);
- if (err)
- goto done_unlock;
- else
- goto done;
+ if (!(err = do_md_stop (mddev, 0)))
+ mddev = NULL;
+ goto done_unlock;
case STOP_ARRAY_RO:
err = do_md_stop (mddev, 1);
@@ -2837,7 +2838,8 @@ static int md_ioctl (struct inode *inode, struct file *file,
*/
if (err) {
mddev->sb_dirty = 0;
- do_md_stop (mddev, 0);
+ if (!do_md_stop (mddev, 0))
+ mddev = NULL;
}
goto done_unlock;
}
@@ -2852,8 +2854,6 @@ done_unlock:
abort_unlock:
if (mddev)
unlock_mddev(mddev);
- else
- printk("huh11?\n");
return err;
done:
@@ -3248,6 +3248,19 @@ static mdp_disk_t *get_spare(mddev_t *mddev)
return NULL;
}
+static unsigned int sync_io[DK_MAX_MAJOR][DK_MAX_DISK];
+void md_sync_acct(kdev_t dev, unsigned long nr_sectors)
+{
+ unsigned int major = MAJOR(dev);
+ unsigned int index;
+
+ index = disk_index(dev);
+ if ((index >= DK_MAX_DISK) || (major >= DK_MAX_MAJOR))
+ return;
+
+ sync_io[major][index] += nr_sectors;
+}
+
static int is_mddev_idle (mddev_t *mddev)
{
mdk_rdev_t * rdev;
@@ -3260,8 +3273,12 @@ static int is_mddev_idle (mddev_t *mddev)
int major = MAJOR(rdev->dev);
int idx = disk_index(rdev->dev);
+ if ((idx >= DK_MAX_DISK) || (major >= DK_MAX_MAJOR))
+ continue;
+
curr_events = kstat.dk_drive_rblk[major][idx] +
kstat.dk_drive_wblk[major][idx] ;
+ curr_events -= sync_io[major][idx];
// printk("events(major: %d, idx: %d): %ld\n", major, idx, curr_events);
if (curr_events != rdev->last_events) {
// printk("!I(%ld)", curr_events - rdev->last_events);
@@ -3561,32 +3578,28 @@ struct notifier_block md_notifier = {
0
};
-void md__init raid_setup(char *str, int *ints)
+void md__init raid_setup(char *str)
{
- char tmpline[100];
- int len, pos, nr, i;
+ int len, pos;
len = strlen(str) + 1;
- nr = 0;
pos = 0;
- for (i = 0; i < len; i++) {
- char c = str[i];
+ while (pos < len) {
+ char *comma = strchr(str+pos, ',');
+ int wlen;
+ if (comma)
+ wlen = (comma-str)-pos;
+ else wlen = (len-1)-pos;
- if (c == ',' || !c) {
- tmpline[pos] = 0;
- if (!strcmp(tmpline,"noautodetect"))
- raid_setup_args.noautodetect = 1;
- nr++;
- pos = 0;
- continue;
- }
- tmpline[pos] = c;
- pos++;
+ if (strncmp(str, "noautodetect", wlen) == 0)
+ raid_setup_args.noautodetect = 1;
+ pos += wlen+1;
}
raid_setup_args.set = 1;
return;
}
+__setup("raid=", raid_setup);
static void md_geninit (void)
{
@@ -3842,6 +3855,7 @@ MD_EXPORT_SYMBOL(unregister_md_personality);
MD_EXPORT_SYMBOL(partition_name);
MD_EXPORT_SYMBOL(md_error);
MD_EXPORT_SYMBOL(md_do_sync);
+MD_EXPORT_SYMBOL(md_sync_acct);
MD_EXPORT_SYMBOL(md_done_sync);
MD_EXPORT_SYMBOL(md_recover_arrays);
MD_EXPORT_SYMBOL(md_register_thread);