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)
committerNeilBrown <neilb@suse.com>
Mon, 31 Aug 2015 17:38:17 +0000 (19:38 +0200)
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>
drivers/md/md.c

index b326cd26b0277d534b13013a92c65bd1ee03ef44..84dc5d7a445b354b32656f050e6ed1389eb9e006 100644 (file)
@@ -7880,6 +7880,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;
                if (mddev_is_clustered(mddev))
@@ -7948,6 +7951,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);