diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2012-05-17 12:44:35 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2012-05-17 12:44:35 -0400 |
commit | 36a1987cd891fa82d9981886c3abbbe82c428c0d (patch) | |
tree | 26f2c1ebc2d0485de222f13ebf812456ee8a7cb8 | |
parent | 31ae98359d26ff89b745c4f8094093cbf6ccbdc6 (diff) | |
parent | 0d9f4f135eb6dea06bdcb7065b1e4ff78274a5e9 (diff) |
Merge tag 'md-3.4-fixes' of git://neil.brown.name/md
Pull two md fixes from NeilBrown:
"One fixes a bug in the new raid10 resize code so is relevant to 3.4
only.
The other fixes a bug in the use of md by dm-raid, so is relevant to
any kernel with dm-raid support"
* tag 'md-3.4-fixes' of git://neil.brown.name/md:
MD: Add del_timer_sync to mddev_suspend (fix nasty panic)
md/raid10: set dev_sectors properly when resizing devices in array.
-rw-r--r-- | drivers/md/md.c | 2 | ||||
-rw-r--r-- | drivers/md/raid10.c | 56 |
2 files changed, 34 insertions, 24 deletions
diff --git a/drivers/md/md.c b/drivers/md/md.c index 477eb2e180c0..01233d855eb2 100644 --- a/drivers/md/md.c +++ b/drivers/md/md.c | |||
@@ -391,6 +391,8 @@ void mddev_suspend(struct mddev *mddev) | |||
391 | synchronize_rcu(); | 391 | synchronize_rcu(); |
392 | wait_event(mddev->sb_wait, atomic_read(&mddev->active_io) == 0); | 392 | wait_event(mddev->sb_wait, atomic_read(&mddev->active_io) == 0); |
393 | mddev->pers->quiesce(mddev, 1); | 393 | mddev->pers->quiesce(mddev, 1); |
394 | |||
395 | del_timer_sync(&mddev->safemode_timer); | ||
394 | } | 396 | } |
395 | EXPORT_SYMBOL_GPL(mddev_suspend); | 397 | EXPORT_SYMBOL_GPL(mddev_suspend); |
396 | 398 | ||
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 | } |