diff options
author | Jes Sorensen <Jes.Sorensen@redhat.com> | 2012-04-01 23:48:38 +1000 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2012-06-01 15:15:55 +0800 |
commit | 4f1f847dc0563d85b05decd5128741c1103d4035 (patch) | |
tree | 056a46fa9f14b79f1a29ea6a1a5aa849fc4f5799 | |
parent | 0bbc87944127ab0cd27fbf2251f60dc134b1d4c0 (diff) |
md: Avoid OOPS when reshaping raid1 to raid0
commit 24b961f811a3e790a9b93604d2594bfb6cce4fa4 upstream.
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>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-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 7294bd115e3..ce454f045d6 100644 --- a/drivers/md/raid0.c +++ b/drivers/md/raid0.c @@ -609,6 +609,7 @@ static void *raid0_takeover_raid10(struct mddev *mddev) static void *raid0_takeover_raid1(struct mddev *mddev) { struct r0conf *priv_conf; + int chunksect; /* Check layout: * - (N - 1) mirror drives must be already faulty @@ -619,10 +620,25 @@ static void *raid0_takeover_raid1(struct mddev *mddev) return ERR_PTR(-EINVAL); } + /* + * a raid1 doesn't have the notion of chunk size, so + * figure out the largest suitable size we can use. + */ + chunksect = 64 * 2; /* 64K by default */ + + /* The array must be an exact multiple of chunksize */ + while (chunksect && (mddev->array_sectors & (chunksect - 1))) + chunksect >>= 1; + + if ((chunksect << 9) < PAGE_SIZE) + /* array size does not allow a suitable chunk size */ + return ERR_PTR(-EINVAL); + /* Set new parameters */ mddev->new_level = 0; mddev->new_layout = 0; - mddev->new_chunk_sectors = 128; /* by default set chunk size to 64k */ + mddev->new_chunk_sectors = chunksect; + mddev->chunk_sectors = chunksect; mddev->delta_disks = 1 - mddev->raid_disks; mddev->raid_disks = 1; /* make sure it will be not marked as dirty */ |