/*
 * QEMU Block driver for NBD
 *
 * Copyright (c) 2019 Virtuozzo International GmbH.
 * Copyright Red Hat
 * Copyright (C) 2008 Bull S.A.S.
 *     Author: Laurent Vivier <Laurent.Vivier@bull.net>
 *
 * Some parts:
 *    Copyright (C) 2007 Anthony Liguori <anthony@codemonkey.ws>
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 */

#include "qemu/osdep.h"

#include "trace.h"
#include "qemu/option.h"
#include "qemu/cutils.h"
#include "qemu/main-loop.h"

#include "qapi/qapi-visit-sockets.h"
#include "qapi/qmp/qstring.h"
#include "qapi/clone-visitor.h"

#include "block/qdict.h"
#include "block/nbd.h"
#include "block/block_int.h"
#include "block/coroutines.h"

#include "qemu/yank.h"

#define EN_OPTSTR ":exportname="
#define MAX_NBD_REQUESTS    16

#define COOKIE_TO_INDEX(cookie) ((cookie) - 1)
#define INDEX_TO_COOKIE(index)  ((index) + 1)

typedef struct {
    Coroutine *coroutine;
    uint64_t offset;        /* original offset of the request */
    bool receiving;         /* sleeping in the yield in nbd_receive_replies */
} NBDClientRequest;

typedef enum NBDClientState {
    NBD_CLIENT_CONNECTING_WAIT,
    NBD_CLIENT_CONNECTING_NOWAIT,
    NBD_CLIENT_CONNECTED,
    NBD_CLIENT_QUIT
} NBDClientState;

typedef struct BDRVNBDState {
    QIOChannel *ioc; /* The current I/O channel */
    NBDExportInfo info;

    /*
     * Protects state, free_sema, in_flight, requests[].coroutine,
     * reconnect_delay_timer.
     */
    QemuMutex requests_lock;
    NBDClientState state;
    CoQueue free_sema;
    unsigned in_flight;
    NBDClientRequest requests[MAX_NBD_REQUESTS];
    QEMUTimer *reconnect_delay_timer;

    /* Protects sending data on the socket.  */
    CoMutex send_mutex;

    /*
     * Protects receiving reply headers from the socket, as well as the
     * fields reply and requests[].receiving
     */
    CoMutex receive_mutex;
    NBDReply reply;

    QEMUTimer *open_timer;

    BlockDriverState *bs;

    /* Connection parameters */
    uint32_t reconnect_delay;
    uint32_t open_timeout;
    SocketAddress *saddr;
    char *export;
    char *tlscredsid;
    QCryptoTLSCreds *tlscreds;
    char *tlshostname;
    char *x_dirty_bitmap;
    bool alloc_depth;

    NBDClientConnection *conn;
} BDRVNBDState;

static void nbd_yank(void *opaque);

static void nbd_clear_bdrvstate(BlockDriverState *bs)
{
    BDRVNBDState *s = (BDRVNBDState *)bs->opaque;

    nbd_client_connection_release(s->conn);
    s->conn = NULL;

    yank_unregister_instance(BLOCKDEV_YANK_INSTANCE(bs->node_name));

    /* Must not leave timers behind that would access freed data */
    assert(!s->reconnect_delay_timer);
    assert(!s->open_timer);

    object_unref(OBJECT(s->tlscreds));
    qapi_free_SocketAddress(s->saddr);
    s->saddr = NULL;
    g_free(s->export);
    s->export = NULL;
    g_free(s->tlscredsid);
    s->tlscredsid = NULL;
    g_free(s->tlshostname);
    s->tlshostname = NULL;
    g_free(s->x_dirty_bitmap);
    s->x_dirty_bitmap = NULL;
}

/* Called with s->receive_mutex taken.  */
static bool coroutine_fn nbd_recv_coroutine_wake_one(NBDClientRequest *req)
{
    if (req->receiving) {
        req->receiving = false;
        aio_co_wake(req->coroutine);
        return true;
    }

    return false;
}

static void coroutine_fn nbd_recv_coroutines_wake(BDRVNBDState *s)
{
    int i;

    QEMU_LOCK_GUARD(&s->receive_mutex);
    for (i = 0; i < MAX_NBD_REQUESTS; i++) {
        if (nbd_recv_coroutine_wake_one(&s->requests[i])) {
            return;
        }
    }
}

/* Called with s->requests_lock held.  */
static void coroutine_fn nbd_channel_error_locked(BDRVNBDState *s, int ret)
{
    if (s->state == NBD_CLIENT_CONNECTED) {
        qio_channel_shutdown(s->ioc, QIO_CHANNEL_SHUTDOWN_BOTH, NULL);
    }

    if (ret == -EIO) {
        if (s->state == NBD_CLIENT_CONNECTED) {
            s->state = s->reconnect_delay ? NBD_CLIENT_CONNECTING_WAIT :
                                            NBD_CLIENT_CONNECTING_NOWAIT;
        }
    } else {
        s->state = NBD_CLIENT_QUIT;
    }
}

static void coroutine_fn nbd_channel_error(BDRVNBDState *s, int ret)
{
    QEMU_LOCK_GUARD(&s->requests_lock);
    nbd_channel_error_locked(s, ret);
}

static void reconnect_delay_timer_del(BDRVNBDState *s)
{
    if (s->reconnect_delay_timer) {
        timer_free(s->reconnect_delay_timer);
        s->reconnect_delay_timer = NULL;
    }
}

static void reconnect_delay_timer_cb(void *opaque)
{
    BDRVNBDState *s = opaque;

    reconnect_delay_timer_del(s);
    WITH_QEMU_LOCK_GUARD(&s->requests_lock) {
        if (s->state != NBD_CLIENT_CONNECTING_WAIT) {
            return;
        }
        s->state = NBD_CLIENT_CONNECTING_NOWAIT;
    }
    nbd_co_establish_connection_cancel(s->conn);
}

static void reconnect_delay_timer_init(BDRVNBDState *s, uint64_t expire_time_ns)
{
    assert(!s->reconnect_delay_timer);
    s->reconnect_delay_timer = aio_timer_new(bdrv_get_aio_context(s->bs),
                                             QEMU_CLOCK_REALTIME,
                                             SCALE_NS,
                                             reconnect_delay_timer_cb, s);
    timer_mod(s->reconnect_delay_timer, expire_time_ns);
}

static void nbd_teardown_connection(BlockDriverState *bs)
{
    BDRVNBDState *s = (BDRVNBDState *)bs->opaque;

    assert(!s->in_flight);

    if (s->ioc) {
        qio_channel_shutdown(s->ioc, QIO_CHANNEL_SHUTDOWN_BOTH, NULL);
        yank_unregister_function(BLOCKDEV_YANK_INSTANCE(s->bs->node_name),
                                 nbd_yank, s->bs);
        object_unref(OBJECT(s->ioc));
        s->ioc = NULL;
    }

    WITH_QEMU_LOCK_GUARD(&s->requests_lock) {
        s->state = NBD_CLIENT_QUIT;
    }
}

static void open_timer_del(BDRVNBDState *s)
{
    if (s->open_timer) {
        timer_free(s->open_timer);
        s->open_timer = NULL;
    }
}

static void open_timer_cb(void *opaque)
{
    BDRVNBDState *s = opaque;

    nbd_co_establish_connection_cancel(s->conn);
    open_timer_del(s);
}

static void open_timer_init(BDRVNBDState *s, uint64_t expire_time_ns)
{
    assert(!s->open_timer);
    s->open_timer = aio_timer_new(bdrv_get_aio_context(s->bs),
                                  QEMU_CLOCK_REALTIME,
                                  SCALE_NS,
                                  open_timer_cb, s);
    timer_mod(s->open_timer, expire_time_ns);
}

static bool nbd_client_will_reconnect(BDRVNBDState *s)
{
    /*
     * Called only after a socket error, so this is not performance sensitive.
     */
    QEMU_LOCK_GUARD(&s->requests_lock);
    return 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 coroutine_fn GRAPH_RDLOCK
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;
}

int coroutine_fn nbd_co_do_establish_connection(BlockDriverState *bs,
                                                bool blocking, Error **errp)
{
    BDRVNBDState *s = (BDRVNBDState *)bs->opaque;
    int ret;
    IO_CODE();

    assert_bdrv_graph_readable();
    assert(!s->ioc);

    s->ioc = nbd_co_establish_connection(s->conn, &s->info, blocking, errp);
    if (!s->ioc) {
        return -ECONNREFUSED;
    }

    yank_register_function(BLOCKDEV_YANK_INSTANCE(s->bs->node_name), nbd_yank,
                           bs);

    ret = nbd_handle_updated_info(s->bs, NULL);
    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, .mode = s->info.mode };

        nbd_send_request(s->ioc, &request);

        yank_unregister_function(BLOCKDEV_YANK_INSTANCE(s->bs->node_name),
                                 nbd_yank, bs);
        object_unref(OBJECT(s->ioc));
        s->ioc = NULL;

        return ret;
    }

    qio_channel_set_blocking(s->ioc, false, NULL);
    qio_channel_set_follow_coroutine_ctx(s->ioc, true);

    /* successfully connected */
    WITH_QEMU_LOCK_GUARD(&s->requests_lock) {
        s->state = NBD_CLIENT_CONNECTED;
    }

    return 0;
}

/* Called with s->requests_lock held.  */
static bool nbd_client_connecting(BDRVNBDState *s)
{
    return s->state == NBD_CLIENT_CONNECTING_WAIT ||
        s->state == NBD_CLIENT_CONNECTING_NOWAIT;
}

/* Called with s->requests_lock taken.  */
static void coroutine_fn GRAPH_RDLOCK nbd_reconnect_attempt(BDRVNBDState *s)
{
    int ret;
    bool blocking = s->state == NBD_CLIENT_CONNECTING_WAIT;

    /*
     * Now we are sure that nobody is accessing the channel, and no one will
     * try until we set the state to CONNECTED.
     */
    assert(nbd_client_connecting(s));
    assert(s->in_flight == 1);

    trace_nbd_reconnect_attempt(s->bs->in_flight);

    if (blocking && !s->reconnect_delay_timer) {
        /*
         * It's the first reconnect attempt after switching to
         * NBD_CLIENT_CONNECTING_WAIT
         */
        g_assert(s->reconnect_delay);
        reconnect_delay_timer_init(s,
            qemu_clock_get_ns(QEMU_CLOCK_REALTIME) +
            s->reconnect_delay * NANOSECONDS_PER_SECOND);
    }

    /* Finalize previous connection if any */
    if (s->ioc) {
        yank_unregister_function(BLOCKDEV_YANK_INSTANCE(s->bs->node_name),
                                 nbd_yank, s->bs);
        object_unref(OBJECT(s->ioc));
        s->ioc = NULL;
    }

    qemu_mutex_unlock(&s->requests_lock);
    ret = nbd_co_do_establish_connection(s->bs, blocking, NULL);
    trace_nbd_reconnect_attempt_result(ret, s->bs->in_flight);
    qemu_mutex_lock(&s->requests_lock);

    /*
     * The reconnect attempt is done (maybe successfully, maybe not), so
     * we no longer need this timer.  Delete it so it will not outlive
     * this I/O request (so draining removes all timers).
     */
    reconnect_delay_timer_del(s);
}

static coroutine_fn int nbd_receive_replies(BDRVNBDState *s, uint64_t cookie,
                                            Error **errp)
{
    int ret;
    uint64_t ind = COOKIE_TO_INDEX(cookie), ind2;
    QEMU_LOCK_GUARD(&s->receive_mutex);

    while (true) {
        if (s->reply.cookie == cookie) {
            /* We are done */
            return 0;
        }

        if (s->reply.cookie != 0) {
            /*
             * Some other request is being handled now. It should already be
             * woken by whoever set s->reply.cookie (or never wait in this
             * yield). So, we should not wake it here.
             */
            ind2 = COOKIE_TO_INDEX(s->reply.cookie);
            assert(!s->requests[ind2].receiving);

            s->requests[ind].receiving = true;
            qemu_co_mutex_unlock(&s->receive_mutex);

            qemu_coroutine_yield();
            /*
             * We may be woken for 2 reasons:
             * 1. From this function, executing in parallel coroutine, when our
             *    cookie is received.
             * 2. From nbd_co_receive_one_chunk(), when previous request is
             *    finished and s->reply.cookie set to 0.
             * Anyway, it's OK to lock the mutex and go to the next iteration.
             */

            qemu_co_mutex_lock(&s->receive_mutex);
            assert(!s->requests[ind].receiving);
            continue;
        }

        /* We are under mutex and cookie is 0. We have to do the dirty work. */
        assert(s->reply.cookie == 0);
        ret = nbd_receive_reply(s->bs, s->ioc, &s->reply, s->info.mode, errp);
        if (ret == 0) {
            ret = -EIO;
            error_setg(errp, "server dropped connection");
        }
        if (ret < 0) {
            nbd_channel_error(s, ret);
            return ret;
        }
        if (nbd_reply_is_structured(&s->reply) &&
            s->info.mode < NBD_MODE_STRUCTURED) {
            nbd_channel_error(s, -EINVAL);
            error_setg(errp, "unexpected structured reply");
            return -EINVAL;
        }
        ind2 = COOKIE_TO_INDEX(s->reply.cookie);
        if (ind2 >= MAX_NBD_REQUESTS || !s->requests[ind2].coroutine) {
            nbd_channel_error(s, -EINVAL);
            error_setg(errp, "unexpected cookie value");
            return -EINVAL;
        }
        if (s->reply.cookie == cookie) {
            /* We are done */
            return 0;
        }
        nbd_recv_coroutine_wake_one(&s->requests[ind2]);
    }
}

static int coroutine_fn GRAPH_RDLOCK
nbd_co_send_request(BlockDriverState *bs, NBDRequest *request,
                    QEMUIOVector *qiov)
{
    BDRVNBDState *s = (BDRVNBDState *)bs->opaque;
    int rc, i = -1;

    qemu_mutex_lock(&s->requests_lock);
    while (s->in_flight == MAX_NBD_REQUESTS ||
           (s->state != NBD_CLIENT_CONNECTED && s->in_flight > 0)) {
        qemu_co_queue_wait(&s->free_sema, &s->requests_lock);
    }

    s->in_flight++;
    if (s->state != NBD_CLIENT_CONNECTED) {
        if (nbd_client_connecting(s)) {
            nbd_reconnect_attempt(s);
            qemu_co_queue_restart_all(&s->free_sema);
        }
        if (s->state != NBD_CLIENT_CONNECTED) {
            rc = -EIO;
            goto err;
        }
    }

    for (i = 0; i < MAX_NBD_REQUESTS; i++) {
        if (s->requests[i].coroutine == NULL) {
            break;
        }
    }

    assert(i < MAX_NBD_REQUESTS);
    s->requests[i].coroutine = qemu_coroutine_self();
    s->requests[i].offset = request->from;
    s->requests[i].receiving = false;
    qemu_mutex_unlock(&s->requests_lock);

    qemu_co_mutex_lock(&s->send_mutex);
    request->cookie = INDEX_TO_COOKIE(i);
    request->mode = s->info.mode;

    assert(s->ioc);

    if (qiov) {
        qio_channel_set_cork(s->ioc, true);
        rc = nbd_send_request(s->ioc, request);
        if (rc >= 0 && qio_channel_writev_all(s->ioc, qiov->iov, qiov->niov,
                                              NULL) < 0) {
            rc = -EIO;
        }
        qio_channel_set_cork(s->ioc, false);
    } else {
        rc = nbd_send_request(s->ioc, request);
    }
    qemu_co_mutex_unlock(&s->send_mutex);

    if (rc < 0) {
        qemu_mutex_lock(&s->requests_lock);
err:
        nbd_channel_error_locked(s, rc);
        if (i != -1) {
            s->requests[i].coroutine = NULL;
        }
        s->in_flight--;
        qemu_co_queue_next(&s->free_sema);
        qemu_mutex_unlock(&s->requests_lock);
    }
    return rc;
}

static inline uint16_t payload_advance16(uint8_t **payload)
{
    *payload += 2;
    return lduw_be_p(*payload - 2);
}

static inline uint32_t payload_advance32(uint8_t **payload)
{
    *payload += 4;
    return ldl_be_p(*payload - 4);
}

static inline uint64_t payload_advance64(uint8_t **payload)
{
    *payload += 8;
    return ldq_be_p(*payload - 8);
}

static int nbd_parse_offset_hole_payload(BDRVNBDState *s,
                                         NBDStructuredReplyChunk *chunk,
                                         uint8_t *payload, uint64_t orig_offset,
                                         QEMUIOVector *qiov, Error **errp)
{
    uint64_t offset;
    uint32_t hole_size;

    if (chunk->length != sizeof(offset) + sizeof(hole_size)) {
        error_setg(errp, "Protocol error: invalid payload for "
                         "NBD_REPLY_TYPE_OFFSET_HOLE");
        return -EINVAL;
    }

    offset = payload_advance64(&payload);
    hole_size = payload_advance32(&payload);

    if (!hole_size || offset < orig_offset || hole_size > qiov->size ||
        offset > orig_offset + qiov->size - hole_size) {
        error_setg(errp, "Protocol error: server sent chunk exceeding requested"
                         " region");
        return -EINVAL;
    }
    if (s->info.min_block &&
        !QEMU_IS_ALIGNED(hole_size, s->info.min_block)) {
        trace_nbd_structured_read_compliance("hole");
    }

    qemu_iovec_memset(qiov, offset - orig_offset, 0, hole_size);

    return 0;
}

/*
 * nbd_parse_blockstatus_payload
 * Based on our request, we expect only one extent in reply, for the
 * base:allocation context.
 */
static int nbd_parse_blockstatus_payload(BDRVNBDState *s,
                                         NBDStructuredReplyChunk *chunk,
                                         uint8_t *payload, bool wide,
                                         uint64_t orig_length,
                                         NBDExtent64 *extent, Error **errp)
{
    uint32_t context_id;
    uint32_t count;
    size_t ext_len = wide ? sizeof(*extent) : sizeof(NBDExtent32);
    size_t pay_len = sizeof(context_id) + wide * sizeof(count) + ext_len;

    /* The server succeeded, so it must have sent [at least] one extent */
    if (chunk->length < pay_len) {
        error_setg(errp, "Protocol error: invalid payload for "
                         "NBD_REPLY_TYPE_BLOCK_STATUS");
        return -EINVAL;
    }

    context_id = payload_advance32(&payload);
    if (s->info.context_id != context_id) {
        error_setg(errp, "Protocol error: unexpected context id %d for "
                         "NBD_REPLY_TYPE_BLOCK_STATUS, when negotiated context "
                         "id is %d", context_id,
                         s->info.context_id);
        return -EINVAL;
    }

    if (wide) {
        count = payload_advance32(&payload);
        extent->length = payload_advance64(&payload);
        extent->flags = payload_advance64(&payload);
    } else {
        count = 0;
        extent->length = payload_advance32(&payload);
        extent->flags = payload_advance32(&payload);
    }

    if (extent->length == 0) {
        error_setg(errp, "Protocol error: server sent status chunk with "
                   "zero length");
        return -EINVAL;
    }

    /*
     * A server sending unaligned block status is in violation of the
     * protocol, but as qemu-nbd 3.1 is such a server (at least for
     * POSIX files that are not a multiple of 512 bytes, since qemu
     * rounds files up to 512-byte multiples but lseek(SEEK_HOLE)
     * still sees an implicit hole beyond the real EOF), it's nicer to
     * work around the misbehaving server. If the request included
     * more than the final unaligned block, truncate it back to an
     * aligned result; if the request was only the final block, round
     * up to the full block and change the status to fully-allocated
     * (always a safe status, even if it loses information).
     */
    if (s->info.min_block && !QEMU_IS_ALIGNED(extent->length,
                                              s->info.min_block)) {
        trace_nbd_parse_blockstatus_compliance("extent length is unaligned");
        if (extent->length > s->info.min_block) {
            extent->length = QEMU_ALIGN_DOWN(extent->length,
                                             s->info.min_block);
        } else {
            extent->length = s->info.min_block;
            extent->flags = 0;
        }
    }

    /*
     * We used NBD_CMD_FLAG_REQ_ONE, so the server should not have
     * sent us any more than one extent, nor should it have included
     * status beyond our request in that extent. Furthermore, a wide
     * server should have replied with an accurate count (we left
     * count at 0 for a narrow server).  However, it's easy enough to
     * ignore the server's noncompliance without killing the
     * connection; just ignore trailing extents, and clamp things to
     * the length of our request.
     */
    if (count != wide || chunk->length > pay_len) {
        trace_nbd_parse_blockstatus_compliance("unexpected extent count");
    }
    if (extent->length > orig_length) {
        extent->length = orig_length;
        trace_nbd_parse_blockstatus_compliance("extent length too large");
    }

    /*
     * HACK: if we are using x-dirty-bitmaps to access
     * qemu:allocation-depth, treat all depths > 2 the same as 2,
     * since nbd_client_co_block_status is only expecting the low two
     * bits to be set.
     */
    if (s->alloc_depth && extent->flags > 2) {
        extent->flags = 2;
    }

    return 0;
}

/*
 * nbd_parse_error_payload
 * on success @errp contains message describing nbd error reply
 */
static int nbd_parse_error_payload(NBDStructuredReplyChunk *chunk,
                                   uint8_t *payload, int *request_ret,
                                   Error **errp)
{
    uint32_t error;
    uint16_t message_size;

    assert(chunk->type & (1 << 15));

    if (chunk->length < sizeof(error) + sizeof(message_size)) {
        error_setg(errp,
                   "Protocol error: invalid payload for structured error");
        return -EINVAL;
    }

    error = nbd_errno_to_system_errno(payload_advance32(&payload));
    if (error == 0) {
        error_setg(errp, "Protocol error: server sent structured error chunk "
                         "with error = 0");
        return -EINVAL;
    }

    *request_ret = -error;
    message_size = payload_advance16(&payload);

    if (message_size > chunk->length - sizeof(error) - sizeof(message_size)) {
        error_setg(errp, "Protocol error: server sent structured error chunk "
                         "with incorrect message size");
        return -EINVAL;
    }

    /* TODO: Add a trace point to mention the server complaint */

    /* TODO handle ERROR_OFFSET */

    return 0;
}

static int coroutine_fn
nbd_co_receive_offset_data_payload(BDRVNBDState *s, uint64_t orig_offset,
                                   QEMUIOVector *qiov, Error **errp)
{
    QEMUIOVector sub_qiov;
    uint64_t offset;
    size_t data_size;
    int ret;
    NBDStructuredReplyChunk *chunk = &s->reply.structured;

    assert(nbd_reply_is_structured(&s->reply));

    /* The NBD spec requires at least one byte of payload */
    if (chunk->length <= sizeof(offset)) {
        error_setg(errp, "Protocol error: invalid payload for "
                         "NBD_REPLY_TYPE_OFFSET_DATA");
        return -EINVAL;
    }

    if (nbd_read64(s->ioc, &offset, "OFFSET_DATA offset", errp) < 0) {
        return -EIO;
    }

    data_size = chunk->length - sizeof(offset);
    assert(data_size);
    if (offset < orig_offset || data_size > qiov->size ||
        offset > orig_offset + qiov->size - data_size) {
        error_setg(errp, "Protocol error: server sent chunk exceeding requested"
                         " region");
        return -EINVAL;
    }
    if (s->info.min_block && !QEMU_IS_ALIGNED(data_size, s->info.min_block)) {
        trace_nbd_structured_read_compliance("data");
    }

    qemu_iovec_init(&sub_qiov, qiov->niov);
    qemu_iovec_concat(&sub_qiov, qiov, offset - orig_offset, data_size);
    ret = qio_channel_readv_all(s->ioc, sub_qiov.iov, sub_qiov.niov, errp);
    qemu_iovec_destroy(&sub_qiov);

    return ret < 0 ? -EIO : 0;
}

#define NBD_MAX_MALLOC_PAYLOAD 1000
static coroutine_fn int nbd_co_receive_structured_payload(
        BDRVNBDState *s, void **payload, Error **errp)
{
    int ret;
    uint32_t len;

    assert(nbd_reply_is_structured(&s->reply));

    len = s->reply.structured.length;

    if (len == 0) {
        return 0;
    }

    if (payload == NULL) {
        error_setg(errp, "Unexpected structured payload");
        return -EINVAL;
    }

    if (len > NBD_MAX_MALLOC_PAYLOAD) {
        error_setg(errp, "Payload too large");
        return -EINVAL;
    }

    *payload = g_new(char, len);
    ret = nbd_read(s->ioc, *payload, len, "structured payload", errp);
    if (ret < 0) {
        g_free(*payload);
        *payload = NULL;
        return ret;
    }

    return 0;
}

/*
 * nbd_co_do_receive_one_chunk
 * for simple reply:
 *   set request_ret to received reply error
 *   if qiov is not NULL: read payload to @qiov
 * for structured reply chunk:
 *   if error chunk: read payload, set @request_ret, do not set @payload
 *   else if offset_data chunk: read payload data to @qiov, do not set @payload
 *   else: read payload to @payload
 *
 * If function fails, @errp contains corresponding error message, and the
 * connection with the server is suspect.  If it returns 0, then the
 * transaction succeeded (although @request_ret may be a negative errno
 * corresponding to the server's error reply), and errp is unchanged.
 */
static coroutine_fn int nbd_co_do_receive_one_chunk(
        BDRVNBDState *s, uint64_t cookie, bool only_structured,
        int *request_ret, QEMUIOVector *qiov, void **payload, Error **errp)
{
    ERRP_GUARD();
    int ret;
    int i = COOKIE_TO_INDEX(cookie);
    void *local_payload = NULL;
    NBDStructuredReplyChunk *chunk;

    if (payload) {
        *payload = NULL;
    }
    *request_ret = 0;

    ret = nbd_receive_replies(s, cookie, errp);
    if (ret < 0) {
        error_prepend(errp, "Connection closed: ");
        return -EIO;
    }
    assert(s->ioc);

    assert(s->reply.cookie == cookie);

    if (nbd_reply_is_simple(&s->reply)) {
        if (only_structured) {
            error_setg(errp, "Protocol error: simple reply when structured "
                             "reply chunk was expected");
            return -EINVAL;
        }

        *request_ret = -nbd_errno_to_system_errno(s->reply.simple.error);
        if (*request_ret < 0 || !qiov) {
            return 0;
        }

        return qio_channel_readv_all(s->ioc, qiov->iov, qiov->niov,
                                     errp) < 0 ? -EIO : 0;
    }

    /* handle structured reply chunk */
    assert(s->info.mode >= NBD_MODE_STRUCTURED);
    chunk = &s->reply.structured;

    if (chunk->type == NBD_REPLY_TYPE_NONE) {
        if (!(chunk->flags & NBD_REPLY_FLAG_DONE)) {
            error_setg(errp, "Protocol error: NBD_REPLY_TYPE_NONE chunk without"
                       " NBD_REPLY_FLAG_DONE flag set");
            return -EINVAL;
        }
        if (chunk->length) {
            error_setg(errp, "Protocol error: NBD_REPLY_TYPE_NONE chunk with"
                       " nonzero length");
            return -EINVAL;
        }
        return 0;
    }

    if (chunk->type == NBD_REPLY_TYPE_OFFSET_DATA) {
        if (!qiov) {
            error_setg(errp, "Unexpected NBD_REPLY_TYPE_OFFSET_DATA chunk");
            return -EINVAL;
        }

        return nbd_co_receive_offset_data_payload(s, s->requests[i].offset,
                                                  qiov, errp);
    }

    if (nbd_reply_type_is_error(chunk->type)) {
        payload = &local_payload;
    }

    ret = nbd_co_receive_structured_payload(s, payload, errp);
    if (ret < 0) {
        return ret;
    }

    if (nbd_reply_type_is_error(chunk->type)) {
        ret = nbd_parse_error_payload(chunk, local_payload, request_ret, errp);
        g_free(local_payload);
        return ret;
    }

    return 0;
}

/*
 * nbd_co_receive_one_chunk
 * Read reply, wake up connection_co and set s->quit if needed.
 * Return value is a fatal error code or normal nbd reply error code
 */
static coroutine_fn int nbd_co_receive_one_chunk(
        BDRVNBDState *s, uint64_t cookie, bool only_structured,
        int *request_ret, QEMUIOVector *qiov, NBDReply *reply, void **payload,
        Error **errp)
{
    int ret = nbd_co_do_receive_one_chunk(s, cookie, only_structured,
                                          request_ret, qiov, payload, errp);

    if (ret < 0) {
        memset(reply, 0, sizeof(*reply));
        nbd_channel_error(s, ret);
    } else {
        /* For assert at loop start in nbd_connection_entry */
        *reply = s->reply;
    }
    s->reply.cookie = 0;

    nbd_recv_coroutines_wake(s);

    return ret;
}

typedef struct NBDReplyChunkIter {
    int ret;
    int request_ret;
    Error *err;
    bool done, only_structured;
} NBDReplyChunkIter;

static void nbd_iter_channel_error(NBDReplyChunkIter *iter,
                                   int ret, Error **local_err)
{
    assert(local_err && *local_err);
    assert(ret < 0);

    if (!iter->ret) {
        iter->ret = ret;
        error_propagate(&iter->err, *local_err);
    } else {
        error_free(*local_err);
    }

    *local_err = NULL;
}

static void nbd_iter_request_error(NBDReplyChunkIter *iter, int ret)
{
    assert(ret < 0);

    if (!iter->request_ret) {
        iter->request_ret = ret;
    }
}

/*
 * NBD_FOREACH_REPLY_CHUNK
 * The pointer stored in @payload requires g_free() to free it.
 */
#define NBD_FOREACH_REPLY_CHUNK(s, iter, cookie, structured, \
                                qiov, reply, payload) \
    for (iter = (NBDReplyChunkIter) { .only_structured = structured }; \
         nbd_reply_chunk_iter_receive(s, &iter, cookie, qiov, reply, payload);)

/*
 * nbd_reply_chunk_iter_receive
 * The pointer stored in @payload requires g_free() to free it.
 */
static bool coroutine_fn nbd_reply_chunk_iter_receive(BDRVNBDState *s,
                                                      NBDReplyChunkIter *iter,
                                                      uint64_t cookie,
                                                      QEMUIOVector *qiov,
                                                      NBDReply *reply,
                                                      void **payload)
{
    int ret, request_ret;
    NBDReply local_reply;
    NBDStructuredReplyChunk *chunk;
    Error *local_err = NULL;

    if (iter->done) {
        /* Previous iteration was last. */
        goto break_loop;
    }

    if (reply == NULL) {
        reply = &local_reply;
    }

    ret = nbd_co_receive_one_chunk(s, cookie, iter->only_structured,
                                   &request_ret, qiov, reply, payload,
                                   &local_err);
    if (ret < 0) {
        nbd_iter_channel_error(iter, ret, &local_err);
    } else if (request_ret < 0) {
        nbd_iter_request_error(iter, request_ret);
    }

    /* Do not execute the body of NBD_FOREACH_REPLY_CHUNK for simple reply. */
    if (nbd_reply_is_simple(reply) || iter->ret < 0) {
        goto break_loop;
    }

    chunk = &reply->structured;
    iter->only_structured = true;

    if (chunk->type == NBD_REPLY_TYPE_NONE) {
        /* NBD_REPLY_FLAG_DONE is already checked in nbd_co_receive_one_chunk */
        assert(chunk->flags & NBD_REPLY_FLAG_DONE);
        goto break_loop;
    }

    if (chunk->flags & NBD_REPLY_FLAG_DONE) {
        /* This iteration is last. */
        iter->done = true;
    }

    /* Execute the loop body */
    return true;

break_loop:
    qemu_mutex_lock(&s->requests_lock);
    s->requests[COOKIE_TO_INDEX(cookie)].coroutine = NULL;
    s->in_flight--;
    qemu_co_queue_next(&s->free_sema);
    qemu_mutex_unlock(&s->requests_lock);

    return false;
}

static int coroutine_fn
nbd_co_receive_return_code(BDRVNBDState *s, uint64_t cookie,
                           int *request_ret, Error **errp)
{
    NBDReplyChunkIter iter;

    NBD_FOREACH_REPLY_CHUNK(s, iter, cookie, false, NULL, NULL, NULL) {
        /* nbd_reply_chunk_iter_receive does all the work */
    }

    error_propagate(errp, iter.err);
    *request_ret = iter.request_ret;
    return iter.ret;
}

static int coroutine_fn
nbd_co_receive_cmdread_reply(BDRVNBDState *s, uint64_t cookie,
                             uint64_t offset, QEMUIOVector *qiov,
                             int *request_ret, Error **errp)
{
    NBDReplyChunkIter iter;
    NBDReply reply;
    void *payload = NULL;
    Error *local_err = NULL;

    NBD_FOREACH_REPLY_CHUNK(s, iter, cookie,
                            s->info.mode >= NBD_MODE_STRUCTURED,
                            qiov, &reply, &payload)
    {
        int ret;
        NBDStructuredReplyChunk *chunk = &reply.structured;

        assert(nbd_reply_is_structured(&reply));

        switch (chunk->type) {
        case NBD_REPLY_TYPE_OFFSET_DATA:
            /*
             * special cased in nbd_co_receive_one_chunk, data is already
             * in qiov
             */
            break;
        case NBD_REPLY_TYPE_OFFSET_HOLE:
            ret = nbd_parse_offset_hole_payload(s, &reply.structured, payload,
                                                offset, qiov, &local_err);
            if (ret < 0) {
                nbd_channel_error(s, ret);
                nbd_iter_channel_error(&iter, ret, &local_err);
            }
            break;
        default:
            if (!nbd_reply_type_is_error(chunk->type)) {
                /* not allowed reply type */
                nbd_channel_error(s, -EINVAL);
                error_setg(&local_err,
                           "Unexpected reply type: %d (%s) for CMD_READ",
                           chunk->type, nbd_reply_type_lookup(chunk->type));
                nbd_iter_channel_error(&iter, -EINVAL, &local_err);
            }
        }

        g_free(payload);
        payload = NULL;
    }

    error_propagate(errp, iter.err);
    *request_ret = iter.request_ret;
    return iter.ret;
}

static int coroutine_fn
nbd_co_receive_blockstatus_reply(BDRVNBDState *s, uint64_t cookie,
                                 uint64_t length, NBDExtent64 *extent,
                                 int *request_ret, Error **errp)
{
    NBDReplyChunkIter iter;
    NBDReply reply;
    void *payload = NULL;
    Error *local_err = NULL;
    bool received = false;

    assert(!extent->length);
    NBD_FOREACH_REPLY_CHUNK(s, iter, cookie, false, NULL, &reply, &payload) {
        int ret;
        NBDStructuredReplyChunk *chunk = &reply.structured;
        bool wide;

        assert(nbd_reply_is_structured(&reply));

        switch (chunk->type) {
        case NBD_REPLY_TYPE_BLOCK_STATUS_EXT:
        case NBD_REPLY_TYPE_BLOCK_STATUS:
            wide = chunk->type == NBD_REPLY_TYPE_BLOCK_STATUS_EXT;
            if ((s->info.mode >= NBD_MODE_EXTENDED) != wide) {
                trace_nbd_extended_headers_compliance("block_status");
            }
            if (received) {
                nbd_channel_error(s, -EINVAL);
                error_setg(&local_err, "Several BLOCK_STATUS chunks in reply");
                nbd_iter_channel_error(&iter, -EINVAL, &local_err);
            }
            received = true;

            ret = nbd_parse_blockstatus_payload(
                s, &reply.structured, payload, wide,
                length, extent, &local_err);
            if (ret < 0) {
                nbd_channel_error(s, ret);
                nbd_iter_channel_error(&iter, ret, &local_err);
            }
            break;
        default:
            if (!nbd_reply_type_is_error(chunk->type)) {
                nbd_channel_error(s, -EINVAL);
                error_setg(&local_err,
                           "Unexpected reply type: %d (%s) "
                           "for CMD_BLOCK_STATUS",
                           chunk->type, nbd_reply_type_lookup(chunk->type));
                nbd_iter_channel_error(&iter, -EINVAL, &local_err);
            }
        }

        g_free(payload);
        payload = NULL;
    }

    if (!extent->length && !iter.request_ret) {
        error_setg(&local_err, "Server did not reply with any status extents");
        nbd_iter_channel_error(&iter, -EIO, &local_err);
    }

    error_propagate(errp, iter.err);
    *request_ret = iter.request_ret;
    return iter.ret;
}

static int coroutine_fn GRAPH_RDLOCK
nbd_co_request(BlockDriverState *bs, NBDRequest *request,
               QEMUIOVector *write_qiov)
{
    int ret, request_ret;
    Error *local_err = NULL;
    BDRVNBDState *s = (BDRVNBDState *)bs->opaque;

    assert(request->type != NBD_CMD_READ);
    if (write_qiov) {
        assert(request->type == NBD_CMD_WRITE);
        assert(request->len == iov_size(write_qiov->iov, write_qiov->niov));
    } else {
        assert(request->type != NBD_CMD_WRITE);
    }

    do {
        ret = nbd_co_send_request(bs, request, write_qiov);
        if (ret < 0) {
            continue;
        }

        ret = nbd_co_receive_return_code(s, request->cookie,
                                         &request_ret, &local_err);
        if (local_err) {
            trace_nbd_co_request_fail(request->from, request->len,
                                      request->cookie, request->flags,
                                      request->type,
                                      nbd_cmd_lookup(request->type),
                                      ret, error_get_pretty(local_err));
            error_free(local_err);
            local_err = NULL;
        }
    } while (ret < 0 && nbd_client_will_reconnect(s));

    return ret ? ret : request_ret;
}

static int coroutine_fn GRAPH_RDLOCK
nbd_client_co_preadv(BlockDriverState *bs, int64_t offset, int64_t bytes,
                     QEMUIOVector *qiov, BdrvRequestFlags flags)
{
    int ret, request_ret;
    Error *local_err = NULL;
    BDRVNBDState *s = (BDRVNBDState *)bs->opaque;
    NBDRequest request = {
        .type = NBD_CMD_READ,
        .from = offset,
        .len = bytes,
    };

    assert(bytes <= NBD_MAX_BUFFER_SIZE);

    if (!bytes) {
        return 0;
    }
    /*
     * Work around the fact that the block layer doesn't do
     * byte-accurate sizing yet - if the read exceeds the server's
     * advertised size because the block layer rounded size up, then
     * truncate the request to the server and tail-pad with zero.
     */
    if (offset >= s->info.size) {
        assert(bytes < BDRV_SECTOR_SIZE);
        qemu_iovec_memset(qiov, 0, 0, bytes);
        return 0;
    }
    if (offset + bytes > s->info.size) {
        uint64_t slop = offset + bytes - s->info.size;

        assert(slop < BDRV_SECTOR_SIZE);
        qemu_iovec_memset(qiov, bytes - slop, 0, slop);
        request.len -= slop;
    }

    do {
        ret = nbd_co_send_request(bs, &request, NULL);
        if (ret < 0) {
            continue;
        }

        ret = nbd_co_receive_cmdread_reply(s, request.cookie, offset, qiov,
                                           &request_ret, &local_err);
        if (local_err) {
            trace_nbd_co_request_fail(request.from, request.len, request.cookie,
                                      request.flags, request.type,
                                      nbd_cmd_lookup(request.type),
                                      ret, error_get_pretty(local_err));
            error_free(local_err);
            local_err = NULL;
        }
    } while (ret < 0 && nbd_client_will_reconnect(s));

    return ret ? ret : request_ret;
}

static int coroutine_fn GRAPH_RDLOCK
nbd_client_co_pwritev(BlockDriverState *bs, int64_t offset, int64_t bytes,
                      QEMUIOVector *qiov, BdrvRequestFlags flags)
{
    BDRVNBDState *s = (BDRVNBDState *)bs->opaque;
    NBDRequest request = {
        .type = NBD_CMD_WRITE,
        .from = offset,
        .len = bytes,
    };

    assert(!(s->info.flags & NBD_FLAG_READ_ONLY));
    if (flags & BDRV_REQ_FUA) {
        assert(s->info.flags & NBD_FLAG_SEND_FUA);
        request.flags |= NBD_CMD_FLAG_FUA;
    }

    assert(bytes <= NBD_MAX_BUFFER_SIZE);

    if (!bytes) {
        return 0;
    }
    return nbd_co_request(bs, &request, qiov);
}

static int coroutine_fn GRAPH_RDLOCK
nbd_client_co_pwrite_zeroes(BlockDriverState *bs, int64_t offset, int64_t bytes,
                            BdrvRequestFlags flags)
{
    BDRVNBDState *s = (BDRVNBDState *)bs->opaque;
    NBDRequest request = {
        .type = NBD_CMD_WRITE_ZEROES,
        .from = offset,
        .len = bytes,
    };

    /* rely on max_pwrite_zeroes */
    assert(bytes <= UINT32_MAX || s->info.mode >= NBD_MODE_EXTENDED);

    assert(!(s->info.flags & NBD_FLAG_READ_ONLY));
    if (!(s->info.flags & NBD_FLAG_SEND_WRITE_ZEROES)) {
        return -ENOTSUP;
    }

    if (flags & BDRV_REQ_FUA) {
        assert(s->info.flags & NBD_FLAG_SEND_FUA);
        request.flags |= NBD_CMD_FLAG_FUA;
    }
    if (!(flags & BDRV_REQ_MAY_UNMAP)) {
        request.flags |= NBD_CMD_FLAG_NO_HOLE;
    }
    if (flags & BDRV_REQ_NO_FALLBACK) {
        assert(s->info.flags & NBD_FLAG_SEND_FAST_ZERO);
        request.flags |= NBD_CMD_FLAG_FAST_ZERO;
    }

    if (!bytes) {
        return 0;
    }
    return nbd_co_request(bs, &request, NULL);
}

static int coroutine_fn GRAPH_RDLOCK nbd_client_co_flush(BlockDriverState *bs)
{
    BDRVNBDState *s = (BDRVNBDState *)bs->opaque;
    NBDRequest request = { .type = NBD_CMD_FLUSH };

    if (!(s->info.flags & NBD_FLAG_SEND_FLUSH)) {
        return 0;
    }

    request.from = 0;
    request.len = 0;

    return nbd_co_request(bs, &request, NULL);
}

static int coroutine_fn GRAPH_RDLOCK
nbd_client_co_pdiscard(BlockDriverState *bs, int64_t offset, int64_t bytes)
{
    BDRVNBDState *s = (BDRVNBDState *)bs->opaque;
    NBDRequest request = {
        .type = NBD_CMD_TRIM,
        .from = offset,
        .len = bytes,
    };

    /* rely on max_pdiscard */
    assert(bytes <= UINT32_MAX || s->info.mode >= NBD_MODE_EXTENDED);

    assert(!(s->info.flags & NBD_FLAG_READ_ONLY));
    if (!(s->info.flags & NBD_FLAG_SEND_TRIM) || !bytes) {
        return 0;
    }

    return nbd_co_request(bs, &request, NULL);
}

static int coroutine_fn GRAPH_RDLOCK nbd_client_co_block_status(
        BlockDriverState *bs, bool want_zero, int64_t offset, int64_t bytes,
        int64_t *pnum, int64_t *map, BlockDriverState **file)
{
    int ret, request_ret;
    NBDExtent64 extent = { 0 };
    BDRVNBDState *s = (BDRVNBDState *)bs->opaque;
    Error *local_err = NULL;

    NBDRequest request = {
        .type = NBD_CMD_BLOCK_STATUS,
        .from = offset,
        .len = MIN(bytes, s->info.size - offset),
        .flags = NBD_CMD_FLAG_REQ_ONE,
    };

    if (!s->info.base_allocation) {
        *pnum = bytes;
        *map = offset;
        *file = bs;
        return BDRV_BLOCK_DATA | BDRV_BLOCK_OFFSET_VALID;
    }
    if (s->info.mode < NBD_MODE_EXTENDED) {
        request.len = MIN(QEMU_ALIGN_DOWN(INT_MAX, bs->bl.request_alignment),
                          request.len);
    }

    /*
     * Work around the fact that the block layer doesn't do
     * byte-accurate sizing yet - if the status request exceeds the
     * server's advertised size because the block layer rounded size
     * up, we truncated the request to the server (above), or are
     * called on just the hole.
     */
    if (offset >= s->info.size) {
        *pnum = bytes;
        assert(bytes < BDRV_SECTOR_SIZE);
        /* Intentionally don't report offset_valid for the hole */
        return BDRV_BLOCK_ZERO;
    }

    if (s->info.min_block) {
        assert(QEMU_IS_ALIGNED(request.len, s->info.min_block));
    }
    do {
        ret = nbd_co_send_request(bs, &request, NULL);
        if (ret < 0) {
            continue;
        }

        ret = nbd_co_receive_blockstatus_reply(s, request.cookie, bytes,
                                               &extent, &request_ret,
                                               &local_err);
        if (local_err) {
            trace_nbd_co_request_fail(request.from, request.len, request.cookie,
                                      request.flags, request.type,
                                      nbd_cmd_lookup(request.type),
                                      ret, error_get_pretty(local_err));
            error_free(local_err);
            local_err = NULL;
        }
    } while (ret < 0 && nbd_client_will_reconnect(s));

    if (ret < 0 || request_ret < 0) {
        return ret ? ret : request_ret;
    }

    assert(extent.length);
    *pnum = extent.length;
    *map = offset;
    *file = bs;
    return (extent.flags & NBD_STATE_HOLE ? 0 : BDRV_BLOCK_DATA) |
        (extent.flags & NBD_STATE_ZERO ? BDRV_BLOCK_ZERO : 0) |
        BDRV_BLOCK_OFFSET_VALID;
}

static int nbd_client_reopen_prepare(BDRVReopenState *state,
                                     BlockReopenQueue *queue, Error **errp)
{
    BDRVNBDState *s = (BDRVNBDState *)state->bs->opaque;

    if ((state->flags & BDRV_O_RDWR) && (s->info.flags & NBD_FLAG_READ_ONLY)) {
        error_setg(errp, "Can't reopen read-only NBD mount as read/write");
        return -EACCES;
    }
    return 0;
}

static void nbd_yank(void *opaque)
{
    BlockDriverState *bs = opaque;
    BDRVNBDState *s = (BDRVNBDState *)bs->opaque;

    QEMU_LOCK_GUARD(&s->requests_lock);
    qio_channel_shutdown(s->ioc, QIO_CHANNEL_SHUTDOWN_BOTH, NULL);
    s->state = NBD_CLIENT_QUIT;
}

static void nbd_client_close(BlockDriverState *bs)
{
    BDRVNBDState *s = (BDRVNBDState *)bs->opaque;
    NBDRequest request = { .type = NBD_CMD_DISC, .mode = s->info.mode };

    if (s->ioc) {
        nbd_send_request(s->ioc, &request);
    }

    nbd_teardown_connection(bs);
}


/*
 * Parse nbd_open options
 */

static int nbd_parse_uri(const char *filename, QDict *options)
{
    g_autoptr(GUri) uri = g_uri_parse(filename, G_URI_FLAGS_NONE, NULL);
    g_autoptr(GHashTable) qp = NULL;
    const char *p;
    int qp_n;
    bool is_unix;
    const char *uri_scheme, *uri_query, *uri_server;
    int uri_port;

    if (!uri) {
        return -EINVAL;
    }

    /* transport */
    uri_scheme = g_uri_get_scheme(uri);
    if (!g_strcmp0(uri_scheme, "nbd")) {
        is_unix = false;
    } else if (!g_strcmp0(uri_scheme, "nbd+tcp")) {
        is_unix = false;
    } else if (!g_strcmp0(uri_scheme, "nbd+unix")) {
        is_unix = true;
    } else {
        return -EINVAL;
    }

    p = g_uri_get_path(uri) ?: "";
    if (p[0] == '/') {
        p++;
    }
    if (p[0]) {
        qdict_put_str(options, "export", p);
    }

    uri_query = g_uri_get_query(uri);
    if (uri_query) {
        qp = g_uri_parse_params(uri_query, -1, "&", G_URI_PARAMS_NONE, NULL);
        if (!qp) {
            return -EINVAL;
        }
        qp_n = g_hash_table_size(qp);
        if (qp_n > 1 || (is_unix && !qp_n) || (!is_unix && qp_n)) {
            return -EINVAL;
        }
     }

    uri_server = g_uri_get_host(uri);
    if (uri_server && !uri_server[0]) {
        uri_server = NULL;
    }
    uri_port = g_uri_get_port(uri);

    if (is_unix) {
        /* nbd+unix:///export?socket=path */
        const char *uri_socket = g_hash_table_lookup(qp, "socket");
        if (uri_server || uri_port != -1 || !uri_socket) {
            return -EINVAL;
        }
        qdict_put_str(options, "server.type", "unix");
        qdict_put_str(options, "server.path", uri_socket);
    } else {
        char *port_str;

        /* nbd[+tcp]://host[:port]/export */
        if (!uri_server) {
            return -EINVAL;
        }

        qdict_put_str(options, "server.type", "inet");
        qdict_put_str(options, "server.host", uri_server);

        port_str = g_strdup_printf("%d", uri_port > 0 ? uri_port
                                                      : NBD_DEFAULT_PORT);
        qdict_put_str(options, "server.port", port_str);
        g_free(port_str);
    }

    return 0;
}

static bool nbd_has_filename_options_conflict(QDict *options, Error **errp)
{
    const QDictEntry *e;

    for (e = qdict_first(options); e; e = qdict_next(options, e)) {
        if (!strcmp(e->key, "host") ||
            !strcmp(e->key, "port") ||
            !strcmp(e->key, "path") ||
            !strcmp(e->key, "export") ||
            strstart(e->key, "server.", NULL))
        {
            error_setg(errp, "Option '%s' cannot be used with a file name",
                       e->key);
            return true;
        }
    }

    return false;
}

static void nbd_parse_filename(const char *filename, QDict *options,
                               Error **errp)
{
    g_autofree char *file = NULL;
    char *export_name;
    const char *host_spec;
    const char *unixpath;

    if (nbd_has_filename_options_conflict(options, errp)) {
        return;
    }

    if (strstr(filename, "://")) {
        int ret = nbd_parse_uri(filename, options);
        if (ret < 0) {
            error_setg(errp, "No valid URL specified");
        }
        return;
    }

    file = g_strdup(filename);

    export_name = strstr(file, EN_OPTSTR);
    if (export_name) {
        if (export_name[strlen(EN_OPTSTR)] == 0) {
            return;
        }
        export_name[0] = 0; /* truncate 'file' */
        export_name += strlen(EN_OPTSTR);

        qdict_put_str(options, "export", export_name);
    }

    /* extract the host_spec - fail if it's not nbd:... */
    if (!strstart(file, "nbd:", &host_spec)) {
        error_setg(errp, "File name string for NBD must start with 'nbd:'");
        return;
    }

    if (!*host_spec) {
        return;
    }

    /* are we a UNIX or TCP socket? */
    if (strstart(host_spec, "unix:", &unixpath)) {
        qdict_put_str(options, "server.type", "unix");
        qdict_put_str(options, "server.path", unixpath);
    } else {
        InetSocketAddress *addr = g_new(InetSocketAddress, 1);

        if (inet_parse(addr, host_spec, errp)) {
            goto out_inet;
        }

        qdict_put_str(options, "server.type", "inet");
        qdict_put_str(options, "server.host", addr->host);
        qdict_put_str(options, "server.port", addr->port);
    out_inet:
        qapi_free_InetSocketAddress(addr);
    }
}

static bool nbd_process_legacy_socket_options(QDict *output_options,
                                              QemuOpts *legacy_opts,
                                              Error **errp)
{
    const char *path = qemu_opt_get(legacy_opts, "path");
    const char *host = qemu_opt_get(legacy_opts, "host");
    const char *port = qemu_opt_get(legacy_opts, "port");
    const QDictEntry *e;

    if (!path && !host && !port) {
        return true;
    }

    for (e = qdict_first(output_options); e; e = qdict_next(output_options, e))
    {
        if (strstart(e->key, "server.", NULL)) {
            error_setg(errp, "Cannot use 'server' and path/host/port at the "
                       "same time");
            return false;
        }
    }

    if (path && host) {
        error_setg(errp, "path and host may not be used at the same time");
        return false;
    } else if (path) {
        if (port) {
            error_setg(errp, "port may not be used without host");
            return false;
        }

        qdict_put_str(output_options, "server.type", "unix");
        qdict_put_str(output_options, "server.path", path);
    } else if (host) {
        qdict_put_str(output_options, "server.type", "inet");
        qdict_put_str(output_options, "server.host", host);
        qdict_put_str(output_options, "server.port",
                      port ?: stringify(NBD_DEFAULT_PORT));
    }

    return true;
}

static SocketAddress *nbd_config(BDRVNBDState *s, QDict *options,
                                 Error **errp)
{
    SocketAddress *saddr = NULL;
    QDict *addr = NULL;
    Visitor *iv = NULL;

    qdict_extract_subqdict(options, &addr, "server.");
    if (!qdict_size(addr)) {
        error_setg(errp, "NBD server address missing");
        goto done;
    }

    iv = qobject_input_visitor_new_flat_confused(addr, errp);
    if (!iv) {
        goto done;
    }

    if (!visit_type_SocketAddress(iv, NULL, &saddr, errp)) {
        goto done;
    }

    if (socket_address_parse_named_fd(saddr, errp) < 0) {
        qapi_free_SocketAddress(saddr);
        saddr = NULL;
        goto done;
    }

done:
    qobject_unref(addr);
    visit_free(iv);
    return saddr;
}

static QCryptoTLSCreds *nbd_get_tls_creds(const char *id, Error **errp)
{
    Object *obj;
    QCryptoTLSCreds *creds;

    obj = object_resolve_path_component(
        object_get_objects_root(), id);
    if (!obj) {
        error_setg(errp, "No TLS credentials with id '%s'",
                   id);
        return NULL;
    }
    creds = (QCryptoTLSCreds *)
        object_dynamic_cast(obj, TYPE_QCRYPTO_TLS_CREDS);
    if (!creds) {
        error_setg(errp, "Object with id '%s' is not TLS credentials",
                   id);
        return NULL;
    }

    if (!qcrypto_tls_creds_check_endpoint(creds,
                                          QCRYPTO_TLS_CREDS_ENDPOINT_CLIENT,
                                          errp)) {
        return NULL;
    }
    object_ref(obj);
    return creds;
}


static QemuOptsList nbd_runtime_opts = {
    .name = "nbd",
    .head = QTAILQ_HEAD_INITIALIZER(nbd_runtime_opts.head),
    .desc = {
        {
            .name = "host",
            .type = QEMU_OPT_STRING,
            .help = "TCP host to connect to",
        },
        {
            .name = "port",
            .type = QEMU_OPT_STRING,
            .help = "TCP port to connect to",
        },
        {
            .name = "path",
            .type = QEMU_OPT_STRING,
            .help = "Unix socket path to connect to",
        },
        {
            .name = "export",
            .type = QEMU_OPT_STRING,
            .help = "Name of the NBD export to open",
        },
        {
            .name = "tls-creds",
            .type = QEMU_OPT_STRING,
            .help = "ID of the TLS credentials to use",
        },
        {
            .name = "tls-hostname",
            .type = QEMU_OPT_STRING,
            .help = "Override hostname for validating TLS x509 certificate",
        },
        {
            .name = "x-dirty-bitmap",
            .type = QEMU_OPT_STRING,
            .help = "experimental: expose named dirty bitmap in place of "
                    "block status",
        },
        {
            .name = "reconnect-delay",
            .type = QEMU_OPT_NUMBER,
            .help = "On an unexpected disconnect, the nbd client tries to "
                    "connect again until succeeding or encountering a serious "
                    "error.  During the first @reconnect-delay seconds, all "
                    "requests are paused and will be rerun on a successful "
                    "reconnect. After that time, any delayed requests and all "
                    "future requests before a successful reconnect will "
                    "immediately fail. Default 0",
        },
        {
            .name = "open-timeout",
            .type = QEMU_OPT_NUMBER,
            .help = "In seconds. If zero, the nbd driver tries the connection "
                    "only once, and fails to open if the connection fails. "
                    "If non-zero, the nbd driver will repeat connection "
                    "attempts until successful or until @open-timeout seconds "
                    "have elapsed. Default 0",
        },
        { /* end of list */ }
    },
};

static int nbd_process_options(BlockDriverState *bs, QDict *options,
                               Error **errp)
{
    BDRVNBDState *s = bs->opaque;
    QemuOpts *opts;
    int ret = -EINVAL;

    opts = qemu_opts_create(&nbd_runtime_opts, NULL, 0, &error_abort);
    if (!qemu_opts_absorb_qdict(opts, options, errp)) {
        goto error;
    }

    /* Translate @host, @port, and @path to a SocketAddress */
    if (!nbd_process_legacy_socket_options(options, opts, errp)) {
        goto error;
    }

    /* Pop the config into our state object. Exit if invalid. */
    s->saddr = nbd_config(s, options, errp);
    if (!s->saddr) {
        goto error;
    }

    s->export = g_strdup(qemu_opt_get(opts, "export"));
    if (s->export && strlen(s->export) > NBD_MAX_STRING_SIZE) {
        error_setg(errp, "export name too long to send to server");
        goto error;
    }

    s->tlscredsid = g_strdup(qemu_opt_get(opts, "tls-creds"));
    if (s->tlscredsid) {
        s->tlscreds = nbd_get_tls_creds(s->tlscredsid, errp);
        if (!s->tlscreds) {
            goto error;
        }

        s->tlshostname = g_strdup(qemu_opt_get(opts, "tls-hostname"));
        if (!s->tlshostname &&
            s->saddr->type == SOCKET_ADDRESS_TYPE_INET) {
            s->tlshostname = g_strdup(s->saddr->u.inet.host);
        }
    }

    s->x_dirty_bitmap = g_strdup(qemu_opt_get(opts, "x-dirty-bitmap"));
    if (s->x_dirty_bitmap && strlen(s->x_dirty_bitmap) > NBD_MAX_STRING_SIZE) {
        error_setg(errp, "x-dirty-bitmap query too long to send to server");
        goto error;
    }

    s->reconnect_delay = qemu_opt_get_number(opts, "reconnect-delay", 0);
    s->open_timeout = qemu_opt_get_number(opts, "open-timeout", 0);

    ret = 0;

 error:
    qemu_opts_del(opts);
    return ret;
}

static int nbd_open(BlockDriverState *bs, QDict *options, int flags,
                    Error **errp)
{
    int ret;
    BDRVNBDState *s = (BDRVNBDState *)bs->opaque;

    s->bs = bs;
    qemu_mutex_init(&s->requests_lock);
    qemu_co_queue_init(&s->free_sema);
    qemu_co_mutex_init(&s->send_mutex);
    qemu_co_mutex_init(&s->receive_mutex);

    if (!yank_register_instance(BLOCKDEV_YANK_INSTANCE(bs->node_name), errp)) {
        return -EEXIST;
    }

    ret = nbd_process_options(bs, options, errp);
    if (ret < 0) {
        goto fail;
    }

    s->conn = nbd_client_connection_new(s->saddr, true, s->export,
                                        s->x_dirty_bitmap, s->tlscreds,
                                        s->tlshostname);

    if (s->open_timeout) {
        nbd_client_connection_enable_retry(s->conn);
        open_timer_init(s, qemu_clock_get_ns(QEMU_CLOCK_REALTIME) +
                        s->open_timeout * NANOSECONDS_PER_SECOND);
    }

    s->state = NBD_CLIENT_CONNECTING_WAIT;
    ret = nbd_do_establish_connection(bs, true, errp);
    if (ret < 0) {
        goto fail;
    }

    /*
     * The connect attempt is done, so we no longer need this timer.
     * Delete it, because we do not want it to be around when this node
     * is drained or closed.
     */
    open_timer_del(s);

    nbd_client_connection_enable_retry(s->conn);

    return 0;

fail:
    open_timer_del(s);
    nbd_clear_bdrvstate(bs);
    return ret;
}

static void nbd_refresh_limits(BlockDriverState *bs, Error **errp)
{
    BDRVNBDState *s = (BDRVNBDState *)bs->opaque;
    uint32_t min = s->info.min_block;
    uint32_t max = MIN_NON_ZERO(NBD_MAX_BUFFER_SIZE, s->info.max_block);

    /*
     * If the server did not advertise an alignment:
     * - a size that is not sector-aligned implies that an alignment
     *   of 1 can be used to access those tail bytes
     * - advertisement of block status requires an alignment of 1, so
     *   that we don't violate block layer constraints that block
     *   status is always aligned (as we can't control whether the
     *   server will report sub-sector extents, such as a hole at EOF
     *   on an unaligned POSIX file)
     * - otherwise, assume the server is so old that we are safer avoiding
     *   sub-sector requests
     */
    if (!min) {
        min = (!QEMU_IS_ALIGNED(s->info.size, BDRV_SECTOR_SIZE) ||
               s->info.base_allocation) ? 1 : BDRV_SECTOR_SIZE;
    }

    bs->bl.request_alignment = min;
    bs->bl.max_pdiscard = QEMU_ALIGN_DOWN(INT_MAX, min);
    bs->bl.max_pwrite_zeroes = max;
    bs->bl.max_transfer = max;

    /*
     * Assume that if the server supports extended headers, it also
     * supports unlimited size zero and trim commands.
     */
    if (s->info.mode >= NBD_MODE_EXTENDED) {
        bs->bl.max_pdiscard = bs->bl.max_pwrite_zeroes = 0;
    }

    if (s->info.opt_block &&
        s->info.opt_block > bs->bl.opt_transfer) {
        bs->bl.opt_transfer = s->info.opt_block;
    }
}

static void nbd_close(BlockDriverState *bs)
{
    nbd_client_close(bs);
    nbd_clear_bdrvstate(bs);
}

/*
 * NBD cannot truncate, but if the caller asks to truncate to the same size, or
 * to a smaller size with exact=false, there is no reason to fail the
 * operation.
 *
 * Preallocation mode is ignored since it does not seems useful to fail when
 * we never change anything.
 */
static int coroutine_fn nbd_co_truncate(BlockDriverState *bs, int64_t offset,
                                        bool exact, PreallocMode prealloc,
                                        BdrvRequestFlags flags, Error **errp)
{
    BDRVNBDState *s = bs->opaque;

    if (offset != s->info.size && exact) {
        error_setg(errp, "Cannot resize NBD nodes");
        return -ENOTSUP;
    }

    if (offset > s->info.size) {
        error_setg(errp, "Cannot grow NBD nodes");
        return -EINVAL;
    }

    return 0;
}

static int64_t coroutine_fn nbd_co_getlength(BlockDriverState *bs)
{
    BDRVNBDState *s = bs->opaque;

    return s->info.size;
}

static void nbd_refresh_filename(BlockDriverState *bs)
{
    BDRVNBDState *s = bs->opaque;
    const char *host = NULL, *port = NULL, *path = NULL;
    size_t len = 0;

    if (s->saddr->type == SOCKET_ADDRESS_TYPE_INET) {
        const InetSocketAddress *inet = &s->saddr->u.inet;
        if (!inet->has_ipv4 && !inet->has_ipv6 && !inet->has_to) {
            host = inet->host;
            port = inet->port;
        }
    } else if (s->saddr->type == SOCKET_ADDRESS_TYPE_UNIX) {
        path = s->saddr->u.q_unix.path;
    } /* else can't represent as pseudo-filename */

    if (path && s->export) {
        len = snprintf(bs->exact_filename, sizeof(bs->exact_filename),
                       "nbd+unix:///%s?socket=%s", s->export, path);
    } else if (path && !s->export) {
        len = snprintf(bs->exact_filename, sizeof(bs->exact_filename),
                       "nbd+unix://?socket=%s", path);
    } else if (host && s->export) {
        len = snprintf(bs->exact_filename, sizeof(bs->exact_filename),
                       "nbd://%s:%s/%s", host, port, s->export);
    } else if (host && !s->export) {
        len = snprintf(bs->exact_filename, sizeof(bs->exact_filename),
                       "nbd://%s:%s", host, port);
    }
    if (len >= sizeof(bs->exact_filename)) {
        /* Name is too long to represent exactly, so leave it empty. */
        bs->exact_filename[0] = '\0';
    }
}

static char *nbd_dirname(BlockDriverState *bs, Error **errp)
{
    /* The generic bdrv_dirname() implementation is able to work out some
     * directory name for NBD nodes, but that would be wrong. So far there is no
     * specification for how "export paths" would work, so NBD does not have
     * directory names. */
    error_setg(errp, "Cannot generate a base directory for NBD nodes");
    return NULL;
}

static const char *const nbd_strong_runtime_opts[] = {
    "path",
    "host",
    "port",
    "export",
    "tls-creds",
    "tls-hostname",
    "server.",

    NULL
};

static void nbd_cancel_in_flight(BlockDriverState *bs)
{
    BDRVNBDState *s = (BDRVNBDState *)bs->opaque;

    reconnect_delay_timer_del(s);

    qemu_mutex_lock(&s->requests_lock);
    if (s->state == NBD_CLIENT_CONNECTING_WAIT) {
        s->state = NBD_CLIENT_CONNECTING_NOWAIT;
    }
    qemu_mutex_unlock(&s->requests_lock);

    nbd_co_establish_connection_cancel(s->conn);
}

static void nbd_attach_aio_context(BlockDriverState *bs,
                                   AioContext *new_context)
{
    BDRVNBDState *s = bs->opaque;

    /* The open_timer is used only during nbd_open() */
    assert(!s->open_timer);

    /*
     * The reconnect_delay_timer is scheduled in I/O paths when the
     * connection is lost, to cancel the reconnection attempt after a
     * given time.  Once this attempt is done (successfully or not),
     * nbd_reconnect_attempt() ensures the timer is deleted before the
     * respective I/O request is resumed.
     * Since the AioContext can only be changed when a node is drained,
     * the reconnect_delay_timer cannot be active here.
     */
    assert(!s->reconnect_delay_timer);
}

static void nbd_detach_aio_context(BlockDriverState *bs)
{
    BDRVNBDState *s = bs->opaque;

    assert(!s->open_timer);
    assert(!s->reconnect_delay_timer);
}

static BlockDriver bdrv_nbd = {
    .format_name                = "nbd",
    .protocol_name              = "nbd",
    .instance_size              = sizeof(BDRVNBDState),
    .bdrv_parse_filename        = nbd_parse_filename,
    .bdrv_co_create_opts        = bdrv_co_create_opts_simple,
    .create_opts                = &bdrv_create_opts_simple,
    .bdrv_file_open             = nbd_open,
    .bdrv_reopen_prepare        = nbd_client_reopen_prepare,
    .bdrv_co_preadv             = nbd_client_co_preadv,
    .bdrv_co_pwritev            = nbd_client_co_pwritev,
    .bdrv_co_pwrite_zeroes      = nbd_client_co_pwrite_zeroes,
    .bdrv_close                 = nbd_close,
    .bdrv_co_flush_to_os        = nbd_client_co_flush,
    .bdrv_co_pdiscard           = nbd_client_co_pdiscard,
    .bdrv_refresh_limits        = nbd_refresh_limits,
    .bdrv_co_truncate           = nbd_co_truncate,
    .bdrv_co_getlength          = nbd_co_getlength,
    .bdrv_refresh_filename      = nbd_refresh_filename,
    .bdrv_co_block_status       = nbd_client_co_block_status,
    .bdrv_dirname               = nbd_dirname,
    .strong_runtime_opts        = nbd_strong_runtime_opts,
    .bdrv_cancel_in_flight      = nbd_cancel_in_flight,

    .bdrv_attach_aio_context    = nbd_attach_aio_context,
    .bdrv_detach_aio_context    = nbd_detach_aio_context,
};

static BlockDriver bdrv_nbd_tcp = {
    .format_name                = "nbd",
    .protocol_name              = "nbd+tcp",
    .instance_size              = sizeof(BDRVNBDState),
    .bdrv_parse_filename        = nbd_parse_filename,
    .bdrv_co_create_opts        = bdrv_co_create_opts_simple,
    .create_opts                = &bdrv_create_opts_simple,
    .bdrv_file_open             = nbd_open,
    .bdrv_reopen_prepare        = nbd_client_reopen_prepare,
    .bdrv_co_preadv             = nbd_client_co_preadv,
    .bdrv_co_pwritev            = nbd_client_co_pwritev,
    .bdrv_co_pwrite_zeroes      = nbd_client_co_pwrite_zeroes,
    .bdrv_close                 = nbd_close,
    .bdrv_co_flush_to_os        = nbd_client_co_flush,
    .bdrv_co_pdiscard           = nbd_client_co_pdiscard,
    .bdrv_refresh_limits        = nbd_refresh_limits,
    .bdrv_co_truncate           = nbd_co_truncate,
    .bdrv_co_getlength          = nbd_co_getlength,
    .bdrv_refresh_filename      = nbd_refresh_filename,
    .bdrv_co_block_status       = nbd_client_co_block_status,
    .bdrv_dirname               = nbd_dirname,
    .strong_runtime_opts        = nbd_strong_runtime_opts,
    .bdrv_cancel_in_flight      = nbd_cancel_in_flight,

    .bdrv_attach_aio_context    = nbd_attach_aio_context,
    .bdrv_detach_aio_context    = nbd_detach_aio_context,
};

static BlockDriver bdrv_nbd_unix = {
    .format_name                = "nbd",
    .protocol_name              = "nbd+unix",
    .instance_size              = sizeof(BDRVNBDState),
    .bdrv_parse_filename        = nbd_parse_filename,
    .bdrv_co_create_opts        = bdrv_co_create_opts_simple,
    .create_opts                = &bdrv_create_opts_simple,
    .bdrv_file_open             = nbd_open,
    .bdrv_reopen_prepare        = nbd_client_reopen_prepare,
    .bdrv_co_preadv             = nbd_client_co_preadv,
    .bdrv_co_pwritev            = nbd_client_co_pwritev,
    .bdrv_co_pwrite_zeroes      = nbd_client_co_pwrite_zeroes,
    .bdrv_close                 = nbd_close,
    .bdrv_co_flush_to_os        = nbd_client_co_flush,
    .bdrv_co_pdiscard           = nbd_client_co_pdiscard,
    .bdrv_refresh_limits        = nbd_refresh_limits,
    .bdrv_co_truncate           = nbd_co_truncate,
    .bdrv_co_getlength          = nbd_co_getlength,
    .bdrv_refresh_filename      = nbd_refresh_filename,
    .bdrv_co_block_status       = nbd_client_co_block_status,
    .bdrv_dirname               = nbd_dirname,
    .strong_runtime_opts        = nbd_strong_runtime_opts,
    .bdrv_cancel_in_flight      = nbd_cancel_in_flight,

    .bdrv_attach_aio_context    = nbd_attach_aio_context,
    .bdrv_detach_aio_context    = nbd_detach_aio_context,
};

static void bdrv_nbd_init(void)
{
    bdrv_register(&bdrv_nbd);
    bdrv_register(&bdrv_nbd_tcp);
    bdrv_register(&bdrv_nbd_unix);
}

block_init(bdrv_nbd_init);
