block/nbd: split nbd_handle_updated_info out of nbd_client_handshake()

To be reused in the following patch.

Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
Reviewed-by: Roman Kagan <rvkagan@yandex-team.ru>
Reviewed-by: Eric Blake <eblake@redhat.com>
Message-Id: <20210610100802.5888-23-vsementsov@virtuozzo.com>
Signed-off-by: Eric Blake <eblake@redhat.com>
This commit is contained in:
Vladimir Sementsov-Ogievskiy 2021-06-10 13:07:52 +03:00 committed by Eric Blake
parent f58b2dfe3e
commit e9ba7788b0
1 changed files with 58 additions and 42 deletions

View File

@ -314,6 +314,51 @@ static bool nbd_client_connecting_wait(BDRVNBDState *s)
return qatomic_load_acquire(&s->state) == NBD_CLIENT_CONNECTING_WAIT; return qatomic_load_acquire(&s->state) == NBD_CLIENT_CONNECTING_WAIT;
} }
/*
* Update @bs with information learned during a completed negotiation process.
* Return failure if the server's advertised options are incompatible with the
* client's needs.
*/
static int nbd_handle_updated_info(BlockDriverState *bs, Error **errp)
{
BDRVNBDState *s = (BDRVNBDState *)bs->opaque;
int ret;
if (s->x_dirty_bitmap) {
if (!s->info.base_allocation) {
error_setg(errp, "requested x-dirty-bitmap %s not found",
s->x_dirty_bitmap);
return -EINVAL;
}
if (strcmp(s->x_dirty_bitmap, "qemu:allocation-depth") == 0) {
s->alloc_depth = true;
}
}
if (s->info.flags & NBD_FLAG_READ_ONLY) {
ret = bdrv_apply_auto_read_only(bs, "NBD export is read-only", errp);
if (ret < 0) {
return ret;
}
}
if (s->info.flags & NBD_FLAG_SEND_FUA) {
bs->supported_write_flags = BDRV_REQ_FUA;
bs->supported_zero_flags |= BDRV_REQ_FUA;
}
if (s->info.flags & NBD_FLAG_SEND_WRITE_ZEROES) {
bs->supported_zero_flags |= BDRV_REQ_MAY_UNMAP;
if (s->info.flags & NBD_FLAG_SEND_FAST_ZERO) {
bs->supported_zero_flags |= BDRV_REQ_NO_FALLBACK;
}
}
trace_nbd_client_handshake_success(s->export);
return 0;
}
static coroutine_fn void nbd_reconnect_attempt(BDRVNBDState *s) static coroutine_fn void nbd_reconnect_attempt(BDRVNBDState *s)
{ {
int ret; int ret;
@ -1575,49 +1620,13 @@ static int nbd_client_handshake(BlockDriverState *bs, Error **errp)
s->sioc = NULL; s->sioc = NULL;
return ret; return ret;
} }
if (s->x_dirty_bitmap) {
if (!s->info.base_allocation) {
error_setg(errp, "requested x-dirty-bitmap %s not found",
s->x_dirty_bitmap);
ret = -EINVAL;
goto fail;
}
if (strcmp(s->x_dirty_bitmap, "qemu:allocation-depth") == 0) {
s->alloc_depth = true;
}
}
if (s->info.flags & NBD_FLAG_READ_ONLY) {
ret = bdrv_apply_auto_read_only(bs, "NBD export is read-only", errp);
if (ret < 0) {
goto fail;
}
}
if (s->info.flags & NBD_FLAG_SEND_FUA) {
bs->supported_write_flags = BDRV_REQ_FUA;
bs->supported_zero_flags |= BDRV_REQ_FUA;
}
if (s->info.flags & NBD_FLAG_SEND_WRITE_ZEROES) {
bs->supported_zero_flags |= BDRV_REQ_MAY_UNMAP;
if (s->info.flags & NBD_FLAG_SEND_FAST_ZERO) {
bs->supported_zero_flags |= BDRV_REQ_NO_FALLBACK;
}
}
if (!s->ioc) { ret = nbd_handle_updated_info(bs, errp);
s->ioc = QIO_CHANNEL(s->sioc); if (ret < 0) {
object_ref(OBJECT(s->ioc)); /*
} * We have connected, but must fail for other reasons.
* Send NBD_CMD_DISC as a courtesy to the server.
trace_nbd_client_handshake_success(s->export); */
return 0;
fail:
/*
* We have connected, but must fail for other reasons.
* Send NBD_CMD_DISC as a courtesy to the server.
*/
{
NBDRequest request = { .type = NBD_CMD_DISC }; NBDRequest request = { .type = NBD_CMD_DISC };
nbd_send_request(s->ioc ?: QIO_CHANNEL(s->sioc), &request); nbd_send_request(s->ioc ?: QIO_CHANNEL(s->sioc), &request);
@ -1631,6 +1640,13 @@ static int nbd_client_handshake(BlockDriverState *bs, Error **errp)
return ret; return ret;
} }
if (!s->ioc) {
s->ioc = QIO_CHANNEL(s->sioc);
object_ref(OBJECT(s->ioc));
}
return 0;
} }
/* /*