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>

NeilBrown 6508fdbf b16b1b6c

+32 -24
+32 -24
drivers/md/raid10.c
··· 3164 3164 return size << conf->chunk_shift; 3165 3165 } 3166 3166 3167 + static 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 3168 3197 static struct r10conf *setup_conf(struct mddev *mddev) 3169 3198 { 3170 3199 struct r10conf *conf = NULL; 3171 3200 int nc, fc, fo; 3172 - sector_t stride, size; 3173 3201 int err = -EINVAL; 3174 3202 3175 3203 if (mddev->new_chunk_sectors < (PAGE_SIZE >> 9) || ··· 3247 3219 if (!conf->r10bio_pool) 3248 3220 goto out; 3249 3221 3250 - size = mddev->dev_sectors >> conf->chunk_shift; 3251 - sector_div(size, fc); 3252 - size = size * conf->raid_disks; 3253 - sector_div(size, nc); 3254 - /* 'size' is now the number of chunks in the array */ 3255 - /* calculate "used chunks per device" in 'stride' */ 3256 - stride = size * conf->copies; 3257 - 3258 - /* We need to round up when dividing by raid_disks to 3259 - * get the stride size. 3260 - */ 3261 - stride += conf->raid_disks - 1; 3262 - sector_div(stride, conf->raid_disks); 3263 - 3264 - conf->dev_sectors = stride << conf->chunk_shift; 3265 - 3266 - if (fo) 3267 - stride = 1; 3268 - else 3269 - sector_div(stride, fc); 3270 - conf->stride = stride << conf->chunk_shift; 3271 - 3222 + calc_sectors(conf, mddev->dev_sectors); 3272 3223 3273 3224 spin_lock_init(&conf->device_lock); 3274 3225 INIT_LIST_HEAD(&conf->retry_list); ··· 3475 3468 mddev->recovery_cp = oldsize; 3476 3469 set_bit(MD_RECOVERY_NEEDED, &mddev->recovery); 3477 3470 } 3478 - mddev->dev_sectors = sectors; 3471 + calc_sectors(conf, sectors); 3472 + mddev->dev_sectors = conf->dev_sectors; 3479 3473 mddev->resync_max_sectors = size; 3480 3474 return 0; 3481 3475 }