diff --git a/Grow.c b/Grow.c index eb19c93..d7c7553 100644 --- a/Grow.c +++ b/Grow.c @@ -905,6 +905,31 @@ release: return d; } +unsigned long compute_backup_blocks(int nchunk, int ochunk, + unsigned int ndata, unsigned int odata) +{ + unsigned long a, b, blocks; + /* So how much do we need to backup. + * We need an amount of data which is both a whole number of + * old stripes and a whole number of new stripes. + * So LCM for (chunksize*datadisks). + */ + a = (ochunk/512) * odata; + b = (nchunk/512) * ndata; + /* Find GCD */ + while (a != b) { + if (a < b) + b -= a; + if (b < a) + a -= b; + } + /* LCM == product / GCD */ + blocks = (ochunk/512) * (nchunk/512) * odata * ndata / a; + + return blocks; +} + + int Grow_reshape(char *devname, int fd, int quiet, char *backup_file, long long size, int level, char *layout_str, int chunksize, int raid_disks) @@ -944,7 +969,7 @@ int Grow_reshape(char *devname, int fd, int quiet, char *backup_file, int nrdisks; int err; int frozen; - unsigned long a,b, blocks, stripes; + unsigned long blocks, stripes; unsigned long cache; unsigned long long array_size; int changed = 0; @@ -1534,22 +1559,7 @@ int Grow_reshape(char *devname, int fd, int quiet, char *backup_file, break; } - /* So how much do we need to backup. - * We need an amount of data which is both a whole number of - * old stripes and a whole number of new stripes. - * So LCM for (chunksize*datadisks). - */ - a = (ochunk/512) * odata; - b = (nchunk/512) * ndata; - /* Find GCD */ - while (a != b) { - if (a < b) - b -= a; - if (b < a) - a -= b; - } - /* LCM == product / GCD */ - blocks = (ochunk/512) * (nchunk/512) * odata * ndata / a; + blocks = compute_backup_blocks(nchunk, ochunk, ndata, odata); sysfs_free(sra); sra = sysfs_read(fd, 0, diff --git a/mdadm.h b/mdadm.h index 3a1b66d..05bf0b8 100644 --- a/mdadm.h +++ b/mdadm.h @@ -487,6 +487,8 @@ extern void reshape_free_fdlist(int *fdlist, unsigned long long *offsets, int size); +extern unsigned long compute_backup_blocks(int nchunk, int ochunk, + unsigned int ndata, unsigned int odata); extern int save_stripes(int *source, unsigned long long *offsets, int raid_disks, int chunk_size, int level, int layout,