aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/md
diff options
context:
space:
mode:
authorNeilBrown <neilb@suse.de>2009-04-14 02:28:34 -0400
committerNeilBrown <neilb@suse.de>2009-04-14 02:28:34 -0400
commitacb180b0e335ad88acfed6c8a33e39c05b95dc49 (patch)
treefa980978bb66b178fd8c2f474194754139c0921d /drivers/md
parent6d56e278444bc8323b1bcfcada126b8e4dbba0f4 (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')
-rw-r--r--drivers/md/bitmap.c1
-rw-r--r--drivers/md/md.c34
-rw-r--r--drivers/md/raid5.c4
3 files changed, 27 insertions, 12 deletions
diff --git a/drivers/md/bitmap.c b/drivers/md/bitmap.c
index f8a9f7ab2cb..e4510c976b3 100644
--- a/drivers/md/bitmap.c
+++ b/drivers/md/bitmap.c
@@ -1479,6 +1479,7 @@ void bitmap_cond_end_sync(struct bitmap *bitmap, sector_t sector)
1479 s += blocks; 1479 s += blocks;
1480 } 1480 }
1481 bitmap->last_end_sync = jiffies; 1481 bitmap->last_end_sync = jiffies;
1482 sysfs_notify(&bitmap->mddev->kobj, NULL, "sync_completed");
1482} 1483}
1483 1484
1484static void bitmap_set_memory_bits(struct bitmap *bitmap, sector_t offset, int needed) 1485static void bitmap_set_memory_bits(struct bitmap *bitmap, sector_t offset, int needed)
diff --git a/drivers/md/md.c b/drivers/md/md.c
index 298731b8e95..7af64f3846a 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");
diff --git a/drivers/md/raid5.c b/drivers/md/raid5.c
index 3bbc6d64704..76892ac7254 100644
--- a/drivers/md/raid5.c
+++ b/drivers/md/raid5.c
@@ -3845,6 +3845,7 @@ static sector_t reshape_request(mddev_t *mddev, sector_t sector_nr, int *skipped
3845 wait_event(conf->wait_for_overlap, 3845 wait_event(conf->wait_for_overlap,
3846 atomic_read(&conf->reshape_stripes)==0); 3846 atomic_read(&conf->reshape_stripes)==0);
3847 mddev->reshape_position = conf->reshape_progress; 3847 mddev->reshape_position = conf->reshape_progress;
3848 mddev->curr_resync_completed = mddev->curr_resync;
3848 conf->reshape_checkpoint = jiffies; 3849 conf->reshape_checkpoint = jiffies;
3849 set_bit(MD_CHANGE_DEVS, &mddev->flags); 3850 set_bit(MD_CHANGE_DEVS, &mddev->flags);
3850 md_wakeup_thread(mddev->thread); 3851 md_wakeup_thread(mddev->thread);
@@ -3854,6 +3855,7 @@ static sector_t reshape_request(mddev_t *mddev, sector_t sector_nr, int *skipped
3854 conf->reshape_safe = mddev->reshape_position; 3855 conf->reshape_safe = mddev->reshape_position;
3855 spin_unlock_irq(&conf->device_lock); 3856 spin_unlock_irq(&conf->device_lock);
3856 wake_up(&conf->wait_for_overlap); 3857 wake_up(&conf->wait_for_overlap);
3858 sysfs_notify(&mddev->kobj, NULL, "sync_completed");
3857 } 3859 }
3858 3860
3859 if (mddev->delta_disks < 0) { 3861 if (mddev->delta_disks < 0) {
@@ -3943,6 +3945,7 @@ static sector_t reshape_request(mddev_t *mddev, sector_t sector_nr, int *skipped
3943 wait_event(conf->wait_for_overlap, 3945 wait_event(conf->wait_for_overlap,
3944 atomic_read(&conf->reshape_stripes) == 0); 3946 atomic_read(&conf->reshape_stripes) == 0);
3945 mddev->reshape_position = conf->reshape_progress; 3947 mddev->reshape_position = conf->reshape_progress;
3948 mddev->curr_resync_completed = mddev->curr_resync;
3946 conf->reshape_checkpoint = jiffies; 3949 conf->reshape_checkpoint = jiffies;
3947 set_bit(MD_CHANGE_DEVS, &mddev->flags); 3950 set_bit(MD_CHANGE_DEVS, &mddev->flags);
3948 md_wakeup_thread(mddev->thread); 3951 md_wakeup_thread(mddev->thread);
@@ -3953,6 +3956,7 @@ static sector_t reshape_request(mddev_t *mddev, sector_t sector_nr, int *skipped
3953 conf->reshape_safe = mddev->reshape_position; 3956 conf->reshape_safe = mddev->reshape_position;
3954 spin_unlock_irq(&conf->device_lock); 3957 spin_unlock_irq(&conf->device_lock);
3955 wake_up(&conf->wait_for_overlap); 3958 wake_up(&conf->wait_for_overlap);
3959 sysfs_notify(&mddev->kobj, NULL, "sync_completed");
3956 } 3960 }
3957 return reshape_sectors; 3961 return reshape_sectors;
3958} 3962}