diff options
-rw-r--r-- | drivers/md/bitmap.c | 21 | ||||
-rw-r--r-- | drivers/md/bitmap.h | 3 | ||||
-rw-r--r-- | drivers/md/md-cluster.c | 27 |
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 | } |
1598 | EXPORT_SYMBOL(bitmap_cond_end_sync); | 1598 | EXPORT_SYMBOL(bitmap_cond_end_sync); |
1599 | 1599 | ||
1600 | void 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 | } | ||
1619 | EXPORT_SYMBOL(bitmap_sync_with_cluster); | ||
1620 | |||
1600 | static void bitmap_set_memory_bits(struct bitmap *bitmap, sector_t offset, int needed) | 1621 | static 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, | |||
258 | void bitmap_end_sync(struct bitmap *bitmap, sector_t offset, sector_t *blocks, int aborted); | 258 | void bitmap_end_sync(struct bitmap *bitmap, sector_t offset, sector_t *blocks, int aborted); |
259 | void bitmap_close_sync(struct bitmap *bitmap); | 259 | void bitmap_close_sync(struct bitmap *bitmap); |
260 | void bitmap_cond_end_sync(struct bitmap *bitmap, sector_t sector, bool force); | 260 | void bitmap_cond_end_sync(struct bitmap *bitmap, sector_t sector, bool force); |
261 | void 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 | ||
262 | void bitmap_unplug(struct bitmap *bitmap); | 265 | void bitmap_unplug(struct bitmap *bitmap); |
263 | void bitmap_daemon_work(struct mddev *mddev); | 266 | void 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 | ||
90 | enum msg_type { | 93 | enum 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; |