diff options
-rw-r--r-- | nbd/server.c | 26 |
1 files changed, 15 insertions, 11 deletions
diff --git a/nbd/server.c b/nbd/server.c index 77fdecd..42d494b 100644 --- a/nbd/server.c +++ b/nbd/server.c @@ -104,8 +104,7 @@ static QTAILQ_HEAD(, NBDExport) exports = QTAILQ_HEAD_INITIALIZER(exports); * NBD_OPT_LIST_META_CONTEXT. */ typedef struct NBDExportMetaContexts { NBDExport *exp; - bool valid; /* means that negotiation of the option finished without - errors */ + size_t count; /* number of negotiated contexts */ bool base_allocation; /* export base:allocation context (block status) */ bool bitmap; /* export qemu:dirty-bitmap:<export bitmap name> */ } NBDExportMetaContexts; @@ -445,7 +444,9 @@ static int nbd_negotiate_handle_list(NBDClient *client, Error **errp) static void nbd_check_meta_export(NBDClient *client) { - client->export_meta.valid &= client->exp == client->export_meta.exp; + if (client->exp != client->export_meta.exp) { + client->export_meta.count = 0; + } } /* Send a reply to NBD_OPT_EXPORT_NAME. @@ -945,6 +946,7 @@ static int nbd_negotiate_meta_queries(NBDClient *client, NBDExportMetaContexts local_meta; uint32_t nb_queries; int i; + size_t count = 0; if (!client->structured_reply) { return nbd_opt_invalid(client, errp, @@ -1001,6 +1003,7 @@ static int nbd_negotiate_meta_queries(NBDClient *client, if (ret < 0) { return ret; } + count++; } if (meta->bitmap) { @@ -1014,11 +1017,12 @@ static int nbd_negotiate_meta_queries(NBDClient *client, if (ret < 0) { return ret; } + count++; } ret = nbd_negotiate_send_rep(client, NBD_REP_ACK, errp); if (ret == 0) { - meta->valid = true; + meta->count = count; } return ret; @@ -2337,18 +2341,16 @@ static coroutine_fn int nbd_handle_request(NBDClient *client, return nbd_send_generic_reply(client, request->handle, -EINVAL, "need non-zero length", errp); } - if (client->export_meta.valid && - (client->export_meta.base_allocation || - client->export_meta.bitmap)) - { + if (client->export_meta.count) { bool dont_fragment = request->flags & NBD_CMD_FLAG_REQ_ONE; + int contexts_remaining = client->export_meta.count; if (client->export_meta.base_allocation) { ret = nbd_co_send_block_status(client, request->handle, blk_bs(exp->common.blk), request->from, request->len, dont_fragment, - !client->export_meta.bitmap, + !--contexts_remaining, NBD_META_ID_BASE_ALLOCATION, errp); if (ret < 0) { @@ -2360,13 +2362,15 @@ static coroutine_fn int nbd_handle_request(NBDClient *client, ret = nbd_co_send_bitmap(client, request->handle, client->exp->export_bitmap, request->from, request->len, - dont_fragment, - true, NBD_META_ID_DIRTY_BITMAP, errp); + dont_fragment, !--contexts_remaining, + NBD_META_ID_DIRTY_BITMAP, errp); if (ret < 0) { return ret; } } + assert(!contexts_remaining); + return 0; } else { return nbd_send_generic_reply(client, request->handle, -EINVAL, |