All of lore.kernel.org
 help / color / mirror / Atom feed
From: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
To: qemu-block@nongnu.org, qemu-devel@nongnu.org
Cc: famz@redhat.com, jsnow@redhat.com, kwolf@redhat.com,
	mreitz@redhat.com, pbonzini@redhat.com, armbru@redhat.com,
	eblake@redhat.com, den@virtuozzo.com, stefanha@redhat.com
Subject: [Qemu-devel] [PATCH 17/18] nbd: BLOCK_STATUS for standard get_block_status function: server part
Date: Fri,  3 Feb 2017 18:47:56 +0300	[thread overview]
Message-ID: <20170203154757.36140-18-vsementsov@virtuozzo.com> (raw)
In-Reply-To: <20170203154757.36140-1-vsementsov@virtuozzo.com>

Minimal realization: only one extent in server answer is supported.

Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
---
 include/block/nbd.h |  3 ++
 nbd/nbd-internal.h  |  1 +
 nbd/server.c        | 80 ++++++++++++++++++++++++++++++++++++++++++++++++-----
 3 files changed, 77 insertions(+), 7 deletions(-)

diff --git a/include/block/nbd.h b/include/block/nbd.h
index 08d5e51f21..69aee1eda1 100644
--- a/include/block/nbd.h
+++ b/include/block/nbd.h
@@ -181,6 +181,9 @@ enum {
 #define NBD_REPLY_TYPE_ERROR ((1 << 15) + 1)
 #define NBD_REPLY_TYPE_ERROR_OFFSET ((1 << 15) + 2)
 
+#define NBD_STATE_HOLE 1
+#define NBD_STATE_ZERO (1 << 1)
+
 #define NBD_MAX_BITMAP_EXTENTS (0x100000 / 8) /* 1 mb of extents data */
 
 ssize_t nbd_wr_syncv(QIOChannel *ioc,
diff --git a/nbd/nbd-internal.h b/nbd/nbd-internal.h
index fbbcf69925..f89baa6049 100644
--- a/nbd/nbd-internal.h
+++ b/nbd/nbd-internal.h
@@ -86,6 +86,7 @@
 #define NBD_OPT_LIST_META_CONTEXT (9)
 #define NBD_OPT_SET_META_CONTEXT  (10)
 
+#define NBD_META_NS_BASE "base"
 #define NBD_META_NS_BITMAPS "qemu-dirty-bitmap"
 
 /* NBD errors are based on errno numbers, so there is a 1:1 mapping,
diff --git a/nbd/server.c b/nbd/server.c
index c96dda4086..cb87481382 100644
--- a/nbd/server.c
+++ b/nbd/server.c
@@ -103,6 +103,7 @@ struct NBDClient {
 
     bool structured_reply;
     BdrvDirtyBitmap *export_bitmap;
+    bool export_block_status;
 };
 
 /* That's all folks */
@@ -506,8 +507,24 @@ static int nbd_negotiate_one_bitmap_query(QIOChannel *ioc, BlockDriverState *bs,
     return 0;
 }
 
+static int nbd_negotiate_one_base_query(QIOChannel *ioc, BlockDriverState *bs,
+                                        uint32_t opt, const char *query,
+                                        bool *block_status)
+{
+    if (query[0] == '\0' || strcmp(query, "allocation") == 0) {
+        if (block_status != NULL) {
+            *block_status = true;
+        }
+
+        return nbd_negotiate_send_meta_context(ioc, "base:allocation", opt);
+    }
+
+    return 0;
+}
+
 static int nbd_negotiate_one_meta_query(QIOChannel *ioc, BlockDriverState *bs,
-                                        uint32_t opt, BdrvDirtyBitmap **bitmap)
+                                        uint32_t opt, BdrvDirtyBitmap **bitmap,
+                                        bool *block_status)
 {
     int ret = 0, nb_read;
     char *query, *colon, *namespace, *subquery;
@@ -530,6 +547,9 @@ static int nbd_negotiate_one_meta_query(QIOChannel *ioc, BlockDriverState *bs,
 
     if (strcmp(namespace, NBD_META_NS_BITMAPS) == 0) {
         ret = nbd_negotiate_one_bitmap_query(ioc, bs, opt, subquery, bitmap);
+    } else if (strcmp(namespace, NBD_META_NS_BASE) == 0) {
+        ret = nbd_negotiate_one_base_query(ioc, bs, opt, subquery,
+                                           block_status);
     }
 
 out:
@@ -663,7 +683,8 @@ static int nbd_negotiate_list_meta_context(NBDClient *client, uint32_t length)
 
     for (i = 0; i < nb_queries; ++i) {
         ret = nbd_negotiate_one_meta_query(client->ioc, bs,
-                                           NBD_OPT_LIST_META_CONTEXT, NULL);
+                                           NBD_OPT_LIST_META_CONTEXT, NULL,
+                                           NULL);
         if (ret < 0) {
             return ret;
         }
@@ -712,7 +733,8 @@ static int nbd_negotiate_set_meta_context(NBDClient *client, uint32_t length)
 
     ret = nbd_negotiate_one_meta_query(client->ioc, bs,
                                        NBD_OPT_SET_META_CONTEXT,
-                                       &client->export_bitmap);
+                                       &client->export_bitmap,
+                                       &client->export_block_status);
     if (ret < 0) {
         return ret;
     }
@@ -1497,6 +1519,30 @@ static unsigned add_extents(NBDExtent *extents, unsigned nb_extents,
     return i;
 }
 
+static int blockstatus_to_extent(BlockDriverState *bs, uint64_t offset,
+                                  uint64_t length, NBDExtent *extent)
+{
+    BlockDriverState *file;
+    uint64_t start_sector = offset >> BDRV_SECTOR_BITS;
+    uint64_t last_sector = (offset + length - 1) >> BDRV_SECTOR_BITS;
+    uint64_t begin = start_sector;
+    uint64_t end = last_sector + 1;
+
+    int nb = MIN(INT_MAX, end - begin);
+    int64_t ret = bdrv_get_block_status_above(bs, NULL, begin, nb, &nb, &file);
+    if (ret < 0) {
+        return ret;
+    }
+
+    extent->flags =
+        cpu_to_be32((ret & BDRV_BLOCK_ALLOCATED ? 0 : NBD_STATE_HOLE) |
+                    (ret & BDRV_BLOCK_ZERO      ? NBD_STATE_ZERO : 0));
+    extent->length = cpu_to_be32((nb << BDRV_SECTOR_BITS) -
+                                 (offset - (start_sector << BDRV_SECTOR_BITS)));
+
+    return 0;
+}
+
 static unsigned bitmap_to_extents(BdrvDirtyBitmap *bitmap, uint64_t offset,
                                   uint64_t length, NBDExtent *extents,
                                   unsigned nb_extents)
@@ -1589,6 +1635,21 @@ static int nbd_co_send_bitmap(NBDClient *client, uint64_t handle,
     return ret;
 }
 
+static int nbd_co_send_block_status(NBDClient *client, uint64_t handle,
+                                    BlockDriverState *bs, uint64_t offset,
+                                    uint64_t length, uint32_t context_id)
+{
+    int ret;
+    NBDExtent extent;
+
+    ret = blockstatus_to_extent(bs, offset, length, &extent);
+    if (ret < 0) {
+        return nbd_co_send_structured_error(client, handle, -ret);
+    }
+
+    return nbd_co_send_extents(client, handle, &extent, 1, context_id);
+}
+
 /* Collect a client request.  Return 0 if request looks valid, -EAGAIN
  * to keep trying the collection, -EIO to drop connection right away,
  * and any other negative value to report an error to the client
@@ -1869,13 +1930,18 @@ static void nbd_trip(void *opaque)
         break;
     case NBD_CMD_BLOCK_STATUS:
         TRACE("Request type is BLOCK_STATUS");
-        if (client->export_bitmap == NULL) {
+        if (!!client->export_bitmap) {
+            ret = nbd_co_send_bitmap(req->client, request.handle,
+                                     client->export_bitmap, request.from,
+                                     request.len, 0);
+        } else if (client->export_block_status) {
+            ret = nbd_co_send_block_status(req->client, request.handle,
+                                           blk_bs(exp->blk), request.from,
+                                           request.len, 0);
+        } else {
             reply.error = EINVAL;
             goto error_reply;
         }
-        ret = nbd_co_send_bitmap(req->client, request.handle,
-                                 client->export_bitmap, request.from,
-                                 request.len, 0);
         if (ret < 0) {
             goto out;
         }
-- 
2.11.0

  parent reply	other threads:[~2017-02-03 15:48 UTC|newest]

Thread overview: 58+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2017-02-03 15:47 [Qemu-devel] [PATCH 00/18] nbd: BLOCK_STATUS Vladimir Sementsov-Ogievskiy
2017-02-03 15:47 ` [Qemu-devel] [PATCH 01/18] nbd: rename NBD_REPLY_MAGIC to NBD_SIMPLE_REPLY_MAGIC Vladimir Sementsov-Ogievskiy
2017-02-06 19:54   ` Eric Blake
2017-02-03 15:47 ` [Qemu-devel] [PATCH 02/18] nbd-server: refactor simple reply sending Vladimir Sementsov-Ogievskiy
2017-02-06 21:09   ` Eric Blake
2017-02-03 15:47 ` [Qemu-devel] [PATCH 03/18] nbd: Minimal structured read for server Vladimir Sementsov-Ogievskiy
2017-02-06 23:01   ` Eric Blake
2017-02-07 17:44     ` Paolo Bonzini
2017-05-04 10:58     ` Vladimir Sementsov-Ogievskiy
2017-05-04 13:28       ` Eric Blake
2017-05-05 11:30         ` Vladimir Sementsov-Ogievskiy
2017-02-03 15:47 ` [Qemu-devel] [PATCH 04/18] nbd/client: refactor nbd_receive_starttls Vladimir Sementsov-Ogievskiy
2017-02-07 16:32   ` Eric Blake
2017-02-09  6:20     ` Vladimir Sementsov-Ogievskiy
2017-02-09 14:41       ` Eric Blake
2017-02-10 11:23         ` Vladimir Sementsov-Ogievskiy
2017-02-11 19:30           ` Eric Blake
2017-02-20 16:14             ` Eric Blake
2017-02-03 15:47 ` [Qemu-devel] [PATCH 05/18] nbd/client: fix drop_sync Vladimir Sementsov-Ogievskiy
2017-02-06 23:17   ` Eric Blake
2017-02-15 14:50     ` Eric Blake
2017-02-03 15:47 ` [Qemu-devel] [PATCH 06/18] nbd/client: refactor drop_sync Vladimir Sementsov-Ogievskiy
2017-02-06 23:19   ` Eric Blake
2017-02-08  7:55     ` Vladimir Sementsov-Ogievskiy
2017-02-15 16:52       ` Paolo Bonzini
2017-02-03 15:47 ` [Qemu-devel] [PATCH 07/18] nbd: Minimal structured read for client Vladimir Sementsov-Ogievskiy
2017-02-07 20:14   ` Eric Blake
2017-02-15 16:54     ` Paolo Bonzini
2017-08-01 15:41     ` Vladimir Sementsov-Ogievskiy
2017-08-01 15:56       ` Vladimir Sementsov-Ogievskiy
2017-02-03 15:47 ` [Qemu-devel] [PATCH 08/18] hbitmap: add next_zero function Vladimir Sementsov-Ogievskiy
2017-02-07 22:55   ` Eric Blake
2017-02-15 16:57     ` Paolo Bonzini
2017-02-03 15:47 ` [Qemu-devel] [PATCH 09/18] block/dirty-bitmap: add bdrv_dirty_bitmap_next() Vladimir Sementsov-Ogievskiy
2017-02-03 15:47 ` [Qemu-devel] [PATCH 10/18] block/dirty-bitmap: add bdrv_load_dirty_bitmap Vladimir Sementsov-Ogievskiy
2017-02-08 11:45   ` Fam Zheng
2017-02-16 12:37   ` Denis V. Lunev
2017-02-03 15:47 ` [Qemu-devel] [PATCH 11/18] nbd: BLOCK_STATUS for bitmap export: server part Vladimir Sementsov-Ogievskiy
2017-02-08 13:13   ` Eric Blake
2017-02-16 13:00   ` Denis V. Lunev
2017-02-03 15:47 ` [Qemu-devel] [PATCH 12/18] nbd: BLOCK_STATUS for bitmap export: client part Vladimir Sementsov-Ogievskiy
2017-02-08 23:06   ` Eric Blake
2017-02-03 15:47 ` [Qemu-devel] [PATCH 13/18] nbd: add nbd_dirty_bitmap_load Vladimir Sementsov-Ogievskiy
2017-02-03 15:47 ` [Qemu-devel] [PATCH 14/18] qmp: add x-debug-block-dirty-bitmap-sha256 Vladimir Sementsov-Ogievskiy
2017-02-03 15:47 ` [Qemu-devel] [PATCH 15/18] qmp: add block-dirty-bitmap-load Vladimir Sementsov-Ogievskiy
2017-02-07 12:04   ` Fam Zheng
2017-02-09 15:18   ` Eric Blake
2017-02-15 16:57   ` Paolo Bonzini
2017-02-03 15:47 ` [Qemu-devel] [PATCH 16/18] iotests: add test for nbd dirty bitmap export Vladimir Sementsov-Ogievskiy
2017-02-03 15:47 ` Vladimir Sementsov-Ogievskiy [this message]
2017-02-09 15:38   ` [Qemu-devel] [PATCH 17/18] nbd: BLOCK_STATUS for standard get_block_status function: server part Eric Blake
2017-02-15 17:02     ` Paolo Bonzini
2017-02-15 17:02     ` Paolo Bonzini
2017-02-03 15:47 ` [Qemu-devel] [PATCH 18/18] nbd: BLOCK_STATUS for standard get_block_status function: client part Vladimir Sementsov-Ogievskiy
2017-02-09 16:00   ` Eric Blake
2017-02-15 17:04     ` Paolo Bonzini
2017-02-15 17:05 ` [Qemu-devel] [PATCH 00/18] nbd: BLOCK_STATUS Paolo Bonzini
2017-07-13 11:10   ` Eric Blake

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20170203154757.36140-18-vsementsov@virtuozzo.com \
    --to=vsementsov@virtuozzo.com \
    --cc=armbru@redhat.com \
    --cc=den@virtuozzo.com \
    --cc=eblake@redhat.com \
    --cc=famz@redhat.com \
    --cc=jsnow@redhat.com \
    --cc=kwolf@redhat.com \
    --cc=mreitz@redhat.com \
    --cc=pbonzini@redhat.com \
    --cc=qemu-block@nongnu.org \
    --cc=qemu-devel@nongnu.org \
    --cc=stefanha@redhat.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.