|
@@ -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))
|