|
|
b38b0f |
From 1832a90928232cb91a8542613b754079fd1f0f0e Mon Sep 17 00:00:00 2001
|
|
|
b38b0f |
From: Max Reitz <mreitz@redhat.com>
|
|
|
b38b0f |
Date: Tue, 23 Jul 2019 14:45:46 +0100
|
|
|
b38b0f |
Subject: [PATCH 08/14] nbd/server: Advertise actual minimum block size
|
|
|
b38b0f |
|
|
|
b38b0f |
RH-Author: Max Reitz <mreitz@redhat.com>
|
|
|
b38b0f |
Message-id: <20190723144546.23701-8-mreitz@redhat.com>
|
|
|
b38b0f |
Patchwork-id: 89652
|
|
|
b38b0f |
O-Subject: [RHEL-8.1.0 qemu-kvm PATCH 7/7] nbd/server: Advertise actual minimum block size
|
|
|
b38b0f |
Bugzilla: 1678979
|
|
|
b38b0f |
RH-Acked-by: Kevin Wolf <kwolf@redhat.com>
|
|
|
b38b0f |
RH-Acked-by: Stefano Garzarella <sgarzare@redhat.com>
|
|
|
b38b0f |
RH-Acked-by: John Snow <jsnow@redhat.com>
|
|
|
b38b0f |
|
|
|
b38b0f |
From: Eric Blake <eblake@redhat.com>
|
|
|
b38b0f |
|
|
|
b38b0f |
Both NBD_CMD_BLOCK_STATUS and structured NBD_CMD_READ will split their
|
|
|
b38b0f |
reply according to bdrv_block_status() boundaries. If the block device
|
|
|
b38b0f |
has a request_alignment smaller than 512, but we advertise a block
|
|
|
b38b0f |
alignment of 512 to the client, then this can result in the server
|
|
|
b38b0f |
reply violating client expectations by reporting a smaller region of
|
|
|
b38b0f |
the export than what the client is permitted to address (although this
|
|
|
b38b0f |
is less of an issue for qemu 4.0 clients, given recent client patches
|
|
|
b38b0f |
to overlook our non-compliance at EOF). Since it's always better to
|
|
|
b38b0f |
be strict in what we send, it is worth advertising the actual minimum
|
|
|
b38b0f |
block limit rather than blindly rounding it up to 512.
|
|
|
b38b0f |
|
|
|
b38b0f |
Note that this patch is not foolproof - it is still possible to
|
|
|
b38b0f |
provoke non-compliant server behavior using:
|
|
|
b38b0f |
|
|
|
b38b0f |
$ qemu-nbd --image-opts driver=blkdebug,align=512,image.driver=file,image.filename=/path/to/non-aligned-file
|
|
|
b38b0f |
|
|
|
b38b0f |
That is arguably a bug in the blkdebug driver (it should never pass
|
|
|
b38b0f |
back block status smaller than its alignment, even if it has to make
|
|
|
b38b0f |
multiple bdrv_get_status calls and determine the
|
|
|
b38b0f |
least-common-denominator status among the group to return). It may
|
|
|
b38b0f |
also be possible to observe issues with a backing layer with smaller
|
|
|
b38b0f |
alignment than the active layer, although so far I have been unable to
|
|
|
b38b0f |
write a reliable iotest for that scenario (but again, an issue like
|
|
|
b38b0f |
that could be argued to be a bug in the block layer, or something
|
|
|
b38b0f |
where we need a flag to bdrv_block_status() to state whether the
|
|
|
b38b0f |
result must be aligned to the current layer's limits or can be
|
|
|
b38b0f |
subdivided for accuracy when chasing backing files).
|
|
|
b38b0f |
|
|
|
b38b0f |
Anyways, as blkdebug is not normally used, and as this patch makes our
|
|
|
b38b0f |
server more interoperable with qemu 3.1 clients, it is worth applying
|
|
|
b38b0f |
now, even while we still work on a larger patch series for the 4.1
|
|
|
b38b0f |
timeframe to have byte-accurate file lengths.
|
|
|
b38b0f |
|
|
|
b38b0f |
Note that the iotests output changes - for 223 and 233, we can see the
|
|
|
b38b0f |
server's better granularity advertisement; and for 241, the three test
|
|
|
b38b0f |
cases have the following effects:
|
|
|
b38b0f |
- natural alignment: the server's smaller alignment is now advertised,
|
|
|
b38b0f |
and the hole reported at EOF is now the right result; we've gotten rid
|
|
|
b38b0f |
of the server's non-compliance
|
|
|
b38b0f |
- forced server alignment: the server still advertises 512 bytes, but
|
|
|
b38b0f |
still sends a mid-sector hole. This is still a server compliance bug,
|
|
|
b38b0f |
which needs to be fixed in the block layer in a later patch; output
|
|
|
b38b0f |
does not change because the client is already being tolerant of the
|
|
|
b38b0f |
non-compliance
|
|
|
b38b0f |
- forced client alignment: the server's smaller alignment means that
|
|
|
b38b0f |
the client now sees the server's status change mid-sector without any
|
|
|
b38b0f |
protocol violations, but the fact that the map shows an unaligned
|
|
|
b38b0f |
mid-sector hole is evidence of the block layer problems with aligned
|
|
|
b38b0f |
block status, to be fixed in a later patch
|
|
|
b38b0f |
|
|
|
b38b0f |
Signed-off-by: Eric Blake <eblake@redhat.com>
|
|
|
b38b0f |
Message-Id: <20190329042750.14704-7-eblake@redhat.com>
|
|
|
b38b0f |
Reviewed-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
|
|
|
b38b0f |
[eblake: rebase to enhanced iotest 241 coverage]
|
|
|
b38b0f |
(cherry picked from commit b0245d6478ea5906e3d7a542244d5c015fd47bc7)
|
|
|
b38b0f |
|
|
|
b38b0f |
Signed-off-by: Danilo C. L. de Paula <ddepaula@redhat.com>
|
|
|
b38b0f |
|
|
|
b38b0f |
Conflicts:
|
|
|
b38b0f |
- tests/qemu-iotests/223.out: We are missing
|
|
|
b38b0f |
ddd09448fd833d646952c769ae9ce3d39bee989f downstream, which adds
|
|
|
b38b0f |
qemu-nbd --list tests to 223. (qemu-nbd --list does not exist
|
|
|
b38b0f |
downstream.)
|
|
|
b38b0f |
|
|
|
b38b0f |
- tests/qemu-iotests/233.out: Does not exist downstream.
|
|
|
b38b0f |
|
|
|
b38b0f |
- tests/qemu-iotests/241.out: Does not exist downstream, because it
|
|
|
b38b0f |
would require qemu-nbd --list.
|
|
|
b38b0f |
|
|
|
b38b0f |
Signed-off-by: Max Reitz <mreitz@redhat.com>
|
|
|
b38b0f |
Signed-off-by: Danilo C. L. de Paula <ddepaula@redhat.com>
|
|
|
b38b0f |
---
|
|
|
b38b0f |
nbd/server.c | 13 ++++++++-----
|
|
|
b38b0f |
1 file changed, 8 insertions(+), 5 deletions(-)
|
|
|
b38b0f |
|
|
|
b38b0f |
diff --git a/nbd/server.c b/nbd/server.c
|
|
|
b38b0f |
index e094300..96b6631 100644
|
|
|
b38b0f |
--- a/nbd/server.c
|
|
|
b38b0f |
+++ b/nbd/server.c
|
|
|
b38b0f |
@@ -608,13 +608,16 @@ static int nbd_negotiate_handle_info(NBDClient *client, uint16_t myflags,
|
|
|
b38b0f |
/* Send NBD_INFO_BLOCK_SIZE always, but tweak the minimum size
|
|
|
b38b0f |
* according to whether the client requested it, and according to
|
|
|
b38b0f |
* whether this is OPT_INFO or OPT_GO. */
|
|
|
b38b0f |
- /* minimum - 1 for back-compat, or 512 if client is new enough.
|
|
|
b38b0f |
- * TODO: consult blk_bs(blk)->bl.request_alignment? */
|
|
|
b38b0f |
- sizes[0] =
|
|
|
b38b0f |
- (client->opt == NBD_OPT_INFO || blocksize) ? BDRV_SECTOR_SIZE : 1;
|
|
|
b38b0f |
+ /* minimum - 1 for back-compat, or actual if client will obey it. */
|
|
|
b38b0f |
+ if (client->opt == NBD_OPT_INFO || blocksize) {
|
|
|
b38b0f |
+ sizes[0] = blk_get_request_alignment(exp->blk);
|
|
|
b38b0f |
+ } else {
|
|
|
b38b0f |
+ sizes[0] = 1;
|
|
|
b38b0f |
+ }
|
|
|
b38b0f |
+ assert(sizes[0] <= NBD_MAX_BUFFER_SIZE);
|
|
|
b38b0f |
/* preferred - Hard-code to 4096 for now.
|
|
|
b38b0f |
* TODO: is blk_bs(blk)->bl.opt_transfer appropriate? */
|
|
|
b38b0f |
- sizes[1] = 4096;
|
|
|
b38b0f |
+ sizes[1] = MAX(4096, sizes[0]);
|
|
|
b38b0f |
/* maximum - At most 32M, but smaller as appropriate. */
|
|
|
b38b0f |
sizes[2] = MIN(blk_get_max_transfer(exp->blk), NBD_MAX_BUFFER_SIZE);
|
|
|
b38b0f |
trace_nbd_negotiate_handle_info_block_size(sizes[0], sizes[1], sizes[2]);
|
|
|
b38b0f |
--
|
|
|
b38b0f |
1.8.3.1
|
|
|
b38b0f |
|