[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