[sheepdog] [PATCH] sheep: make 'collie vdi delete' wait for response synchronously

levin li levin108 at gmail.com
Wed Jun 27 09:24:58 CEST 2012


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




More information about the sheepdog mailing list