diff options
Diffstat (limited to 'drivers/md')
-rw-r--r-- | drivers/md/raid10.c | 38 |
1 files changed, 38 insertions, 0 deletions
diff --git a/drivers/md/raid10.c b/drivers/md/raid10.c index e4a66ab6b0fb..3540316886f2 100644 --- a/drivers/md/raid10.c +++ b/drivers/md/raid10.c | |||
@@ -3436,6 +3436,43 @@ static void raid10_quiesce(struct mddev *mddev, int state) | |||
3436 | } | 3436 | } |
3437 | } | 3437 | } |
3438 | 3438 | ||
3439 | static int raid10_resize(struct mddev *mddev, sector_t sectors) | ||
3440 | { | ||
3441 | /* Resize of 'far' arrays is not supported. | ||
3442 | * For 'near' and 'offset' arrays we can set the | ||
3443 | * number of sectors used to be an appropriate multiple | ||
3444 | * of the chunk size. | ||
3445 | * For 'offset', this is far_copies*chunksize. | ||
3446 | * For 'near' the multiplier is the LCM of | ||
3447 | * near_copies and raid_disks. | ||
3448 | * So if far_copies > 1 && !far_offset, fail. | ||
3449 | * Else find LCM(raid_disks, near_copy)*far_copies and | ||
3450 | * multiply by chunk_size. Then round to this number. | ||
3451 | * This is mostly done by raid10_size() | ||
3452 | */ | ||
3453 | struct r10conf *conf = mddev->private; | ||
3454 | sector_t oldsize, size; | ||
3455 | |||
3456 | if (conf->far_copies > 1 && !conf->far_offset) | ||
3457 | return -EINVAL; | ||
3458 | |||
3459 | oldsize = raid10_size(mddev, 0, 0); | ||
3460 | size = raid10_size(mddev, sectors, 0); | ||
3461 | md_set_array_sectors(mddev, size); | ||
3462 | if (mddev->array_sectors > size) | ||
3463 | return -EINVAL; | ||
3464 | set_capacity(mddev->gendisk, mddev->array_sectors); | ||
3465 | revalidate_disk(mddev->gendisk); | ||
3466 | if (sectors > mddev->dev_sectors && | ||
3467 | mddev->recovery_cp > oldsize) { | ||
3468 | mddev->recovery_cp = oldsize; | ||
3469 | set_bit(MD_RECOVERY_NEEDED, &mddev->recovery); | ||
3470 | } | ||
3471 | mddev->dev_sectors = sectors; | ||
3472 | mddev->resync_max_sectors = size; | ||
3473 | return 0; | ||
3474 | } | ||
3475 | |||
3439 | static void *raid10_takeover_raid0(struct mddev *mddev) | 3476 | static void *raid10_takeover_raid0(struct mddev *mddev) |
3440 | { | 3477 | { |
3441 | struct md_rdev *rdev; | 3478 | struct md_rdev *rdev; |
@@ -3505,6 +3542,7 @@ static struct md_personality raid10_personality = | |||
3505 | .sync_request = sync_request, | 3542 | .sync_request = sync_request, |
3506 | .quiesce = raid10_quiesce, | 3543 | .quiesce = raid10_quiesce, |
3507 | .size = raid10_size, | 3544 | .size = raid10_size, |
3545 | .resize = raid10_resize, | ||
3508 | .takeover = raid10_takeover, | 3546 | .takeover = raid10_takeover, |
3509 | }; | 3547 | }; |
3510 | 3548 | ||