]> Git Repo - qemu.git/blobdiff - nbd/server.c
nbd-server: Use a separate BlockBackend
[qemu.git] / nbd / server.c
index a677e266ffac8568781612eefc49aecc7645ce41..472f584c323ed28635ed34c101a4454fca505c79 100644 (file)
@@ -63,12 +63,13 @@ struct NBDExport {
     char *name;
     off_t dev_offset;
     off_t size;
-    uint32_t nbdflags;
+    uint16_t nbdflags;
     QTAILQ_HEAD(, NBDClient) clients;
     QTAILQ_ENTRY(NBDExport) next;
 
     AioContext *ctx;
 
+    BlockBackend *eject_notifier_blk;
     Notifier eject_notifier;
 };
 
@@ -106,7 +107,7 @@ static gboolean nbd_negotiate_continue(QIOChannel *ioc,
                                        GIOCondition condition,
                                        void *opaque)
 {
-    qemu_coroutine_enter(opaque, NULL);
+    qemu_coroutine_enter(opaque);
     return TRUE;
 }
 
@@ -544,8 +545,8 @@ static coroutine_fn int nbd_negotiate(NBDClientNewData *data)
     NBDClient *client = data->client;
     char buf[8 + 8 + 8 + 128];
     int rc;
-    const int myflags = (NBD_FLAG_HAS_FLAGS | NBD_FLAG_SEND_TRIM |
-                         NBD_FLAG_SEND_FLUSH | NBD_FLAG_SEND_FUA);
+    const uint16_t myflags = (NBD_FLAG_HAS_FLAGS | NBD_FLAG_SEND_TRIM |
+                              NBD_FLAG_SEND_FLUSH | NBD_FLAG_SEND_FUA);
     bool oldStyle;
 
     /* Old style negotiation header without options
@@ -575,7 +576,6 @@ static coroutine_fn int nbd_negotiate(NBDClientNewData *data)
 
     oldStyle = client->exp != NULL && !client->tlscreds;
     if (oldStyle) {
-        assert ((client->exp->nbdflags & ~65535) == 0);
         TRACE("advertising size %" PRIu64 " and flags %x",
               client->exp->size, client->exp->nbdflags | myflags);
         stq_be_p(buf + 8, NBD_CLIENT_MAGIC);
@@ -606,7 +606,6 @@ static coroutine_fn int nbd_negotiate(NBDClientNewData *data)
             goto fail;
         }
 
-        assert ((client->exp->nbdflags & ~65535) == 0);
         TRACE("advertising size %" PRIu64 " and flags %x",
               client->exp->size, client->exp->nbdflags | myflags);
         stq_be_p(buf + 18, client->exp->size);
@@ -809,11 +808,18 @@ static void nbd_eject_notifier(Notifier *n, void *data)
     nbd_export_close(exp);
 }
 
-NBDExport *nbd_export_new(BlockBackend *blk, off_t dev_offset, off_t size,
-                          uint32_t nbdflags, void (*close)(NBDExport *),
+NBDExport *nbd_export_new(BlockDriverState *bs, off_t dev_offset, off_t size,
+                          uint16_t nbdflags, void (*close)(NBDExport *),
+                          bool writethrough, BlockBackend *on_eject_blk,
                           Error **errp)
 {
+    BlockBackend *blk;
     NBDExport *exp = g_malloc0(sizeof(NBDExport));
+
+    blk = blk_new();
+    blk_insert_bs(blk, bs);
+    blk_set_enable_write_cache(blk, !writethrough);
+
     exp->refcount = 1;
     QTAILQ_INIT(&exp->clients);
     exp->blk = blk;
@@ -829,11 +835,14 @@ NBDExport *nbd_export_new(BlockBackend *blk, off_t dev_offset, off_t size,
 
     exp->close = close;
     exp->ctx = blk_get_aio_context(blk);
-    blk_ref(blk);
     blk_add_aio_context_notifier(blk, blk_aio_attached, blk_aio_detach, exp);
 
-    exp->eject_notifier.notify = nbd_eject_notifier;
-    blk_add_remove_bs_notifier(blk, &exp->eject_notifier);
+    if (on_eject_blk) {
+        blk_ref(on_eject_blk);
+        exp->eject_notifier_blk = on_eject_blk;
+        exp->eject_notifier.notify = nbd_eject_notifier;
+        blk_add_remove_bs_notifier(on_eject_blk, &exp->eject_notifier);
+    }
 
     /*
      * NBD exports are used for non-shared storage migration.  Make sure
@@ -846,6 +855,7 @@ NBDExport *nbd_export_new(BlockBackend *blk, off_t dev_offset, off_t size,
     return exp;
 
 fail:
+    blk_unref(blk);
     g_free(exp);
     return NULL;
 }
@@ -916,7 +926,10 @@ void nbd_export_put(NBDExport *exp)
         }
 
         if (exp->blk) {
-            notifier_remove(&exp->eject_notifier);
+            if (exp->eject_notifier_blk) {
+                notifier_remove(&exp->eject_notifier);
+                blk_unref(exp->eject_notifier_blk);
+            }
             blk_remove_aio_context_notifier(exp->blk, blk_aio_attached,
                                             blk_aio_detach, exp);
             blk_unref(exp->blk);
@@ -1057,7 +1070,8 @@ static ssize_t nbd_co_receive_request(NBDRequest *req,
     if (request->type & ~NBD_CMD_MASK_COMMAND & ~NBD_CMD_FLAG_FUA) {
         LOG("unsupported flags (got 0x%x)",
             request->type & ~NBD_CMD_MASK_COMMAND);
-        return -EINVAL;
+        rc = -EINVAL;
+        goto out;
     }
 
     rc = 0;
@@ -1182,20 +1196,11 @@ static void nbd_trip(void *opaque)
         break;
     case NBD_CMD_TRIM:
         TRACE("Request type is TRIM");
-        /* Ignore unaligned head or tail, until block layer adds byte
-         * interface */
-        if (request.len >= BDRV_SECTOR_SIZE) {
-            request.len -= (request.from + request.len) % BDRV_SECTOR_SIZE;
-            ret = blk_co_discard(exp->blk,
-                                 DIV_ROUND_UP(request.from + exp->dev_offset,
-                                              BDRV_SECTOR_SIZE),
-                                 request.len / BDRV_SECTOR_SIZE);
-            if (ret < 0) {
-                LOG("discard failed");
-                reply.error = -ret;
-            }
-        } else {
-            TRACE("trim request too small, ignoring");
+        ret = blk_co_pdiscard(exp->blk, request.from + exp->dev_offset,
+                              request.len);
+        if (ret < 0) {
+            LOG("discard failed");
+            reply.error = -ret;
         }
         if (nbd_co_send_reply(req, &reply, 0) < 0) {
             goto out;
@@ -1230,9 +1235,9 @@ static void nbd_read(void *opaque)
     NBDClient *client = opaque;
 
     if (client->recv_coroutine) {
-        qemu_coroutine_enter(client->recv_coroutine, NULL);
+        qemu_coroutine_enter(client->recv_coroutine);
     } else {
-        qemu_coroutine_enter(qemu_coroutine_create(nbd_trip), client);
+        qemu_coroutine_enter(qemu_coroutine_create(nbd_trip, client));
     }
 }
 
@@ -1240,7 +1245,7 @@ static void nbd_restart_write(void *opaque)
 {
     NBDClient *client = opaque;
 
-    qemu_coroutine_enter(client->send_coroutine, NULL);
+    qemu_coroutine_enter(client->send_coroutine);
 }
 
 static void nbd_set_handlers(NBDClient *client)
@@ -1324,6 +1329,6 @@ void nbd_client_new(NBDExport *exp,
     client->close = close_fn;
 
     data->client = client;
-    data->co = qemu_coroutine_create(nbd_co_client_start);
-    qemu_coroutine_enter(data->co, data);
+    data->co = qemu_coroutine_create(nbd_co_client_start, data);
+    qemu_coroutine_enter(data->co);
 }
This page took 0.0299 seconds and 4 git commands to generate.