From: levin li <xingke.lwp at taobao.com> this patch is based on my previous patch set: http://lists.wpkg.org/pipermail/sheepdog/2012-June/004843.html -------------------------------------------------------------- >8 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 | 6 +++++- sheep/ops.c | 4 ++-- sheep/sdnet.c | 1 + sheep/sheep_priv.h | 8 +++++--- sheep/vdi.c | 24 ++++++++++++++++-------- 5 files changed, 29 insertions(+), 14 deletions(-) diff --git a/sheep/group.c b/sheep/group.c index d3f7c49..e951f6e 100644 --- a/sheep/group.c +++ b/sheep/group.c @@ -898,7 +898,10 @@ 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); + + req->done = 1; + if (list_empty(&req->blocking_list)) + req_done(req); } } @@ -1160,6 +1163,7 @@ int create_cluster(int port, int64_t zone, int nr_vnodes, INIT_LIST_HEAD(&sys->delayed_nodes); INIT_LIST_HEAD(&sys->blocking_conn_list); + INIT_LIST_HEAD(&sys->blocking_req_list); INIT_LIST_HEAD(&sys->wait_req_queue); INIT_LIST_HEAD(&sys->wait_rw_queue); diff --git a/sheep/ops.c b/sheep/ops.c index 6bdcc83..122ba63 100644 --- a/sheep/ops.c +++ b/sheep/ops.c @@ -141,8 +141,8 @@ static int cluster_del_vdi(struct request *req) uint32_t vid = 0, nr_copies = sys->nr_copies; int ret; - ret = del_vdi(req->vnodes, hdr->epoch, req->data, hdr->data_length, - &vid, hdr->vdi.snapid, &nr_copies); + ret = del_vdi(req, req->vnodes, hdr->epoch, req->data, + hdr->data_length, &vid, hdr->vdi.snapid, &nr_copies); if (sys->enable_write_cache && ret == SD_RES_SUCCESS) object_cache_delete(vid); diff --git a/sheep/sdnet.c b/sheep/sdnet.c index 1060e8d..182b384 100644 --- a/sheep/sdnet.c +++ b/sheep/sdnet.c @@ -454,6 +454,7 @@ static struct request *alloc_request(struct client_info *ci, int data_length) } INIT_LIST_HEAD(&req->request_list); + INIT_LIST_HEAD(&req->blocking_list); sys->nr_outstanding_reqs++; sys->outstanding_data_size += data_length; diff --git a/sheep/sheep_priv.h b/sheep/sheep_priv.h index 75d468b..2a01c04 100644 --- a/sheep/sheep_priv.h +++ b/sheep/sheep_priv.h @@ -72,6 +72,7 @@ struct request { struct client_info *ci; struct list_head request_list; struct list_head pending_list; + struct list_head blocking_list; int local; int done; @@ -117,6 +118,7 @@ struct cluster_info { DECLARE_BITMAP(vdi_inuse, SD_NR_VDIS); struct list_head blocking_conn_list; + struct list_head blocking_req_list; int nr_copies; int req_efd; @@ -213,9 +215,9 @@ int add_vdi(struct vnode_info *vnode_info, uint32_t epoch, char *data, uint32_t base_vid, uint32_t copies, int is_snapshot, unsigned int *nr_copies); -int del_vdi(struct vnode_info *vnode_info, uint32_t epoch, char *data, - int data_len, uint32_t *vid, uint32_t snapid, - unsigned int *nr_copies); +int del_vdi(struct request *req, struct vnode_info *vnode_info, + uint32_t epoch, char *data, int data_len, uint32_t *vid, + uint32_t snapid, unsigned int *nr_copies); int lookup_vdi(struct vnode_info *vnode_info, uint32_t epoch, char *name, char *tag, uint32_t *vid, uint32_t snapid, diff --git a/sheep/vdi.c b/sheep/vdi.c index db046c4..61418db 100644 --- a/sheep/vdi.c +++ b/sheep/vdi.c @@ -326,12 +326,12 @@ int add_vdi(struct vnode_info *vnode_info, uint32_t epoch, char *data, is_snapshot); } -static int start_deletion(struct vnode_info *vnode_info, uint32_t vid, - uint32_t epoch); +static int start_deletion(struct request *req, struct vnode_info *vnode_info, + uint32_t vid, uint32_t epoch); -int del_vdi(struct vnode_info *vnode_info, uint32_t epoch, char *data, - int data_len, uint32_t *vid, uint32_t snapid, - unsigned int *nr_copies) +int del_vdi(struct request *req, struct vnode_info *vnode_info, + uint32_t epoch, char *data, int data_len, uint32_t *vid, + uint32_t snapid, unsigned int *nr_copies) { char *name = data, *tag; uint32_t dummy0; @@ -352,7 +352,7 @@ int del_vdi(struct vnode_info *vnode_info, uint32_t epoch, char *data, if (ret != SD_RES_SUCCESS) goto out; - ret = start_deletion(vnode_info, *vid, epoch); + ret = start_deletion(req, vnode_info, *vid, epoch); out: return ret; } @@ -374,6 +374,7 @@ struct deletion_work { struct work work; struct list_head dw_siblings; + struct request *req; uint32_t vid; @@ -486,6 +487,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) { @@ -495,6 +497,10 @@ static void delete_one_done(struct work *work) list_del(&dw->dw_siblings); + list_del_init(&req->blocking_list); + if (req->done) + req_done(req); + put_vnode_info(dw->vnodes); free(dw->buf); free(dw); @@ -599,8 +605,8 @@ out: return vid; } -static int start_deletion(struct vnode_info *vnode_info, uint32_t vid, - uint32_t epoch) +static int start_deletion(struct request *req, struct vnode_info *vnode_info, + uint32_t vid, uint32_t epoch) { struct deletion_work *dw = NULL; int ret = SD_RES_NO_MEM, cloned; @@ -618,6 +624,7 @@ static int start_deletion(struct vnode_info *vnode_info, uint32_t vid, dw->count = 0; dw->vid = vid; dw->epoch = epoch; + dw->req = req; dw->work.fn = delete_one; dw->work.done = delete_one_done; @@ -662,6 +669,7 @@ static int start_deletion(struct vnode_info *vnode_info, uint32_t vid, goto out; } + list_add_tail(&req->blocking_list, &sys->blocking_req_list); list_add_tail(&dw->dw_siblings, &deletion_work_list); queue_work(sys->deletion_wqueue, &dw->work); out: -- 1.7.10 |