diff options
author | NeilBrown <neilb@suse.de> | 2010-06-15 04:36:03 -0400 |
---|---|---|
committer | NeilBrown <neilb@suse.de> | 2010-06-23 23:33:24 -0400 |
commit | e93f68a1fc6244c05ad8fae28e75835ec74ab34e (patch) | |
tree | d282978aac8f6fcec512be2a6e61287bbb6241b1 /drivers/md/raid0.c | |
parent | 0544a21db02c1d8883158fd6f323364f830a120a (diff) |
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/raid0.c')
-rw-r--r-- | drivers/md/raid0.c | 11 |
1 files changed, 3 insertions, 8 deletions
diff --git a/drivers/md/raid0.c b/drivers/md/raid0.c index e70f004c99e8..7c7c38058bc2 100644 --- a/drivers/md/raid0.c +++ b/drivers/md/raid0.c | |||
@@ -173,9 +173,11 @@ static int create_strip_zones(mddev_t *mddev, raid0_conf_t **private_conf) | |||
173 | list_for_each_entry(rdev1, &mddev->disks, same_set) { | 173 | list_for_each_entry(rdev1, &mddev->disks, same_set) { |
174 | int j = rdev1->raid_disk; | 174 | int j = rdev1->raid_disk; |
175 | 175 | ||
176 | if (mddev->level == 10) | 176 | if (mddev->level == 10) { |
177 | /* taking over a raid10-n2 array */ | 177 | /* taking over a raid10-n2 array */ |
178 | j /= 2; | 178 | j /= 2; |
179 | rdev1->new_raid_disk = j; | ||
180 | } | ||
179 | 181 | ||
180 | if (j < 0 || j >= mddev->raid_disks) { | 182 | if (j < 0 || j >= mddev->raid_disks) { |
181 | printk(KERN_ERR "md/raid0:%s: bad disk number %d - " | 183 | printk(KERN_ERR "md/raid0:%s: bad disk number %d - " |
@@ -361,12 +363,6 @@ static int raid0_run(mddev_t *mddev) | |||
361 | mddev->private = conf; | 363 | mddev->private = conf; |
362 | } | 364 | } |
363 | conf = mddev->private; | 365 | conf = mddev->private; |
364 | if (conf->scale_raid_disks) { | ||
365 | int i; | ||
366 | for (i=0; i < conf->strip_zone[0].nb_dev; i++) | ||
367 | conf->devlist[i]->raid_disk /= conf->scale_raid_disks; | ||
368 | /* FIXME update sysfs rd links */ | ||
369 | } | ||
370 | 366 | ||
371 | /* calculate array device size */ | 367 | /* calculate array device size */ |
372 | md_set_array_sectors(mddev, raid0_size(mddev, 0, 0)); | 368 | md_set_array_sectors(mddev, raid0_size(mddev, 0, 0)); |
@@ -643,7 +639,6 @@ static void *raid0_takeover_raid10(mddev_t *mddev) | |||
643 | mddev->recovery_cp = MaxSector; | 639 | mddev->recovery_cp = MaxSector; |
644 | 640 | ||
645 | create_strip_zones(mddev, &priv_conf); | 641 | create_strip_zones(mddev, &priv_conf); |
646 | priv_conf->scale_raid_disks = 2; | ||
647 | return priv_conf; | 642 | return priv_conf; |
648 | } | 643 | } |
649 | 644 | ||