md: don't allow arrays to contain devices with bad blocks.
authorNeilBrown <neilb@suse.de>
Thu, 28 Jul 2011 01:31:47 +0000 (11:31 +1000)
committerNeilBrown <neilb@suse.de>
Thu, 28 Jul 2011 01:31:47 +0000 (11:31 +1000)
As no personality understand bad block lists yet, we must
reject any device that is known to contain bad blocks.
As the personalities get taught, these tests can be removed.

This only applies to raid1/raid5/raid10.
For linear/raid0/multipath/faulty the whole concept of bad blocks
doesn't mean anything so there is no point adding the checks.

Signed-off-by: NeilBrown <neilb@suse.de>
Reviewed-by: Namhyung Kim <namhyung@gmail.com>
drivers/md/raid1.c
drivers/md/raid10.c
drivers/md/raid5.c

index 3cbf0ac2aaad3b6bdab9c859d36f44369e027ff7..8db311d7cddcd35079d6a3aaa413b0dea5e610b7 100644 (file)
@@ -1055,6 +1055,9 @@ static int raid1_add_disk(mddev_t *mddev, mdk_rdev_t *rdev)
        if (mddev->recovery_disabled == conf->recovery_disabled)
                return -EBUSY;
 
+       if (rdev->badblocks.count)
+               return -EINVAL;
+
        if (rdev->raid_disk >= 0)
                first = last = rdev->raid_disk;
 
@@ -1994,6 +1997,10 @@ static int run(mddev_t *mddev)
                        blk_queue_segment_boundary(mddev->queue,
                                                   PAGE_CACHE_SIZE - 1);
                }
+               if (rdev->badblocks.count) {
+                       printk(KERN_ERR "md/raid1: Cannot handle bad blocks yet\n");
+                       return -EINVAL;
+               }
        }
 
        mddev->degraded = 0;
index 5def27c28be7c68c52784ef369b1ccc26ab3d791..8aadd2f52dc81ff44f9f6340094970ae9f32e324 100644 (file)
@@ -1101,6 +1101,9 @@ static int raid10_add_disk(mddev_t *mddev, mdk_rdev_t *rdev)
        int first = 0;
        int last = conf->raid_disks - 1;
 
+       if (rdev->badblocks.count)
+               return -EINVAL;
+
        if (mddev->recovery_cp < MaxSector)
                /* only hot-add to in-sync arrays, as recovery is
                 * very different from resync
@@ -2263,6 +2266,11 @@ static int run(mddev_t *mddev)
                                 (conf->raid_disks / conf->near_copies));
 
        list_for_each_entry(rdev, &mddev->disks, same_set) {
+
+               if (rdev->badblocks.count) {
+                       printk(KERN_ERR "md/raid10: cannot handle bad blocks yet\n");
+                       goto out_free_conf;
+               }
                disk_idx = rdev->raid_disk;
                if (disk_idx >= conf->raid_disks
                    || disk_idx < 0)
index b874f42694e24fb10321eaa04a4b38ad9aa5c0c4..719445004dd992b95792127aa42f1c3e1680abfd 100644 (file)
@@ -4667,6 +4667,10 @@ static int run(mddev_t *mddev)
         * 0 for a fully functional array, 1 or 2 for a degraded array.
         */
        list_for_each_entry(rdev, &mddev->disks, same_set) {
+               if (rdev->badblocks.count) {
+                       printk(KERN_ERR "md/raid5: cannot handle bad blocks yet\n");
+                       goto abort;
+               }
                if (rdev->raid_disk < 0)
                        continue;
                if (test_bit(In_sync, &rdev->flags)) {
@@ -4975,6 +4979,9 @@ static int raid5_add_disk(mddev_t *mddev, mdk_rdev_t *rdev)
        int first = 0;
        int last = conf->raid_disks - 1;
 
+       if (rdev->badblocks.count)
+               return -EINVAL;
+
        if (has_failed(conf))
                /* no point adding a device */
                return -EINVAL;