md-cluster: sync bitmap when node received RESYNCING msg
authorGuoqing Jiang <gqjiang@suse.com>
Mon, 2 May 2016 15:50:12 +0000 (11:50 -0400)
committerShaohua Li <shli@fb.com>
Wed, 4 May 2016 19:39:35 +0000 (12:39 -0700)
If the node received RESYNCING message which means
another node will perform resync with the area, then
we don't want to do it again in another node.

Let's set RESYNC_MASK and clear NEEDED_MASK for the
region from old-low to new-low which has finished
syncing, and the region from old-hi to new-hi is about
to syncing, bitmap_sync_with_cluste is introduced for
the purpose.

Reviewed-by: NeilBrown <neilb@suse.com>
Signed-off-by: Guoqing Jiang <gqjiang@suse.com>
Signed-off-by: Shaohua Li <shli@fb.com>
drivers/md/bitmap.c
drivers/md/bitmap.h
drivers/md/md-cluster.c

index 431da21cb488878cf84e01c9c564381ac020ffe4..ac93d874578a6e4a0f7ab1d0d69c4b9051740703 100644 (file)
@@ -1597,6 +1597,27 @@ void bitmap_cond_end_sync(struct bitmap *bitmap, sector_t sector, bool force)
 }
 EXPORT_SYMBOL(bitmap_cond_end_sync);
 
+void bitmap_sync_with_cluster(struct mddev *mddev,
+                             sector_t old_lo, sector_t old_hi,
+                             sector_t new_lo, sector_t new_hi)
+{
+       struct bitmap *bitmap = mddev->bitmap;
+       sector_t sector, blocks = 0;
+
+       for (sector = old_lo; sector < new_lo; ) {
+               bitmap_end_sync(bitmap, sector, &blocks, 0);
+               sector += blocks;
+       }
+       WARN((blocks > new_lo) && old_lo, "alignment is not correct for lo\n");
+
+       for (sector = old_hi; sector < new_hi; ) {
+               bitmap_start_sync(bitmap, sector, &blocks, 0);
+               sector += blocks;
+       }
+       WARN((blocks > new_hi) && old_hi, "alignment is not correct for hi\n");
+}
+EXPORT_SYMBOL(bitmap_sync_with_cluster);
+
 static void bitmap_set_memory_bits(struct bitmap *bitmap, sector_t offset, int needed)
 {
        /* For each chunk covered by any of these sectors, set the
index 5e3fcd6ecf779e5e490bec8df8af8354da3fffe5..5b6dd63dda91421d0f8f0f2b4a656ee73c746d6a 100644 (file)
@@ -258,6 +258,9 @@ int bitmap_start_sync(struct bitmap *bitmap, sector_t offset, sector_t *blocks,
 void bitmap_end_sync(struct bitmap *bitmap, sector_t offset, sector_t *blocks, int aborted);
 void bitmap_close_sync(struct bitmap *bitmap);
 void bitmap_cond_end_sync(struct bitmap *bitmap, sector_t sector, bool force);
+void bitmap_sync_with_cluster(struct mddev *mddev,
+                             sector_t old_lo, sector_t old_hi,
+                             sector_t new_lo, sector_t new_hi);
 
 void bitmap_unplug(struct bitmap *bitmap);
 void bitmap_daemon_work(struct mddev *mddev);
index 30f1160142c15353d5d09a9ff7277a1c7b4a9c42..a55b5f4d0dbebd264d8f04cdff379d822e658636 100644 (file)
@@ -85,6 +85,9 @@ struct md_cluster_info {
        struct completion newdisk_completion;
        wait_queue_head_t wait;
        unsigned long state;
+       /* record the region in RESYNCING message */
+       sector_t sync_low;
+       sector_t sync_hi;
 };
 
 enum msg_type {
@@ -411,6 +414,30 @@ static void process_suspend_info(struct mddev *mddev,
                md_wakeup_thread(mddev->thread);
                return;
        }
+
+       /*
+        * The bitmaps are not same for different nodes
+        * if RESYNCING is happening in one node, then
+        * the node which received the RESYNCING message
+        * probably will perform resync with the region
+        * [lo, hi] again, so we could reduce resync time
+        * a lot if we can ensure that the bitmaps among
+        * different nodes are match up well.
+        *
+        * sync_low/hi is used to record the region which
+        * arrived in the previous RESYNCING message,
+        *
+        * Call bitmap_sync_with_cluster to clear
+        * NEEDED_MASK and set RESYNC_MASK since
+        * resync thread is running in another node,
+        * so we don't need to do the resync again
+        * with the same section */
+       bitmap_sync_with_cluster(mddev, cinfo->sync_low,
+                                       cinfo->sync_hi,
+                                       lo, hi);
+       cinfo->sync_low = lo;
+       cinfo->sync_hi = hi;
+
        s = kzalloc(sizeof(struct suspend_info), GFP_KERNEL);
        if (!s)
                return;
This page took 0.031609 seconds and 5 git commands to generate.