Skip to content

Commit

Permalink
nbd/client: Report offsets in bdrv_block_status
Browse files Browse the repository at this point in the history
It is desirable for 'qemu-img map' to have the same output for a file
whether it is served over file or nbd protocols. However, ever since
we implemented block status for NBD (2.12), the NBD protocol forgot to
inform the block layer that as the final layer in the chain, the
offset is valid; without an offset, the human-readable form of
qemu-img map gives up with the unhelpful:

$ nbdkit -U - data data="1" size=512 --run 'qemu-img map $nbd'
Offset          Length          Mapped to       File
qemu-img: File contains external, encrypted or compressed clusters.

The --output=json form always works, because it is reporting the
lower-level bdrv_block_status results directly rather than trying to
filter out sparse ranges for human consumption - but now it also
shows the offset member.

With this patch, the human output changes to:

Offset          Length          Mapped to       File
0               0x200           0               nbd+unix://?socket=/tmp/nbdkitOxeoLa/socket

This change is observable to several iotests.

Fixes: 78a33ab
Reported-by: Richard W.M. Jones <rjones@redhat.com>
Signed-off-by: Eric Blake <eblake@redhat.com>
Message-Id: <20190329042750.14704-4-eblake@redhat.com>
Reviewed-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
  • Loading branch information
ebblake committed Mar 31, 2019
1 parent 7da537f commit a62a85e
Show file tree
Hide file tree
Showing 4 changed files with 21 additions and 16 deletions.
9 changes: 7 additions & 2 deletions block/nbd-client.c
Expand Up @@ -972,7 +972,9 @@ int coroutine_fn nbd_client_co_block_status(BlockDriverState *bs,

if (!client->info.base_allocation) {
*pnum = bytes;
return BDRV_BLOCK_DATA;
*map = offset;
*file = bs;
return BDRV_BLOCK_DATA | BDRV_BLOCK_OFFSET_VALID;
}

ret = nbd_co_send_request(bs, &request, NULL);
Expand All @@ -995,8 +997,11 @@ int coroutine_fn nbd_client_co_block_status(BlockDriverState *bs,

assert(extent.length);
*pnum = extent.length;
*map = offset;
*file = bs;
return (extent.flags & NBD_STATE_HOLE ? 0 : BDRV_BLOCK_DATA) |
(extent.flags & NBD_STATE_ZERO ? BDRV_BLOCK_ZERO : 0);
(extent.flags & NBD_STATE_ZERO ? BDRV_BLOCK_ZERO : 0) |
BDRV_BLOCK_OFFSET_VALID;
}

void nbd_client_detach_aio_context(BlockDriverState *bs)
Expand Down
4 changes: 2 additions & 2 deletions tests/qemu-iotests/209.out
@@ -1,2 +1,2 @@
[{ "start": 0, "length": 524288, "depth": 0, "zero": false, "data": true},
{ "start": 524288, "length": 524288, "depth": 0, "zero": true, "data": false}]
[{ "start": 0, "length": 524288, "depth": 0, "zero": false, "data": true, "offset": 0},
{ "start": 524288, "length": 524288, "depth": 0, "zero": true, "data": false, "offset": 524288}]
18 changes: 9 additions & 9 deletions tests/qemu-iotests/223.out
Expand Up @@ -67,18 +67,18 @@ read 1048576/1048576 bytes at offset 1048576
1 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
read 2097152/2097152 bytes at offset 2097152
2 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
[{ "start": 0, "length": 4096, "depth": 0, "zero": false, "data": true},
{ "start": 4096, "length": 1044480, "depth": 0, "zero": true, "data": false},
{ "start": 1048576, "length": 3145728, "depth": 0, "zero": false, "data": true}]
[{ "start": 0, "length": 4096, "depth": 0, "zero": false, "data": true, "offset": OFFSET},
{ "start": 4096, "length": 1044480, "depth": 0, "zero": true, "data": false, "offset": OFFSET},
{ "start": 1048576, "length": 3145728, "depth": 0, "zero": false, "data": true, "offset": OFFSET}]
[{ "start": 0, "length": 65536, "depth": 0, "zero": false, "data": false},
{ "start": 65536, "length": 2031616, "depth": 0, "zero": false, "data": true},
{ "start": 65536, "length": 2031616, "depth": 0, "zero": false, "data": true, "offset": OFFSET},
{ "start": 2097152, "length": 2097152, "depth": 0, "zero": false, "data": false}]

=== Contrast to small granularity dirty-bitmap ===

[{ "start": 0, "length": 512, "depth": 0, "zero": false, "data": true},
[{ "start": 0, "length": 512, "depth": 0, "zero": false, "data": true, "offset": OFFSET},
{ "start": 512, "length": 512, "depth": 0, "zero": false, "data": false},
{ "start": 1024, "length": 2096128, "depth": 0, "zero": false, "data": true},
{ "start": 1024, "length": 2096128, "depth": 0, "zero": false, "data": true, "offset": OFFSET},
{ "start": 2097152, "length": 2097152, "depth": 0, "zero": false, "data": false}]

=== End qemu NBD server ===
Expand All @@ -94,10 +94,10 @@ read 2097152/2097152 bytes at offset 2097152
=== Use qemu-nbd as server ===

[{ "start": 0, "length": 65536, "depth": 0, "zero": false, "data": false},
{ "start": 65536, "length": 2031616, "depth": 0, "zero": false, "data": true},
{ "start": 65536, "length": 2031616, "depth": 0, "zero": false, "data": true, "offset": OFFSET},
{ "start": 2097152, "length": 2097152, "depth": 0, "zero": false, "data": false}]
[{ "start": 0, "length": 512, "depth": 0, "zero": false, "data": true},
[{ "start": 0, "length": 512, "depth": 0, "zero": false, "data": true, "offset": OFFSET},
{ "start": 512, "length": 512, "depth": 0, "zero": false, "data": false},
{ "start": 1024, "length": 2096128, "depth": 0, "zero": false, "data": true},
{ "start": 1024, "length": 2096128, "depth": 0, "zero": false, "data": true, "offset": OFFSET},
{ "start": 2097152, "length": 2097152, "depth": 0, "zero": false, "data": false}]
*** done
6 changes: 3 additions & 3 deletions tests/qemu-iotests/241.out
Expand Up @@ -4,7 +4,7 @@ QA output created by 241

size: 1024
min block: 512
[{ "start": 0, "length": 1024, "depth": 0, "zero": false, "data": true}]
[{ "start": 0, "length": 1024, "depth": 0, "zero": false, "data": true, "offset": OFFSET}]
1 KiB (0x400) bytes allocated at offset 0 bytes (0x0)

=== Exporting unaligned raw image, forced server sector alignment ===
Expand All @@ -14,13 +14,13 @@ WARNING: Image format was not specified for '/home/eblake/qemu/tests/qemu-iotest
Specify the 'raw' format explicitly to remove the restrictions.
size: 1024
min block: 512
[{ "start": 0, "length": 1024, "depth": 0, "zero": false, "data": true}]
[{ "start": 0, "length": 1024, "depth": 0, "zero": false, "data": true, "offset": OFFSET}]
1 KiB (0x400) bytes allocated at offset 0 bytes (0x0)

=== Exporting unaligned raw image, forced client sector alignment ===

size: 1024
min block: 512
[{ "start": 0, "length": 1024, "depth": 0, "zero": false, "data": true}]
[{ "start": 0, "length": 1024, "depth": 0, "zero": false, "data": true, "offset": OFFSET}]
1 KiB (0x400) bytes allocated at offset 0 bytes (0x0)
*** done

0 comments on commit a62a85e

Please sign in to comment.