]> git.karo-electronics.de Git - karo-tx-linux.git/commitdiff
md/raid1: If there is a spare and a replaceable device, start replacement.
authorNeilBrown <neilb@suse.de>
Thu, 15 Dec 2011 06:25:59 +0000 (17:25 +1100)
committerNeilBrown <neilb@suse.de>
Thu, 15 Dec 2011 06:25:59 +0000 (17:25 +1100)
When attempting to add a spare to a RAID1 array, also consider
adding it as a replacement for a replaceable device.

Signed-off-by: NeilBrown <neilb@suse.de>
drivers/md/raid1.c

index 602796bac0cd7d1afae85cb6a894540c8cc98ee2..c902772880b57a4cafcbd8cc61bcfc67b6bda130 100644 (file)
@@ -1314,8 +1314,9 @@ static int raid1_add_disk(struct mddev *mddev, struct md_rdev *rdev)
        if (rdev->raid_disk >= 0)
                first = last = rdev->raid_disk;
 
-       for (mirror = first; mirror <= last; mirror++)
-               if ( !(p=conf->mirrors+mirror)->rdev) {
+       for (mirror = first; mirror <= last; mirror++) {
+               p = conf->mirrors+mirror;
+               if (!p->rdev) {
 
                        disk_stack_limits(mddev->gendisk, rdev->bdev,
                                          rdev->data_offset << 9);
@@ -1342,6 +1343,18 @@ static int raid1_add_disk(struct mddev *mddev, struct md_rdev *rdev)
                        rcu_assign_pointer(p->rdev, rdev);
                        break;
                }
+               if (test_bit(Replaceable, &p->rdev->flags) &&
+                   p[conf->raid_disks].rdev == NULL) {
+                       /* Add this device as a replacement */
+                       clear_bit(In_sync, &rdev->flags);
+                       set_bit(Replacement, &rdev->flags);
+                       rdev->raid_disk = mirror;
+                       err = 0;
+                       conf->fullsync = 1;
+                       rcu_assign_pointer(p[conf->raid_disks].rdev, rdev);
+                       break;
+               }
+       }
        md_integrity_add_rdev(rdev, mddev);
        print_conf(conf);
        return err;