[sheepdog] [PATCH 6/6] sheep: refactor start_deletion

Liu Yuan namei.unix at gmail.com
Sat Apr 27 07:44:22 CEST 2013


From: Liu Yuan <tailai.ly at taobao.com>

- rename dw_siblings as list
- squash vdi_get_root into vdi_fill_list

Signed-off-by: Liu Yuan <tailai.ly at taobao.com>
---
 sheep/vdi.c |  143 +++++++++++++++++++++++++++--------------------------------
 1 file changed, 65 insertions(+), 78 deletions(-)

diff --git a/sheep/vdi.c b/sheep/vdi.c
index df42cff..b1f999c 100644
--- a/sheep/vdi.c
+++ b/sheep/vdi.c
@@ -559,16 +559,13 @@ int read_vdis(char *data, int len, unsigned int *rsp_len)
 }
 
 struct deletion_work {
-	uint32_t done;
-
+	struct list_head list;
 	struct work work;
-	struct list_head dw_siblings;
 	struct request *req;
-
 	uint32_t vid;
-
-	int count;
+	uint32_t done;
 	uint32_t *buf;
+	int count;
 };
 
 static LIST_HEAD(deletion_work_list);
@@ -674,7 +671,7 @@ static void delete_one_done(struct work *work)
 		return;
 	}
 
-	list_del(&dw->dw_siblings);
+	list_del(&dw->list);
 
 	put_request(req);
 
@@ -683,80 +680,96 @@ static void delete_one_done(struct work *work)
 
 	if (!list_empty(&deletion_work_list)) {
 		dw = list_first_entry(&deletion_work_list,
-				      struct deletion_work, dw_siblings);
+				      struct deletion_work, list);
 
 		queue_work(sys->deletion_wqueue, &dw->work);
 	}
 }
 
-static int fill_vdi_list(struct deletion_work *dw, uint32_t root_vid)
+static uint64_t vdi_get_root(uint32_t vid, bool *cloned)
 {
-	int i;
 	struct sd_inode *inode = NULL;
-	int done = dw->count;
-	uint32_t vid;
 
-	dw->buf[dw->count++] = root_vid;
-again:
-	vid = dw->buf[done++];
+	*cloned = false;
+next:
 	inode = vdi_get_inode(vid);
 	if (!inode)
 		return 0;
 
-	if (!vdi_is_deleted(inode) && vid != dw->vid) {
-		free(inode);
-		return 1;
+	if (vid == inode->vdi_id && inode->snap_id == 1
+	    && inode->parent_vdi_id != 0
+	    && !inode->snap_ctime) {
+		sd_dprintf("vdi %" PRIx32 " is a cloned vdi.", vid);
+		*cloned = true;
 	}
 
-	for (i = 0; i < ARRAY_SIZE(inode->child_vdi_id); i++) {
-		if (!inode->child_vdi_id[i])
-			continue;
+	if (!inode->parent_vdi_id)
+		goto out;
 
-		dw->buf[dw->count++] = inode->child_vdi_id[i];
-	}
+	vid = inode->parent_vdi_id;
+	free(inode);
 
+	goto next;
+out:
 	free(inode);
-	if (dw->buf[done])
-		goto again;
-	return 0;
+	return vid;
 }
 
-static uint64_t get_vdi_root(uint32_t vid, bool *cloned)
+static int vdi_fill_list(struct deletion_work *dw)
 {
+	int i;
 	struct sd_inode *inode = NULL;
+	int done = 0;
+	uint32_t vid, root_vid;
+	bool cloned;
 
-	*cloned = false;
-next:
+	root_vid = vdi_get_root(dw->vid, &cloned);
+	if (!root_vid)
+		return SD_RES_EIO;
+
+	dw->buf[dw->count++] = root_vid;
+again:
+	vid = dw->buf[done++];
 	inode = vdi_get_inode(vid);
 	if (!inode)
-		return 0;
+		return SD_RES_EIO;
 
-	if (vid == inode->vdi_id && inode->snap_id == 1
-			&& inode->parent_vdi_id != 0
-			&& !inode->snap_ctime) {
-		sd_dprintf("vdi %" PRIx32 " is a cloned vdi.", vid);
-		/* current vdi is a cloned vdi */
-		*cloned = true;
+	if (!vdi_is_deleted(inode) && vid != dw->vid) {
+		free(inode);
+		if (cloned) {
+			/*
+			 * If the VDI is a cloned VDI, delete its objects no
+			 * matter whether the snapshot chain is valid.
+			 */
+			dw->buf[0] = dw->vid;
+			dw->count = 1;
+			return SD_RES_SUCCESS;
+		}
+		sd_dprintf("snapshot chain has valid vdi, "
+			   "just mark vdi %" PRIx32 " as deleted.", dw->vid);
+		dw->count = 0;
+		return vdi_delete_inode(dw->vid);
 	}
 
-	if (!inode->parent_vdi_id)
-		goto out;
+	for (i = 0; i < ARRAY_SIZE(inode->child_vdi_id); i++) {
+		if (!inode->child_vdi_id[i])
+			continue;
 
-	vid = inode->parent_vdi_id;
-	free(inode);
+		dw->buf[dw->count++] = inode->child_vdi_id[i];
+	}
 
-	goto next;
-out:
 	free(inode);
-	return vid;
+	if (dw->buf[done])
+		/* Check next child */
+		goto again;
+
+	return SD_RES_SUCCESS;
 }
 
 static int start_deletion(struct request *req, uint32_t vid)
 {
 	struct deletion_work *dw = NULL;
 	int ret = SD_RES_NO_MEM;
-	bool cloned;
-	uint32_t root_vid;
 
 	dw = xzalloc(sizeof(struct deletion_work));
 	/* buf is to store vdi id of every object */
@@ -764,52 +777,26 @@ static int start_deletion(struct request *req, uint32_t vid)
 	dw->count = 0;
 	dw->vid = vid;
 	dw->req = req;
-
 	dw->work.fn = delete_one;
 	dw->work.done = delete_one_done;
 
-	root_vid = get_vdi_root(dw->vid, &cloned);
-	if (!root_vid) {
-		ret = SD_RES_EIO;
+	ret = vdi_fill_list(dw);
+	sd_dprintf("%x, %d", ret, dw->count);
+	if (ret != SD_RES_SUCCESS || dw->count == 0)
 		goto err;
-	}
-
-	ret = fill_vdi_list(dw, root_vid);
-	if (ret) {
-		/*
-		 * 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 {
-			sd_dprintf("snapshot chain has valid vdi, "
-				   "just mark vdi %" PRIx32 " as deleted.",
-				   dw->vid);
-			return vdi_delete_inode(dw->vid);
-		}
-	}
-
-	sd_dprintf("%d", dw->count);
-
-	if (dw->count == 0)
-		goto out;
 
 	uatomic_inc(&req->refcnt);
 
 	if (list_empty(&deletion_work_list)) {
-		list_add_tail(&dw->dw_siblings, &deletion_work_list);
+		list_add_tail(&dw->list, &deletion_work_list);
 		queue_work(sys->deletion_wqueue, &dw->work);
 	} else
-		list_add_tail(&dw->dw_siblings, &deletion_work_list);
-out:
+		list_add_tail(&dw->list, &deletion_work_list);
+
 	return SD_RES_SUCCESS;
 err:
-	if (dw)
-		free(dw->buf);
+	free(dw->buf);
 	free(dw);
-
 	return ret;
 }
 
-- 
1.7.9.5




More information about the sheepdog mailing list