diff options
-rw-r--r-- | drivers/md/raid10.c | 56 |
1 files changed, 32 insertions, 24 deletions
diff --git a/drivers/md/raid10.c b/drivers/md/raid10.c index c8dbb84d5357..3e7b1548111a 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 | ||
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 | static struct r10conf *setup_conf(struct mddev *mddev) | 3197 | static 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 | } |