qemu with hax to log dma reads & writes jcs.org/2018/11/12/vfio

nbd: Prepare for NBD_CMD_FLAG_FAST_ZERO

Commit fe0480d6 and friends added BDRV_REQ_NO_FALLBACK as a way to
avoid wasting time on a preliminary write-zero request that will later
be rewritten by actual data, if it is known that the write-zero
request will use a slow fallback; but in doing so, could not optimize
for NBD. The NBD specification is now considering an extension that
will allow passing on those semantics; this patch updates the new
protocol bits and 'qemu-nbd --list' output to recognize the bit, as
well as the new errno value possible when using the new flag; while
upcoming patches will improve the client to use the feature when
present, and the server to advertise support for it.

The NBD spec recommends (but not requires) that ENOTSUP be avoided for
all but failures of a fast zero (the only time it is mandatory to
avoid an ENOTSUP failure is when fast zero is supported but not
requested during write zeroes; the questionable use is for ENOTSUP to
other actions like a normal write request). However, clients that get
an unexpected ENOTSUP will either already be treating it the same as
EINVAL, or may appreciate the extra bit of information. We were
equally loose for returning EOVERFLOW in more situations than
recommended by the spec, so if it turns out to be a problem in
practice, a later patch can tighten handling for both error codes.

Signed-off-by: Eric Blake <eblake@redhat.com>
Message-Id: <20190823143726.27062-3-eblake@redhat.com>
Reviewed-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
[eblake: tweak commit message, also handle EOPNOTSUPP]

+17 -1
+2 -1
docs/interop/nbd.txt
··· 53 53 * 2.12: NBD_CMD_BLOCK_STATUS for "base:allocation" 54 54 * 3.0: NBD_OPT_STARTTLS with TLS Pre-Shared Keys (PSK), 55 55 NBD_CMD_BLOCK_STATUS for "qemu:dirty-bitmap:", NBD_CMD_CACHE 56 - * 4.2: NBD_FLAG_CAN_MULTI_CONN for sharable read-only exports 56 + * 4.2: NBD_FLAG_CAN_MULTI_CONN for sharable read-only exports, 57 + NBD_CMD_FLAG_FAST_ZERO
+4
include/block/nbd.h
··· 140 140 NBD_FLAG_CAN_MULTI_CONN_BIT = 8, /* Multi-client cache consistent */ 141 141 NBD_FLAG_SEND_RESIZE_BIT = 9, /* Send resize */ 142 142 NBD_FLAG_SEND_CACHE_BIT = 10, /* Send CACHE (prefetch) */ 143 + NBD_FLAG_SEND_FAST_ZERO_BIT = 11, /* FAST_ZERO flag for WRITE_ZEROES */ 143 144 }; 144 145 145 146 #define NBD_FLAG_HAS_FLAGS (1 << NBD_FLAG_HAS_FLAGS_BIT) ··· 153 154 #define NBD_FLAG_CAN_MULTI_CONN (1 << NBD_FLAG_CAN_MULTI_CONN_BIT) 154 155 #define NBD_FLAG_SEND_RESIZE (1 << NBD_FLAG_SEND_RESIZE_BIT) 155 156 #define NBD_FLAG_SEND_CACHE (1 << NBD_FLAG_SEND_CACHE_BIT) 157 + #define NBD_FLAG_SEND_FAST_ZERO (1 << NBD_FLAG_SEND_FAST_ZERO_BIT) 156 158 157 159 /* New-style handshake (global) flags, sent from server to client, and 158 160 control what will happen during handshake phase. */ ··· 205 207 #define NBD_CMD_FLAG_DF (1 << 2) /* don't fragment structured read */ 206 208 #define NBD_CMD_FLAG_REQ_ONE (1 << 3) /* only one extent in BLOCK_STATUS 207 209 * reply chunk */ 210 + #define NBD_CMD_FLAG_FAST_ZERO (1 << 4) /* fail if WRITE_ZEROES is not fast */ 208 211 209 212 /* Supported request types */ 210 213 enum { ··· 270 273 #define NBD_EINVAL 22 271 274 #define NBD_ENOSPC 28 272 275 #define NBD_EOVERFLOW 75 276 + #define NBD_ENOTSUP 95 273 277 #define NBD_ESHUTDOWN 108 274 278 275 279 /* Details collected by NBD_OPT_EXPORT_NAME and NBD_OPT_GO */
+5
nbd/common.c
··· 201 201 return "ENOSPC"; 202 202 case NBD_EOVERFLOW: 203 203 return "EOVERFLOW"; 204 + case NBD_ENOTSUP: 205 + return "ENOTSUP"; 204 206 case NBD_ESHUTDOWN: 205 207 return "ESHUTDOWN"; 206 208 default: ··· 230 232 break; 231 233 case NBD_EOVERFLOW: 232 234 ret = EOVERFLOW; 235 + break; 236 + case NBD_ENOTSUP: 237 + ret = ENOTSUP; 233 238 break; 234 239 case NBD_ESHUTDOWN: 235 240 ret = ESHUTDOWN;
+5
nbd/server.c
··· 55 55 return NBD_ENOSPC; 56 56 case EOVERFLOW: 57 57 return NBD_EOVERFLOW; 58 + case ENOTSUP: 59 + #if ENOTSUP != EOPNOTSUPP 60 + case EOPNOTSUPP: 61 + #endif 62 + return NBD_ENOTSUP; 58 63 case ESHUTDOWN: 59 64 return NBD_ESHUTDOWN; 60 65 case EINVAL:
+1
qemu-nbd.c
··· 294 294 [NBD_FLAG_CAN_MULTI_CONN_BIT] = "multi", 295 295 [NBD_FLAG_SEND_RESIZE_BIT] = "resize", 296 296 [NBD_FLAG_SEND_CACHE_BIT] = "cache", 297 + [NBD_FLAG_SEND_FAST_ZERO_BIT] = "fast-zero", 297 298 }; 298 299 299 300 printf(" size: %" PRIu64 "\n", list[i].size);