From: NeilBrown Date: Tue, 11 Jan 2011 23:34:44 +0000 (+1100) Subject: Fix calculations for max_progress and completed. X-Git-Tag: mdadm-3.2~108 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=92d1991fffcc56c7b7ce4667f847559e2df23449;p=thirdparty%2Fmdadm.git 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 --- diff --git a/Grow.c b/Grow.c index 708a6c74..7c7fa647 100644 --- a/Grow.c +++ b/Grow.c @@ -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) {