[Sheepdog] [PATCH 1/2] traverse the VDI tree before delete cloned VDI

levin li levin108 at gmail.com
Fri May 11 07:51:46 CEST 2012


On 05/07/2012 01:45 PM, levin li wrote:
> Even if the VDI is a cloned VDI (not the VDI just created
> by 'clone' operation, but the cloned VDI on the leaf node
> of the VDI tree), we also should traverse the vdi tree from
> the root VDI.
>
> But if there's a VDI not deleted in the tree path, and the
> VDI to delete is a cloned VDI, we should delete it's data
> objects so as to save disk space. If all the VDIs have been
> deleted in the tree path, then we traverse the path to delete
> all the objects of the VDIs.
>
> I'd like to explain again why we need to deleted the objects
> created by copy-on-write when we try to delete a cloned VDI,
> in the old logic, objects of cloned VDI can only be deleted
> after all the VDI in the tree path has been deleted, but there's
> a problem, we may clone many VDIs from one snapshot, and these
> VDIs can be deleted frequently, but we may always not delete the
> snapshot VDI, so in this case, objects of cloned VDI would
> always stay in the disk, as we know, they're already useless
> and should be deleted, and waste too much disk space, but we can
> only make it deleted after all the VDI in the tree path, including
> the snapshot VDI have beed deleted, it's really not good.
>
> Signed-off-by: levin li<xingke.lwp at taobao.com>
> ---
>   sheep/vdi.c |   26 ++++++++++++++++++--------
>   1 file changed, 18 insertions(+), 8 deletions(-)
>
> diff --git a/sheep/vdi.c b/sheep/vdi.c
> index 5b96dbb..cd6b557 100644
> --- a/sheep/vdi.c
> +++ b/sheep/vdi.c
> @@ -562,12 +562,14 @@ out:
>   }
>
>   static uint64_t get_vdi_root(struct vnode_info *vnode_info, uint32_t epoch,
> -		uint32_t vid)
> +		uint32_t vid, int *cloned)
>   {
>   	int ret;
>   	struct sheepdog_inode *inode = NULL;
>   	int nr_copies = get_nr_copies(vnode_info);
>
> +	*cloned = 0;
> +
>   	inode = malloc(SD_INODE_HEADER_SIZE);
>   	if (!inode) {
>   		eprintf("failed to allocate memory\n");
> @@ -583,7 +585,7 @@ next:
>   			&&  !inode->snap_ctime) {
>   		dprintf("vdi %" PRIx32 " is a cloned vdi.\n", vid);
>   		/* current vdi is a cloned vdi */
> -		goto out;
> +		*cloned = 1;
>   	}
>
>   	if (ret != SD_RES_SUCCESS) {
> @@ -607,7 +609,7 @@ out:
>   int start_deletion(uint32_t vid, uint32_t epoch)
>   {
>   	struct deletion_work *dw = NULL;
> -	int ret = SD_RES_NO_MEM;
> +	int ret = SD_RES_NO_MEM, cloned;
>   	uint32_t root_vid;
>
>   	dw = zalloc(sizeof(struct deletion_work));
> @@ -628,7 +630,7 @@ int start_deletion(uint32_t vid, uint32_t epoch)
>
>   	dw->vnodes = get_vnode_info();
>
> -	root_vid = get_vdi_root(dw->vnodes, dw->epoch, dw->vid);
> +	root_vid = get_vdi_root(dw->vnodes, dw->epoch, dw->vid,&cloned);
>   	if (!root_vid) {
>   		ret = SD_RES_EIO;
>   		goto err;
> @@ -636,10 +638,18 @@ int start_deletion(uint32_t vid, uint32_t epoch)
>
>   	ret = fill_vdi_list(dw, root_vid);
>   	if (ret) {
> -		dprintf("snapshot chain has valid vdi, "
> -				"just mark vdi %" PRIx32 " as deleted.\n", dw->vid);
> -		delete_inode(dw);
> -		return SD_RES_SUCCESS;
> +		/* if the VDI is a cloned VDI, delete its objects
> +		 * no matter whether the VDI tree is clear. */
> +		if (cloned) {
> +			dw->buf[0] = vid;
> +			dw->count = 1;
> +		} else {
> +			dprintf("snapshot chain has valid vdi, "
> +				"just mark vdi %" PRIx32 " as deleted.\n",
> +				dw->vid);
> +			delete_inode(dw);
> +			return SD_RES_SUCCESS;
> +		}
>   	}
>
>   	dprintf("%d\n", dw->count);
Any comments to these two patches?
I fix some bugs, and they're critical to VDI deletion.

thanks,

levin



More information about the sheepdog mailing list