summary refs log tree commit diff
path: root/drivers/md/raid10.c
diff options
context:
space:
mode:
authorNeilBrown <neilb@suse.de>2012-05-22 13:55:33 +1000
committerNeilBrown <neilb@suse.de>2012-05-22 13:55:33 +1000
commit63aced61023a054825ffd6e33ac1ab99036dadd2 (patch)
treeb41a4cde223c78ec787df3b02d839e1242d2a9e5 /drivers/md/raid10.c
parentda7613b8b042ab1d3ea55459ed97301e4a2097bb (diff)
downloadlinux-63aced61023a054825ffd6e33ac1ab99036dadd2.tar.gz
md/raid10: Remove extras after reshape to smaller number of devices.
When a reshape which reduced the number of devices finishes
we must remove the extra devices.

So ensure  that raid10_remove_disk won't try to keep them, and
have raid10_finish_reshape clear the 'in_sync' flag.  Then
remove_and_add_spares will be able to remove them.

Reported-by: Hannes Reinecke <hare@suse.com>
Signed-off-by: NeilBrown <neilb@suse.de>
Diffstat (limited to 'drivers/md/raid10.c')
-rw-r--r--drivers/md/raid10.c13
1 files changed, 13 insertions, 0 deletions
diff --git a/drivers/md/raid10.c b/drivers/md/raid10.c
index ae2a5a4c6bc5..987db37cb875 100644
--- a/drivers/md/raid10.c
+++ b/drivers/md/raid10.c
@@ -1731,6 +1731,7 @@ static int raid10_remove_disk(struct mddev *mddev, struct md_rdev *rdev)
 	if (!test_bit(Faulty, &rdev->flags) &&
 	    mddev->recovery_disabled != p->recovery_disabled &&
 	    (!p->replacement || p->replacement == rdev) &&
+	    number < conf->geo.raid_disks &&
 	    enough(conf, -1)) {
 		err = -EBUSY;
 		goto abort;
@@ -4485,6 +4486,18 @@ static void raid10_finish_reshape(struct mddev *mddev)
 		mddev->resync_max_sectors = size;
 		set_capacity(mddev->gendisk, mddev->array_sectors);
 		revalidate_disk(mddev->gendisk);
+	} else {
+		int d;
+		for (d = conf->geo.raid_disks ;
+		     d < conf->geo.raid_disks - mddev->delta_disks;
+		     d++) {
+			struct md_rdev *rdev = conf->mirrors[d].rdev;
+			if (rdev)
+				clear_bit(In_sync, &rdev->flags);
+			rdev = conf->mirrors[d].replacement;
+			if (rdev)
+				clear_bit(In_sync, &rdev->flags);
+		}
 	}
 	mddev->layout = mddev->new_layout;
 	mddev->chunk_sectors = 1 << conf->geo.chunk_shift;