From 92d1991fffcc56c7b7ce4667f847559e2df23449 Mon Sep 17 00:00:00 2001 From: NeilBrown Date: Wed, 12 Jan 2011 10:34:44 +1100 Subject: [PATCH] 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 --- Grow.c | 21 +++++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/Grow.c b/Grow.c index 708a6c7..7c7fa64 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) {