[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[PATCH v2 14/15] RFC: nbd/client: Accept 64-bit hole chunks
From: |
Eric Blake |
Subject: |
[PATCH v2 14/15] RFC: nbd/client: Accept 64-bit hole chunks |
Date: |
Mon, 14 Nov 2022 16:48:47 -0600 |
As part of adding extended headers, the NBD spec debated about adding
support for reading 64-bit holes. It was documented in a separate
upstream commit XXX[*] to make it easier to decide whether 64-bit
holes should be required of all clients supporting extended headers,
or whether it is an unneeded feature; hence, the qemu work to support
it is also pulled out into a separate commit.
Note that we can also tolerate a non-compliant server sending the new
chunk even when it should not.
Signed-off-by: Eric Blake <eblake@redhat.com>
---
[*] Fix commit id if we actually go with idea
---
include/block/nbd.h | 8 ++++++++
block/nbd.c | 26 ++++++++++++++++++++------
nbd/common.c | 4 +++-
3 files changed, 31 insertions(+), 7 deletions(-)
diff --git a/include/block/nbd.h b/include/block/nbd.h
index 2a65c606c9..18b6bad038 100644
--- a/include/block/nbd.h
+++ b/include/block/nbd.h
@@ -133,6 +133,13 @@ typedef struct NBDStructuredReadHole {
uint32_t length;
} QEMU_PACKED NBDStructuredReadHole;
+/* Complete chunk for NBD_REPLY_TYPE_OFFSET_HOLE_EXT */
+typedef struct NBDStructuredReadHoleExt {
+ /* header's length == 16 */
+ uint64_t offset;
+ uint64_t length;
+} QEMU_PACKED NBDStructuredReadHoleExt;
+
/* Header of all NBD_REPLY_TYPE_ERROR* errors */
typedef struct NBDStructuredError {
/* header's length >= 6 */
@@ -309,6 +316,7 @@ enum {
#define NBD_REPLY_TYPE_NONE 0
#define NBD_REPLY_TYPE_OFFSET_DATA 1
#define NBD_REPLY_TYPE_OFFSET_HOLE 2
+#define NBD_REPLY_TYPE_OFFSET_HOLE_EXT 3
#define NBD_REPLY_TYPE_BLOCK_STATUS 5
#define NBD_REPLY_TYPE_BLOCK_STATUS_EXT 6
#define NBD_REPLY_TYPE_ERROR NBD_REPLY_ERR(1)
diff --git a/block/nbd.c b/block/nbd.c
index 44ab5437ea..968d5d8a37 100644
--- a/block/nbd.c
+++ b/block/nbd.c
@@ -570,20 +570,26 @@ static inline uint64_t payload_advance64(uint8_t
**payload)
static int nbd_parse_offset_hole_payload(BDRVNBDState *s,
NBDStructuredReplyChunk *chunk,
- uint8_t *payload, uint64_t
orig_offset,
+ uint8_t *payload, bool wide,
+ uint64_t orig_offset,
QEMUIOVector *qiov, Error **errp)
{
uint64_t offset;
- uint32_t hole_size;
+ uint64_t hole_size;
+ size_t len = wide ? sizeof(hole_size) : sizeof(uint32_t);
- if (chunk->length != sizeof(offset) + sizeof(hole_size)) {
+ if (chunk->length != sizeof(offset) + len) {
error_setg(errp, "Protocol error: invalid payload for "
"NBD_REPLY_TYPE_OFFSET_HOLE");
return -EINVAL;
}
offset = payload_advance64(&payload);
- hole_size = payload_advance32(&payload);
+ if (wide) {
+ hole_size = payload_advance64(&payload);
+ } else {
+ hole_size = payload_advance32(&payload);
+ }
if (!hole_size || offset < orig_offset || hole_size > qiov->size ||
offset > orig_offset + qiov->size - hole_size) {
@@ -596,6 +602,7 @@ static int nbd_parse_offset_hole_payload(BDRVNBDState *s,
trace_nbd_structured_read_compliance("hole");
}
+ assert(hole_size <= SIZE_MAX);
qemu_iovec_memset(qiov, offset - orig_offset, 0, hole_size);
return 0;
@@ -1094,9 +1101,16 @@ static int coroutine_fn
nbd_co_receive_cmdread_reply(BDRVNBDState *s, uint64_t h
* in qiov
*/
break;
+ case NBD_REPLY_TYPE_OFFSET_HOLE_EXT:
+ if (!s->info.extended_headers) {
+ trace_nbd_extended_headers_compliance("hole_ext");
+ }
+ /* fallthrough */
case NBD_REPLY_TYPE_OFFSET_HOLE:
- ret = nbd_parse_offset_hole_payload(s, &reply.structured, payload,
- offset, qiov, &local_err);
+ ret = nbd_parse_offset_hole_payload(
+ s, &reply.structured, payload,
+ chunk->type == NBD_REPLY_TYPE_OFFSET_HOLE_EXT,
+ offset, qiov, &local_err);
if (ret < 0) {
nbd_channel_error(s, ret);
nbd_iter_channel_error(&iter, ret, &local_err);
diff --git a/nbd/common.c b/nbd/common.c
index 137466defd..54f7d6a4fd 100644
--- a/nbd/common.c
+++ b/nbd/common.c
@@ -174,7 +174,9 @@ const char *nbd_reply_type_lookup(uint16_t type)
case NBD_REPLY_TYPE_OFFSET_DATA:
return "data";
case NBD_REPLY_TYPE_OFFSET_HOLE:
- return "hole";
+ return "hole (32-bit)";
+ case NBD_REPLY_TYPE_OFFSET_HOLE_EXT:
+ return "hole (64-bit)";
case NBD_REPLY_TYPE_BLOCK_STATUS:
return "block status (32-bit)";
case NBD_REPLY_TYPE_BLOCK_STATUS_EXT:
--
2.38.1
- [libnbd PATCH v2 08/23] block_status: Track 64-bit extents internally, (continued)
- [libnbd PATCH v2 08/23] block_status: Track 64-bit extents internally, Eric Blake, 2022/11/14
- [libnbd PATCH v2 01/23] block_status: Refactor array storage, Eric Blake, 2022/11/14
- [libnbd PATCH v2 05/23] states: Prepare to receive 64-bit replies, Eric Blake, 2022/11/14
- [libnbd PATCH v2 18/23] generator: Actually request extended headers, Eric Blake, 2022/11/14
- [libnbd PATCH v2 20/23] interop: Add test of 64-bit block status, Eric Blake, 2022/11/14
- [libnbd PATCH v2 06/23] states: Break deadlock if server goofs on extended replies, Eric Blake, 2022/11/14
- [libnbd PATCH v2 17/23] ocaml: Add example for 64-bit extents, Eric Blake, 2022/11/14
- [libnbd PATCH v2 07/23] generator: Add struct nbd_extent in prep for 64-bit extents, Eric Blake, 2022/11/14
- [PATCH v2 00/15] qemu patches for 64-bit NBD extensions, Eric Blake, 2022/11/14
- [PATCH v2 15/15] RFC: nbd/server: Send 64-bit hole chunk, Eric Blake, 2022/11/14
- [PATCH v2 14/15] RFC: nbd/client: Accept 64-bit hole chunks,
Eric Blake <=
- [PATCH v2 06/15] nbd/server: Refactor to pass full request around, Eric Blake, 2022/11/14
- [PATCH v2 11/15] nbd/client: Request extended headers during negotiation, Eric Blake, 2022/11/14
- [PATCH v2 12/15] nbd/server: Prepare for per-request filtering of BLOCK_STATUS, Eric Blake, 2022/11/14
- [PATCH v2 13/15] nbd/server: Add FLAG_PAYLOAD support to CMD_BLOCK_STATUS, Eric Blake, 2022/11/14
- [PATCH v2 10/15] nbd/client: Accept 64-bit block status chunks, Eric Blake, 2022/11/14
- [PATCH v2 07/15] nbd/server: Initial support for extended headers, Eric Blake, 2022/11/14
- [PATCH v2 03/15] nbd: Prepare for 64-bit request effect lengths, Eric Blake, 2022/11/14
- [PATCH v2 09/15] nbd/client: Initial support for extended headers, Eric Blake, 2022/11/14
- [PATCH v2 05/15] nbd/server: Refactor handling of request payload, Eric Blake, 2022/11/14
- [PATCH v2 08/15] nbd/server: Support 64-bit block status, Eric Blake, 2022/11/14