summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJes Sorensen <Jes.Sorensen@redhat.com>2012-04-01 23:48:38 +1000
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2012-06-01 15:15:55 +0800
commit4f1f847dc0563d85b05decd5128741c1103d4035 (patch)
tree056a46fa9f14b79f1a29ea6a1a5aa849fc4f5799
parent0bbc87944127ab0cd27fbf2251f60dc134b1d4c0 (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.c18
1 files changed, 17 insertions, 1 deletions
diff --git a/drivers/md/raid0.c b/drivers/md/raid0.c
index 7294bd115e34..ce454f045d6e 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 */