diff options
Diffstat (limited to 'drivers/md/bitmap.c')
| -rw-r--r-- | drivers/md/bitmap.c | 28 | 
1 files changed, 17 insertions, 11 deletions
diff --git a/drivers/md/bitmap.c b/drivers/md/bitmap.c index ed2346ddf4c9..e51de52eeb94 100644 --- a/drivers/md/bitmap.c +++ b/drivers/md/bitmap.c @@ -494,7 +494,7 @@ static int bitmap_new_disk_sb(struct bitmap *bitmap)  	bitmap_super_t *sb;  	unsigned long chunksize, daemon_sleep, write_behind; -	bitmap->storage.sb_page = alloc_page(GFP_KERNEL); +	bitmap->storage.sb_page = alloc_page(GFP_KERNEL | __GFP_ZERO);  	if (bitmap->storage.sb_page == NULL)  		return -ENOMEM;  	bitmap->storage.sb_page->index = 0; @@ -541,6 +541,7 @@ static int bitmap_new_disk_sb(struct bitmap *bitmap)  	sb->state = cpu_to_le32(bitmap->flags);  	bitmap->events_cleared = bitmap->mddev->events;  	sb->events_cleared = cpu_to_le64(bitmap->mddev->events); +	bitmap->mddev->bitmap_info.nodes = 0;  	kunmap_atomic(sb); @@ -558,6 +559,7 @@ static int bitmap_read_sb(struct bitmap *bitmap)  	unsigned long sectors_reserved = 0;  	int err = -EINVAL;  	struct page *sb_page; +	loff_t offset = bitmap->mddev->bitmap_info.offset;  	if (!bitmap->storage.file && !bitmap->mddev->bitmap_info.offset) {  		chunksize = 128 * 1024 * 1024; @@ -584,9 +586,9 @@ re_read:  		bm_blocks = ((bm_blocks+7) >> 3) + sizeof(bitmap_super_t);  		/* to 4k blocks */  		bm_blocks = DIV_ROUND_UP_SECTOR_T(bm_blocks, 4096); -		bitmap->mddev->bitmap_info.offset += bitmap->cluster_slot * (bm_blocks << 3); +		offset = bitmap->mddev->bitmap_info.offset + (bitmap->cluster_slot * (bm_blocks << 3));  		pr_info("%s:%d bm slot: %d offset: %llu\n", __func__, __LINE__, -			bitmap->cluster_slot, (unsigned long long)bitmap->mddev->bitmap_info.offset); +			bitmap->cluster_slot, offset);  	}  	if (bitmap->storage.file) { @@ -597,7 +599,7 @@ re_read:  				bitmap, bytes, sb_page);  	} else {  		err = read_sb_page(bitmap->mddev, -				   bitmap->mddev->bitmap_info.offset, +				   offset,  				   sb_page,  				   0, sizeof(bitmap_super_t));  	} @@ -611,8 +613,16 @@ re_read:  	daemon_sleep = le32_to_cpu(sb->daemon_sleep) * HZ;  	write_behind = le32_to_cpu(sb->write_behind);  	sectors_reserved = le32_to_cpu(sb->sectors_reserved); -	nodes = le32_to_cpu(sb->nodes); -	strlcpy(bitmap->mddev->bitmap_info.cluster_name, sb->cluster_name, 64); +	/* XXX: This is a hack to ensure that we don't use clustering +	 *  in case: +	 *	- dm-raid is in use and +	 *	- the nodes written in bitmap_sb is erroneous. +	 */ +	if (!bitmap->mddev->sync_super) { +		nodes = le32_to_cpu(sb->nodes); +		strlcpy(bitmap->mddev->bitmap_info.cluster_name, +				sb->cluster_name, 64); +	}  	/* verify that the bitmap-specific fields are valid */  	if (sb->magic != cpu_to_le32(BITMAP_MAGIC)) @@ -671,7 +681,7 @@ out:  	kunmap_atomic(sb);  	/* Assiging chunksize is required for "re_read" */  	bitmap->mddev->bitmap_info.chunksize = chunksize; -	if (nodes && (bitmap->cluster_slot < 0)) { +	if (err == 0 && nodes && (bitmap->cluster_slot < 0)) {  		err = md_setup_cluster(bitmap->mddev, nodes);  		if (err) {  			pr_err("%s: Could not setup cluster service (%d)\n", @@ -1866,10 +1876,6 @@ int bitmap_copy_from_slot(struct mddev *mddev, int slot,  	if (IS_ERR(bitmap))  		return PTR_ERR(bitmap); -	rv = bitmap_read_sb(bitmap); -	if (rv) -		goto err; -  	rv = bitmap_init_from_disk(bitmap, 0);  	if (rv)  		goto err;  |