md: sync sync_completed has correct value as recovery finishes.
authorNeilBrown <neilb@suse.com>
Fri, 24 Jul 2015 03:27:08 +0000 (13:27 +1000)
committerSasha Levin <alexander.levin@verizon.com>
Thu, 24 Nov 2016 04:08:55 +0000 (23:08 -0500)
[ Upstream commit 5ed1df2eacc0ba92c8c7e2499c97594b5ef928a8 ]

There can be a small window between the moment that recovery
actually writes the last block and the time when various sysfs
and /proc/mdstat attributes report that it has finished.
During this time, 'sync_completed' can have the wrong value.
This can confuse monitoring software.

So:
 - don't set curr_resync_completed beyond the end of the devices,
 - set it correctly when resync/recovery has completed.

Signed-off-by: NeilBrown <neilb@suse.com>
Signed-off-by: Sasha Levin <alexander.levin@verizon.com>
drivers/md/md.c

index 3d2cc7453ec190905ae50101d3e5563854bc7180..7987e87a1be01e4096c42ef95193403e7874d553 100644 (file)
@@ -7409,6 +7409,9 @@ void md_do_sync(struct md_thread *thread)
                        break;
 
                j += sectors;
+               if (j > max_sectors)
+                       /* when skipping, extra large numbers can be returned. */
+                       j = max_sectors;
                if (j > 2)
                        mddev->curr_resync = j;
                mddev->curr_mark_cnt = io_sectors;
@@ -7468,6 +7471,12 @@ void md_do_sync(struct md_thread *thread)
        blk_finish_plug(&plug);
        wait_event(mddev->recovery_wait, !atomic_read(&mddev->recovery_active));
 
+       if (!test_bit(MD_RECOVERY_RESHAPE, &mddev->recovery) &&
+           !test_bit(MD_RECOVERY_INTR, &mddev->recovery) &&
+           mddev->curr_resync > 2) {
+               mddev->curr_resync_completed = mddev->curr_resync;
+               sysfs_notify(&mddev->kobj, NULL, "sync_completed");
+       }
        /* tell personality that we are finished */
        mddev->pers->sync_request(mddev, max_sectors, &skipped, 1);