aboutsummaryrefslogtreecommitdiff
path: root/drivers/md/md.c
diff options
context:
space:
mode:
authorNeilBrown <neilb@suse.com>2015-07-24 13:27:08 +1000
committerSasha Levin <alexander.levin@verizon.com>2016-11-25 22:57:03 -0500
commite1e5cab9b43c37c8069519cb671baa9ff986466a (patch)
tree03d9613d9785c718a4aff9bb479f49fc7c72d3d9 /drivers/md/md.c
parent97d53c4d89e0f2833b932b8e3f0c2d7312a55b52 (diff)
md: sync sync_completed has correct value as recovery finishes.
[ 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>
Diffstat (limited to 'drivers/md/md.c')
-rw-r--r--drivers/md/md.c9
1 files changed, 9 insertions, 0 deletions
diff --git a/drivers/md/md.c b/drivers/md/md.c
index 72dc91de80f8..f284be86bcef 100644
--- a/drivers/md/md.c
+++ b/drivers/md/md.c
@@ -7847,6 +7847,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))
@@ -7915,6 +7918,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);