Correctly handle the final partial backup of an in-place reshape.

The array might not be a multiple of the chosen backup size, so
the last bit to be backed up might be a bit smaller.  Handle that
correctly.

Signed-off-by: NeilBrown <neilb@suse.de>
This commit is contained in:
NeilBrown 2011-01-12 14:01:36 +11:00
parent 49cd738ba2
commit e97ca00244
1 changed files with 14 additions and 6 deletions

20
Grow.c
View File

@ -2824,6 +2824,7 @@ static int child_monitor(int afd, struct mdinfo *sra, struct reshape *reshape,
while (rv) {
unsigned long long offset;
unsigned long actual_stripes;
/* Need to backup some data.
* If 'part' is not used and the desired
* backup size is suspended, do a backup,
@ -2836,16 +2837,23 @@ static int child_monitor(int afd, struct mdinfo *sra, struct reshape *reshape,
break;
offset = backup_point / data;
actual_stripes = stripes;
if (increasing) {
if (offset + stripes * (chunk/512) >
if (offset + actual_stripes * (chunk/512) >
sra->component_size)
actual_stripes = ((sra->component_size - offset)
/ (chunk/512));
if (offset + actual_stripes * (chunk/512) >
suspend_point/data)
break;
} else {
offset -= stripes * (chunk/512);
if (offset > suspend_point/data)
if (offset < actual_stripes * (chunk/512))
actual_stripes = offset / (chunk/512);
offset -= actual_stripes * (chunk/512);
if (offset < suspend_point/data)
break;
}
grow_backup(sra, offset, stripes,
grow_backup(sra, offset, actual_stripes,
fds, offsets,
disks, chunk, level, layout,
dests, destfd, destoffsets,
@ -2854,9 +2862,9 @@ static int child_monitor(int afd, struct mdinfo *sra, struct reshape *reshape,
/* record where 'part' is up to */
part = !part;
if (increasing)
backup_point += stripes * (chunk/512) * data;
backup_point += actual_stripes * (chunk/512) * data;
else
backup_point -= stripes * (chunk/512) * data;
backup_point -= actual_stripes * (chunk/512) * data;
}
}