From: levin li <xingke.lwp at taobao.com> When deleting a cloned vdi, sheep find the root vdi and then traverse the vdi chain(such as base --> snapshot --> clone) to check wheter there's an undeleted vdi in the chain, if some vdi in the chain isn't deleted, sheep just mark the cloned vdi as deleted by clear its vdi name. But in fact a cloned vdi may created its own objects by copy-on-write, these objects can be deleted when deleting the vdi, so we make the cloned vdi to be deleted as the root vdi, then we can deleting its data objects, in delete_one() we check whether the object belongs to itself to determine whether to delete the object. Signed-off-by: levin li <xingke.lwp at taobao.com> --- sheep/vdi.c | 14 ++++++++++++++ 1 files changed, 14 insertions(+), 0 deletions(-) diff --git a/sheep/vdi.c b/sheep/vdi.c index d2a522d..c8085c8 100644 --- a/sheep/vdi.c +++ b/sheep/vdi.c @@ -478,6 +478,12 @@ static void delete_one(struct work *work) if (!inode->data_vdi_id[i]) continue; + if (inode->data_vdi_id[i] != inode->vdi_id) { + dprintf("object %" PRIx64 " is base's data, would not be deleted.\n", + vid_to_data_oid(inode->data_vdi_id[i], i)); + continue; + } + ret = remove_object(dw->entries, dw->nr_vnodes, dw->nr_zones, dw->epoch, vid_to_data_oid(inode->data_vdi_id[i], i), inode->nr_copies); @@ -587,6 +593,14 @@ next: vid_to_vdi_oid(vid), (char *)inode, SD_INODE_HEADER_SIZE, 0, sys->nr_sobjs); + if (vid == inode->vdi_id && inode->snap_id == 1 + && inode->parent_vdi_id != 0 + && !inode->snap_ctime) { + dprintf("vdi %" PRIx32 " is a cloned vdi.\n", vid); + /* current vdi is a cloned vdi */ + goto out; + } + if (ret != SD_RES_SUCCESS) { eprintf("cannot find VDI object\n"); vid = 0; -- 1.7.1 |