Skip to content

Commit

Permalink
md: Avoid OOPS when reshaping raid1 to raid0
Browse files Browse the repository at this point in the history
commit 24b961f 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>
  • Loading branch information
Jes Sorensen authored and Greg Kroah-Hartman committed Jun 1, 2012
1 parent 0bbc879 commit 4f1f847
Showing 1 changed file with 17 additions and 1 deletion.
18 changes: 17 additions & 1 deletion drivers/md/raid0.c
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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 */
Expand Down

0 comments on commit 4f1f847

Please sign in to comment.