[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