aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/md
diff options
context:
space:
mode:
authorNeilBrown <neilb@suse.de>2015-02-11 22:09:57 -0500
committerNeilBrown <neilb@suse.de>2015-02-11 22:09:57 -0500
commit53a6ab4d3f6d6dc87ec8f14998b4b5536ee2968c (patch)
tree995504ece355dc6279170fb6cee3f8e85349b115 /drivers/md
parentdfe15ac1c6ad301b092ed295f0cfdb16cfaf5cfa (diff)
md/raid10: fix conversion from RAID0 to RAID10
A RAID0 array (like a LINEAR array) does not have a concept of 'size' being the amount of each device that is in use. Rather, as much of each device as is available is used. So the 'size' is set to 0 and ignored. RAID10 does have this concept and needs it to be set correctly. So when we convert RAID0 to RAID10 we must determine the 'size' (that being the size of the first 'strip_zone' in the RAID0), and set it correctly. Reported-and-tested-by: Xiao Ni <xni@redhat.com> Signed-off-by: NeilBrown <neilb@suse.de>
Diffstat (limited to 'drivers/md')
-rw-r--r--drivers/md/raid10.c12
1 files changed, 9 insertions, 3 deletions
diff --git a/drivers/md/raid10.c b/drivers/md/raid10.c
index d1203cddb024..b8d76b1fba64 100644
--- a/drivers/md/raid10.c
+++ b/drivers/md/raid10.c
@@ -3872,7 +3872,7 @@ static int raid10_resize(struct mddev *mddev, sector_t sectors)
3872 return 0; 3872 return 0;
3873} 3873}
3874 3874
3875static void *raid10_takeover_raid0(struct mddev *mddev) 3875static void *raid10_takeover_raid0(struct mddev *mddev, sector_t size, int devs)
3876{ 3876{
3877 struct md_rdev *rdev; 3877 struct md_rdev *rdev;
3878 struct r10conf *conf; 3878 struct r10conf *conf;
@@ -3882,6 +3882,7 @@ static void *raid10_takeover_raid0(struct mddev *mddev)
3882 mdname(mddev)); 3882 mdname(mddev));
3883 return ERR_PTR(-EINVAL); 3883 return ERR_PTR(-EINVAL);
3884 } 3884 }
3885 sector_div(size, devs);
3885 3886
3886 /* Set new parameters */ 3887 /* Set new parameters */
3887 mddev->new_level = 10; 3888 mddev->new_level = 10;
@@ -3892,12 +3893,15 @@ static void *raid10_takeover_raid0(struct mddev *mddev)
3892 mddev->raid_disks *= 2; 3893 mddev->raid_disks *= 2;
3893 /* make sure it will be not marked as dirty */ 3894 /* make sure it will be not marked as dirty */
3894 mddev->recovery_cp = MaxSector; 3895 mddev->recovery_cp = MaxSector;
3896 mddev->dev_sectors = size;
3895 3897
3896 conf = setup_conf(mddev); 3898 conf = setup_conf(mddev);
3897 if (!IS_ERR(conf)) { 3899 if (!IS_ERR(conf)) {
3898 rdev_for_each(rdev, mddev) 3900 rdev_for_each(rdev, mddev)
3899 if (rdev->raid_disk >= 0) 3901 if (rdev->raid_disk >= 0) {
3900 rdev->new_raid_disk = rdev->raid_disk * 2; 3902 rdev->new_raid_disk = rdev->raid_disk * 2;
3903 rdev->sectors = size;
3904 }
3901 conf->barrier = 1; 3905 conf->barrier = 1;
3902 } 3906 }
3903 3907
@@ -3920,7 +3924,9 @@ static void *raid10_takeover(struct mddev *mddev)
3920 mdname(mddev)); 3924 mdname(mddev));
3921 return ERR_PTR(-EINVAL); 3925 return ERR_PTR(-EINVAL);
3922 } 3926 }
3923 return raid10_takeover_raid0(mddev); 3927 return raid10_takeover_raid0(mddev,
3928 raid0_conf->strip_zone->zone_end,
3929 raid0_conf->strip_zone->nb_dev);
3924 } 3930 }
3925 return ERR_PTR(-EINVAL); 3931 return ERR_PTR(-EINVAL);
3926} 3932}