aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/md/md.c29
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))