aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/md
diff options
context:
space:
mode:
authorNeilBrown <neilb@suse.de>2012-05-20 19:28:33 -0400
committerNeilBrown <neilb@suse.de>2012-05-20 19:28:33 -0400
commitdeb200d08590622d987718135a1e6323f83154aa (patch)
tree7baf2fc97e48d229d7a311f55bf0f96ce6e445ba /drivers/md
parentf8c9e74ff0832f2244d7991d2aea13851b20a622 (diff)
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: NeilBrown <neilb@suse.de>
Diffstat (limited to 'drivers/md')
-rw-r--r--drivers/md/raid10.c67
1 files changed, 49 insertions, 18 deletions
diff --git a/drivers/md/raid10.c b/drivers/md/raid10.c
index 1c90005ab343..f102e88fc785 100644
--- a/drivers/md/raid10.c
+++ b/drivers/md/raid10.c
@@ -3253,26 +3253,64 @@ static void calc_sectors(struct r10conf *conf, sector_t size)
3253 } 3253 }
3254} 3254}
3255 3255
3256enum geo_type {geo_new, geo_old, geo_start};
3257static int setup_geo(struct geom *geo, struct mddev *mddev, enum geo_type new)
3258{
3259 int nc, fc, fo;
3260 int layout, chunk, disks;
3261 switch (new) {
3262 case geo_old:
3263 layout = mddev->layout;
3264 chunk = mddev->chunk_sectors;
3265 disks = mddev->raid_disks - mddev->delta_disks;
3266 break;
3267 case geo_new:
3268 layout = mddev->new_layout;
3269 chunk = mddev->new_chunk_sectors;
3270 disks = mddev->raid_disks;
3271 break;
3272 default: /* avoid 'may be unused' warnings */
3273 case geo_start: /* new when starting reshape - raid_disks not
3274 * updated yet. */
3275 layout = mddev->new_layout;
3276 chunk = mddev->new_chunk_sectors;
3277 disks = mddev->raid_disks + mddev->delta_disks;
3278 break;
3279 }
3280 if (layout >> 17)
3281 return -1;
3282 if (chunk < (PAGE_SIZE >> 9) ||
3283 !is_power_of_2(chunk))
3284 return -2;
3285 nc = layout & 255;
3286 fc = (layout >> 8) & 255;
3287 fo = layout & (1<<16);
3288 geo->raid_disks = disks;
3289 geo->near_copies = nc;
3290 geo->far_copies = fc;
3291 geo->far_offset = fo;
3292 geo->chunk_mask = chunk - 1;
3293 geo->chunk_shift = ffz(~chunk);
3294 return nc*fc;
3295}
3296
3256static struct r10conf *setup_conf(struct mddev *mddev) 3297static struct r10conf *setup_conf(struct mddev *mddev)
3257{ 3298{
3258 struct r10conf *conf = NULL; 3299 struct r10conf *conf = NULL;
3259 int nc, fc, fo;
3260 int err = -EINVAL; 3300 int err = -EINVAL;
3301 struct geom geo;
3302 int copies;
3303
3304 copies = setup_geo(&geo, mddev, geo_new);
3261 3305
3262 if (mddev->new_chunk_sectors < (PAGE_SIZE >> 9) || 3306 if (copies == -2) {
3263 !is_power_of_2(mddev->new_chunk_sectors)) {
3264 printk(KERN_ERR "md/raid10:%s: chunk size must be " 3307 printk(KERN_ERR "md/raid10:%s: chunk size must be "
3265 "at least PAGE_SIZE(%ld) and be a power of 2.\n", 3308 "at least PAGE_SIZE(%ld) and be a power of 2.\n",
3266 mdname(mddev), PAGE_SIZE); 3309 mdname(mddev), PAGE_SIZE);
3267 goto out; 3310 goto out;
3268 } 3311 }
3269 3312
3270 nc = mddev->new_layout & 255; 3313 if (copies < 2 || copies > mddev->raid_disks) {
3271 fc = (mddev->new_layout >> 8) & 255;
3272 fo = mddev->new_layout & (1<<16);
3273
3274 if ((nc*fc) <2 || (nc*fc) > mddev->raid_disks ||
3275 (mddev->new_layout >> 17)) {
3276 printk(KERN_ERR "md/raid10:%s: unsupported raid10 layout: 0x%8x\n", 3314 printk(KERN_ERR "md/raid10:%s: unsupported raid10 layout: 0x%8x\n",
3277 mdname(mddev), mddev->new_layout); 3315 mdname(mddev), mddev->new_layout);
3278 goto out; 3316 goto out;
@@ -3292,15 +3330,8 @@ static struct r10conf *setup_conf(struct mddev *mddev)
3292 if (!conf->tmppage) 3330 if (!conf->tmppage)
3293 goto out; 3331 goto out;
3294 3332
3295 3333 conf->geo = geo;
3296 conf->geo.raid_disks = mddev->raid_disks; 3334 conf->copies = copies;
3297 conf->geo.near_copies = nc;
3298 conf->geo.far_copies = fc;
3299 conf->copies = nc*fc;
3300 conf->geo.far_offset = fo;
3301 conf->geo.chunk_mask = mddev->new_chunk_sectors - 1;
3302 conf->geo.chunk_shift = ffz(~mddev->new_chunk_sectors);
3303
3304 conf->r10bio_pool = mempool_create(NR_RAID10_BIOS, r10bio_pool_alloc, 3335 conf->r10bio_pool = mempool_create(NR_RAID10_BIOS, r10bio_pool_alloc,
3305 r10bio_pool_free, conf); 3336 r10bio_pool_free, conf);
3306 if (!conf->r10bio_pool) 3337 if (!conf->r10bio_pool)