mirror of
https://github.com/Motorhead1991/qemu.git
synced 2025-08-05 08:43:55 -06:00
nbd/server: Enable initial support for extended headers
Time to start supporting clients that request extended headers. Now we can finally reach the code added across several previous patches. Even though the NBD spec has been altered to allow us to accept NBD_CMD_READ larger than the max payload size (provided our response is a hole or broken up over more than one data chunk), we are not planning to take advantage of that, and continue to cap NBD_CMD_READ to 32M regardless of header size. For NBD_CMD_WRITE_ZEROES and NBD_CMD_TRIM, the block layer already supports 64-bit operations without any effort on our part. For NBD_CMD_BLOCK_STATUS, the client's length is a hint, and the previous patch took care of implementing the required NBD_REPLY_TYPE_BLOCK_STATUS_EXT. We do not yet support clients that want to do request payload filtering of NBD_CMD_BLOCK_STATUS; that will be added in later patches, but is not essential for qemu as a client since qemu only requests the single context base:allocation. Signed-off-by: Eric Blake <eblake@redhat.com> Reviewed-by: Vladimir Sementsov-Ogievskiy <vsementsov@yandex-team.ru> Message-ID: <20230925192229.3186470-19-eblake@redhat.com>
This commit is contained in:
parent
bcc16cc19e
commit
9c1d261437
2 changed files with 22 additions and 0 deletions
21
nbd/server.c
21
nbd/server.c
|
@ -482,6 +482,10 @@ static int nbd_negotiate_handle_export_name(NBDClient *client, bool no_zeroes,
|
|||
[10 .. 133] reserved (0) [unless no_zeroes]
|
||||
*/
|
||||
trace_nbd_negotiate_handle_export_name();
|
||||
if (client->mode >= NBD_MODE_EXTENDED) {
|
||||
error_setg(errp, "Extended headers already negotiated");
|
||||
return -EINVAL;
|
||||
}
|
||||
if (client->optlen > NBD_MAX_STRING_SIZE) {
|
||||
error_setg(errp, "Bad length received");
|
||||
return -EINVAL;
|
||||
|
@ -1264,6 +1268,10 @@ static int nbd_negotiate_options(NBDClient *client, Error **errp)
|
|||
case NBD_OPT_STRUCTURED_REPLY:
|
||||
if (length) {
|
||||
ret = nbd_reject_length(client, false, errp);
|
||||
} else if (client->mode >= NBD_MODE_EXTENDED) {
|
||||
ret = nbd_negotiate_send_rep_err(
|
||||
client, NBD_REP_ERR_EXT_HEADER_REQD, errp,
|
||||
"extended headers already negotiated");
|
||||
} else if (client->mode >= NBD_MODE_STRUCTURED) {
|
||||
ret = nbd_negotiate_send_rep_err(
|
||||
client, NBD_REP_ERR_INVALID, errp,
|
||||
|
@ -1280,6 +1288,19 @@ static int nbd_negotiate_options(NBDClient *client, Error **errp)
|
|||
errp);
|
||||
break;
|
||||
|
||||
case NBD_OPT_EXTENDED_HEADERS:
|
||||
if (length) {
|
||||
ret = nbd_reject_length(client, false, errp);
|
||||
} else if (client->mode >= NBD_MODE_EXTENDED) {
|
||||
ret = nbd_negotiate_send_rep_err(
|
||||
client, NBD_REP_ERR_INVALID, errp,
|
||||
"extended headers already negotiated");
|
||||
} else {
|
||||
ret = nbd_negotiate_send_rep(client, NBD_REP_ACK, errp);
|
||||
client->mode = NBD_MODE_EXTENDED;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
ret = nbd_opt_drop(client, NBD_REP_ERR_UNSUP, errp,
|
||||
"Unsupported option %" PRIu32 " (%s)",
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue