[sheepdog] [PATCH v5 1/5] sheep: handle VID overflow correctly

Hitoshi Mitake mitake.hitoshi at gmail.com
Sat May 30 14:30:47 CEST 2015


At Sat, 30 May 2015 18:34:23 +0900,
Hitoshi Mitake wrote:
> 
> Current sheep cannot handle a case of VID overflow correctly. The main
> cause of this problem is invalid usage of fill_vdi_info_range() by
> fill_vdi_info() in a case of overflow. This patch fixes this problem.
> 
> In addition, this patch lets 0x000000 be an invalid VID. It is for VID
> recycling. In some places of sheepdog, parent_vid is used as a
> value which indicates that the VDI has a parent (clone or snapshot) or
> not (working VDI). So this patch lets the first VID 0x000001 and
> prevent this sort of confusion.
> 
> Signed-off-by: Hitoshi Mitake <mitake.hitoshi at lab.ntt.co.jp>
> ---
>  sheep/vdi.c | 24 +++++++++++++++++++-----
>  1 file changed, 19 insertions(+), 5 deletions(-)

Applied this series.

Thanks,
Hitoshi

> 
> diff --git a/sheep/vdi.c b/sheep/vdi.c
> index 63e578d..0505d7d 100644
> --- a/sheep/vdi.c
> +++ b/sheep/vdi.c
> @@ -1345,7 +1345,7 @@ out:
>  /*
>   * Return SUCCESS (range of bits set):
>   * Iff we get a bitmap range [left, right) that VDI might be set between. if
> - * right < start, this means a wrap around case where we should examine the
> + * right < left, this means a wrap around case where we should examine the
>   * two split ranges, [left, SD_NR_VDIS - 1] and [0, right). 'Right' is the free
>   * bit that might be used by newly created VDI.
>   *
> @@ -1356,13 +1356,17 @@ static int get_vdi_bitmap_range(const char *name, unsigned long *left,
>  				unsigned long *right)
>  {
>  	*left = sd_hash_vdi(name);
> +
> +	if (unlikely(!*left))
> +		*left = 1;	/* 0x000000 should be skipeed */
> +
>  	*right = find_next_zero_bit(sys->vdi_inuse, SD_NR_VDIS, *left);
>  	if (*left == *right)
>  		return SD_RES_NO_VDI;
>  
>  	if (*right == SD_NR_VDIS) {
>  		/* Wrap around */
> -		*right = find_next_zero_bit(sys->vdi_inuse, SD_NR_VDIS, 0);
> +		*right = find_next_zero_bit(sys->vdi_inuse, SD_NR_VDIS, 1);
>  		if (*right == SD_NR_VDIS)
>  			return SD_RES_FULL_VDI;
>  	}
> @@ -1404,7 +1408,7 @@ static int fill_vdi_info_range(uint32_t left, uint32_t right,
>  		ret = SD_RES_NO_MEM;
>  		goto out;
>  	}
> -	for (i = right - 1; i >= left; i--) {
> +	for (i = right - 1; i >= left && i; i--) {
>  		ret = sd_read_object(vid_to_vdi_oid(i), (char *)inode,
>  				     SD_INODE_HEADER_SIZE, 0);
>  		if (ret != SD_RES_SUCCESS)
> @@ -1448,14 +1452,24 @@ static int fill_vdi_info(unsigned long left, unsigned long right,
>  {
>  	int ret;
>  
> +	assert(left != right);
> +	/*
> +	 * If left == right, fill_vdi_info() shouldn't called by vdi_lookup().
> +	 * vdi_lookup() must return SD_RES_NO_VDI to its caller.
> +	 */
> +
>  	if (left < right)
>  		return fill_vdi_info_range(left, right, iocb, info);
>  
> -	ret = fill_vdi_info_range(0, right, iocb, info);
> +	if (likely(1 < right))
> +		ret = fill_vdi_info_range(1, right, iocb, info);
> +	else
> +		ret = SD_RES_NO_VDI;
> +
>  	switch (ret) {
>  	case SD_RES_NO_VDI:
>  	case SD_RES_NO_TAG:
> -		ret = fill_vdi_info_range(left, SD_NR_VDIS - 1, iocb, info);
> +		ret = fill_vdi_info_range(left, SD_NR_VDIS, iocb, info);
>  		break;
>  	default:
>  		break;
> -- 
> 1.9.1
> 


More information about the sheepdog mailing list