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 |