aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/md/raid5.c
diff options
context:
space:
mode:
authorNeilBrown <neilb@suse.de>2008-02-06 04:39:52 -0500
committerLinus Torvalds <torvalds@woody.linux-foundation.org>2008-02-06 13:41:18 -0500
commitc620727779f7cc8ea96efb71f0651a26349e59c1 (patch)
tree777abdad9c9ef10cb4df5c0efc736e6c64851ed8 /drivers/md/raid5.c
parentc303da6d713b87b7b3f999f5acce8ecc76ff1adb (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.c25
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.