aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/md/bitmap.c21
-rw-r--r--drivers/md/bitmap.h3
-rw-r--r--drivers/md/md-cluster.c27
3 files changed, 51 insertions, 0 deletions
diff --git a/drivers/md/bitmap.c b/drivers/md/bitmap.c
index 431da21cb488..ac93d874578a 100644
--- a/drivers/md/bitmap.c
+++ b/drivers/md/bitmap.c
@@ -1597,6 +1597,27 @@ void bitmap_cond_end_sync(struct bitmap *bitmap, sector_t sector, bool force)
1597} 1597}
1598EXPORT_SYMBOL(bitmap_cond_end_sync); 1598EXPORT_SYMBOL(bitmap_cond_end_sync);
1599 1599
1600void bitmap_sync_with_cluster(struct mddev *mddev,
1601 sector_t old_lo, sector_t old_hi,
1602 sector_t new_lo, sector_t new_hi)
1603{
1604 struct bitmap *bitmap = mddev->bitmap;
1605 sector_t sector, blocks = 0;
1606
1607 for (sector = old_lo; sector < new_lo; ) {
1608 bitmap_end_sync(bitmap, sector, &blocks, 0);
1609 sector += blocks;
1610 }
1611 WARN((blocks > new_lo) && old_lo, "alignment is not correct for lo\n");
1612
1613 for (sector = old_hi; sector < new_hi; ) {
1614 bitmap_start_sync(bitmap, sector, &blocks, 0);
1615 sector += blocks;
1616 }
1617 WARN((blocks > new_hi) && old_hi, "alignment is not correct for hi\n");
1618}
1619EXPORT_SYMBOL(bitmap_sync_with_cluster);
1620
1600static void bitmap_set_memory_bits(struct bitmap *bitmap, sector_t offset, int needed) 1621static void bitmap_set_memory_bits(struct bitmap *bitmap, sector_t offset, int needed)
1601{ 1622{
1602 /* For each chunk covered by any of these sectors, set the 1623 /* For each chunk covered by any of these sectors, set the
diff --git a/drivers/md/bitmap.h b/drivers/md/bitmap.h
index 5e3fcd6ecf77..5b6dd63dda91 100644
--- a/drivers/md/bitmap.h
+++ b/drivers/md/bitmap.h
@@ -258,6 +258,9 @@ int bitmap_start_sync(struct bitmap *bitmap, sector_t offset, sector_t *blocks,
258void bitmap_end_sync(struct bitmap *bitmap, sector_t offset, sector_t *blocks, int aborted); 258void bitmap_end_sync(struct bitmap *bitmap, sector_t offset, sector_t *blocks, int aborted);
259void bitmap_close_sync(struct bitmap *bitmap); 259void bitmap_close_sync(struct bitmap *bitmap);
260void bitmap_cond_end_sync(struct bitmap *bitmap, sector_t sector, bool force); 260void bitmap_cond_end_sync(struct bitmap *bitmap, sector_t sector, bool force);
261void bitmap_sync_with_cluster(struct mddev *mddev,
262 sector_t old_lo, sector_t old_hi,
263 sector_t new_lo, sector_t new_hi);
261 264
262void bitmap_unplug(struct bitmap *bitmap); 265void bitmap_unplug(struct bitmap *bitmap);
263void bitmap_daemon_work(struct mddev *mddev); 266void bitmap_daemon_work(struct mddev *mddev);
diff --git a/drivers/md/md-cluster.c b/drivers/md/md-cluster.c
index 30f1160142c1..a55b5f4d0dbe 100644
--- a/drivers/md/md-cluster.c
+++ b/drivers/md/md-cluster.c
@@ -85,6 +85,9 @@ struct md_cluster_info {
85 struct completion newdisk_completion; 85 struct completion newdisk_completion;
86 wait_queue_head_t wait; 86 wait_queue_head_t wait;
87 unsigned long state; 87 unsigned long state;
88 /* record the region in RESYNCING message */
89 sector_t sync_low;
90 sector_t sync_hi;
88}; 91};
89 92
90enum msg_type { 93enum msg_type {
@@ -411,6 +414,30 @@ static void process_suspend_info(struct mddev *mddev,
411 md_wakeup_thread(mddev->thread); 414 md_wakeup_thread(mddev->thread);
412 return; 415 return;
413 } 416 }
417
418 /*
419 * The bitmaps are not same for different nodes
420 * if RESYNCING is happening in one node, then
421 * the node which received the RESYNCING message
422 * probably will perform resync with the region
423 * [lo, hi] again, so we could reduce resync time
424 * a lot if we can ensure that the bitmaps among
425 * different nodes are match up well.
426 *
427 * sync_low/hi is used to record the region which
428 * arrived in the previous RESYNCING message,
429 *
430 * Call bitmap_sync_with_cluster to clear
431 * NEEDED_MASK and set RESYNC_MASK since
432 * resync thread is running in another node,
433 * so we don't need to do the resync again
434 * with the same section */
435 bitmap_sync_with_cluster(mddev, cinfo->sync_low,
436 cinfo->sync_hi,
437 lo, hi);
438 cinfo->sync_low = lo;
439 cinfo->sync_hi = hi;
440
414 s = kzalloc(sizeof(struct suspend_info), GFP_KERNEL); 441 s = kzalloc(sizeof(struct suspend_info), GFP_KERNEL);
415 if (!s) 442 if (!s)
416 return; 443 return;