Commit deb200d0 authored by NeilBrown's avatar NeilBrown

md/raid10: split out interpretation of layout to separate function.

We will soon be interpreting the layout (and chunksize etc) from
multiple places to support reshape.  So split it out into separate
function.
Signed-off-by: default avatarNeilBrown <neilb@suse.de>
parent f8c9e74f
...@@ -3253,26 +3253,64 @@ static void calc_sectors(struct r10conf *conf, sector_t size) ...@@ -3253,26 +3253,64 @@ static void calc_sectors(struct r10conf *conf, sector_t size)
} }
} }
enum geo_type {geo_new, geo_old, geo_start};
static int setup_geo(struct geom *geo, struct mddev *mddev, enum geo_type new)
{
int nc, fc, fo;
int layout, chunk, disks;
switch (new) {
case geo_old:
layout = mddev->layout;
chunk = mddev->chunk_sectors;
disks = mddev->raid_disks - mddev->delta_disks;
break;
case geo_new:
layout = mddev->new_layout;
chunk = mddev->new_chunk_sectors;
disks = mddev->raid_disks;
break;
default: /* avoid 'may be unused' warnings */
case geo_start: /* new when starting reshape - raid_disks not
* updated yet. */
layout = mddev->new_layout;
chunk = mddev->new_chunk_sectors;
disks = mddev->raid_disks + mddev->delta_disks;
break;
}
if (layout >> 17)
return -1;
if (chunk < (PAGE_SIZE >> 9) ||
!is_power_of_2(chunk))
return -2;
nc = layout & 255;
fc = (layout >> 8) & 255;
fo = layout & (1<<16);
geo->raid_disks = disks;
geo->near_copies = nc;
geo->far_copies = fc;
geo->far_offset = fo;
geo->chunk_mask = chunk - 1;
geo->chunk_shift = ffz(~chunk);
return nc*fc;
}
static struct r10conf *setup_conf(struct mddev *mddev) static struct r10conf *setup_conf(struct mddev *mddev)
{ {
struct r10conf *conf = NULL; struct r10conf *conf = NULL;
int nc, fc, fo;
int err = -EINVAL; int err = -EINVAL;
struct geom geo;
int copies;
copies = setup_geo(&geo, mddev, geo_new);
if (mddev->new_chunk_sectors < (PAGE_SIZE >> 9) || if (copies == -2) {
!is_power_of_2(mddev->new_chunk_sectors)) {
printk(KERN_ERR "md/raid10:%s: chunk size must be " printk(KERN_ERR "md/raid10:%s: chunk size must be "
"at least PAGE_SIZE(%ld) and be a power of 2.\n", "at least PAGE_SIZE(%ld) and be a power of 2.\n",
mdname(mddev), PAGE_SIZE); mdname(mddev), PAGE_SIZE);
goto out; goto out;
} }
nc = mddev->new_layout & 255; if (copies < 2 || copies > mddev->raid_disks) {
fc = (mddev->new_layout >> 8) & 255;
fo = mddev->new_layout & (1<<16);
if ((nc*fc) <2 || (nc*fc) > mddev->raid_disks ||
(mddev->new_layout >> 17)) {
printk(KERN_ERR "md/raid10:%s: unsupported raid10 layout: 0x%8x\n", printk(KERN_ERR "md/raid10:%s: unsupported raid10 layout: 0x%8x\n",
mdname(mddev), mddev->new_layout); mdname(mddev), mddev->new_layout);
goto out; goto out;
...@@ -3292,15 +3330,8 @@ static struct r10conf *setup_conf(struct mddev *mddev) ...@@ -3292,15 +3330,8 @@ static struct r10conf *setup_conf(struct mddev *mddev)
if (!conf->tmppage) if (!conf->tmppage)
goto out; goto out;
conf->geo = geo;
conf->geo.raid_disks = mddev->raid_disks; conf->copies = copies;
conf->geo.near_copies = nc;
conf->geo.far_copies = fc;
conf->copies = nc*fc;
conf->geo.far_offset = fo;
conf->geo.chunk_mask = mddev->new_chunk_sectors - 1;
conf->geo.chunk_shift = ffz(~mddev->new_chunk_sectors);
conf->r10bio_pool = mempool_create(NR_RAID10_BIOS, r10bio_pool_alloc, conf->r10bio_pool = mempool_create(NR_RAID10_BIOS, r10bio_pool_alloc,
r10bio_pool_free, conf); r10bio_pool_free, conf);
if (!conf->r10bio_pool) if (!conf->r10bio_pool)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment