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

md-cluster: fix bitmap sub-offset in bitmap_read_sb

bitmap_read_sb is modifying mddev->bitmap_info.offset. This works for
the first bitmap read. However, when multiple bitmaps need to be opened
by the same node, it ends up corrupting the offset. Fix it by using a
local variable.

Also, bitmap_read_sb is not required in bitmap_copy_from_slot since
it is called in bitmap_create. Remove bitmap_read_sb().

Signed-off-by: Goldwyn Rodrigues <rgoldwyn@suse.com>
Signed-off-by: NeilBrown <neilb@suse.com>

authored by

Goldwyn Rodrigues and committed by
NeilBrown
33e38ac6 b0c26a79

+4 -7
+4 -7
drivers/md/bitmap.c
··· 559 559 unsigned long sectors_reserved = 0; 560 560 int err = -EINVAL; 561 561 struct page *sb_page; 562 + loff_t offset = bitmap->mddev->bitmap_info.offset; 562 563 563 564 if (!bitmap->storage.file && !bitmap->mddev->bitmap_info.offset) { 564 565 chunksize = 128 * 1024 * 1024; ··· 586 585 bm_blocks = ((bm_blocks+7) >> 3) + sizeof(bitmap_super_t); 587 586 /* to 4k blocks */ 588 587 bm_blocks = DIV_ROUND_UP_SECTOR_T(bm_blocks, 4096); 589 - bitmap->mddev->bitmap_info.offset += bitmap->cluster_slot * (bm_blocks << 3); 588 + offset = bitmap->mddev->bitmap_info.offset + (bitmap->cluster_slot * (bm_blocks << 3)); 590 589 pr_info("%s:%d bm slot: %d offset: %llu\n", __func__, __LINE__, 591 - bitmap->cluster_slot, (unsigned long long)bitmap->mddev->bitmap_info.offset); 590 + bitmap->cluster_slot, offset); 592 591 } 593 592 594 593 if (bitmap->storage.file) { ··· 599 598 bitmap, bytes, sb_page); 600 599 } else { 601 600 err = read_sb_page(bitmap->mddev, 602 - bitmap->mddev->bitmap_info.offset, 601 + offset, 603 602 sb_page, 604 603 0, sizeof(bitmap_super_t)); 605 604 } ··· 1875 1874 1876 1875 if (IS_ERR(bitmap)) 1877 1876 return PTR_ERR(bitmap); 1878 - 1879 - rv = bitmap_read_sb(bitmap); 1880 - if (rv) 1881 - goto err; 1882 1877 1883 1878 rv = bitmap_init_from_disk(bitmap, 0); 1884 1879 if (rv)