aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/md
diff options
context:
space:
mode:
authorJes Sorensen <Jes.Sorensen@redhat.com>2012-04-01 09:48:38 -0400
committerNeilBrown <neilb@suse.de>2012-04-03 01:37:26 -0400
commit24b961f811a3e790a9b93604d2594bfb6cce4fa4 (patch)
tree8cde643f6d3d142538d8e2499e65b368f5320bcc /drivers/md
parent18b9837ea0dc3cf844c6c4196871ce91d047bddb (diff)
md: Avoid OOPS when reshaping raid1 to raid0
raid1 arrays do not have the notion of chunk size. Calculate the largest chunk sector size we can use to avoid a divide by zero OOPS when aligning the size of the new array to the chunk size. Signed-off-by: Jes Sorensen <Jes.Sorensen@redhat.com> Signed-off-by: NeilBrown <neilb@suse.de>
Diffstat (limited to 'drivers/md')
-rw-r--r--drivers/md/raid0.c18
1 files changed, 17 insertions, 1 deletions
diff --git a/drivers/md/raid0.c b/drivers/md/raid0.c
index c9809453a346..de63a1fc3737 100644
--- a/drivers/md/raid0.c
+++ b/drivers/md/raid0.c
@@ -632,6 +632,7 @@ static void *raid0_takeover_raid10(struct mddev *mddev)
632static void *raid0_takeover_raid1(struct mddev *mddev) 632static void *raid0_takeover_raid1(struct mddev *mddev)
633{ 633{
634 struct r0conf *priv_conf; 634 struct r0conf *priv_conf;
635 int chunksect;
635 636
636 /* Check layout: 637 /* Check layout:
637 * - (N - 1) mirror drives must be already faulty 638 * - (N - 1) mirror drives must be already faulty
@@ -642,10 +643,25 @@ static void *raid0_takeover_raid1(struct mddev *mddev)
642 return ERR_PTR(-EINVAL); 643 return ERR_PTR(-EINVAL);
643 } 644 }
644 645
646 /*
647 * a raid1 doesn't have the notion of chunk size, so
648 * figure out the largest suitable size we can use.
649 */
650 chunksect = 64 * 2; /* 64K by default */
651
652 /* The array must be an exact multiple of chunksize */
653 while (chunksect && (mddev->array_sectors & (chunksect - 1)))
654 chunksect >>= 1;
655
656 if ((chunksect << 9) < PAGE_SIZE)
657 /* array size does not allow a suitable chunk size */
658 return ERR_PTR(-EINVAL);
659
645 /* Set new parameters */ 660 /* Set new parameters */
646 mddev->new_level = 0; 661 mddev->new_level = 0;
647 mddev->new_layout = 0; 662 mddev->new_layout = 0;
648 mddev->new_chunk_sectors = 128; /* by default set chunk size to 64k */ 663 mddev->new_chunk_sectors = chunksect;
664 mddev->chunk_sectors = chunksect;
649 mddev->delta_disks = 1 - mddev->raid_disks; 665 mddev->delta_disks = 1 - mddev->raid_disks;
650 mddev->raid_disks = 1; 666 mddev->raid_disks = 1;
651 /* make sure it will be not marked as dirty */ 667 /* make sure it will be not marked as dirty */