[Sheepdog] [PATCH 2/2] fix a bug of deleting base vdi fail

levin li levin108 at gmail.com
Mon May 7 07:45:32 CEST 2012


Take a view of the following snapshot tree:

base vdi --> snapshot vdi --> cloned vdi

when cloned vdi has its own data objects created by copy-on-write,
we firstly delete the cloned VDI, then delete the base VDI, at last
we delete snapshot VDI, the the snapshot VDI would delete fail in this
case because in the old code, I try to delete all the VDIs from the
VDI tree, but the base VDI and the cloned VDI have beed deleted,
and it causes an error which finally cause snapshot VDI delete fail.

This patch is another version of my previous one which is here:
http://lists.wpkg.org/pipermail/sheepdog/2012-May/003332.html

I simplely reset the delete_error flag, as Kazutaka mentions, it's
not good to do this, but we should never try to delete the VDIs
already deleted again, so I mark an VDI as deeply deleted by clearing
its name and size, which means the VDI and it data objects have already
been deleted, then in the next deletion work, we can just ignore these
VDIs. If the data objects haven't been deleted, then we just clear its
name to mark it as deleted, next time, we can try to delete its data
objects.

Signed-off-by: levin li <xingke.lwp at taobao.com>
---
 sheep/vdi.c |   14 ++++++++++----
 1 file changed, 10 insertions(+), 4 deletions(-)

diff --git a/sheep/vdi.c b/sheep/vdi.c
index cd6b557..445aeda 100644
--- a/sheep/vdi.c
+++ b/sheep/vdi.c
@@ -391,7 +391,7 @@ struct deletion_work {
 
 static LIST_HEAD(deletion_work_list);
 
-static int delete_inode(struct deletion_work *dw)
+static int delete_inode(struct deletion_work *dw, int objs_deleted)
 {
 	struct sheepdog_inode *inode = NULL;
 	int ret = SD_RES_SUCCESS;
@@ -414,8 +414,11 @@ static int delete_inode(struct deletion_work *dw)
 
 	if (dw->delete_error)
 		inode->vdi_size = 0;
-	else
+	else {
 		memset(inode->name, 0, sizeof(inode->name));
+		if (objs_deleted)
+			inode->vdi_size = 0;
+	}
 
 	ret = write_object(dw->vnodes, dw->epoch, vid_to_vdi_oid(dw->vid),
 			   (char *)inode, SD_INODE_HEADER_SIZE, 0, 0,
@@ -458,6 +461,9 @@ static void delete_one(struct work *work)
 		goto out;
 	}
 
+	if (inode->vdi_size == 0 && inode->name[0] == '\0')
+		goto out;
+
 	for (i = 0; i < MAX_DATA_OBJS; i++) {
 		if (!inode->data_vdi_id[i])
 			continue;
@@ -497,7 +503,7 @@ static void delete_one_done(struct work *work)
 		return;
 	}
 
-	delete_inode(dw);
+	delete_inode(dw, 1);
 
 	list_del(&dw->dw_siblings);
 
@@ -647,7 +653,7 @@ int start_deletion(uint32_t vid, uint32_t epoch)
 			dprintf("snapshot chain has valid vdi, "
 				"just mark vdi %" PRIx32 " as deleted.\n",
 				dw->vid);
-			delete_inode(dw);
+			delete_inode(dw, 0);
 			return SD_RES_SUCCESS;
 		}
 	}
-- 
1.7.10




More information about the sheepdog mailing list