[Ocfs2-tools-devel] [PATCH 1/2] o2image: allocate bitmap blocks only for metadata blocks when backing-up

piaojun piaojun at huawei.com
Mon Apr 9 00:15:41 PDT 2018


Hi Joseph,

I have been thinking about striping the malloc from marking bitmap, but
that means a lot of code change as ocfs2_image_mark_bitmap() is called in
many places. And we can hardly calculate the whole bitmap blocks which
metadata need. I'm glad to hear your suggestion.

Thanks,
Jun

On 2018/4/9 11:09, Joseph Qi wrote:
> You malloc map array when marking bitmap and check if it has been
> allocated around. This looks a bit weird.
> 
> Thanks,
> Joseph
> 
> On 18/4/8 09:36, piaojun wrote:
>> Allocate bitmap blocks for all the filesystem blocks will cost lots of
>> memory, e.g. 64T LUN will cost 2G memory. And that will cause OOM when
>> multi-o2image processes run at the same time. We could allocate bitmap
>> blocks only for metadata blocks to save lots of memory.
>>
>> Signed-off-by: Jun Piao <piaojun at huawei.com>
>> ---
>>  include/ocfs2/image.h |  1 -
>>  libocfs2/image.c      | 66 ++++++++-------------------------------------------
>>  o2image/o2image.c     | 15 ++++++++----
>>  3 files changed, 20 insertions(+), 62 deletions(-)
>>
>> diff --git a/include/ocfs2/image.h b/include/ocfs2/image.h
>> index 1acc191..ee4acbc 100644
>> --- a/include/ocfs2/image.h
>> +++ b/include/ocfs2/image.h
>> @@ -77,7 +77,6 @@ struct ocfs2_image_hdr {
>>   */
>>  struct _ocfs2_image_bitmap_arr {
>>  	uint64_t	arr_set_bit_cnt;
>> -	char		*arr_self;
>>  	char    	*arr_map;
>>  };
>>  typedef struct _ocfs2_image_bitmap_arr ocfs2_image_bitmap_arr;
>> diff --git a/libocfs2/image.c b/libocfs2/image.c
>> index 872bdb3..68f4fda 100644
>> --- a/libocfs2/image.c
>> +++ b/libocfs2/image.c
>> @@ -70,8 +70,8 @@ void ocfs2_image_free_bitmap(ocfs2_filesys *ofs)
>>  		return;
>>
>>  	for (i=0; i<ost->ost_bmpblks; i++)
>> -		if (ost->ost_bmparr[i].arr_self)
>> -			ocfs2_free(&ost->ost_bmparr[i].arr_self);
>> +		if (ost->ost_bmparr[i].arr_map)
>> +			ocfs2_free(&ost->ost_bmparr[i].arr_map);
>>
>>  	if (ost->ost_bmparr)
>>  		ocfs2_free(&ost->ost_bmparr);
>> @@ -85,11 +85,9 @@ void ocfs2_image_free_bitmap(ocfs2_filesys *ofs)
>>   */
>>  errcode_t ocfs2_image_alloc_bitmap(ocfs2_filesys *ofs)
>>  {
>> -	uint64_t blks, allocsize, leftsize;
>> +	uint64_t blks;
>>  	struct ocfs2_image_state *ost = ofs->ost;
>> -	int indx, i, n;
>>  	errcode_t ret;
>> -	char *buf;
>>
>>  	ost->ost_bmpblks =
>>  		((ost->ost_fsblkcnt - 1) / (OCFS2_IMAGE_BITS_IN_BLOCK)) + 1;
>> @@ -99,56 +97,6 @@ errcode_t ocfs2_image_alloc_bitmap(ocfs2_filesys *ofs)
>>  	/* allocate memory for an array to track bitmap blocks */
>>  	ret = ocfs2_malloc0((blks * sizeof(ocfs2_image_bitmap_arr)),
>>  			    &ost->ost_bmparr);
>> -	if (ret)
>> -		return ret;
>> -
>> -	allocsize = blks * OCFS2_IMAGE_BITMAP_BLOCKSIZE;
>> -	leftsize = allocsize;
>> -	indx = 0;
>> -
>> -	/* allocate bitmap blocks and assign blocks to above array */
>> -	while (leftsize) {
>> -		ret = ocfs2_malloc_blocks(ofs->fs_io,
>> -					  allocsize/io_get_blksize(ofs->fs_io),
>> -					  &buf);
>> -		if (ret && (ret != -ENOMEM))
>> -			goto out;
>> -
>> -		if (ret == -ENOMEM) {
>> -			if (allocsize == OCFS2_IMAGE_BITMAP_BLOCKSIZE)
>> -				goto out;
>> -			allocsize >>= 1;
>> -			if (allocsize % OCFS2_IMAGE_BITMAP_BLOCKSIZE) {
>> -				allocsize /= OCFS2_IMAGE_BITMAP_BLOCKSIZE;
>> -				allocsize *= OCFS2_IMAGE_BITMAP_BLOCKSIZE;
>> -			}
>> -			continue;
>> -		}
>> -
>> -		n = allocsize / OCFS2_IMAGE_BITMAP_BLOCKSIZE;
>> -		for (i = 0; i < n; i++) {
>> -			ost->ost_bmparr[indx].arr_set_bit_cnt = 0;
>> -			ost->ost_bmparr[indx].arr_map =
>> -				((char *)buf + (i *
>> -						OCFS2_IMAGE_BITMAP_BLOCKSIZE));
>> -
>> -			/* remember buf address to free it later */
>> -			if (!i)
>> -				ost->ost_bmparr[indx].arr_self = buf;
>> -			indx++;
>> -		}
>> -		leftsize -= allocsize;
>> -		if (leftsize <= allocsize)
>> -			allocsize = leftsize;
>> -	}
>> -out:
>> -	/* If allocation failed free and return error */
>> -	if (leftsize) {
>> -		for (i = 0; i < indx; i++)
>> -			if (ost->ost_bmparr[i].arr_self)
>> -				ocfs2_free(&ost->ost_bmparr[i].arr_self);
>> -		ocfs2_free(&ost->ost_bmparr);
>> -	}
>>
>>  	return ret;
>>  }
>> @@ -251,6 +199,11 @@ void ocfs2_image_mark_bitmap(ocfs2_filesys *ofs, uint64_t blkno)
>>  	bit = blkno % OCFS2_IMAGE_BITS_IN_BLOCK;
>>  	bitmap_blk = blkno / OCFS2_IMAGE_BITS_IN_BLOCK;
>>
>> +	if (!ost->ost_bmparr[bitmap_blk].arr_map) {
>> +		ocfs2_malloc0(ost->ost_bmpblksz,
>> +				   &ost->ost_bmparr[bitmap_blk].arr_map);
>> +	}
>> +
>>  	ocfs2_set_bit(bit, ost->ost_bmparr[bitmap_blk].arr_map);
>>  }
>>
>> @@ -263,7 +216,8 @@ int ocfs2_image_test_bit(ocfs2_filesys *ofs, uint64_t blkno)
>>  	bit = blkno % OCFS2_IMAGE_BITS_IN_BLOCK;
>>  	bitmap_blk = blkno / OCFS2_IMAGE_BITS_IN_BLOCK;
>>
>> -	if (ocfs2_test_bit(bit, ost->ost_bmparr[bitmap_blk].arr_map))
>> +	if (ost->ost_bmparr[bitmap_blk].arr_map &&
>> +			   ocfs2_test_bit(bit, ost->ost_bmparr[bitmap_blk].arr_map))
>>  		return 1;
>>  	else
>>  		return 0;
>> diff --git a/o2image/o2image.c b/o2image/o2image.c
>> index 1dd16ed..15e0d2d 100644
>> --- a/o2image/o2image.c
>> +++ b/o2image/o2image.c
>> @@ -602,8 +602,11 @@ static errcode_t write_image_file(ocfs2_filesys *ofs, int fd)
>>  	}
>>  	/* write bitmap blocks at the end */
>>  	for(blk = 0; blk < ost->ost_bmpblks; blk++) {
>> -		bytes = write(fd, ost->ost_bmparr[blk].arr_map,
>> -			      ost->ost_bmpblksz);
>> +		if (ost->ost_bmparr[blk].arr_map)
>> +			bytes = write(fd, ost->ost_bmparr[blk].arr_map,
>> +				      ost->ost_bmpblksz);
>> +		else
>> +			lseek(fd, ost->ost_bmpblksz, SEEK_CUR);
>>  		if ((bytes == -1) || (bytes < ost->ost_bmpblksz)) {
>>  			com_err(program_name, errno, "error writing bitmap "
>>  				"blk %"PRIu64" bytes %u", blk, bytes);
>> @@ -637,9 +640,11 @@ static errcode_t scan_raw_disk(ocfs2_filesys *ofs)
>>  	/* update set_bit_cnt for future use */
>>  	for (i = 0; i < ost->ost_bmpblks; i++) {
>>  		ost->ost_bmparr[i].arr_set_bit_cnt = bits_set;
>> -		for (j = 0; j < (ost->ost_bmpblksz * 8); j++)
>> -			if (ocfs2_test_bit(j, ost->ost_bmparr[i].arr_map))
>> -				bits_set++;
>> +		if (ost->ost_bmparr[i].arr_map) {
>> +			for (j = 0; j < (ost->ost_bmpblksz * 8); j++)
>> +				if (ocfs2_test_bit(j, ost->ost_bmparr[i].arr_map))
>> +					bits_set++;
>> +		}
>>  	}
>>
>>  out:
>>
> .
> 



More information about the Ocfs2-tools-devel mailing list