diff options
author | Jes Sorensen <Jes.Sorensen@redhat.com> | 2012-04-01 09:48:38 -0400 |
---|---|---|
committer | NeilBrown <neilb@suse.de> | 2012-04-03 01:37:26 -0400 |
commit | 24b961f811a3e790a9b93604d2594bfb6cce4fa4 (patch) | |
tree | 8cde643f6d3d142538d8e2499e65b368f5320bcc /drivers/md | |
parent | 18b9837ea0dc3cf844c6c4196871ce91d047bddb (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.c | 18 |
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) | |||
632 | static void *raid0_takeover_raid1(struct mddev *mddev) | 632 | static 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 */ |