Patchwork [08/15] qemu-nbd: introduce NBDExport

login
register
mail settings
Submitter Paolo Bonzini
Date Oct. 10, 2011, 9:37 a.m.
Message ID <1318239477-31451-9-git-send-email-pbonzini@redhat.com>
Download mbox | patch
Permalink /patch/118662/
State New
Headers show

Comments

Paolo Bonzini - Oct. 10, 2011, 9:37 a.m.
Wrap the common parameters of nbd_trip in a single opaque struct.

Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
 nbd.c      |   57 ++++++++++++++++++++++++++++++++++++++++++---------------
 nbd.h      |    9 +++++++--
 qemu-nbd.c |   18 ++++++------------
 3 files changed, 55 insertions(+), 29 deletions(-)

Patch

diff --git a/nbd.c b/nbd.c
index 898206f..00764da 100644
--- a/nbd.c
+++ b/nbd.c
@@ -18,6 +18,7 @@ 
 
 #include "nbd.h"
 #include "block.h"
+#include "block_int.h"
 
 #include <errno.h>
 #include <string.h>
@@ -585,6 +586,33 @@  static int nbd_send_reply(int csock, struct nbd_reply *reply)
     return 0;
 }
 
+struct NBDExport {
+    BlockDriverState *bs;
+    off_t dev_offset;
+    off_t size;
+    uint8_t *data;
+    uint32_t nbdflags;
+};
+
+NBDExport *nbd_export_new(BlockDriverState *bs, off_t dev_offset,
+                          off_t size, uint32_t nbdflags)
+{
+    NBDExport *exp = g_malloc0(sizeof(NBDExport));
+    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);
+    bdrv_close(exp->bs);
+    g_free(exp);
+}
+
 static int nbd_do_send_reply(int csock, struct nbd_reply *reply,
                              uint8_t *data, int len)
 {
@@ -654,9 +682,7 @@  out:
     return rc;
 }
 
-int nbd_trip(BlockDriverState *bs, int csock, off_t size,
-             uint64_t dev_offset, uint32_t nbdflags,
-             uint8_t *data)
+int nbd_trip(NBDExport *exp, int csock)
 {
     struct nbd_request request;
     struct nbd_reply reply;
@@ -664,7 +690,7 @@  int nbd_trip(BlockDriverState *bs, int csock, off_t size,
 
     TRACE("Reading request.");
 
-    ret = nbd_do_receive_request(csock, &request, data);
+    ret = nbd_do_receive_request(csock, &request, exp->data);
     if (ret == -EIO) {
         return -1;
     }
@@ -677,10 +703,11 @@  int nbd_trip(BlockDriverState *bs, int csock, off_t size,
         goto error_reply;
     }
 
-    if ((request.from + request.len) > size) {
+    if ((request.from + request.len) > exp->size) {
             LOG("From: %" PRIu64 ", Len: %u, Size: %" PRIu64
             ", Offset: %" PRIu64 "\n",
-                    request.from, request.len, (uint64_t)size, dev_offset);
+                    request.from, request.len,
+                    (uint64_t)exp->size, exp->dev_offset);
         LOG("requested operation past EOF--bad client?");
         goto invalid_request;
     }
@@ -689,8 +716,8 @@  int nbd_trip(BlockDriverState *bs, int csock, off_t size,
     case NBD_CMD_READ:
         TRACE("Request type is READ");
 
-        ret = bdrv_read(bs, (request.from + dev_offset) / 512,
-                        data, request.len / 512);
+        ret = bdrv_read(exp->bs, (request.from + exp->dev_offset) / 512,
+                        exp->data, request.len / 512);
         if (ret < 0) {
             LOG("reading from file failed");
             reply.error = -ret;
@@ -698,13 +725,13 @@  int nbd_trip(BlockDriverState *bs, int csock, off_t size,
         }
 
         TRACE("Read %u byte(s)", request.len);
-        if (nbd_do_send_reply(csock, &reply, data, request.len) < 0)
+        if (nbd_do_send_reply(csock, &reply, exp->data, request.len) < 0)
             return -1;
         break;
     case NBD_CMD_WRITE:
         TRACE("Request type is WRITE");
 
-        if (nbdflags & NBD_FLAG_READ_ONLY) {
+        if (exp->nbdflags & NBD_FLAG_READ_ONLY) {
             TRACE("Server is read-only, return error");
             reply.error = EROFS;
             goto error_reply;
@@ -712,8 +739,8 @@  int nbd_trip(BlockDriverState *bs, int csock, off_t size,
 
         TRACE("Writing to device");
 
-        ret = bdrv_write(bs, (request.from + dev_offset) / 512,
-                         data, request.len / 512);
+        ret = bdrv_write(exp->bs, (request.from + exp->dev_offset) / 512,
+                         exp->data, request.len / 512);
         if (ret < 0) {
             LOG("writing to file failed");
             reply.error = -ret;
@@ -721,7 +748,7 @@  int nbd_trip(BlockDriverState *bs, int csock, off_t size,
         }
 
         if (request.type & NBD_CMD_FLAG_FUA) {
-            ret = bdrv_flush(bs);
+            ret = bdrv_flush(exp->bs);
             if (ret < 0) {
                 LOG("flush failed");
                 reply.error = -ret;
@@ -739,7 +766,7 @@  int nbd_trip(BlockDriverState *bs, int csock, off_t size,
     case NBD_CMD_FLUSH:
         TRACE("Request type is FLUSH");
 
-        ret = bdrv_flush(bs);
+        ret = bdrv_flush(exp->bs);
         if (ret < 0) {
             LOG("flush failed");
             reply.error = -ret;
@@ -750,7 +777,7 @@  int nbd_trip(BlockDriverState *bs, int csock, off_t size,
         break;
     case NBD_CMD_TRIM:
         TRACE("Request type is TRIM");
-        ret = bdrv_discard(bs, (request.from + dev_offset) / 512,
+        ret = bdrv_discard(exp->bs, (request.from + exp->dev_offset) / 512,
                            request.len / 512);
         if (ret < 0) {
             LOG("discard failed");
diff --git a/nbd.h b/nbd.h
index dbc4c0d..d368156 100644
--- a/nbd.h
+++ b/nbd.h
@@ -73,9 +73,14 @@  int nbd_receive_negotiate(int csock, const char *name, uint32_t *flags,
 int nbd_init(int fd, int csock, uint32_t flags, off_t size, size_t blocksize);
 int nbd_send_request(int csock, struct nbd_request *request);
 int nbd_receive_reply(int csock, struct nbd_reply *reply);
-int nbd_trip(BlockDriverState *bs, int csock, off_t size, uint64_t dev_offset,
-             uint32_t nbdflags, uint8_t *data);
 int nbd_client(int fd);
 int nbd_disconnect(int fd);
 
+typedef struct NBDExport NBDExport;
+
+NBDExport *nbd_export_new(BlockDriverState *bs, off_t dev_offset,
+                          off_t size, uint32_t nbdflags);
+void nbd_export_close(NBDExport *exp);
+int nbd_trip(NBDExport *exp, int csock);
+
 #endif
diff --git a/qemu-nbd.c b/qemu-nbd.c
index befbbfd..9fa3979 100644
--- a/qemu-nbd.c
+++ b/qemu-nbd.c
@@ -34,6 +34,7 @@ 
 
 #define SOCKET_PATH    "/var/lock/qemu-nbd-%s"
 
+static NBDExport *exp;
 static int verbose;
 
 static void usage(const char *name)
@@ -188,7 +189,7 @@  int main(int argc, char **argv)
     int port = NBD_DEFAULT_PORT;
     struct sockaddr_in addr;
     socklen_t addr_len = sizeof(addr);
-    off_t fd_size;
+    off_t fd_size = -1;
     char *device = NULL;
     char *socket = NULL;
     char sockpath[128];
@@ -219,7 +220,6 @@  int main(int argc, char **argv)
     int partition = -1;
     int ret;
     int shared = 1;
-    uint8_t *data;
     fd_set fds;
     int *sharing_fds;
     int fd;
@@ -338,12 +338,12 @@  int main(int argc, char **argv)
         err(EXIT_FAILURE, "Failed to bdrv_open '%s'", argv[optind]);
     }
 
-    fd_size = bs->total_sectors * 512;
-
     if (partition != -1 &&
         find_partition(bs, partition, &dev_offset, &fd_size))
         err(EXIT_FAILURE, "Could not find partition %d", partition);
 
+    exp = nbd_export_new(bs, dev_offset, fd_size, nbdflags);
+
     if (device) {
         pid_t pid;
         int sock;
@@ -440,10 +440,6 @@  int main(int argc, char **argv)
     max_fd = sharing_fds[0];
     nb_fds++;
 
-    data = qemu_blockalign(bs, NBD_BUFFER_SIZE);
-    if (data == NULL)
-        errx(EXIT_FAILURE, "Cannot allocate data buffer");
-
     do {
 
         FD_ZERO(&fds);
@@ -458,8 +454,7 @@  int main(int argc, char **argv)
             ret--;
         for (i = 1; i < nb_fds && ret; i++) {
             if (FD_ISSET(sharing_fds[i], &fds)) {
-                if (nbd_trip(bs, sharing_fds[i], fd_size, dev_offset,
-                             nbdflags, data) != 0) {
+                if (nbd_trip(exp, sharing_fds[i]) != 0) {
                     close(sharing_fds[i]);
                     nb_fds--;
                     sharing_fds[i] = sharing_fds[nb_fds];
@@ -483,10 +478,9 @@  int main(int argc, char **argv)
             }
         }
     } while (persistent || nb_fds > 1);
-    qemu_vfree(data);
 
     close(sharing_fds[0]);
-    bdrv_close(bs);
+    nbd_export_close(exp);
     g_free(sharing_fds);
     if (socket)
         unlink(socket);