summary refs log tree commit diff
path: root/drivers/md/md.c
diff options
context:
space:
mode:
authormajianpeng <majianpeng@gmail.com>2012-10-31 11:59:10 +1100
committerNeilBrown <neilb@suse.de>2012-12-13 16:41:40 +1100
commit54f89341e8b8da0cdac8a7b873491739de19f098 (patch)
tree360f937ada4613db9772ef1a28f9503cb4457169 /drivers/md/md.c
parent35d78c66969fbbb51046e9f251849cf54e9ed88c (diff)
downloadlinux-54f89341e8b8da0cdac8a7b873491739de19f098.tar.gz
md: Update checkpoint of resync/recovery based on time.
md will current only only checkpoint recovery or resync ever 1/16th
of the device size.  As devices get larger this can become a long time
an so a lot of work that might need to be duplicated after a shutdown.

So add a time-based checkpoint.  Every 5 minutes limits the amount of
duplicated effort to at most 5 minutes, and has almost zero impact on
performance.

[changelog entry re-written by NeilBrown]

Signed-off-by: Jianpeng Ma <majianpeng@gmail.com>
Signed-off-by: NeilBrown <neilb@suse.de>
Diffstat (limited to 'drivers/md/md.c')
-rw-r--r--drivers/md/md.c5
1 files changed, 5 insertions, 0 deletions
diff --git a/drivers/md/md.c b/drivers/md/md.c
index f97083476475..6aefa4434819 100644
--- a/drivers/md/md.c
+++ b/drivers/md/md.c
@@ -7277,6 +7277,7 @@ EXPORT_SYMBOL_GPL(md_allow_write);
 
 #define SYNC_MARKS	10
 #define	SYNC_MARK_STEP	(3*HZ)
+#define UPDATE_FREQUENCY (5*60*HZ)
 void md_do_sync(struct md_thread *thread)
 {
 	struct mddev *mddev = thread->mddev;
@@ -7285,6 +7286,7 @@ void md_do_sync(struct md_thread *thread)
 		 window;
 	sector_t max_sectors,j, io_sectors;
 	unsigned long mark[SYNC_MARKS];
+	unsigned long update_time;
 	sector_t mark_cnt[SYNC_MARKS];
 	int last_mark,m;
 	struct list_head *tmp;
@@ -7444,6 +7446,7 @@ void md_do_sync(struct md_thread *thread)
 	mddev->curr_resync_completed = j;
 	sysfs_notify(&mddev->kobj, NULL, "sync_completed");
 	md_new_event(mddev);
+	update_time = jiffies;
 
 	blk_start_plug(&plug);
 	while (j < max_sectors) {
@@ -7455,6 +7458,7 @@ void md_do_sync(struct md_thread *thread)
 		    ((mddev->curr_resync > mddev->curr_resync_completed &&
 		      (mddev->curr_resync - mddev->curr_resync_completed)
 		      > (max_sectors >> 4)) ||
+		     time_after_eq(jiffies, update_time + UPDATE_FREQUENCY) ||
 		     (j - mddev->curr_resync_completed)*2
 		     >= mddev->resync_max - mddev->curr_resync_completed
 			    )) {
@@ -7465,6 +7469,7 @@ void md_do_sync(struct md_thread *thread)
 			if (test_bit(MD_RECOVERY_SYNC, &mddev->recovery) &&
 			    j > mddev->recovery_cp)
 				mddev->recovery_cp = j;
+			update_time = jiffies;
 			set_bit(MD_CHANGE_CLEAN, &mddev->flags);
 			sysfs_notify(&mddev->kobj, NULL, "sync_completed");
 		}