aboutsummaryrefslogtreecommitdiff
path: root/nbd
diff options
context:
space:
mode:
Diffstat (limited to 'nbd')
-rw-r--r--nbd/client-connection.c4
-rw-r--r--nbd/client.c18
-rw-r--r--nbd/server.c31
3 files changed, 29 insertions, 24 deletions
diff --git a/nbd/client-connection.c b/nbd/client-connection.c
index 53a6549914..aa0201b710 100644
--- a/nbd/client-connection.c
+++ b/nbd/client-connection.c
@@ -1,5 +1,5 @@
/*
- * QEMU Block driver for NBD
+ * QEMU Block driver for NBD
*
* Copyright (c) 2021 Virtuozzo International GmbH.
*
@@ -93,7 +93,7 @@ NBDClientConnection *nbd_client_connection_new(const SocketAddress *saddr,
.do_negotiation = do_negotiation,
.initial_info.request_sizes = true,
- .initial_info.structured_reply = true,
+ .initial_info.mode = NBD_MODE_STRUCTURED,
.initial_info.base_allocation = true,
.initial_info.x_dirty_bitmap = g_strdup(x_dirty_bitmap),
.initial_info.name = g_strdup(export_name ?: "")
diff --git a/nbd/client.c b/nbd/client.c
index bd7e200136..844be42181 100644
--- a/nbd/client.c
+++ b/nbd/client.c
@@ -879,7 +879,7 @@ static int nbd_list_meta_contexts(QIOChannel *ioc,
*/
static int nbd_start_negotiate(QIOChannel *ioc, QCryptoTLSCreds *tlscreds,
const char *hostname, QIOChannel **outioc,
- bool structured_reply, bool *zeroes,
+ NBDMode max_mode, bool *zeroes,
Error **errp)
{
ERRP_GUARD();
@@ -953,7 +953,7 @@ static int nbd_start_negotiate(QIOChannel *ioc, QCryptoTLSCreds *tlscreds,
if (fixedNewStyle) {
int result = 0;
- if (structured_reply) {
+ if (max_mode >= NBD_MODE_STRUCTURED) {
result = nbd_request_simple_option(ioc,
NBD_OPT_STRUCTURED_REPLY,
false, errp);
@@ -1022,20 +1022,19 @@ int nbd_receive_negotiate(QIOChannel *ioc, QCryptoTLSCreds *tlscreds,
trace_nbd_receive_negotiate_name(info->name);
result = nbd_start_negotiate(ioc, tlscreds, hostname, outioc,
- info->structured_reply, &zeroes, errp);
+ info->mode, &zeroes, errp);
if (result < 0) {
return result;
}
- info->structured_reply = false;
+ info->mode = result;
info->base_allocation = false;
if (tlscreds && *outioc) {
ioc = *outioc;
}
- switch ((NBDMode)result) {
+ switch (info->mode) {
case NBD_MODE_STRUCTURED:
- info->structured_reply = true;
if (base_allocation) {
result = nbd_negotiate_simple_meta_context(ioc, info, errp);
if (result < 0) {
@@ -1144,8 +1143,8 @@ int nbd_receive_export_list(QIOChannel *ioc, QCryptoTLSCreds *tlscreds,
QIOChannel *sioc = NULL;
*info = NULL;
- result = nbd_start_negotiate(ioc, tlscreds, hostname, &sioc, true,
- NULL, errp);
+ result = nbd_start_negotiate(ioc, tlscreds, hostname, &sioc,
+ NBD_MODE_STRUCTURED, NULL, errp);
if (tlscreds && sioc) {
ioc = sioc;
}
@@ -1176,7 +1175,7 @@ int nbd_receive_export_list(QIOChannel *ioc, QCryptoTLSCreds *tlscreds,
memset(&array[count - 1], 0, sizeof(*array));
array[count - 1].name = name;
array[count - 1].description = desc;
- array[count - 1].structured_reply = result == NBD_MODE_STRUCTURED;
+ array[count - 1].mode = result;
}
for (i = 0; i < count; i++) {
@@ -1209,6 +1208,7 @@ int nbd_receive_export_list(QIOChannel *ioc, QCryptoTLSCreds *tlscreds,
/* Lone export name is implied, but we can parse length and flags */
array = g_new0(NBDExportInfo, 1);
array->name = g_strdup("");
+ array->mode = NBD_MODE_OLDSTYLE;
count = 1;
if (nbd_negotiate_finish_oldstyle(ioc, array, errp) < 0) {
diff --git a/nbd/server.c b/nbd/server.c
index b5f93a20c9..936c35e55c 100644
--- a/nbd/server.c
+++ b/nbd/server.c
@@ -143,7 +143,7 @@ struct NBDClient {
uint32_t check_align; /* If non-zero, check for aligned client requests */
- bool structured_reply;
+ NBDMode mode;
NBDExportMetaContexts export_meta;
uint32_t opt; /* Current option being negotiated */
@@ -502,7 +502,7 @@ static int nbd_negotiate_handle_export_name(NBDClient *client, bool no_zeroes,
}
myflags = client->exp->nbdflags;
- if (client->structured_reply) {
+ if (client->mode >= NBD_MODE_STRUCTURED) {
myflags |= NBD_FLAG_SEND_DF;
}
trace_nbd_negotiate_new_style_size_flags(client->exp->size, myflags);
@@ -687,7 +687,7 @@ static int nbd_negotiate_handle_info(NBDClient *client, Error **errp)
/* Send NBD_INFO_EXPORT always */
myflags = exp->nbdflags;
- if (client->structured_reply) {
+ if (client->mode >= NBD_MODE_STRUCTURED) {
myflags |= NBD_FLAG_SEND_DF;
}
trace_nbd_negotiate_new_style_size_flags(exp->size, myflags);
@@ -985,7 +985,8 @@ static int nbd_negotiate_meta_queries(NBDClient *client,
size_t i;
size_t count = 0;
- if (client->opt == NBD_OPT_SET_META_CONTEXT && !client->structured_reply) {
+ if (client->opt == NBD_OPT_SET_META_CONTEXT &&
+ client->mode < NBD_MODE_STRUCTURED) {
return nbd_opt_invalid(client, errp,
"request option '%s' when structured reply "
"is not negotiated",
@@ -1122,10 +1123,12 @@ static int nbd_negotiate_options(NBDClient *client, Error **errp)
if (nbd_read32(client->ioc, &flags, "flags", errp) < 0) {
return -EIO;
}
+ client->mode = NBD_MODE_EXPORT_NAME;
trace_nbd_negotiate_options_flags(flags);
if (flags & NBD_FLAG_C_FIXED_NEWSTYLE) {
fixedNewstyle = true;
flags &= ~NBD_FLAG_C_FIXED_NEWSTYLE;
+ client->mode = NBD_MODE_SIMPLE;
}
if (flags & NBD_FLAG_C_NO_ZEROES) {
no_zeroes = true;
@@ -1261,13 +1264,13 @@ 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->structured_reply) {
+ } else if (client->mode >= NBD_MODE_STRUCTURED) {
ret = nbd_negotiate_send_rep_err(
client, NBD_REP_ERR_INVALID, errp,
"structured reply already negotiated");
} else {
ret = nbd_negotiate_send_rep(client, NBD_REP_ACK, errp);
- client->structured_reply = true;
+ client->mode = NBD_MODE_STRUCTURED;
}
break;
@@ -1895,7 +1898,9 @@ static int coroutine_fn nbd_co_send_simple_reply(NBDClient *client,
};
assert(!len || !nbd_err);
- assert(!client->structured_reply || request->type != NBD_CMD_READ);
+ assert(client->mode < NBD_MODE_STRUCTURED ||
+ (client->mode == NBD_MODE_STRUCTURED &&
+ request->type != NBD_CMD_READ));
trace_nbd_co_send_simple_reply(request->cookie, nbd_err,
nbd_err_lookup(nbd_err), len);
set_be_simple_reply(&reply, nbd_err, request->cookie);
@@ -1971,7 +1976,7 @@ static int coroutine_fn nbd_co_send_chunk_read(NBDClient *client,
return nbd_co_send_iov(client, iov, 3, errp);
}
-/*ebb*/
+
static int coroutine_fn nbd_co_send_chunk_error(NBDClient *client,
NBDRequest *request,
uint32_t error,
@@ -2397,7 +2402,7 @@ static int coroutine_fn nbd_co_receive_request(NBDRequestData *req, NBDRequest *
client->check_align);
}
valid_flags = NBD_CMD_FLAG_FUA;
- if (request->type == NBD_CMD_READ && client->structured_reply) {
+ if (request->type == NBD_CMD_READ && client->mode >= NBD_MODE_STRUCTURED) {
valid_flags |= NBD_CMD_FLAG_DF;
} else if (request->type == NBD_CMD_WRITE_ZEROES) {
valid_flags |= NBD_CMD_FLAG_NO_HOLE | NBD_CMD_FLAG_FAST_ZERO;
@@ -2423,7 +2428,7 @@ static coroutine_fn int nbd_send_generic_reply(NBDClient *client,
const char *error_msg,
Error **errp)
{
- if (client->structured_reply && ret < 0) {
+ if (client->mode >= NBD_MODE_STRUCTURED && ret < 0) {
return nbd_co_send_chunk_error(client, request, -ret, error_msg, errp);
} else {
return nbd_co_send_simple_reply(client, request, ret < 0 ? -ret : 0,
@@ -2451,8 +2456,8 @@ static coroutine_fn int nbd_do_cmd_read(NBDClient *client, NBDRequest *request,
}
}
- if (client->structured_reply && !(request->flags & NBD_CMD_FLAG_DF) &&
- request->len)
+ if (client->mode >= NBD_MODE_STRUCTURED &&
+ !(request->flags & NBD_CMD_FLAG_DF) && request->len)
{
return nbd_co_send_sparse_read(client, request, request->from,
data, request->len, errp);
@@ -2464,7 +2469,7 @@ static coroutine_fn int nbd_do_cmd_read(NBDClient *client, NBDRequest *request,
"reading from file failed", errp);
}
- if (client->structured_reply) {
+ if (client->mode >= NBD_MODE_STRUCTURED) {
if (request->len) {
return nbd_co_send_chunk_read(client, request, request->from, data,
request->len, true, errp);