From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([140.186.70.92]:56134) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1RDCJV-0001zx-BQ for qemu-devel@nongnu.org; Mon, 10 Oct 2011 05:38:26 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1RDCJJ-00011d-Ly for qemu-devel@nongnu.org; Mon, 10 Oct 2011 05:38:25 -0400 Received: from mail-bw0-f45.google.com ([209.85.214.45]:62527) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1RDCJI-0000ux-Mg for qemu-devel@nongnu.org; Mon, 10 Oct 2011 05:38:13 -0400 Received: by mail-bw0-f45.google.com with SMTP id zv15so8235464bkb.4 for ; Mon, 10 Oct 2011 02:38:12 -0700 (PDT) Sender: Paolo Bonzini From: Paolo Bonzini Date: Mon, 10 Oct 2011 11:37:51 +0200 Message-Id: <1318239477-31451-10-git-send-email-pbonzini@redhat.com> In-Reply-To: <1318239477-31451-1-git-send-email-pbonzini@redhat.com> References: <1318239477-31451-1-git-send-email-pbonzini@redhat.com> Subject: [Qemu-devel] [PATCH 09/15] qemu-nbd: introduce NBDRequest List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: qemu-devel@nongnu.org Move the buffer from NBDExport to a new structure, so that it will be possible to have multiple in-flight requests for the same export (and for the same client too---we get that for free). Signed-off-by: Paolo Bonzini --- nbd.c | 65 +++++++++++++++++++++++++++++++++++++++++++++++++++-------------- 1 files changed, 51 insertions(+), 14 deletions(-) diff --git a/nbd.c b/nbd.c index 00764da..ae7f5ab 100644 --- a/nbd.c +++ b/nbd.c @@ -36,6 +36,7 @@ #endif #include "qemu_socket.h" +#include "qemu-queue.h" //#define DEBUG_NBD @@ -586,29 +587,60 @@ static int nbd_send_reply(int csock, struct nbd_reply *reply) return 0; } +typedef struct NBDRequest NBDRequest; + +struct NBDRequest { + QSIMPLEQ_ENTRY(NBDRequest) entry; + uint8_t *data; +}; + struct NBDExport { BlockDriverState *bs; off_t dev_offset; off_t size; - uint8_t *data; uint32_t nbdflags; + QSIMPLEQ_HEAD(, NBDRequest) requests; }; +static NBDRequest *nbd_request_get(NBDExport *exp) +{ + NBDRequest *req; + if (QSIMPLEQ_EMPTY(&exp->requests)) { + req = g_malloc0(sizeof(NBDRequest)); + req->data = qemu_blockalign(exp->bs, NBD_BUFFER_SIZE); + } else { + req = QSIMPLEQ_FIRST(&exp->requests); + QSIMPLEQ_REMOVE_HEAD(&exp->requests, entry); + } + return req; +} + +static void nbd_request_put(NBDExport *exp, NBDRequest *req) +{ + QSIMPLEQ_INSERT_HEAD(&exp->requests, req, entry); +} + NBDExport *nbd_export_new(BlockDriverState *bs, off_t dev_offset, off_t size, uint32_t nbdflags) { NBDExport *exp = g_malloc0(sizeof(NBDExport)); + QSIMPLEQ_INIT(&exp->requests); exp->bs = bs; exp->dev_offset = dev_offset; exp->nbdflags = nbdflags; exp->size = size == -1 ? exp->bs->total_sectors * 512 : size; - exp->data = qemu_blockalign(exp->bs, NBD_BUFFER_SIZE); return exp; } void nbd_export_close(NBDExport *exp) { - qemu_vfree(exp->data); + while (!QSIMPLEQ_EMPTY(&exp->requests)) { + NBDRequest *first = QSIMPLEQ_FIRST(&exp->requests); + QSIMPLEQ_REMOVE_HEAD(&exp->requests, entry); + qemu_vfree(first->data); + g_free(first); + } + bdrv_close(exp->bs); g_free(exp); } @@ -684,15 +716,17 @@ out: int nbd_trip(NBDExport *exp, int csock) { + NBDRequest *req = nbd_request_get(exp); struct nbd_request request; struct nbd_reply reply; + int rc = -1; int ret; TRACE("Reading request."); - ret = nbd_do_receive_request(csock, &request, exp->data); + ret = nbd_do_receive_request(csock, &request, req->data); if (ret == -EIO) { - return -1; + goto out; } reply.handle = request.handle; @@ -717,7 +751,7 @@ int nbd_trip(NBDExport *exp, int csock) TRACE("Request type is READ"); ret = bdrv_read(exp->bs, (request.from + exp->dev_offset) / 512, - exp->data, request.len / 512); + req->data, request.len / 512); if (ret < 0) { LOG("reading from file failed"); reply.error = -ret; @@ -725,8 +759,8 @@ int nbd_trip(NBDExport *exp, int csock) } TRACE("Read %u byte(s)", request.len); - if (nbd_do_send_reply(csock, &reply, exp->data, request.len) < 0) - return -1; + if (nbd_do_send_reply(csock, &reply, req->data, request.len) < 0) + goto out; break; case NBD_CMD_WRITE: TRACE("Request type is WRITE"); @@ -740,7 +774,7 @@ int nbd_trip(NBDExport *exp, int csock) TRACE("Writing to device"); ret = bdrv_write(exp->bs, (request.from + exp->dev_offset) / 512, - exp->data, request.len / 512); + req->data, request.len / 512); if (ret < 0) { LOG("writing to file failed"); reply.error = -ret; @@ -757,7 +791,7 @@ int nbd_trip(NBDExport *exp, int csock) } if (nbd_do_send_reply(csock, &reply, NULL, 0) < 0) - return -1; + goto out; break; case NBD_CMD_DISC: TRACE("Request type is DISCONNECT"); @@ -773,7 +807,7 @@ int nbd_trip(NBDExport *exp, int csock) } if (nbd_do_send_reply(csock, &reply, NULL, 0) < 0) - return -1; + goto out; break; case NBD_CMD_TRIM: TRACE("Request type is TRIM"); @@ -784,7 +818,7 @@ int nbd_trip(NBDExport *exp, int csock) reply.error = -ret; } if (nbd_do_send_reply(csock, &reply, NULL, 0) < 0) - return -1; + goto out; break; default: LOG("invalid request type (%u) received", request.type); @@ -792,11 +826,14 @@ int nbd_trip(NBDExport *exp, int csock) reply.error = -EINVAL; error_reply: if (nbd_do_send_reply(csock, &reply, NULL, 0) == -1) - return -1; + goto out; break; } TRACE("Request/Reply complete"); - return 0; + rc = 0; +out: + nbd_request_put(exp, req); + return rc; } -- 1.7.6