summaryrefslogtreecommitdiff
path: root/drivers/md/raid10.c
diff options
context:
space:
mode:
authorNeilBrown <neilb@suse.de>2010-06-15 09:36:03 +0100
committerNeilBrown <neilb@suse.de>2010-06-24 13:33:24 +1000
commite93f68a1fc6244c05ad8fae28e75835ec74ab34e (patch)
treed282978aac8f6fcec512be2a6e61287bbb6241b1 /drivers/md/raid10.c
parent0544a21db02c1d8883158fd6f323364f830a120a (diff)
downloadlinux-next-e93f68a1fc6244c05ad8fae28e75835ec74ab34e.tar.gz
md: fix handling of array level takeover that re-arranges devices.
Most array level changes leave the list of devices largely unchanged, possibly causing one at the end to become redundant. However conversions between RAID0 and RAID10 need to renumber all devices (except 0). This renumbering is currently being done in the ->run method when the new personality takes over. However this is too late as the common code in md.c might already have invalidated some of the devices if they had a ->raid_disk number that appeared to high. Moving it into the ->takeover method is too early as the array is still active at that time and wrong ->raid_disk numbers could cause confusion. So add a ->new_raid_disk field to mdk_rdev_s and use it to communicate the new raid_disk number. Now the common code knows exactly which devices need to be renumbered, and which can be invalidated, and can do it all at a convenient time when the array is suspend. It can also update some symlinks in sysfs which previously were not be updated correctly. Reported-by: Maciej Trela <maciej.trela@intel.com> Signed-off-by: NeilBrown <neilb@suse.de>
Diffstat (limited to 'drivers/md/raid10.c')
-rw-r--r--drivers/md/raid10.c19
1 files changed, 5 insertions, 14 deletions
diff --git a/drivers/md/raid10.c b/drivers/md/raid10.c
index 6d420cb487b5..1bab3559f3e2 100644
--- a/drivers/md/raid10.c
+++ b/drivers/md/raid10.c
@@ -2241,7 +2241,6 @@ static conf_t *setup_conf(mddev_t *mddev)
if (!conf->thread)
goto out;
- conf->scale_disks = 0;
conf->mddev = mddev;
return conf;
@@ -2300,11 +2299,6 @@ static int run(mddev_t *mddev)
if (disk_idx >= conf->raid_disks
|| disk_idx < 0)
continue;
- if (conf->scale_disks) {
- disk_idx *= conf->scale_disks;
- rdev->raid_disk = disk_idx;
- /* MOVE 'rd%d' link !! */
- }
disk = conf->mirrors + disk_idx;
disk->rdev = rdev;
@@ -2435,13 +2429,6 @@ static void *raid10_takeover_raid0(mddev_t *mddev)
return ERR_PTR(-EINVAL);
}
- /* Update slot numbers to obtain
- * degraded raid10 with missing mirrors
- */
- list_for_each_entry(rdev, &mddev->disks, same_set) {
- rdev->raid_disk *= 2;
- }
-
/* Set new parameters */
mddev->new_level = 10;
/* new layout: far_copies = 1, near_copies = 2 */
@@ -2454,7 +2441,11 @@ static void *raid10_takeover_raid0(mddev_t *mddev)
mddev->recovery_cp = MaxSector;
conf = setup_conf(mddev);
- conf->scale_disks = 2;
+ if (!IS_ERR(conf))
+ list_for_each_entry(rdev, &mddev->disks, same_set)
+ if (rdev->raid_disk >= 0)
+ rdev->new_raid_disk = rdev->raid_disk * 2;
+
return conf;
}