From: levin li <xingke.lwp at taobao.com> VDI deletion work should response to client until all the objects have been deleted just as what file system does, this patch makes it call req_done to send back a response until deletion_one_done() has been called. Signed-off-by: levin li <xingke.lwp at taobao.com> --- sheep/group.c | 1 + sheep/ops.c | 2 +- sheep/sdnet.c | 3 +++ sheep/sheep_priv.h | 5 +++-- sheep/vdi.c | 16 +++++++++++----- 5 files changed, 19 insertions(+), 8 deletions(-) diff --git a/sheep/group.c b/sheep/group.c index 429ef67..3f430ac 100644 --- a/sheep/group.c +++ b/sheep/group.c @@ -903,6 +903,7 @@ void sd_notify_handler(struct sd_node *sender, void *data, size_t data_len) if (has_process_main(req->op)) memcpy(req->data, msg->data, msg->rsp.data_length); memcpy(&req->rp, &msg->rsp, sizeof(req->rp)); + req_done(req); } } diff --git a/sheep/ops.c b/sheep/ops.c index f055da2..6a00719 100644 --- a/sheep/ops.c +++ b/sheep/ops.c @@ -141,7 +141,7 @@ static int cluster_del_vdi(struct request *req) uint32_t vid = 0, nr_copies = sys->nr_copies; int ret; - ret = del_vdi(req->data, hdr->data_length, + ret = del_vdi(req, req->data, hdr->data_length, &vid, hdr->vdi.snapid, &nr_copies); if (sys->enable_write_cache && ret == SD_RES_SUCCESS) diff --git a/sheep/sdnet.c b/sheep/sdnet.c index 85ac02f..917e89d 100644 --- a/sheep/sdnet.c +++ b/sheep/sdnet.c @@ -476,6 +476,9 @@ void req_done(struct request *req) struct client_info *ci = req->ci; eventfd_t value = 1; + if (req->refcnt-- > 0) + return; + if (req->local) { req->done = 1; sys->nr_outstanding_reqs--; diff --git a/sheep/sheep_priv.h b/sheep/sheep_priv.h index d10d8e2..05b44c9 100644 --- a/sheep/sheep_priv.h +++ b/sheep/sheep_priv.h @@ -73,6 +73,7 @@ struct request { struct list_head request_list; struct list_head pending_list; + int refcnt; int local; int done; int wait_efd; @@ -211,8 +212,8 @@ int init_base_path(const char *dir); int add_vdi(char *data, int data_len, uint64_t size, uint32_t *new_vid, uint32_t base_vid, int is_snapshot, unsigned int *nr_copies); -int del_vdi(char *data, int data_len, uint32_t *vid, uint32_t snapid, - unsigned int *nr_copies); +int del_vdi(struct request *req, char *data, int data_len, uint32_t *vid, + uint32_t snapid, unsigned int *nr_copies); int lookup_vdi(char *name, char *tag, uint32_t *vid, uint32_t snapid, unsigned int *nr_copies, uint64_t *ctime); diff --git a/sheep/vdi.c b/sheep/vdi.c index 4a0d165..5063380 100644 --- a/sheep/vdi.c +++ b/sheep/vdi.c @@ -305,10 +305,10 @@ int add_vdi(char *data, int data_len, uint64_t size, uint32_t *new_vid, cur_vid, next_snapid, is_snapshot); } -static int start_deletion(uint32_t vid); +static int start_deletion(struct request *req, uint32_t vid); -int del_vdi(char *data, int data_len, uint32_t *vid, uint32_t snapid, - unsigned int *nr_copies) +int del_vdi(struct request *req, char *data, int data_len, + uint32_t *vid, uint32_t snapid, unsigned int *nr_copies) { char *name = data, *tag; uint32_t dummy0; @@ -330,7 +330,7 @@ int del_vdi(char *data, int data_len, uint32_t *vid, uint32_t snapid, if (ret != SD_RES_SUCCESS) goto out; - ret = start_deletion(*vid); + ret = start_deletion(req, *vid); out: return ret; } @@ -351,6 +351,7 @@ struct deletion_work { struct work work; struct list_head dw_siblings; + struct request *req; uint32_t vid; @@ -454,6 +455,7 @@ out: static void delete_one_done(struct work *work) { struct deletion_work *dw = container_of(work, struct deletion_work, work); + struct request *req = dw->req; dw->done++; if (dw->done < dw->count) { @@ -463,6 +465,8 @@ static void delete_one_done(struct work *work) list_del(&dw->dw_siblings); + req_done(req); + free(dw->buf); free(dw); @@ -561,7 +565,7 @@ out: return vid; } -static int start_deletion(uint32_t vid) +static int start_deletion(struct request *req, uint32_t vid) { struct deletion_work *dw = NULL; int ret = SD_RES_NO_MEM, cloned; @@ -578,6 +582,7 @@ static int start_deletion(uint32_t vid) dw->count = 0; dw->vid = vid; + dw->req = req; dw->work.fn = delete_one; dw->work.done = delete_one_done; @@ -614,6 +619,7 @@ static int start_deletion(uint32_t vid) goto out; } + req->refcnt++; list_add_tail(&dw->dw_siblings, &deletion_work_list); queue_work(sys->deletion_wqueue, &dw->work); out: -- 1.7.10 |