aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/md/raid10.c
diff options
context:
space:
mode:
authorNeilBrown <neilb@suse.de>2012-05-16 20:08:45 -0400
committerNeilBrown <neilb@suse.de>2012-05-16 20:08:45 -0400
commit6508fdbf40a92fd7c19d32780ea33ce8e8362b93 (patch)
treef51e0e36459eeb2f4e7d94f3ff15ffc5ab12de7c /drivers/md/raid10.c
parentb16b1b6cd052acbacc0a15f934bca9b354534d48 (diff)
md/raid10: set dev_sectors properly when resizing devices in array.
raid10 stores dev_sectors in 'conf' separately from the one in 'mddev' because it can have a very significant effect on block addressing and so need to be updated carefully. However raid10_resize isn't updating it at all! To update it correctly, we need to make sure it is a proper multiple of the chunksize taking various details of the layout in to account. This calculation is currently done in setup_conf. So split it out from there and call it from raid10_resize as well. Then set conf->dev_sectors properly. Signed-off-by: NeilBrown <neilb@suse.de>
Diffstat (limited to 'drivers/md/raid10.c')
-rw-r--r--drivers/md/raid10.c56
1 files changed, 32 insertions, 24 deletions
diff --git a/drivers/md/raid10.c b/drivers/md/raid10.c
index c8dbb84d535..3e7b1548111 100644
--- a/drivers/md/raid10.c
+++ b/drivers/md/raid10.c
@@ -3164,12 +3164,40 @@ raid10_size(struct mddev *mddev, sector_t sectors, int raid_disks)
3164 return size << conf->chunk_shift; 3164 return size << conf->chunk_shift;
3165} 3165}
3166 3166
3167static void calc_sectors(struct r10conf *conf, sector_t size)
3168{
3169 /* Calculate the number of sectors-per-device that will
3170 * actually be used, and set conf->dev_sectors and
3171 * conf->stride
3172 */
3173
3174 size = size >> conf->chunk_shift;
3175 sector_div(size, conf->far_copies);
3176 size = size * conf->raid_disks;
3177 sector_div(size, conf->near_copies);
3178 /* 'size' is now the number of chunks in the array */
3179 /* calculate "used chunks per device" */
3180 size = size * conf->copies;
3181
3182 /* We need to round up when dividing by raid_disks to
3183 * get the stride size.
3184 */
3185 size = DIV_ROUND_UP_SECTOR_T(size, conf->raid_disks);
3186
3187 conf->dev_sectors = size << conf->chunk_shift;
3188
3189 if (conf->far_offset)
3190 conf->stride = 1 << conf->chunk_shift;
3191 else {
3192 sector_div(size, conf->near_copies);
3193 conf->stride = size << conf->chunk_shift;
3194 }
3195}
3167 3196
3168static struct r10conf *setup_conf(struct mddev *mddev) 3197static struct r10conf *setup_conf(struct mddev *mddev)
3169{ 3198{
3170 struct r10conf *conf = NULL; 3199 struct r10conf *conf = NULL;
3171 int nc, fc, fo; 3200 int nc, fc, fo;
3172 sector_t stride, size;
3173 int err = -EINVAL; 3201 int err = -EINVAL;
3174 3202
3175 if (mddev->new_chunk_sectors < (PAGE_SIZE >> 9) || 3203 if (mddev->new_chunk_sectors < (PAGE_SIZE >> 9) ||
@@ -3219,28 +3247,7 @@ static struct r10conf *setup_conf(struct mddev *mddev)
3219 if (!conf->r10bio_pool) 3247 if (!conf->r10bio_pool)
3220 goto out; 3248 goto out;
3221 3249
3222 size = mddev->dev_sectors >> conf->chunk_shift; 3250 calc_sectors(conf, mddev->dev_sectors);
3223 sector_div(size, fc);
3224 size = size * conf->raid_disks;
3225 sector_div(size, nc);
3226 /* 'size' is now the number of chunks in the array */
3227 /* calculate "used chunks per device" in 'stride' */
3228 stride = size * conf->copies;
3229
3230 /* We need to round up when dividing by raid_disks to
3231 * get the stride size.
3232 */
3233 stride += conf->raid_disks - 1;
3234 sector_div(stride, conf->raid_disks);
3235
3236 conf->dev_sectors = stride << conf->chunk_shift;
3237
3238 if (fo)
3239 stride = 1;
3240 else
3241 sector_div(stride, fc);
3242 conf->stride = stride << conf->chunk_shift;
3243
3244 3251
3245 spin_lock_init(&conf->device_lock); 3252 spin_lock_init(&conf->device_lock);
3246 INIT_LIST_HEAD(&conf->retry_list); 3253 INIT_LIST_HEAD(&conf->retry_list);
@@ -3468,7 +3475,8 @@ static int raid10_resize(struct mddev *mddev, sector_t sectors)
3468 mddev->recovery_cp = oldsize; 3475 mddev->recovery_cp = oldsize;
3469 set_bit(MD_RECOVERY_NEEDED, &mddev->recovery); 3476 set_bit(MD_RECOVERY_NEEDED, &mddev->recovery);
3470 } 3477 }
3471 mddev->dev_sectors = sectors; 3478 calc_sectors(conf, sectors);
3479 mddev->dev_sectors = conf->dev_sectors;
3472 mddev->resync_max_sectors = size; 3480 mddev->resync_max_sectors = size;
3473 return 0; 3481 return 0;
3474} 3482}