diff options
-rw-r--r-- | drivers/md/md.c | 29 |
1 files changed, 15 insertions, 14 deletions
diff --git a/drivers/md/md.c b/drivers/md/md.c index 20f6ac338349..a02bde70874b 100644 --- a/drivers/md/md.c +++ b/drivers/md/md.c | |||
@@ -444,8 +444,11 @@ static sector_t calc_num_sectors(mdk_rdev_t *rdev, unsigned chunk_size) | |||
444 | { | 444 | { |
445 | sector_t num_sectors = rdev->sb_start; | 445 | sector_t num_sectors = rdev->sb_start; |
446 | 446 | ||
447 | if (chunk_size) | 447 | if (chunk_size) { |
448 | num_sectors &= ~((sector_t)chunk_size/512 - 1); | 448 | unsigned chunk_sects = chunk_size>>9; |
449 | sector_div(num_sectors, chunk_sects); | ||
450 | num_sectors *= chunk_sects; | ||
451 | } | ||
449 | return num_sectors; | 452 | return num_sectors; |
450 | } | 453 | } |
451 | 454 | ||
@@ -1248,8 +1251,12 @@ static int super_1_load(mdk_rdev_t *rdev, mdk_rdev_t *refdev, int minor_version) | |||
1248 | if (rdev->sectors < le64_to_cpu(sb->data_size)) | 1251 | if (rdev->sectors < le64_to_cpu(sb->data_size)) |
1249 | return -EINVAL; | 1252 | return -EINVAL; |
1250 | rdev->sectors = le64_to_cpu(sb->data_size); | 1253 | rdev->sectors = le64_to_cpu(sb->data_size); |
1251 | if (le32_to_cpu(sb->chunksize)) | 1254 | if (le32_to_cpu(sb->chunksize)) { |
1252 | rdev->sectors &= ~((sector_t)le32_to_cpu(sb->chunksize) - 1); | 1255 | int chunk_sects = le32_to_cpu(sb->chunksize); |
1256 | sector_t chunks = rdev->sectors; | ||
1257 | sector_div(chunks, chunk_sects); | ||
1258 | rdev->sectors = chunks * chunk_sects; | ||
1259 | } | ||
1253 | 1260 | ||
1254 | if (le64_to_cpu(sb->size) > rdev->sectors) | 1261 | if (le64_to_cpu(sb->size) > rdev->sectors) |
1255 | return -EINVAL; | 1262 | return -EINVAL; |
@@ -3528,7 +3535,8 @@ min_sync_store(mddev_t *mddev, const char *buf, size_t len) | |||
3528 | 3535 | ||
3529 | /* Must be a multiple of chunk_size */ | 3536 | /* Must be a multiple of chunk_size */ |
3530 | if (mddev->chunk_size) { | 3537 | if (mddev->chunk_size) { |
3531 | if (min & (sector_t)((mddev->chunk_size>>9)-1)) | 3538 | sector_t temp = min; |
3539 | if (sector_div(temp, (mddev->chunk_size>>9))) | ||
3532 | return -EINVAL; | 3540 | return -EINVAL; |
3533 | } | 3541 | } |
3534 | mddev->resync_min = min; | 3542 | mddev->resync_min = min; |
@@ -3565,7 +3573,8 @@ max_sync_store(mddev_t *mddev, const char *buf, size_t len) | |||
3565 | 3573 | ||
3566 | /* Must be a multiple of chunk_size */ | 3574 | /* Must be a multiple of chunk_size */ |
3567 | if (mddev->chunk_size) { | 3575 | if (mddev->chunk_size) { |
3568 | if (max & (sector_t)((mddev->chunk_size>>9)-1)) | 3576 | sector_t temp = max; |
3577 | if (sector_div(temp, (mddev->chunk_size>>9))) | ||
3569 | return -EINVAL; | 3578 | return -EINVAL; |
3570 | } | 3579 | } |
3571 | mddev->resync_max = max; | 3580 | mddev->resync_max = max; |
@@ -4006,14 +4015,6 @@ static int do_md_run(mddev_t * mddev) | |||
4006 | chunk_size, MAX_CHUNK_SIZE); | 4015 | chunk_size, MAX_CHUNK_SIZE); |
4007 | return -EINVAL; | 4016 | return -EINVAL; |
4008 | } | 4017 | } |
4009 | /* | ||
4010 | * chunk-size has to be a power of 2 | ||
4011 | */ | ||
4012 | if ( (1 << ffz(~chunk_size)) != chunk_size) { | ||
4013 | printk(KERN_ERR "chunk_size of %d not valid\n", chunk_size); | ||
4014 | return -EINVAL; | ||
4015 | } | ||
4016 | |||
4017 | /* devices must have minimum size of one chunk */ | 4018 | /* devices must have minimum size of one chunk */ |
4018 | list_for_each_entry(rdev, &mddev->disks, same_set) { | 4019 | list_for_each_entry(rdev, &mddev->disks, same_set) { |
4019 | if (test_bit(Faulty, &rdev->flags)) | 4020 | if (test_bit(Faulty, &rdev->flags)) |