diff options
author | NeilBrown <neilb@suse.de> | 2009-04-14 02:28:34 -0400 |
---|---|---|
committer | NeilBrown <neilb@suse.de> | 2009-04-14 02:28:34 -0400 |
commit | acb180b0e335ad88acfed6c8a33e39c05b95dc49 (patch) | |
tree | fa980978bb66b178fd8c2f474194754139c0921d /drivers/md/md.c | |
parent | 6d56e278444bc8323b1bcfcada126b8e4dbba0f4 (diff) |
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 <neilb@suse.de>
Diffstat (limited to 'drivers/md/md.c')
-rw-r--r-- | drivers/md/md.c | 34 |
1 files changed, 22 insertions, 12 deletions
diff --git a/drivers/md/md.c b/drivers/md/md.c index 298731b8e951..7af64f3846a6 100644 --- a/drivers/md/md.c +++ b/drivers/md/md.c | |||
@@ -2017,6 +2017,8 @@ repeat: | |||
2017 | clear_bit(MD_CHANGE_PENDING, &mddev->flags); | 2017 | clear_bit(MD_CHANGE_PENDING, &mddev->flags); |
2018 | spin_unlock_irq(&mddev->write_lock); | 2018 | spin_unlock_irq(&mddev->write_lock); |
2019 | wake_up(&mddev->sb_wait); | 2019 | wake_up(&mddev->sb_wait); |
2020 | if (test_bit(MD_RECOVERY_RUNNING, &mddev->recovery)) | ||
2021 | sysfs_notify(&mddev->kobj, NULL, "sync_completed"); | ||
2020 | 2022 | ||
2021 | } | 2023 | } |
2022 | 2024 | ||
@@ -3486,12 +3488,15 @@ sync_completed_show(mddev_t *mddev, char *page) | |||
3486 | { | 3488 | { |
3487 | unsigned long max_sectors, resync; | 3489 | unsigned long max_sectors, resync; |
3488 | 3490 | ||
3491 | if (!test_bit(MD_RECOVERY_RUNNING, &mddev->recovery)) | ||
3492 | return sprintf(page, "none\n"); | ||
3493 | |||
3489 | if (test_bit(MD_RECOVERY_SYNC, &mddev->recovery)) | 3494 | if (test_bit(MD_RECOVERY_SYNC, &mddev->recovery)) |
3490 | max_sectors = mddev->resync_max_sectors; | 3495 | max_sectors = mddev->resync_max_sectors; |
3491 | else | 3496 | else |
3492 | max_sectors = mddev->dev_sectors; | 3497 | max_sectors = mddev->dev_sectors; |
3493 | 3498 | ||
3494 | resync = (mddev->curr_resync - atomic_read(&mddev->recovery_active)); | 3499 | resync = mddev->curr_resync_completed; |
3495 | return sprintf(page, "%lu / %lu\n", resync, max_sectors); | 3500 | return sprintf(page, "%lu / %lu\n", resync, max_sectors); |
3496 | } | 3501 | } |
3497 | 3502 | ||
@@ -6338,18 +6343,12 @@ void md_do_sync(mddev_t *mddev) | |||
6338 | sector_t sectors; | 6343 | sector_t sectors; |
6339 | 6344 | ||
6340 | skipped = 0; | 6345 | 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; | ||
6349 | 6346 | ||
6350 | if (mddev->curr_resync > mddev->curr_resync_completed && | 6347 | if ((mddev->curr_resync > mddev->curr_resync_completed && |
6351 | (mddev->curr_resync - mddev->curr_resync_completed) | 6348 | (mddev->curr_resync - mddev->curr_resync_completed) |
6352 | > (max_sectors >> 4)) { | 6349 | > (max_sectors >> 4)) || |
6350 | j >= mddev->resync_max | ||
6351 | ) { | ||
6353 | /* time to update curr_resync_completed */ | 6352 | /* time to update curr_resync_completed */ |
6354 | blk_unplug(mddev->queue); | 6353 | blk_unplug(mddev->queue); |
6355 | wait_event(mddev->recovery_wait, | 6354 | wait_event(mddev->recovery_wait, |
@@ -6357,7 +6356,17 @@ void md_do_sync(mddev_t *mddev) | |||
6357 | mddev->curr_resync_completed = | 6356 | mddev->curr_resync_completed = |
6358 | mddev->curr_resync; | 6357 | mddev->curr_resync; |
6359 | set_bit(MD_CHANGE_CLEAN, &mddev->flags); | 6358 | set_bit(MD_CHANGE_CLEAN, &mddev->flags); |
6359 | sysfs_notify(&mddev->kobj, NULL, "sync_completed"); | ||
6360 | } | 6360 | } |
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 | |||
6361 | sectors = mddev->pers->sync_request(mddev, j, &skipped, | 6370 | sectors = mddev->pers->sync_request(mddev, j, &skipped, |
6362 | currspeed < speed_min(mddev)); | 6371 | currspeed < speed_min(mddev)); |
6363 | if (sectors == 0) { | 6372 | if (sectors == 0) { |
@@ -6465,6 +6474,7 @@ void md_do_sync(mddev_t *mddev) | |||
6465 | 6474 | ||
6466 | skip: | 6475 | skip: |
6467 | mddev->curr_resync = 0; | 6476 | mddev->curr_resync = 0; |
6477 | mddev->curr_resync_completed = 0; | ||
6468 | mddev->resync_min = 0; | 6478 | mddev->resync_min = 0; |
6469 | mddev->resync_max = MaxSector; | 6479 | mddev->resync_max = MaxSector; |
6470 | sysfs_notify(&mddev->kobj, NULL, "sync_completed"); | 6480 | sysfs_notify(&mddev->kobj, NULL, "sync_completed"); |