Commit 17045f52 authored by NeilBrown's avatar NeilBrown

md/raid5: recognise replacements when assembling array.

If a Replacement is seen, file it as such.

If we see two replacements (or two normal devices) for the one slot,
abort.
Reviewed-by: default avatarDan Williams <dan.j.williams@intel.com>
Signed-off-by: default avatarNeilBrown <neilb@suse.de>
parent dd054fce
...@@ -4847,7 +4847,15 @@ static struct r5conf *setup_conf(struct mddev *mddev) ...@@ -4847,7 +4847,15 @@ static struct r5conf *setup_conf(struct mddev *mddev)
continue; continue;
disk = conf->disks + raid_disk; disk = conf->disks + raid_disk;
disk->rdev = rdev; if (test_bit(Replacement, &rdev->flags)) {
if (disk->replacement)
goto abort;
disk->replacement = rdev;
} else {
if (disk->rdev)
goto abort;
disk->rdev = rdev;
}
if (test_bit(In_sync, &rdev->flags)) { if (test_bit(In_sync, &rdev->flags)) {
char b[BDEVNAME_SIZE]; char b[BDEVNAME_SIZE];
...@@ -4936,6 +4944,7 @@ static int run(struct mddev *mddev) ...@@ -4936,6 +4944,7 @@ static int run(struct mddev *mddev)
int dirty_parity_disks = 0; int dirty_parity_disks = 0;
struct md_rdev *rdev; struct md_rdev *rdev;
sector_t reshape_offset = 0; sector_t reshape_offset = 0;
int i;
if (mddev->recovery_cp != MaxSector) if (mddev->recovery_cp != MaxSector)
printk(KERN_NOTICE "md/raid:%s: not clean" printk(KERN_NOTICE "md/raid:%s: not clean"
...@@ -5025,12 +5034,25 @@ static int run(struct mddev *mddev) ...@@ -5025,12 +5034,25 @@ static int run(struct mddev *mddev)
conf->thread = NULL; conf->thread = NULL;
mddev->private = conf; mddev->private = conf;
/* for (i = 0; i < conf->raid_disks && conf->previous_raid_disks;
* 0 for a fully functional array, 1 or 2 for a degraded array. i++) {
*/ rdev = conf->disks[i].rdev;
list_for_each_entry(rdev, &mddev->disks, same_set) { if (!rdev && conf->disks[i].replacement) {
if (rdev->raid_disk < 0) /* The replacement is all we have yet */
rdev = conf->disks[i].replacement;
conf->disks[i].replacement = NULL;
clear_bit(Replacement, &rdev->flags);
conf->disks[i].rdev = rdev;
}
if (!rdev)
continue; continue;
if (conf->disks[i].replacement &&
conf->reshape_progress != MaxSector) {
/* replacements and reshape simply do not mix. */
printk(KERN_ERR "md: cannot handle concurrent "
"replacement and reshape.\n");
goto abort;
}
if (test_bit(In_sync, &rdev->flags)) { if (test_bit(In_sync, &rdev->flags)) {
working_disks++; working_disks++;
continue; continue;
...@@ -5064,6 +5086,9 @@ static int run(struct mddev *mddev) ...@@ -5064,6 +5086,9 @@ static int run(struct mddev *mddev)
dirty_parity_disks++; dirty_parity_disks++;
} }
/*
* 0 for a fully functional array, 1 or 2 for a degraded array.
*/
mddev->degraded = calc_degraded(conf); mddev->degraded = calc_degraded(conf);
if (has_failed(conf)) { if (has_failed(conf)) {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment