diff options
author | Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com> | 2021-06-10 13:07:52 +0300 |
---|---|---|
committer | Eric Blake <eblake@redhat.com> | 2021-06-18 10:59:54 -0500 |
commit | e9ba7788b0c4328f7123eccb60cbb68b0b62bacb (patch) | |
tree | 86c19d0c77f327928075d623a0509dfb7f4be3bc /block/nbd.c | |
parent | f58b2dfe3e815d0c8491b33c36622824e8a08e40 (diff) | |
download | qemu-e9ba7788b0c4328f7123eccb60cbb68b0b62bacb.zip qemu-e9ba7788b0c4328f7123eccb60cbb68b0b62bacb.tar.gz qemu-e9ba7788b0c4328f7123eccb60cbb68b0b62bacb.tar.bz2 |
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>
Diffstat (limited to 'block/nbd.c')
-rw-r--r-- | block/nbd.c | 100 |
1 files changed, 58 insertions, 42 deletions
diff --git a/block/nbd.c b/block/nbd.c index df9d241..240c6e1 100644 --- a/block/nbd.c +++ b/block/nbd.c @@ -314,6 +314,51 @@ static bool nbd_client_connecting_wait(BDRVNBDState *s) 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) { int ret; @@ -1575,49 +1620,13 @@ static int nbd_client_handshake(BlockDriverState *bs, Error **errp) s->sioc = NULL; 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) { - s->ioc = QIO_CHANNEL(s->sioc); - object_ref(OBJECT(s->ioc)); - } - - 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. - */ - { + ret = nbd_handle_updated_info(bs, errp); + if (ret < 0) { + /* + * 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 }; 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; } + + if (!s->ioc) { + s->ioc = QIO_CHANNEL(s->sioc); + object_ref(OBJECT(s->ioc)); + } + + return 0; } /* |