summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNeilBrown <neilb@suse.de>2010-04-29 16:14:30 +1000
committerNeilBrown <neilb@suse.de>2010-04-29 16:14:30 +1000
commit200871adf9e15d5ad985f28c349fd89c386ef48a (patch)
tree0c26b071611cb666bc2a4c81057a66ab979ce388
parent691c6ee1b6bb77bc44a5474d856771b0aec9882d (diff)
downloadmdadm-200871adf9e15d5ad985f28c349fd89c386ef48a.zip
mdadm-200871adf9e15d5ad985f28c349fd89c386ef48a.tar.gz
mdadm-200871adf9e15d5ad985f28c349fd89c386ef48a.tar.xz
Grow: avoid overflow of chunk sizes.
Chunks aren't particularly big, but when you could them in bytes and multiply them together (as we do for calculating the backup size for 'grow') they can overflow a 32bit int. So group the division by 512 more closely with the chunk size so were would need 30Meg chunks to come close to overflowing 32bits. Signed-off-by: NeilBrown <neilb@suse.de>
-rw-r--r--Grow.c48
1 files changed, 24 insertions, 24 deletions
diff --git a/Grow.c b/Grow.c
index 053a372..0916c5d 100644
--- a/Grow.c
+++ b/Grow.c
@@ -931,8 +931,8 @@ int Grow_reshape(char *devname, int fd, int quiet, char *backup_file,
* old stripes and a whole number of new stripes.
* So LCM for (chunksize*datadisks).
*/
- a = ochunk/512 * odata;
- b = nchunk/512 * ndata;
+ a = (ochunk/512) * odata;
+ b = (nchunk/512) * ndata;
/* Find GCD */
while (a != b) {
if (a < b)
@@ -941,7 +941,7 @@ int Grow_reshape(char *devname, int fd, int quiet, char *backup_file,
a -= b;
}
/* LCM == product / GCD */
- blocks = ochunk/512 * nchunk/512 * odata * ndata / a;
+ blocks = (ochunk/512) * (nchunk/512) * odata * ndata / a;
sysfs_free(sra);
sra = sysfs_read(fd, 0,
@@ -1284,7 +1284,7 @@ int grow_backup(struct mdinfo *sra,
odata--;
if (level == 6)
odata--;
- sysfs_set_num(sra, NULL, "suspend_hi", (offset + stripes * chunk/512) * odata);
+ sysfs_set_num(sra, NULL, "suspend_hi", (offset + stripes * (chunk/512)) * odata);
/* Check that array hasn't become degraded, else we might backup the wrong data */
sysfs_get_ll(sra, NULL, "degraded", &new_degraded);
if (new_degraded != *degraded) {
@@ -1312,10 +1312,10 @@ int grow_backup(struct mdinfo *sra,
}
if (part) {
bsb.arraystart2 = __cpu_to_le64(offset * odata);
- bsb.length2 = __cpu_to_le64(stripes * chunk/512 * odata);
+ bsb.length2 = __cpu_to_le64(stripes * (chunk/512) * odata);
} else {
bsb.arraystart = __cpu_to_le64(offset * odata);
- bsb.length = __cpu_to_le64(stripes * chunk/512 * odata);
+ bsb.length = __cpu_to_le64(stripes * (chunk/512) * odata);
}
if (part)
bsb.magic[15] = '2';
@@ -1540,10 +1540,10 @@ static int child_grow(int afd, struct mdinfo *sra, unsigned long stripes,
dests, destfd, destoffsets,
0, &degraded, buf);
validate(afd, destfd[0], destoffsets[0]);
- wait_backup(sra, 0, stripes * chunk / 512, stripes * chunk / 512,
+ wait_backup(sra, 0, stripes * (chunk / 512), stripes * (chunk / 512),
dests, destfd, destoffsets,
0);
- sysfs_set_num(sra, NULL, "suspend_lo", (stripes * chunk/512) * data);
+ sysfs_set_num(sra, NULL, "suspend_lo", (stripes * (chunk/512)) * data);
free(buf);
/* FIXME this should probably be numeric */
sysfs_set_str(sra, NULL, "sync_max", "max");
@@ -1562,12 +1562,12 @@ static int child_shrink(int afd, struct mdinfo *sra, unsigned long stripes,
if (posix_memalign((void**)&buf, 4096, disks * chunk))
return 0;
- start = sra->component_size - stripes * chunk/512;
+ start = sra->component_size - stripes * (chunk/512);
sysfs_set_num(sra, NULL, "sync_max", start);
sysfs_set_str(sra, NULL, "sync_action", "reshape");
sysfs_set_num(sra, NULL, "suspend_lo", 0);
sysfs_set_num(sra, NULL, "suspend_hi", 0);
- rv = wait_backup(sra, 0, start - stripes * chunk/512, stripes * chunk/512,
+ rv = wait_backup(sra, 0, start - stripes * (chunk/512), stripes * (chunk/512),
dests, destfd, destoffsets, 0);
if (rv < 0)
return 0;
@@ -1577,9 +1577,9 @@ static int child_shrink(int afd, struct mdinfo *sra, unsigned long stripes,
dests, destfd, destoffsets,
0, &degraded, buf);
validate(afd, destfd[0], destoffsets[0]);
- wait_backup(sra, start, stripes*chunk/512, 0,
+ wait_backup(sra, start, stripes*(chunk/512), 0,
dests, destfd, destoffsets, 0);
- sysfs_set_num(sra, NULL, "suspend_lo", (stripes * chunk/512) * data);
+ sysfs_set_num(sra, NULL, "suspend_lo", (stripes * (chunk/512)) * data);
free(buf);
/* FIXME this should probably be numeric */
sysfs_set_str(sra, NULL, "sync_max", "max");
@@ -1614,7 +1614,7 @@ static int child_same_size(int afd, struct mdinfo *sra, unsigned long stripes,
disks, chunk, level, layout,
dests, destfd, destoffsets,
0, &degraded, buf);
- grow_backup(sra, (start + stripes) * chunk/512, stripes,
+ grow_backup(sra, (start + stripes) * (chunk/512), stripes,
fds, offsets,
disks, chunk, level, layout,
dests, destfd, destoffsets,
@@ -1624,16 +1624,16 @@ static int child_same_size(int afd, struct mdinfo *sra, unsigned long stripes,
start += stripes * 2; /* where to read next */
size = sra->component_size / (chunk/512);
while (start < size) {
- if (wait_backup(sra, (start-stripes*2)*chunk/512,
- stripes*chunk/512, 0,
+ if (wait_backup(sra, (start-stripes*2)*(chunk/512),
+ stripes*(chunk/512), 0,
dests, destfd, destoffsets,
part) < 0)
return 0;
- sysfs_set_num(sra, NULL, "suspend_lo", start*chunk/512 * data);
+ sysfs_set_num(sra, NULL, "suspend_lo", start*(chunk/512) * data);
if (start + stripes > size)
tailstripes = (size - start);
- grow_backup(sra, start*chunk/512, tailstripes,
+ grow_backup(sra, start*(chunk/512), tailstripes,
fds, offsets,
disks, chunk, level, layout,
dests, destfd, destoffsets,
@@ -1642,15 +1642,15 @@ static int child_same_size(int afd, struct mdinfo *sra, unsigned long stripes,
part = 1 - part;
validate(afd, destfd[0], destoffsets[0]);
}
- if (wait_backup(sra, (start-stripes*2) * chunk/512, stripes * chunk/512, 0,
+ if (wait_backup(sra, (start-stripes*2) * (chunk/512), stripes * (chunk/512), 0,
dests, destfd, destoffsets,
part) < 0)
return 0;
- sysfs_set_num(sra, NULL, "suspend_lo", ((start-stripes)*chunk/512) * data);
- wait_backup(sra, (start-stripes) * chunk/512, tailstripes * chunk/512, 0,
+ sysfs_set_num(sra, NULL, "suspend_lo", ((start-stripes)*(chunk/512)) * data);
+ wait_backup(sra, (start-stripes) * (chunk/512), tailstripes * (chunk/512), 0,
dests, destfd, destoffsets,
1-part);
- sysfs_set_num(sra, NULL, "suspend_lo", (size*chunk/512) * data);
+ sysfs_set_num(sra, NULL, "suspend_lo", (size*(chunk/512)) * data);
sysfs_set_num(sra, NULL, "sync_speed_min", speed);
free(buf);
return 1;
@@ -1991,8 +1991,8 @@ int Grow_continue(int mdfd, struct supertype *st, struct mdinfo *info,
nchunk = info->new_chunk;
- a = ochunk/512 * odata;
- b = nchunk/512 * ndata;
+ a = (ochunk/512) * odata;
+ b = (nchunk/512) * ndata;
/* Find GCD */
while (a != b) {
if (a < b)
@@ -2001,7 +2001,7 @@ int Grow_continue(int mdfd, struct supertype *st, struct mdinfo *info,
a -= b;
}
/* LCM == product / GCD */
- blocks = ochunk/512 * nchunk/512 * odata * ndata / a;
+ blocks = (ochunk/512) * (nchunk/512) * odata * ndata / a;
sra = sysfs_read(-1, devname2devnum(info->sys_name),
GET_COMPONENT|GET_DEVS|GET_OFFSET|GET_STATE|