Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

md-cluster: sync bitmap when node received RESYNCING msg

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>

authored by

Guoqing Jiang and committed by
Shaohua Li
18c9ff7f c9d65032

+51
+21
drivers/md/bitmap.c
··· 1597 1597 } 1598 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 1621 static void bitmap_set_memory_bits(struct bitmap *bitmap, sector_t offset, int needed) 1601 1622 { 1602 1623 /* For each chunk covered by any of these sectors, set the
+3
drivers/md/bitmap.h
··· 258 258 void bitmap_end_sync(struct bitmap *bitmap, sector_t offset, sector_t *blocks, int aborted); 259 259 void bitmap_close_sync(struct bitmap *bitmap); 260 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 265 void bitmap_unplug(struct bitmap *bitmap); 263 266 void bitmap_daemon_work(struct mddev *mddev);
+27
drivers/md/md-cluster.c
··· 85 85 struct completion newdisk_completion; 86 86 wait_queue_head_t wait; 87 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 93 enum msg_type { ··· 414 411 md_wakeup_thread(mddev->thread); 415 412 return; 416 413 } 414 + 415 + /* 416 + * The bitmaps are not same for different nodes 417 + * if RESYNCING is happening in one node, then 418 + * the node which received the RESYNCING message 419 + * probably will perform resync with the region 420 + * [lo, hi] again, so we could reduce resync time 421 + * a lot if we can ensure that the bitmaps among 422 + * different nodes are match up well. 423 + * 424 + * sync_low/hi is used to record the region which 425 + * arrived in the previous RESYNCING message, 426 + * 427 + * Call bitmap_sync_with_cluster to clear 428 + * NEEDED_MASK and set RESYNC_MASK since 429 + * resync thread is running in another node, 430 + * so we don't need to do the resync again 431 + * with the same section */ 432 + bitmap_sync_with_cluster(mddev, cinfo->sync_low, 433 + cinfo->sync_hi, 434 + lo, hi); 435 + cinfo->sync_low = lo; 436 + cinfo->sync_hi = hi; 437 + 417 438 s = kzalloc(sizeof(struct suspend_info), GFP_KERNEL); 418 439 if (!s) 419 440 return;