Skip to content

Commit acb180b

Browse files
committed
md: improve usefulness and accuracy of sysfs file md/sync_completed.
The sync_completed file reports how much of a resync (or recovery or reshape) has been completed. However due to the possibility of out-of-order completion of writes, it is not certain to be accurate. We have an internal value - mddev->curr_resync_completed - which is an accurate value (though it might not always be quite so uptodate). So: - make curr_resync_completed be uptodate a little more often, particularly when raid5 reshape updates status in the metadata - report curr_resync_completed in the sysfs file - allow poll/select to report all updates to md/sync_completed. This makes sync_completed completed usable by any external metadata handler that wants to record this status information in its metadata. Signed-off-by: NeilBrown <[email protected]>
1 parent 6d56e27 commit acb180b

File tree

3 files changed

+27
-12
lines changed

3 files changed

+27
-12
lines changed

drivers/md/bitmap.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1479,6 +1479,7 @@ void bitmap_cond_end_sync(struct bitmap *bitmap, sector_t sector)
14791479
s += blocks;
14801480
}
14811481
bitmap->last_end_sync = jiffies;
1482+
sysfs_notify(&bitmap->mddev->kobj, NULL, "sync_completed");
14821483
}
14831484

14841485
static void bitmap_set_memory_bits(struct bitmap *bitmap, sector_t offset, int needed)

drivers/md/md.c

Lines changed: 22 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -2017,6 +2017,8 @@ static void md_update_sb(mddev_t * mddev, int force_change)
20172017
clear_bit(MD_CHANGE_PENDING, &mddev->flags);
20182018
spin_unlock_irq(&mddev->write_lock);
20192019
wake_up(&mddev->sb_wait);
2020+
if (test_bit(MD_RECOVERY_RUNNING, &mddev->recovery))
2021+
sysfs_notify(&mddev->kobj, NULL, "sync_completed");
20202022

20212023
}
20222024

@@ -3486,12 +3488,15 @@ sync_completed_show(mddev_t *mddev, char *page)
34863488
{
34873489
unsigned long max_sectors, resync;
34883490

3491+
if (!test_bit(MD_RECOVERY_RUNNING, &mddev->recovery))
3492+
return sprintf(page, "none\n");
3493+
34893494
if (test_bit(MD_RECOVERY_SYNC, &mddev->recovery))
34903495
max_sectors = mddev->resync_max_sectors;
34913496
else
34923497
max_sectors = mddev->dev_sectors;
34933498

3494-
resync = (mddev->curr_resync - atomic_read(&mddev->recovery_active));
3499+
resync = mddev->curr_resync_completed;
34953500
return sprintf(page, "%lu / %lu\n", resync, max_sectors);
34963501
}
34973502

@@ -6338,26 +6343,30 @@ void md_do_sync(mddev_t *mddev)
63386343
sector_t sectors;
63396344

63406345
skipped = 0;
6341-
if (j >= mddev->resync_max) {
6342-
sysfs_notify(&mddev->kobj, NULL, "sync_completed");
6343-
wait_event(mddev->recovery_wait,
6344-
mddev->resync_max > j
6345-
|| kthread_should_stop());
6346-
}
6347-
if (kthread_should_stop())
6348-
goto interrupted;
63496346

6350-
if (mddev->curr_resync > mddev->curr_resync_completed &&
6351-
(mddev->curr_resync - mddev->curr_resync_completed)
6352-
> (max_sectors >> 4)) {
6347+
if ((mddev->curr_resync > mddev->curr_resync_completed &&
6348+
(mddev->curr_resync - mddev->curr_resync_completed)
6349+
> (max_sectors >> 4)) ||
6350+
j >= mddev->resync_max
6351+
) {
63536352
/* time to update curr_resync_completed */
63546353
blk_unplug(mddev->queue);
63556354
wait_event(mddev->recovery_wait,
63566355
atomic_read(&mddev->recovery_active) == 0);
63576356
mddev->curr_resync_completed =
63586357
mddev->curr_resync;
63596358
set_bit(MD_CHANGE_CLEAN, &mddev->flags);
6359+
sysfs_notify(&mddev->kobj, NULL, "sync_completed");
63606360
}
6361+
6362+
if (j >= mddev->resync_max)
6363+
wait_event(mddev->recovery_wait,
6364+
mddev->resync_max > j
6365+
|| kthread_should_stop());
6366+
6367+
if (kthread_should_stop())
6368+
goto interrupted;
6369+
63616370
sectors = mddev->pers->sync_request(mddev, j, &skipped,
63626371
currspeed < speed_min(mddev));
63636372
if (sectors == 0) {
@@ -6465,6 +6474,7 @@ void md_do_sync(mddev_t *mddev)
64656474

64666475
skip:
64676476
mddev->curr_resync = 0;
6477+
mddev->curr_resync_completed = 0;
64686478
mddev->resync_min = 0;
64696479
mddev->resync_max = MaxSector;
64706480
sysfs_notify(&mddev->kobj, NULL, "sync_completed");

drivers/md/raid5.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3845,6 +3845,7 @@ static sector_t reshape_request(mddev_t *mddev, sector_t sector_nr, int *skipped
38453845
wait_event(conf->wait_for_overlap,
38463846
atomic_read(&conf->reshape_stripes)==0);
38473847
mddev->reshape_position = conf->reshape_progress;
3848+
mddev->curr_resync_completed = mddev->curr_resync;
38483849
conf->reshape_checkpoint = jiffies;
38493850
set_bit(MD_CHANGE_DEVS, &mddev->flags);
38503851
md_wakeup_thread(mddev->thread);
@@ -3854,6 +3855,7 @@ static sector_t reshape_request(mddev_t *mddev, sector_t sector_nr, int *skipped
38543855
conf->reshape_safe = mddev->reshape_position;
38553856
spin_unlock_irq(&conf->device_lock);
38563857
wake_up(&conf->wait_for_overlap);
3858+
sysfs_notify(&mddev->kobj, NULL, "sync_completed");
38573859
}
38583860

38593861
if (mddev->delta_disks < 0) {
@@ -3943,6 +3945,7 @@ static sector_t reshape_request(mddev_t *mddev, sector_t sector_nr, int *skipped
39433945
wait_event(conf->wait_for_overlap,
39443946
atomic_read(&conf->reshape_stripes) == 0);
39453947
mddev->reshape_position = conf->reshape_progress;
3948+
mddev->curr_resync_completed = mddev->curr_resync;
39463949
conf->reshape_checkpoint = jiffies;
39473950
set_bit(MD_CHANGE_DEVS, &mddev->flags);
39483951
md_wakeup_thread(mddev->thread);
@@ -3953,6 +3956,7 @@ static sector_t reshape_request(mddev_t *mddev, sector_t sector_nr, int *skipped
39533956
conf->reshape_safe = mddev->reshape_position;
39543957
spin_unlock_irq(&conf->device_lock);
39553958
wake_up(&conf->wait_for_overlap);
3959+
sysfs_notify(&mddev->kobj, NULL, "sync_completed");
39563960
}
39573961
return reshape_sectors;
39583962
}

0 commit comments

Comments
 (0)