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

levin li levin108 at gmail.com
Thu Jun 28 04:57:13 CEST 2012


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      |    4 ++++
 sheep/sheep_priv.h |    5 +++--
 sheep/vdi.c        |   16 +++++++++++-----
 5 files changed, 20 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..64b4c7a 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);
+	uatomic_set(&req->refcnt, 1);
 
 	sys->nr_outstanding_reqs++;
 	sys->outstanding_data_size += data_length;
@@ -476,6 +477,9 @@ void req_done(struct request *req)
 	struct client_info *ci = req->ci;
 	eventfd_t value = 1;
 
+	if (uatomic_sub_return(&req->refcnt, 1) > 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..430903f 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;
 	}
 
+	uatomic_inc(&req->refcnt);
 	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