diff options
author | NeilBrown <neilb@suse.de> | 2008-02-06 04:39:52 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2008-02-06 13:41:18 -0500 |
commit | c620727779f7cc8ea96efb71f0651a26349e59c1 (patch) | |
tree | 777abdad9c9ef10cb4df5c0efc736e6c64851ed8 /drivers/md/raid5.c | |
parent | c303da6d713b87b7b3f999f5acce8ecc76ff1adb (diff) |
md: allow a maximum extent to be set for resyncing
This allows userspace to control resync/reshape progress and synchronise it
with other activities, such as shared access in a SAN, or backing up critical
sections during a tricky reshape.
Writing a number of sectors (which must be a multiple of the chunk size if
such is meaningful) causes a resync to pause when it gets to that point.
Signed-off-by: Neil Brown <neilb@suse.de>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'drivers/md/raid5.c')
-rw-r--r-- | drivers/md/raid5.c | 25 |
1 files changed, 25 insertions, 0 deletions
diff --git a/drivers/md/raid5.c b/drivers/md/raid5.c index 388a974d63ef..e946de6f46bc 100644 --- a/drivers/md/raid5.c +++ b/drivers/md/raid5.c | |||
@@ -3698,6 +3698,25 @@ static sector_t reshape_request(mddev_t *mddev, sector_t sector_nr, int *skipped | |||
3698 | release_stripe(sh); | 3698 | release_stripe(sh); |
3699 | first_sector += STRIPE_SECTORS; | 3699 | first_sector += STRIPE_SECTORS; |
3700 | } | 3700 | } |
3701 | /* If this takes us to the resync_max point where we have to pause, | ||
3702 | * then we need to write out the superblock. | ||
3703 | */ | ||
3704 | sector_nr += conf->chunk_size>>9; | ||
3705 | if (sector_nr >= mddev->resync_max) { | ||
3706 | /* Cannot proceed until we've updated the superblock... */ | ||
3707 | wait_event(conf->wait_for_overlap, | ||
3708 | atomic_read(&conf->reshape_stripes) == 0); | ||
3709 | mddev->reshape_position = conf->expand_progress; | ||
3710 | set_bit(MD_CHANGE_DEVS, &mddev->flags); | ||
3711 | md_wakeup_thread(mddev->thread); | ||
3712 | wait_event(mddev->sb_wait, | ||
3713 | !test_bit(MD_CHANGE_DEVS, &mddev->flags) | ||
3714 | || kthread_should_stop()); | ||
3715 | spin_lock_irq(&conf->device_lock); | ||
3716 | conf->expand_lo = mddev->reshape_position; | ||
3717 | spin_unlock_irq(&conf->device_lock); | ||
3718 | wake_up(&conf->wait_for_overlap); | ||
3719 | } | ||
3701 | return conf->chunk_size>>9; | 3720 | return conf->chunk_size>>9; |
3702 | } | 3721 | } |
3703 | 3722 | ||
@@ -3734,6 +3753,12 @@ static inline sector_t sync_request(mddev_t *mddev, sector_t sector_nr, int *ski | |||
3734 | if (test_bit(MD_RECOVERY_RESHAPE, &mddev->recovery)) | 3753 | if (test_bit(MD_RECOVERY_RESHAPE, &mddev->recovery)) |
3735 | return reshape_request(mddev, sector_nr, skipped); | 3754 | return reshape_request(mddev, sector_nr, skipped); |
3736 | 3755 | ||
3756 | /* No need to check resync_max as we never do more than one | ||
3757 | * stripe, and as resync_max will always be on a chunk boundary, | ||
3758 | * if the check in md_do_sync didn't fire, there is no chance | ||
3759 | * of overstepping resync_max here | ||
3760 | */ | ||
3761 | |||
3737 | /* if there is too many failed drives and we are trying | 3762 | /* if there is too many failed drives and we are trying |
3738 | * to resync, then assert that we are finished, because there is | 3763 | * to resync, then assert that we are finished, because there is |
3739 | * nothing we can do. | 3764 | * nothing we can do. |