[Sheepdog] [PATCH] sheep: fix a cluster request race

MORITA Kazutaka morita.kazutaka at lab.ntt.co.jp
Fri Oct 21 03:01:57 CEST 2011


We must process all the cluster requests in cpg_work_queue.  Otherwise
req_done() may be called before __done(), which causes segmentation
fault because the request is freed in req_done().

Signed-off-by: MORITA Kazutaka <morita.kazutaka at lab.ntt.co.jp>
---
 sheep/group.c      |    5 ++++-
 sheep/sdnet.c      |   33 +++++++++++++++++++++++----------
 sheep/sheep_priv.h |    1 +
 3 files changed, 28 insertions(+), 11 deletions(-)

diff --git a/sheep/group.c b/sheep/group.c
index d4af9ec..2f6c4e5 100644
--- a/sheep/group.c
+++ b/sheep/group.c
@@ -1281,7 +1281,10 @@ do_retry:
 				}
 			}
 		}
-		if (req->rq.flags & SD_FLAG_CMD_DIRECT)
+
+		if (is_cluster_request(req->rq.opcode))
+			queue_work(sys->cpg_wqueue, &req->work);
+		else if (req->rq.flags & SD_FLAG_CMD_DIRECT)
 			queue_work(sys->io_wqueue, &req->work);
 		else
 			queue_work(sys->gateway_wqueue, &req->work);
diff --git a/sheep/sdnet.c b/sheep/sdnet.c
index eb375cb..817df84 100644
--- a/sheep/sdnet.c
+++ b/sheep/sdnet.c
@@ -37,6 +37,28 @@ int is_io_request(unsigned op)
 	return ret;
 }
 
+int is_cluster_request(unsigned op)
+{
+	int ret = 0;
+
+	switch (op) {
+	case SD_OP_NEW_VDI:
+	case SD_OP_DEL_VDI:
+	case SD_OP_LOCK_VDI:
+	case SD_OP_RELEASE_VDI:
+	case SD_OP_GET_VDI_INFO:
+	case SD_OP_MAKE_FS:
+	case SD_OP_SHUTDOWN:
+	case SD_OP_GET_VDI_ATTR:
+		ret = 1;
+		break;
+	default:
+		break;
+	}
+
+	return ret;
+}
+
 void resume_pending_requests(void)
 {
 	struct request *next, *tmp;
@@ -104,18 +126,9 @@ static void __done(struct work *work, int idx)
 	if (copies > req->nr_zones)
 		copies = req->nr_zones;
 
-	switch (hdr->opcode) {
-	case SD_OP_NEW_VDI:
-	case SD_OP_DEL_VDI:
-	case SD_OP_LOCK_VDI:
-	case SD_OP_RELEASE_VDI:
-	case SD_OP_GET_VDI_INFO:
-	case SD_OP_MAKE_FS:
-	case SD_OP_SHUTDOWN:
-	case SD_OP_GET_VDI_ATTR:
+	if (is_cluster_request(hdr->opcode))
 		/* request is forwarded to cpg group */
 		return;
-	}
 
 	if (is_io_request(hdr->opcode)) {
 		struct cpg_event *cevent = &req->cev;
diff --git a/sheep/sheep_priv.h b/sheep/sheep_priv.h
index 1f0d265..65bc3aa 100644
--- a/sheep/sheep_priv.h
+++ b/sheep/sheep_priv.h
@@ -153,6 +153,7 @@ extern struct cluster_info *sys;
 int create_listen_port(int port, void *data);
 
 int is_io_request(unsigned op);
+int is_cluster_request(unsigned op);
 int init_store(const char *dir);
 int init_base_path(const char *dir);
 
-- 
1.7.2.5




More information about the sheepdog mailing list