Skip to content

Commit

Permalink
sheepdog: always use coroutine-based network functions
Browse files Browse the repository at this point in the history
This reduces some code duplication.

Signed-off-by: MORITA Kazutaka <morita.kazutaka@lab.ntt.co.jp>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
  • Loading branch information
kazum authored and kevmw committed Jul 17, 2012
1 parent 8361710 commit cddd4ac
Showing 1 changed file with 47 additions and 66 deletions.
113 changes: 47 additions & 66 deletions block/sheepdog.c
Original file line number Diff line number Diff line change
Expand Up @@ -498,26 +498,6 @@ static int connect_to_sdog(const char *addr, const char *port)
return fd;
}

static int send_req(int sockfd, SheepdogReq *hdr, void *data,
unsigned int *wlen)
{
int ret;

ret = qemu_send_full(sockfd, hdr, sizeof(*hdr), 0);
if (ret < sizeof(*hdr)) {
error_report("failed to send a req, %s", strerror(errno));
return -errno;
}

ret = qemu_send_full(sockfd, data, *wlen, 0);
if (ret < *wlen) {
error_report("failed to send a req, %s", strerror(errno));
ret = -errno;
}

return ret;
}

static coroutine_fn int send_co_req(int sockfd, SheepdogReq *hdr, void *data,
unsigned int *wlen)
{
Expand All @@ -537,61 +517,33 @@ static coroutine_fn int send_co_req(int sockfd, SheepdogReq *hdr, void *data,
return ret;
}

static coroutine_fn int do_co_req(int sockfd, SheepdogReq *hdr, void *data,
unsigned int *wlen, unsigned int *rlen);

static int do_req(int sockfd, SheepdogReq *hdr, void *data,
unsigned int *wlen, unsigned int *rlen)
{
int ret;

if (qemu_in_coroutine()) {
return do_co_req(sockfd, hdr, data, wlen, rlen);
}

socket_set_block(sockfd);
ret = send_req(sockfd, hdr, data, wlen);
if (ret < 0) {
goto out;
}

ret = qemu_recv_full(sockfd, hdr, sizeof(*hdr), 0);
if (ret < sizeof(*hdr)) {
error_report("failed to get a rsp, %s", strerror(errno));
ret = -errno;
goto out;
}

if (*rlen > hdr->data_length) {
*rlen = hdr->data_length;
}

if (*rlen) {
ret = qemu_recv_full(sockfd, data, *rlen, 0);
if (ret < *rlen) {
error_report("failed to get the data, %s", strerror(errno));
ret = -errno;
goto out;
}
}
ret = 0;
out:
socket_set_nonblock(sockfd);
return ret;
}

static void restart_co_req(void *opaque)
{
Coroutine *co = opaque;

qemu_coroutine_enter(co, NULL);
}

static coroutine_fn int do_co_req(int sockfd, SheepdogReq *hdr, void *data,
unsigned int *wlen, unsigned int *rlen)
typedef struct SheepdogReqCo {
int sockfd;
SheepdogReq *hdr;
void *data;
unsigned int *wlen;
unsigned int *rlen;
int ret;
bool finished;
} SheepdogReqCo;

static coroutine_fn void do_co_req(void *opaque)
{
int ret;
Coroutine *co;
SheepdogReqCo *srco = opaque;
int sockfd = srco->sockfd;
SheepdogReq *hdr = srco->hdr;
void *data = srco->data;
unsigned int *wlen = srco->wlen;
unsigned int *rlen = srco->rlen;

co = qemu_coroutine_self();
qemu_aio_set_fd_handler(sockfd, NULL, restart_co_req, NULL, co);
Expand Down Expand Up @@ -627,7 +579,36 @@ static coroutine_fn int do_co_req(int sockfd, SheepdogReq *hdr, void *data,
out:
qemu_aio_set_fd_handler(sockfd, NULL, NULL, NULL, NULL);
socket_set_nonblock(sockfd);
return ret;

srco->ret = ret;
srco->finished = true;
}

static int do_req(int sockfd, SheepdogReq *hdr, void *data,
unsigned int *wlen, unsigned int *rlen)
{
Coroutine *co;
SheepdogReqCo srco = {
.sockfd = sockfd,
.hdr = hdr,
.data = data,
.wlen = wlen,
.rlen = rlen,
.ret = 0,
.finished = false,
};

if (qemu_in_coroutine()) {
do_co_req(&srco);
} else {
co = qemu_coroutine_create(do_co_req);
qemu_coroutine_enter(co, &srco);
while (!srco.finished) {
qemu_aio_wait();
}
}

return srco.ret;
}

static int coroutine_fn add_aio_request(BDRVSheepdogState *s, AIOReq *aio_req,
Expand Down

0 comments on commit cddd4ac

Please sign in to comment.