Fix calculations for max_progress and completed.

'sync_completed' can sometimes have a value which is slightly high.
So round-down relevant values to new-chunk size and that is what we
want.

Subtract from component_size after scaling down rather than before as
that is easier.
Make sure max_progress never goes negative when reshaping backwards.

Signed-off-by: NeilBrown <neilb@suse.de>
This commit is contained in:
NeilBrown 2011-01-12 10:34:44 +11:00
parent d0ab945ee1
commit 92d1991fff
1 changed files with 15 additions and 6 deletions

21
Grow.c
View File

@ -2409,14 +2409,20 @@ int progress_reshape(struct mdinfo *info, struct reshape *reshape,
* At the same time we convert wait_point to a similar number
* for comparing against sync_completed.
*/
if (!advancing) {
max_progress = info->component_size * reshape->after.data_disks
- max_progress;
wait_point = info->component_size * reshape->after.data_disks
- wait_point;
}
/* scale down max_progress to per_disk */
max_progress /= reshape->after.data_disks;
/* Round to chunk size as some kernels give an erroneously high number */
max_progress /= info->new_chunk/512;
max_progress *= info->new_chunk/512;
/* Limit progress to the whole device */
if (max_progress > info->component_size)
max_progress = info->component_size;
wait_point /= reshape->after.data_disks;
if (!advancing) {
/* switch from 'device offset' to 'processed block count' */
max_progress = info->component_size - max_progress;
wait_point = info->component_size - wait_point;
}
sysfs_set_num(info, NULL, "sync_max", max_progress);
@ -2452,6 +2458,9 @@ int progress_reshape(struct mdinfo *info, struct reshape *reshape,
return -1;
}
}
/* some kernels can give an incorrectly high 'completed' number */
completed /= (info->new_chunk/512);
completed *= (info->new_chunk/512);
/* Convert 'completed' back in to a 'progress' number */
completed *= reshape->after.data_disks;
if (!advancing) {