]> git.ipfire.org Git - thirdparty/mdadm.git/commitdiff
Fix calculations for max_progress and completed.
authorNeilBrown <neilb@suse.de>
Tue, 11 Jan 2011 23:34:44 +0000 (10:34 +1100)
committerNeilBrown <neilb@suse.de>
Tue, 11 Jan 2011 23:34:44 +0000 (10:34 +1100)
'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>
Grow.c

diff --git a/Grow.c b/Grow.c
index 708a6c745d7e2e55aa120a3cdb44d1468117ca01..7c7fa64753cd4281bc4616e48a92f15d94a0a273 100644 (file)
--- 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) {