summaryrefslogtreecommitdiff
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)
{
sector_t num_sectors = rdev->sb_start;
- if (chunk_size)
- num_sectors &= ~((sector_t)chunk_size/512 - 1);
+ if (chunk_size) {
+ unsigned chunk_sects = chunk_size>>9;
+ sector_div(num_sectors, chunk_sects);
+ num_sectors *= chunk_sects;
+ }
return num_sectors;
}
@@ -1248,8 +1251,12 @@ static int super_1_load(mdk_rdev_t *rdev, mdk_rdev_t *refdev, int minor_version)
if (rdev->sectors < le64_to_cpu(sb->data_size))
return -EINVAL;
rdev->sectors = le64_to_cpu(sb->data_size);
- if (le32_to_cpu(sb->chunksize))
- rdev->sectors &= ~((sector_t)le32_to_cpu(sb->chunksize) - 1);
+ if (le32_to_cpu(sb->chunksize)) {
+ int chunk_sects = le32_to_cpu(sb->chunksize);
+ sector_t chunks = rdev->sectors;
+ sector_div(chunks, chunk_sects);
+ rdev->sectors = chunks * chunk_sects;
+ }
if (le64_to_cpu(sb->size) > rdev->sectors)
return -EINVAL;
@@ -3528,7 +3535,8 @@ min_sync_store(mddev_t *mddev, const char *buf, size_t len)
/* Must be a multiple of chunk_size */
if (mddev->chunk_size) {
- if (min & (sector_t)((mddev->chunk_size>>9)-1))
+ sector_t temp = min;
+ if (sector_div(temp, (mddev->chunk_size>>9)))
return -EINVAL;
}
mddev->resync_min = min;
@@ -3565,7 +3573,8 @@ max_sync_store(mddev_t *mddev, const char *buf, size_t len)
/* Must be a multiple of chunk_size */
if (mddev->chunk_size) {
- if (max & (sector_t)((mddev->chunk_size>>9)-1))
+ sector_t temp = max;
+ if (sector_div(temp, (mddev->chunk_size>>9)))
return -EINVAL;
}
mddev->resync_max = max;
@@ -4006,14 +4015,6 @@ static int do_md_run(mddev_t * mddev)
chunk_size, MAX_CHUNK_SIZE);
return -EINVAL;
}
- /*
- * chunk-size has to be a power of 2
- */
- if ( (1 << ffz(~chunk_size)) != chunk_size) {
- printk(KERN_ERR "chunk_size of %d not valid\n", chunk_size);
- return -EINVAL;
- }
-
/* devices must have minimum size of one chunk */
list_for_each_entry(rdev, &mddev->disks, same_set) {
if (test_bit(Faulty, &rdev->flags))