/*
 * Block layer I/O functions
 *
 * Copyright (c) 2003 Fabrice Bellard
 *
 * 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 "sysemu/block-backend.h"
#include "block/aio-wait.h"
#include "block/blockjob.h"
#include "block/blockjob_int.h"
#include "block/block_int.h"
#include "block/coroutines.h"
#include "block/dirty-bitmap.h"
#include "block/write-threshold.h"
#include "qemu/cutils.h"
#include "qemu/memalign.h"
#include "qapi/error.h"
#include "qemu/error-report.h"
#include "qemu/main-loop.h"
#include "sysemu/replay.h"

/* Maximum bounce buffer for copy-on-read and write zeroes, in bytes */
#define MAX_BOUNCE_BUFFER (32768 << BDRV_SECTOR_BITS)

static void coroutine_fn GRAPH_RDLOCK
bdrv_parent_cb_resize(BlockDriverState *bs);

static int coroutine_fn bdrv_co_do_pwrite_zeroes(BlockDriverState *bs,
    int64_t offset, int64_t bytes, BdrvRequestFlags flags);

static void GRAPH_RDLOCK
bdrv_parent_drained_begin(BlockDriverState *bs, BdrvChild *ignore)
{
    BdrvChild *c, *next;
    IO_OR_GS_CODE();
    assert_bdrv_graph_readable();

    QLIST_FOREACH_SAFE(c, &bs->parents, next_parent, next) {
        if (c == ignore) {
            continue;
        }
        bdrv_parent_drained_begin_single(c);
    }
}

void bdrv_parent_drained_end_single(BdrvChild *c)
{
    GLOBAL_STATE_CODE();

    assert(c->quiesced_parent);
    c->quiesced_parent = false;

    if (c->klass->drained_end) {
        c->klass->drained_end(c);
    }
}

static void GRAPH_RDLOCK
bdrv_parent_drained_end(BlockDriverState *bs, BdrvChild *ignore)
{
    BdrvChild *c;
    IO_OR_GS_CODE();
    assert_bdrv_graph_readable();

    QLIST_FOREACH(c, &bs->parents, next_parent) {
        if (c == ignore) {
            continue;
        }
        bdrv_parent_drained_end_single(c);
    }
}

bool bdrv_parent_drained_poll_single(BdrvChild *c)
{
    IO_OR_GS_CODE();

    if (c->klass->drained_poll) {
        return c->klass->drained_poll(c);
    }
    return false;
}

static bool GRAPH_RDLOCK
bdrv_parent_drained_poll(BlockDriverState *bs, BdrvChild *ignore,
                         bool ignore_bds_parents)
{
    BdrvChild *c, *next;
    bool busy = false;
    IO_OR_GS_CODE();
    assert_bdrv_graph_readable();

    QLIST_FOREACH_SAFE(c, &bs->parents, next_parent, next) {
        if (c == ignore || (ignore_bds_parents && c->klass->parent_is_bds)) {
            continue;
        }
        busy |= bdrv_parent_drained_poll_single(c);
    }

    return busy;
}

void bdrv_parent_drained_begin_single(BdrvChild *c)
{
    GLOBAL_STATE_CODE();

    assert(!c->quiesced_parent);
    c->quiesced_parent = true;

    if (c->klass->drained_begin) {
        /* called with rdlock taken, but it doesn't really need it. */
        c->klass->drained_begin(c);
    }
}

static void bdrv_merge_limits(BlockLimits *dst, const BlockLimits *src)
{
    dst->pdiscard_alignment = MAX(dst->pdiscard_alignment,
                                  src->pdiscard_alignment);
    dst->opt_transfer = MAX(dst->opt_transfer, src->opt_transfer);
    dst->max_transfer = MIN_NON_ZERO(dst->max_transfer, src->max_transfer);
    dst->max_hw_transfer = MIN_NON_ZERO(dst->max_hw_transfer,
                                        src->max_hw_transfer);
    dst->opt_mem_alignment = MAX(dst->opt_mem_alignment,
                                 src->opt_mem_alignment);
    dst->min_mem_alignment = MAX(dst->min_mem_alignment,
                                 src->min_mem_alignment);
    dst->max_iov = MIN_NON_ZERO(dst->max_iov, src->max_iov);
    dst->max_hw_iov = MIN_NON_ZERO(dst->max_hw_iov, src->max_hw_iov);
}

typedef struct BdrvRefreshLimitsState {
    BlockDriverState *bs;
    BlockLimits old_bl;
} BdrvRefreshLimitsState;

static void bdrv_refresh_limits_abort(void *opaque)
{
    BdrvRefreshLimitsState *s = opaque;

    s->bs->bl = s->old_bl;
}

static TransactionActionDrv bdrv_refresh_limits_drv = {
    .abort = bdrv_refresh_limits_abort,
    .clean = g_free,
};

/* @tran is allowed to be NULL, in this case no rollback is possible. */
void bdrv_refresh_limits(BlockDriverState *bs, Transaction *tran, Error **errp)
{
    ERRP_GUARD();
    BlockDriver *drv = bs->drv;
    BdrvChild *c;
    bool have_limits;

    GLOBAL_STATE_CODE();

    if (tran) {
        BdrvRefreshLimitsState *s = g_new(BdrvRefreshLimitsState, 1);
        *s = (BdrvRefreshLimitsState) {
            .bs = bs,
            .old_bl = bs->bl,
        };
        tran_add(tran, &bdrv_refresh_limits_drv, s);
    }

    memset(&bs->bl, 0, sizeof(bs->bl));

    if (!drv) {
        return;
    }

    /* Default alignment based on whether driver has byte interface */
    bs->bl.request_alignment = (drv->bdrv_co_preadv ||
                                drv->bdrv_aio_preadv ||
                                drv->bdrv_co_preadv_part) ? 1 : 512;

    /* Take some limits from the children as a default */
    have_limits = false;
    QLIST_FOREACH(c, &bs->children, next) {
        if (c->role & (BDRV_CHILD_DATA | BDRV_CHILD_FILTERED | BDRV_CHILD_COW))
        {
            bdrv_merge_limits(&bs->bl, &c->bs->bl);
            have_limits = true;
        }

        if (c->role & BDRV_CHILD_FILTERED) {
            bs->bl.has_variable_length |= c->bs->bl.has_variable_length;
        }
    }

    if (!have_limits) {
        bs->bl.min_mem_alignment = 512;
        bs->bl.opt_mem_alignment = qemu_real_host_page_size();

        /* Safe default since most protocols use readv()/writev()/etc */
        bs->bl.max_iov = IOV_MAX;
    }

    /* Then let the driver override it */
    if (drv->bdrv_refresh_limits) {
        drv->bdrv_refresh_limits(bs, errp);
        if (*errp) {
            return;
        }
    }

    if (bs->bl.request_alignment > BDRV_MAX_ALIGNMENT) {
        error_setg(errp, "Driver requires too large request alignment");
    }
}

/**
 * The copy-on-read flag is actually a reference count so multiple users may
 * use the feature without worrying about clobbering its previous state.
 * Copy-on-read stays enabled until all users have called to disable it.
 */
void bdrv_enable_copy_on_read(BlockDriverState *bs)
{
    IO_CODE();
    qatomic_inc(&bs->copy_on_read);
}

void bdrv_disable_copy_on_read(BlockDriverState *bs)
{
    int old = qatomic_fetch_dec(&bs->copy_on_read);
    IO_CODE();
    assert(old >= 1);
}

typedef struct {
    Coroutine *co;
    BlockDriverState *bs;
    bool done;
    bool begin;
    bool poll;
    BdrvChild *parent;
} BdrvCoDrainData;

/* Returns true if BDRV_POLL_WHILE() should go into a blocking aio_poll() */
bool bdrv_drain_poll(BlockDriverState *bs, BdrvChild *ignore_parent,
                     bool ignore_bds_parents)
{
    GLOBAL_STATE_CODE();

    if (bdrv_parent_drained_poll(bs, ignore_parent, ignore_bds_parents)) {
        return true;
    }

    if (qatomic_read(&bs->in_flight)) {
        return true;
    }

    return false;
}

static bool bdrv_drain_poll_top_level(BlockDriverState *bs,
                                      BdrvChild *ignore_parent)
{
    GLOBAL_STATE_CODE();
    GRAPH_RDLOCK_GUARD_MAINLOOP();

    return bdrv_drain_poll(bs, ignore_parent, false);
}

static void bdrv_do_drained_begin(BlockDriverState *bs, BdrvChild *parent,
                                  bool poll);
static void bdrv_do_drained_end(BlockDriverState *bs, BdrvChild *parent);

static void bdrv_co_drain_bh_cb(void *opaque)
{
    BdrvCoDrainData *data = opaque;
    Coroutine *co = data->co;
    BlockDriverState *bs = data->bs;

    if (bs) {
        bdrv_dec_in_flight(bs);
        if (data->begin) {
            bdrv_do_drained_begin(bs, data->parent, data->poll);
        } else {
            assert(!data->poll);
            bdrv_do_drained_end(bs, data->parent);
        }
    } else {
        assert(data->begin);
        bdrv_drain_all_begin();
    }

    data->done = true;
    aio_co_wake(co);
}

static void coroutine_fn bdrv_co_yield_to_drain(BlockDriverState *bs,
                                                bool begin,
                                                BdrvChild *parent,
                                                bool poll)
{
    BdrvCoDrainData data;
    Coroutine *self = qemu_coroutine_self();

    /* Calling bdrv_drain() from a BH ensures the current coroutine yields and
     * other coroutines run if they were queued by aio_co_enter(). */

    assert(qemu_in_coroutine());
    data = (BdrvCoDrainData) {
        .co = self,
        .bs = bs,
        .done = false,
        .begin = begin,
        .parent = parent,
        .poll = poll,
    };

    if (bs) {
        bdrv_inc_in_flight(bs);
    }

    replay_bh_schedule_oneshot_event(qemu_get_aio_context(),
                                     bdrv_co_drain_bh_cb, &data);

    qemu_coroutine_yield();
    /* If we are resumed from some other event (such as an aio completion or a
     * timer callback), it is a bug in the caller that should be fixed. */
    assert(data.done);
}

static void bdrv_do_drained_begin(BlockDriverState *bs, BdrvChild *parent,
                                  bool poll)
{
    IO_OR_GS_CODE();

    if (qemu_in_coroutine()) {
        bdrv_co_yield_to_drain(bs, true, parent, poll);
        return;
    }

    GLOBAL_STATE_CODE();

    /* Stop things in parent-to-child order */
    if (qatomic_fetch_inc(&bs->quiesce_counter) == 0) {
        GRAPH_RDLOCK_GUARD_MAINLOOP();
        bdrv_parent_drained_begin(bs, parent);
        if (bs->drv && bs->drv->bdrv_drain_begin) {
            bs->drv->bdrv_drain_begin(bs);
        }
    }

    /*
     * Wait for drained requests to finish.
     *
     * Calling BDRV_POLL_WHILE() only once for the top-level node is okay: The
     * call is needed so things in this AioContext can make progress even
     * though we don't return to the main AioContext loop - this automatically
     * includes other nodes in the same AioContext and therefore all child
     * nodes.
     */
    if (poll) {
        BDRV_POLL_WHILE(bs, bdrv_drain_poll_top_level(bs, parent));
    }
}

void bdrv_do_drained_begin_quiesce(BlockDriverState *bs, BdrvChild *parent)
{
    bdrv_do_drained_begin(bs, parent, false);
}

void coroutine_mixed_fn
bdrv_drained_begin(BlockDriverState *bs)
{
    IO_OR_GS_CODE();
    bdrv_do_drained_begin(bs, NULL, true);
}

/**
 * This function does not poll, nor must any of its recursively called
 * functions.
 */
static void bdrv_do_drained_end(BlockDriverState *bs, BdrvChild *parent)
{
    int old_quiesce_counter;

    IO_OR_GS_CODE();

    if (qemu_in_coroutine()) {
        bdrv_co_yield_to_drain(bs, false, parent, false);
        return;
    }

    /* At this point, we should be always running in the main loop. */
    GLOBAL_STATE_CODE();
    assert(bs->quiesce_counter > 0);
    GLOBAL_STATE_CODE();

    /* Re-enable things in child-to-parent order */
    old_quiesce_counter = qatomic_fetch_dec(&bs->quiesce_counter);
    if (old_quiesce_counter == 1) {
        GRAPH_RDLOCK_GUARD_MAINLOOP();
        if (bs->drv && bs->drv->bdrv_drain_end) {
            bs->drv->bdrv_drain_end(bs);
        }
        bdrv_parent_drained_end(bs, parent);
    }
}

void bdrv_drained_end(BlockDriverState *bs)
{
    IO_OR_GS_CODE();
    bdrv_do_drained_end(bs, NULL);
}

void bdrv_drain(BlockDriverState *bs)
{
    IO_OR_GS_CODE();
    bdrv_drained_begin(bs);
    bdrv_drained_end(bs);
}

static void bdrv_drain_assert_idle(BlockDriverState *bs)
{
    BdrvChild *child, *next;
    GLOBAL_STATE_CODE();
    GRAPH_RDLOCK_GUARD_MAINLOOP();

    assert(qatomic_read(&bs->in_flight) == 0);
    QLIST_FOREACH_SAFE(child, &bs->children, next, next) {
        bdrv_drain_assert_idle(child->bs);
    }
}

unsigned int bdrv_drain_all_count = 0;

static bool bdrv_drain_all_poll(void)
{
    BlockDriverState *bs = NULL;
    bool result = false;

    GLOBAL_STATE_CODE();
    GRAPH_RDLOCK_GUARD_MAINLOOP();

    /*
     * bdrv_drain_poll() can't make changes to the graph and we hold the BQL,
     * so iterating bdrv_next_all_states() is safe.
     */
    while ((bs = bdrv_next_all_states(bs))) {
        result |= bdrv_drain_poll(bs, NULL, true);
    }

    return result;
}

/*
 * Wait for pending requests to complete across all BlockDriverStates
 *
 * This function does not flush data to disk, use bdrv_flush_all() for that
 * after calling this function.
 *
 * This pauses all block jobs and disables external clients. It must
 * be paired with bdrv_drain_all_end().
 *
 * NOTE: no new block jobs or BlockDriverStates can be created between
 * the bdrv_drain_all_begin() and bdrv_drain_all_end() calls.
 */
void bdrv_drain_all_begin_nopoll(void)
{
    BlockDriverState *bs = NULL;
    GLOBAL_STATE_CODE();

    /*
     * bdrv queue is managed by record/replay,
     * waiting for finishing the I/O requests may
     * be infinite
     */
    if (replay_events_enabled()) {
        return;
    }

    /* AIO_WAIT_WHILE() with a NULL context can only be called from the main
     * loop AioContext, so make sure we're in the main context. */
    assert(qemu_get_current_aio_context() == qemu_get_aio_context());
    assert(bdrv_drain_all_count < INT_MAX);
    bdrv_drain_all_count++;

    /* Quiesce all nodes, without polling in-flight requests yet. The graph
     * cannot change during this loop. */
    while ((bs = bdrv_next_all_states(bs))) {
        bdrv_do_drained_begin(bs, NULL, false);
    }
}

void coroutine_mixed_fn bdrv_drain_all_begin(void)
{
    BlockDriverState *bs = NULL;

    if (qemu_in_coroutine()) {
        bdrv_co_yield_to_drain(NULL, true, NULL, true);
        return;
    }

    /*
     * bdrv queue is managed by record/replay,
     * waiting for finishing the I/O requests may
     * be infinite
     */
    if (replay_events_enabled()) {
        return;
    }

    bdrv_drain_all_begin_nopoll();

    /* Now poll the in-flight requests */
    AIO_WAIT_WHILE_UNLOCKED(NULL, bdrv_drain_all_poll());

    while ((bs = bdrv_next_all_states(bs))) {
        bdrv_drain_assert_idle(bs);
    }
}

void bdrv_drain_all_end_quiesce(BlockDriverState *bs)
{
    GLOBAL_STATE_CODE();

    g_assert(bs->quiesce_counter > 0);
    g_assert(!bs->refcnt);

    while (bs->quiesce_counter) {
        bdrv_do_drained_end(bs, NULL);
    }
}

void bdrv_drain_all_end(void)
{
    BlockDriverState *bs = NULL;
    GLOBAL_STATE_CODE();

    /*
     * bdrv queue is managed by record/replay,
     * waiting for finishing the I/O requests may
     * be endless
     */
    if (replay_events_enabled()) {
        return;
    }

    while ((bs = bdrv_next_all_states(bs))) {
        bdrv_do_drained_end(bs, NULL);
    }

    assert(qemu_get_current_aio_context() == qemu_get_aio_context());
    assert(bdrv_drain_all_count > 0);
    bdrv_drain_all_count--;
}

void bdrv_drain_all(void)
{
    GLOBAL_STATE_CODE();
    bdrv_drain_all_begin();
    bdrv_drain_all_end();
}

/**
 * Remove an active request from the tracked requests list
 *
 * This function should be called when a tracked request is completing.
 */
static void coroutine_fn tracked_request_end(BdrvTrackedRequest *req)
{
    if (req->serialising) {
        qatomic_dec(&req->bs->serialising_in_flight);
    }

    qemu_mutex_lock(&req->bs->reqs_lock);
    QLIST_REMOVE(req, list);
    qemu_mutex_unlock(&req->bs->reqs_lock);

    /*
     * At this point qemu_co_queue_wait(&req->wait_queue, ...) won't be called
     * anymore because the request has been removed from the list, so it's safe
     * to restart the queue outside reqs_lock to minimize the critical section.
     */
    qemu_co_queue_restart_all(&req->wait_queue);
}

/**
 * Add an active request to the tracked requests list
 */
static void coroutine_fn tracked_request_begin(BdrvTrackedRequest *req,
                                               BlockDriverState *bs,
                                               int64_t offset,
                                               int64_t bytes,
                                               enum BdrvTrackedRequestType type)
{
    bdrv_check_request(offset, bytes, &error_abort);

    *req = (BdrvTrackedRequest){
        .bs = bs,
        .offset         = offset,
        .bytes          = bytes,
        .type           = type,
        .co             = qemu_coroutine_self(),
        .serialising    = false,
        .overlap_offset = offset,
        .overlap_bytes  = bytes,
    };

    qemu_co_queue_init(&req->wait_queue);

    qemu_mutex_lock(&bs->reqs_lock);
    QLIST_INSERT_HEAD(&bs->tracked_requests, req, list);
    qemu_mutex_unlock(&bs->reqs_lock);
}

static bool tracked_request_overlaps(BdrvTrackedRequest *req,
                                     int64_t offset, int64_t bytes)
{
    bdrv_check_request(offset, bytes, &error_abort);

    /*        aaaa   bbbb */
    if (offset >= req->overlap_offset + req->overlap_bytes) {
        return false;
    }
    /* bbbb   aaaa        */
    if (req->overlap_offset >= offset + bytes) {
        return false;
    }
    return true;
}

/* Called with self->bs->reqs_lock held */
static coroutine_fn BdrvTrackedRequest *
bdrv_find_conflicting_request(BdrvTrackedRequest *self)
{
    BdrvTrackedRequest *req;

    QLIST_FOREACH(req, &self->bs->tracked_requests, list) {
        if (req == self || (!req->serialising && !self->serialising)) {
            continue;
        }
        if (tracked_request_overlaps(req, self->overlap_offset,
                                     self->overlap_bytes))
        {
            /*
             * Hitting this means there was a reentrant request, for
             * example, a block driver issuing nested requests.  This must
             * never happen since it means deadlock.
             */
            assert(qemu_coroutine_self() != req->co);

            /*
             * If the request is already (indirectly) waiting for us, or
             * will wait for us as soon as it wakes up, then just go on
             * (instead of producing a deadlock in the former case).
             */
            if (!req->waiting_for) {
                return req;
            }
        }
    }

    return NULL;
}

/* Called with self->bs->reqs_lock held */
static void coroutine_fn
bdrv_wait_serialising_requests_locked(BdrvTrackedRequest *self)
{
    BdrvTrackedRequest *req;

    while ((req = bdrv_find_conflicting_request(self))) {
        self->waiting_for = req;
        qemu_co_queue_wait(&req->wait_queue, &self->bs->reqs_lock);
        self->waiting_for = NULL;
    }
}

/* Called with req->bs->reqs_lock held */
static void tracked_request_set_serialising(BdrvTrackedRequest *req,
                                            uint64_t align)
{
    int64_t overlap_offset = req->offset & ~(align - 1);
    int64_t overlap_bytes =
        ROUND_UP(req->offset + req->bytes, align) - overlap_offset;

    bdrv_check_request(req->offset, req->bytes, &error_abort);

    if (!req->serialising) {
        qatomic_inc(&req->bs->serialising_in_flight);
        req->serialising = true;
    }

    req->overlap_offset = MIN(req->overlap_offset, overlap_offset);
    req->overlap_bytes = MAX(req->overlap_bytes, overlap_bytes);
}

/**
 * Return the tracked request on @bs for the current coroutine, or
 * NULL if there is none.
 */
BdrvTrackedRequest *coroutine_fn bdrv_co_get_self_request(BlockDriverState *bs)
{
    BdrvTrackedRequest *req;
    Coroutine *self = qemu_coroutine_self();
    IO_CODE();

    QLIST_FOREACH(req, &bs->tracked_requests, list) {
        if (req->co == self) {
            return req;
        }
    }

    return NULL;
}

/**
 * Round a region to subcluster (if supported) or cluster boundaries
 */
void coroutine_fn GRAPH_RDLOCK
bdrv_round_to_subclusters(BlockDriverState *bs, int64_t offset, int64_t bytes,
                          int64_t *align_offset, int64_t *align_bytes)
{
    BlockDriverInfo bdi;
    IO_CODE();
    if (bdrv_co_get_info(bs, &bdi) < 0 || bdi.subcluster_size == 0) {
        *align_offset = offset;
        *align_bytes = bytes;
    } else {
        int64_t c = bdi.subcluster_size;
        *align_offset = QEMU_ALIGN_DOWN(offset, c);
        *align_bytes = QEMU_ALIGN_UP(offset - *align_offset + bytes, c);
    }
}

static int coroutine_fn GRAPH_RDLOCK bdrv_get_cluster_size(BlockDriverState *bs)
{
    BlockDriverInfo bdi;
    int ret;

    ret = bdrv_co_get_info(bs, &bdi);
    if (ret < 0 || bdi.cluster_size == 0) {
        return bs->bl.request_alignment;
    } else {
        return bdi.cluster_size;
    }
}

void bdrv_inc_in_flight(BlockDriverState *bs)
{
    IO_CODE();
    qatomic_inc(&bs->in_flight);
}

void bdrv_wakeup(BlockDriverState *bs)
{
    IO_CODE();
    aio_wait_kick();
}

void bdrv_dec_in_flight(BlockDriverState *bs)
{
    IO_CODE();
    qatomic_dec(&bs->in_flight);
    bdrv_wakeup(bs);
}

static void coroutine_fn
bdrv_wait_serialising_requests(BdrvTrackedRequest *self)
{
    BlockDriverState *bs = self->bs;

    if (!qatomic_read(&bs->serialising_in_flight)) {
        return;
    }

    qemu_mutex_lock(&bs->reqs_lock);
    bdrv_wait_serialising_requests_locked(self);
    qemu_mutex_unlock(&bs->reqs_lock);
}

void coroutine_fn bdrv_make_request_serialising(BdrvTrackedRequest *req,
                                                uint64_t align)
{
    IO_CODE();

    qemu_mutex_lock(&req->bs->reqs_lock);

    tracked_request_set_serialising(req, align);
    bdrv_wait_serialising_requests_locked(req);

    qemu_mutex_unlock(&req->bs->reqs_lock);
}

int bdrv_check_qiov_request(int64_t offset, int64_t bytes,
                            QEMUIOVector *qiov, size_t qiov_offset,
                            Error **errp)
{
    /*
     * Check generic offset/bytes correctness
     */

    if (offset < 0) {
        error_setg(errp, "offset is negative: %" PRIi64, offset);
        return -EIO;
    }

    if (bytes < 0) {
        error_setg(errp, "bytes is negative: %" PRIi64, bytes);
        return -EIO;
    }

    if (bytes > BDRV_MAX_LENGTH) {
        error_setg(errp, "bytes(%" PRIi64 ") exceeds maximum(%" PRIi64 ")",
                   bytes, BDRV_MAX_LENGTH);
        return -EIO;
    }

    if (offset > BDRV_MAX_LENGTH) {
        error_setg(errp, "offset(%" PRIi64 ") exceeds maximum(%" PRIi64 ")",
                   offset, BDRV_MAX_LENGTH);
        return -EIO;
    }

    if (offset > BDRV_MAX_LENGTH - bytes) {
        error_setg(errp, "sum of offset(%" PRIi64 ") and bytes(%" PRIi64 ") "
                   "exceeds maximum(%" PRIi64 ")", offset, bytes,
                   BDRV_MAX_LENGTH);
        return -EIO;
    }

    if (!qiov) {
        return 0;
    }

    /*
     * Check qiov and qiov_offset
     */

    if (qiov_offset > qiov->size) {
        error_setg(errp, "qiov_offset(%zu) overflow io vector size(%zu)",
                   qiov_offset, qiov->size);
        return -EIO;
    }

    if (bytes > qiov->size - qiov_offset) {
        error_setg(errp, "bytes(%" PRIi64 ") + qiov_offset(%zu) overflow io "
                   "vector size(%zu)", bytes, qiov_offset, qiov->size);
        return -EIO;
    }

    return 0;
}

int bdrv_check_request(int64_t offset, int64_t bytes, Error **errp)
{
    return bdrv_check_qiov_request(offset, bytes, NULL, 0, errp);
}

static int bdrv_check_request32(int64_t offset, int64_t bytes,
                                QEMUIOVector *qiov, size_t qiov_offset)
{
    int ret = bdrv_check_qiov_request(offset, bytes, qiov, qiov_offset, NULL);
    if (ret < 0) {
        return ret;
    }

    if (bytes > BDRV_REQUEST_MAX_BYTES) {
        return -EIO;
    }

    return 0;
}

/*
 * Completely zero out a block device with the help of bdrv_pwrite_zeroes.
 * The operation is sped up by checking the block status and only writing
 * zeroes to the device if they currently do not return zeroes. Optional
 * flags are passed through to bdrv_pwrite_zeroes (e.g. BDRV_REQ_MAY_UNMAP,
 * BDRV_REQ_FUA).
 *
 * Returns < 0 on error, 0 on success. For error codes see bdrv_pwrite().
 */
int bdrv_make_zero(BdrvChild *child, BdrvRequestFlags flags)
{
    int ret;
    int64_t target_size, bytes, offset = 0;
    BlockDriverState *bs = child->bs;
    IO_CODE();

    target_size = bdrv_getlength(bs);
    if (target_size < 0) {
        return target_size;
    }

    for (;;) {
        bytes = MIN(target_size - offset, BDRV_REQUEST_MAX_BYTES);
        if (bytes <= 0) {
            return 0;
        }
        ret = bdrv_block_status(bs, offset, bytes, &bytes, NULL, NULL);
        if (ret < 0) {
            return ret;
        }
        if (ret & BDRV_BLOCK_ZERO) {
            offset += bytes;
            continue;
        }
        ret = bdrv_pwrite_zeroes(child, offset, bytes, flags);
        if (ret < 0) {
            return ret;
        }
        offset += bytes;
    }
}

/*
 * Writes to the file and ensures that no writes are reordered across this
 * request (acts as a barrier)
 *
 * Returns 0 on success, -errno in error cases.
 */
int coroutine_fn bdrv_co_pwrite_sync(BdrvChild *child, int64_t offset,
                                     int64_t bytes, const void *buf,
                                     BdrvRequestFlags flags)
{
    int ret;
    IO_CODE();
    assert_bdrv_graph_readable();

    ret = bdrv_co_pwrite(child, offset, bytes, buf, flags);
    if (ret < 0) {
        return ret;
    }

    ret = bdrv_co_flush(child->bs);
    if (ret < 0) {
        return ret;
    }

    return 0;
}

typedef struct CoroutineIOCompletion {
    Coroutine *coroutine;
    int ret;
} CoroutineIOCompletion;

static void bdrv_co_io_em_complete(void *opaque, int ret)
{
    CoroutineIOCompletion *co = opaque;

    co->ret = ret;
    aio_co_wake(co->coroutine);
}

static int coroutine_fn GRAPH_RDLOCK
bdrv_driver_preadv(BlockDriverState *bs, int64_t offset, int64_t bytes,
                   QEMUIOVector *qiov, size_t qiov_offset, int flags)
{
    BlockDriver *drv = bs->drv;
    int64_t sector_num;
    unsigned int nb_sectors;
    QEMUIOVector local_qiov;
    int ret;
    assert_bdrv_graph_readable();

    bdrv_check_qiov_request(offset, bytes, qiov, qiov_offset, &error_abort);
    assert(!(flags & ~bs->supported_read_flags));

    if (!drv) {
        return -ENOMEDIUM;
    }

    if (drv->bdrv_co_preadv_part) {
        return drv->bdrv_co_preadv_part(bs, offset, bytes, qiov, qiov_offset,
                                        flags);
    }

    if (qiov_offset > 0 || bytes != qiov->size) {
        qemu_iovec_init_slice(&local_qiov, qiov, qiov_offset, bytes);
        qiov = &local_qiov;
    }

    if (drv->bdrv_co_preadv) {
        ret = drv->bdrv_co_preadv(bs, offset, bytes, qiov, flags);
        goto out;
    }

    if (drv->bdrv_aio_preadv) {
        BlockAIOCB *acb;
        CoroutineIOCompletion co = {
            .coroutine = qemu_coroutine_self(),
        };

        acb = drv->bdrv_aio_preadv(bs, offset, bytes, qiov, flags,
                                   bdrv_co_io_em_complete, &co);
        if (acb == NULL) {
            ret = -EIO;
            goto out;
        } else {
            qemu_coroutine_yield();
            ret = co.ret;
            goto out;
        }
    }

    sector_num = offset >> BDRV_SECTOR_BITS;
    nb_sectors = bytes >> BDRV_SECTOR_BITS;

    assert(QEMU_IS_ALIGNED(offset, BDRV_SECTOR_SIZE));
    assert(QEMU_IS_ALIGNED(bytes, BDRV_SECTOR_SIZE));
    assert(bytes <= BDRV_REQUEST_MAX_BYTES);
    assert(drv->bdrv_co_readv);

    ret = drv->bdrv_co_readv(bs, sector_num, nb_sectors, qiov);

out:
    if (qiov == &local_qiov) {
        qemu_iovec_destroy(&local_qiov);
    }

    return ret;
}

static int coroutine_fn GRAPH_RDLOCK
bdrv_driver_pwritev(BlockDriverState *bs, int64_t offset, int64_t bytes,
                    QEMUIOVector *qiov, size_t qiov_offset,
                    BdrvRequestFlags flags)
{
    BlockDriver *drv = bs->drv;
    bool emulate_fua = false;
    int64_t sector_num;
    unsigned int nb_sectors;
    QEMUIOVector local_qiov;
    int ret;
    assert_bdrv_graph_readable();

    bdrv_check_qiov_request(offset, bytes, qiov, qiov_offset, &error_abort);

    if (!drv) {
        return -ENOMEDIUM;
    }

    if ((flags & BDRV_REQ_FUA) &&
        (~bs->supported_write_flags & BDRV_REQ_FUA)) {
        flags &= ~BDRV_REQ_FUA;
        emulate_fua = true;
    }

    flags &= bs->supported_write_flags;

    if (drv->bdrv_co_pwritev_part) {
        ret = drv->bdrv_co_pwritev_part(bs, offset, bytes, qiov, qiov_offset,
                                        flags);
        goto emulate_flags;
    }

    if (qiov_offset > 0 || bytes != qiov->size) {
        qemu_iovec_init_slice(&local_qiov, qiov, qiov_offset, bytes);
        qiov = &local_qiov;
    }

    if (drv->bdrv_co_pwritev) {
        ret = drv->bdrv_co_pwritev(bs, offset, bytes, qiov, flags);
        goto emulate_flags;
    }

    if (drv->bdrv_aio_pwritev) {
        BlockAIOCB *acb;
        CoroutineIOCompletion co = {
            .coroutine = qemu_coroutine_self(),
        };

        acb = drv->bdrv_aio_pwritev(bs, offset, bytes, qiov, flags,
                                    bdrv_co_io_em_complete, &co);
        if (acb == NULL) {
            ret = -EIO;
        } else {
            qemu_coroutine_yield();
            ret = co.ret;
        }
        goto emulate_flags;
    }

    sector_num = offset >> BDRV_SECTOR_BITS;
    nb_sectors = bytes >> BDRV_SECTOR_BITS;

    assert(QEMU_IS_ALIGNED(offset, BDRV_SECTOR_SIZE));
    assert(QEMU_IS_ALIGNED(bytes, BDRV_SECTOR_SIZE));
    assert(bytes <= BDRV_REQUEST_MAX_BYTES);

    assert(drv->bdrv_co_writev);
    ret = drv->bdrv_co_writev(bs, sector_num, nb_sectors, qiov, flags);

emulate_flags:
    if (ret == 0 && emulate_fua) {
        ret = bdrv_co_flush(bs);
    }

    if (qiov == &local_qiov) {
        qemu_iovec_destroy(&local_qiov);
    }

    return ret;
}

static int coroutine_fn GRAPH_RDLOCK
bdrv_driver_pwritev_compressed(BlockDriverState *bs, int64_t offset,
                               int64_t bytes, QEMUIOVector *qiov,
                               size_t qiov_offset)
{
    BlockDriver *drv = bs->drv;
    QEMUIOVector local_qiov;
    int ret;
    assert_bdrv_graph_readable();

    bdrv_check_qiov_request(offset, bytes, qiov, qiov_offset, &error_abort);

    if (!drv) {
        return -ENOMEDIUM;
    }

    if (!block_driver_can_compress(drv)) {
        return -ENOTSUP;
    }

    if (drv->bdrv_co_pwritev_compressed_part) {
        return drv->bdrv_co_pwritev_compressed_part(bs, offset, bytes,
                                                    qiov, qiov_offset);
    }

    if (qiov_offset == 0) {
        return drv->bdrv_co_pwritev_compressed(bs, offset, bytes, qiov);
    }

    qemu_iovec_init_slice(&local_qiov, qiov, qiov_offset, bytes);
    ret = drv->bdrv_co_pwritev_compressed(bs, offset, bytes, &local_qiov);
    qemu_iovec_destroy(&local_qiov);

    return ret;
}

static int coroutine_fn GRAPH_RDLOCK
bdrv_co_do_copy_on_readv(BdrvChild *child, int64_t offset, int64_t bytes,
                         QEMUIOVector *qiov, size_t qiov_offset, int flags)
{
    BlockDriverState *bs = child->bs;

    /* Perform I/O through a temporary buffer so that users who scribble over
     * their read buffer while the operation is in progress do not end up
     * modifying the image file.  This is critical for zero-copy guest I/O
     * where anything might happen inside guest memory.
     */
    void *bounce_buffer = NULL;

    BlockDriver *drv = bs->drv;
    int64_t align_offset;
    int64_t align_bytes;
    int64_t skip_bytes;
    int ret;
    int max_transfer = MIN_NON_ZERO(bs->bl.max_transfer,
                                    BDRV_REQUEST_MAX_BYTES);
    int64_t progress = 0;
    bool skip_write;

    bdrv_check_qiov_request(offset, bytes, qiov, qiov_offset, &error_abort);

    if (!drv) {
        return -ENOMEDIUM;
    }

    /*
     * Do not write anything when the BDS is inactive.  That is not
     * allowed, and it would not help.
     */
    skip_write = (bs->open_flags & BDRV_O_INACTIVE);

    /* FIXME We cannot require callers to have write permissions when all they
     * are doing is a read request. If we did things right, write permissions
     * would be obtained anyway, but internally by the copy-on-read code. As
     * long as it is implemented here rather than in a separate filter driver,
     * the copy-on-read code doesn't have its own BdrvChild, however, for which
     * it could request permissions. Therefore we have to bypass the permission
     * system for the moment. */
    // assert(child->perm & (BLK_PERM_WRITE_UNCHANGED | BLK_PERM_WRITE));

    /* Cover entire cluster so no additional backing file I/O is required when
     * allocating cluster in the image file.  Note that this value may exceed
     * BDRV_REQUEST_MAX_BYTES (even when the original read did not), which
     * is one reason we loop rather than doing it all at once.
     */
    bdrv_round_to_subclusters(bs, offset, bytes, &align_offset, &align_bytes);
    skip_bytes = offset - align_offset;

    trace_bdrv_co_do_copy_on_readv(bs, offset, bytes,
                                   align_offset, align_bytes);

    while (align_bytes) {
        int64_t pnum;

        if (skip_write) {
            ret = 1; /* "already allocated", so nothing will be copied */
            pnum = MIN(align_bytes, max_transfer);
        } else {
            ret = bdrv_co_is_allocated(bs, align_offset,
                                       MIN(align_bytes, max_transfer), &pnum);
            if (ret < 0) {
                /*
                 * Safe to treat errors in querying allocation as if
                 * unallocated; we'll probably fail again soon on the
                 * read, but at least that will set a decent errno.
                 */
                pnum = MIN(align_bytes, max_transfer);
            }

            /* Stop at EOF if the image ends in the middle of the cluster */
            if (ret == 0 && pnum == 0) {
                assert(progress >= bytes);
                break;
            }

            assert(skip_bytes < pnum);
        }

        if (ret <= 0) {
            QEMUIOVector local_qiov;

            /* Must copy-on-read; use the bounce buffer */
            pnum = MIN(pnum, MAX_BOUNCE_BUFFER);
            if (!bounce_buffer) {
                int64_t max_we_need = MAX(pnum, align_bytes - pnum);
                int64_t max_allowed = MIN(max_transfer, MAX_BOUNCE_BUFFER);
                int64_t bounce_buffer_len = MIN(max_we_need, max_allowed);

                bounce_buffer = qemu_try_blockalign(bs, bounce_buffer_len);
                if (!bounce_buffer) {
                    ret = -ENOMEM;
                    goto err;
                }
            }
            qemu_iovec_init_buf(&local_qiov, bounce_buffer, pnum);

            ret = bdrv_driver_preadv(bs, align_offset, pnum,
                                     &local_qiov, 0, 0);
            if (ret < 0) {
                goto err;
            }

            bdrv_co_debug_event(bs, BLKDBG_COR_WRITE);
            if (drv->bdrv_co_pwrite_zeroes &&
                buffer_is_zero(bounce_buffer, pnum)) {
                /* FIXME: Should we (perhaps conditionally) be setting
                 * BDRV_REQ_MAY_UNMAP, if it will allow for a sparser copy
                 * that still correctly reads as zero? */
                ret = bdrv_co_do_pwrite_zeroes(bs, align_offset, pnum,
                                               BDRV_REQ_WRITE_UNCHANGED);
            } else {
                /* This does not change the data on the disk, it is not
                 * necessary to flush even in cache=writethrough mode.
                 */
                ret = bdrv_driver_pwritev(bs, align_offset, pnum,
                                          &local_qiov, 0,
                                          BDRV_REQ_WRITE_UNCHANGED);
            }

            if (ret < 0) {
                /* It might be okay to ignore write errors for guest
                 * requests.  If this is a deliberate copy-on-read
                 * then we don't want to ignore the error.  Simply
                 * report it in all cases.
                 */
                goto err;
            }

            if (!(flags & BDRV_REQ_PREFETCH)) {
                qemu_iovec_from_buf(qiov, qiov_offset + progress,
                                    bounce_buffer + skip_bytes,
                                    MIN(pnum - skip_bytes, bytes - progress));
            }
        } else if (!(flags & BDRV_REQ_PREFETCH)) {
            /* Read directly into the destination */
            ret = bdrv_driver_preadv(bs, offset + progress,
                                     MIN(pnum - skip_bytes, bytes - progress),
                                     qiov, qiov_offset + progress, 0);
            if (ret < 0) {
                goto err;
            }
        }

        align_offset += pnum;
        align_bytes -= pnum;
        progress += pnum - skip_bytes;
        skip_bytes = 0;
    }
    ret = 0;

err:
    qemu_vfree(bounce_buffer);
    return ret;
}

/*
 * Forwards an already correctly aligned request to the BlockDriver. This
 * handles copy on read, zeroing after EOF, and fragmentation of large
 * reads; any other features must be implemented by the caller.
 */
static int coroutine_fn GRAPH_RDLOCK
bdrv_aligned_preadv(BdrvChild *child, BdrvTrackedRequest *req,
                    int64_t offset, int64_t bytes, int64_t align,
                    QEMUIOVector *qiov, size_t qiov_offset, int flags)
{
    BlockDriverState *bs = child->bs;
    int64_t total_bytes, max_bytes;
    int ret = 0;
    int64_t bytes_remaining = bytes;
    int max_transfer;

    bdrv_check_qiov_request(offset, bytes, qiov, qiov_offset, &error_abort);
    assert(is_power_of_2(align));
    assert((offset & (align - 1)) == 0);
    assert((bytes & (align - 1)) == 0);
    assert((bs->open_flags & BDRV_O_NO_IO) == 0);
    max_transfer = QEMU_ALIGN_DOWN(MIN_NON_ZERO(bs->bl.max_transfer, INT_MAX),
                                   align);

    /*
     * TODO: We would need a per-BDS .supported_read_flags and
     * potential fallback support, if we ever implement any read flags
     * to pass through to drivers.  For now, there aren't any
     * passthrough flags except the BDRV_REQ_REGISTERED_BUF optimization hint.
     */
    assert(!(flags & ~(BDRV_REQ_COPY_ON_READ | BDRV_REQ_PREFETCH |
                       BDRV_REQ_REGISTERED_BUF)));

    /* Handle Copy on Read and associated serialisation */
    if (flags & BDRV_REQ_COPY_ON_READ) {
        /* If we touch the same cluster it counts as an overlap.  This
         * guarantees that allocating writes will be serialized and not race
         * with each other for the same cluster.  For example, in copy-on-read
         * it ensures that the CoR read and write operations are atomic and
         * guest writes cannot interleave between them. */
        bdrv_make_request_serialising(req, bdrv_get_cluster_size(bs));
    } else {
        bdrv_wait_serialising_requests(req);
    }

    if (flags & BDRV_REQ_COPY_ON_READ) {
        int64_t pnum;

        /* The flag BDRV_REQ_COPY_ON_READ has reached its addressee */
        flags &= ~BDRV_REQ_COPY_ON_READ;

        ret = bdrv_co_is_allocated(bs, offset, bytes, &pnum);
        if (ret < 0) {
            goto out;
        }

        if (!ret || pnum != bytes) {
            ret = bdrv_co_do_copy_on_readv(child, offset, bytes,
                                           qiov, qiov_offset, flags);
            goto out;
        } else if (flags & BDRV_REQ_PREFETCH) {
            goto out;
        }
    }

    /* Forward the request to the BlockDriver, possibly fragmenting it */
    total_bytes = bdrv_co_getlength(bs);
    if (total_bytes < 0) {
        ret = total_bytes;
        goto out;
    }

    assert(!(flags & ~(bs->supported_read_flags | BDRV_REQ_REGISTERED_BUF)));

    max_bytes = ROUND_UP(MAX(0, total_bytes - offset), align);
    if (bytes <= max_bytes && bytes <= max_transfer) {
        ret = bdrv_driver_preadv(bs, offset, bytes, qiov, qiov_offset, flags);
        goto out;
    }

    while (bytes_remaining) {
        int64_t num;

        if (max_bytes) {
            num = MIN(bytes_remaining, MIN(max_bytes, max_transfer));
            assert(num);

            ret = bdrv_driver_preadv(bs, offset + bytes - bytes_remaining,
                                     num, qiov,
                                     qiov_offset + bytes - bytes_remaining,
                                     flags);
            max_bytes -= num;
        } else {
            num = bytes_remaining;
            ret = qemu_iovec_memset(qiov, qiov_offset + bytes - bytes_remaining,
                                    0, bytes_remaining);
        }
        if (ret < 0) {
            goto out;
        }
        bytes_remaining -= num;
    }

out:
    return ret < 0 ? ret : 0;
}

/*
 * Request padding
 *
 *  |<---- align ----->|                     |<----- align ---->|
 *  |<- head ->|<------------- bytes ------------->|<-- tail -->|
 *  |          |       |                     |     |            |
 * -*----------$-------*-------- ... --------*-----$------------*---
 *  |          |       |                     |     |            |
 *  |          offset  |                     |     end          |
 *  ALIGN_DOWN(offset) ALIGN_UP(offset)      ALIGN_DOWN(end)   ALIGN_UP(end)
 *  [buf   ... )                             [tail_buf          )
 *
 * @buf is an aligned allocation needed to store @head and @tail paddings. @head
 * is placed at the beginning of @buf and @tail at the @end.
 *
 * @tail_buf is a pointer to sub-buffer, corresponding to align-sized chunk
 * around tail, if tail exists.
 *
 * @merge_reads is true for small requests,
 * if @buf_len == @head + bytes + @tail. In this case it is possible that both
 * head and tail exist but @buf_len == align and @tail_buf == @buf.
 *
 * @write is true for write requests, false for read requests.
 *
 * If padding makes the vector too long (exceeding IOV_MAX), then we need to
 * merge existing vector elements into a single one.  @collapse_bounce_buf acts
 * as the bounce buffer in such cases.  @pre_collapse_qiov has the pre-collapse
 * I/O vector elements so for read requests, the data can be copied back after
 * the read is done.
 */
typedef struct BdrvRequestPadding {
    uint8_t *buf;
    size_t buf_len;
    uint8_t *tail_buf;
    size_t head;
    size_t tail;
    bool merge_reads;
    bool write;
    QEMUIOVector local_qiov;

    uint8_t *collapse_bounce_buf;
    size_t collapse_len;
    QEMUIOVector pre_collapse_qiov;
} BdrvRequestPadding;

static bool bdrv_init_padding(BlockDriverState *bs,
                              int64_t offset, int64_t bytes,
                              bool write,
                              BdrvRequestPadding *pad)
{
    int64_t align = bs->bl.request_alignment;
    int64_t sum;

    bdrv_check_request(offset, bytes, &error_abort);
    assert(align <= INT_MAX); /* documented in block/block_int.h */
    assert(align <= SIZE_MAX / 2); /* so we can allocate the buffer */

    memset(pad, 0, sizeof(*pad));

    pad->head = offset & (align - 1);
    pad->tail = ((offset + bytes) & (align - 1));
    if (pad->tail) {
        pad->tail = align - pad->tail;
    }

    if (!pad->head && !pad->tail) {
        return false;
    }

    assert(bytes); /* Nothing good in aligning zero-length requests */

    sum = pad->head + bytes + pad->tail;
    pad->buf_len = (sum > align && pad->head && pad->tail) ? 2 * align : align;
    pad->buf = qemu_blockalign(bs, pad->buf_len);
    pad->merge_reads = sum == pad->buf_len;
    if (pad->tail) {
        pad->tail_buf = pad->buf + pad->buf_len - align;
    }

    pad->write = write;

    return true;
}

static int coroutine_fn GRAPH_RDLOCK
bdrv_padding_rmw_read(BdrvChild *child, BdrvTrackedRequest *req,
                      BdrvRequestPadding *pad, bool zero_middle)
{
    QEMUIOVector local_qiov;
    BlockDriverState *bs = child->bs;
    uint64_t align = bs->bl.request_alignment;
    int ret;

    assert(req->serialising && pad->buf);

    if (pad->head || pad->merge_reads) {
        int64_t bytes = pad->merge_reads ? pad->buf_len : align;

        qemu_iovec_init_buf(&local_qiov, pad->buf, bytes);

        if (pad->head) {
            bdrv_co_debug_event(bs, BLKDBG_PWRITEV_RMW_HEAD);
        }
        if (pad->merge_reads && pad->tail) {
            bdrv_co_debug_event(bs, BLKDBG_PWRITEV_RMW_TAIL);
        }
        ret = bdrv_aligned_preadv(child, req, req->overlap_offset, bytes,
                                  align, &local_qiov, 0, 0);
        if (ret < 0) {
            return ret;
        }
        if (pad->head) {
            bdrv_co_debug_event(bs, BLKDBG_PWRITEV_RMW_AFTER_HEAD);
        }
        if (pad->merge_reads && pad->tail) {
            bdrv_co_debug_event(bs, BLKDBG_PWRITEV_RMW_AFTER_TAIL);
        }

        if (pad->merge_reads) {
            goto zero_mem;
        }
    }

    if (pad->tail) {
        qemu_iovec_init_buf(&local_qiov, pad->tail_buf, align);

        bdrv_co_debug_event(bs, BLKDBG_PWRITEV_RMW_TAIL);
        ret = bdrv_aligned_preadv(
                child, req,
                req->overlap_offset + req->overlap_bytes - align,
                align, align, &local_qiov, 0, 0);
        if (ret < 0) {
            return ret;
        }
        bdrv_co_debug_event(bs, BLKDBG_PWRITEV_RMW_AFTER_TAIL);
    }

zero_mem:
    if (zero_middle) {
        memset(pad->buf + pad->head, 0, pad->buf_len - pad->head - pad->tail);
    }

    return 0;
}

/**
 * Free *pad's associated buffers, and perform any necessary finalization steps.
 */
static void bdrv_padding_finalize(BdrvRequestPadding *pad)
{
    if (pad->collapse_bounce_buf) {
        if (!pad->write) {
            /*
             * If padding required elements in the vector to be collapsed into a
             * bounce buffer, copy the bounce buffer content back
             */
            qemu_iovec_from_buf(&pad->pre_collapse_qiov, 0,
                                pad->collapse_bounce_buf, pad->collapse_len);
        }
        qemu_vfree(pad->collapse_bounce_buf);
        qemu_iovec_destroy(&pad->pre_collapse_qiov);
    }
    if (pad->buf) {
        qemu_vfree(pad->buf);
        qemu_iovec_destroy(&pad->local_qiov);
    }
    memset(pad, 0, sizeof(*pad));
}

/*
 * Create pad->local_qiov by wrapping @iov in the padding head and tail, while
 * ensuring that the resulting vector will not exceed IOV_MAX elements.
 *
 * To ensure this, when necessary, the first two or three elements of @iov are
 * merged into pad->collapse_bounce_buf and replaced by a reference to that
 * bounce buffer in pad->local_qiov.
 *
 * After performing a read request, the data from the bounce buffer must be
 * copied back into pad->pre_collapse_qiov (e.g. by bdrv_padding_finalize()).
 */
static int bdrv_create_padded_qiov(BlockDriverState *bs,
                                   BdrvRequestPadding *pad,
                                   struct iovec *iov, int niov,
                                   size_t iov_offset, size_t bytes)
{
    int padded_niov, surplus_count, collapse_count;

    /* Assert this invariant */
    assert(niov <= IOV_MAX);

    /*
     * Cannot pad if resulting length would exceed SIZE_MAX.  Returning an error
     * to the guest is not ideal, but there is little else we can do.  At least
     * this will practically never happen on 64-bit systems.
     */
    if (SIZE_MAX - pad->head < bytes ||
        SIZE_MAX - pad->head - bytes < pad->tail)
    {
        return -EINVAL;
    }

    /* Length of the resulting IOV if we just concatenated everything */
    padded_niov = !!pad->head + niov + !!pad->tail;

    qemu_iovec_init(&pad->local_qiov, MIN(padded_niov, IOV_MAX));

    if (pad->head) {
        qemu_iovec_add(&pad->local_qiov, pad->buf, pad->head);
    }

    /*
     * If padded_niov > IOV_MAX, we cannot just concatenate everything.
     * Instead, merge the first two or three elements of @iov to reduce the
     * number of vector elements as necessary.
     */
    if (padded_niov > IOV_MAX) {
        /*
         * Only head and tail can have lead to the number of entries exceeding
         * IOV_MAX, so we can exceed it by the head and tail at most.  We need
         * to reduce the number of elements by `surplus_count`, so we merge that
         * many elements plus one into one element.
         */
        surplus_count = padded_niov - IOV_MAX;
        assert(surplus_count <= !!pad->head + !!pad->tail);
        collapse_count = surplus_count + 1;

        /*
         * Move the elements to collapse into `pad->pre_collapse_qiov`, then
         * advance `iov` (and associated variables) by those elements.
         */
        qemu_iovec_init(&pad->pre_collapse_qiov, collapse_count);
        qemu_iovec_concat_iov(&pad->pre_collapse_qiov, iov,
                              collapse_count, iov_offset, SIZE_MAX);
        iov += collapse_count;
        iov_offset = 0;
        niov -= collapse_count;
        bytes -= pad->pre_collapse_qiov.size;

        /*
         * Construct the bounce buffer to match the length of the to-collapse
         * vector elements, and for write requests, initialize it with the data
         * from those elements.  Then add it to `pad->local_qiov`.
         */
        pad->collapse_len = pad->pre_collapse_qiov.size;
        pad->collapse_bounce_buf = qemu_blockalign(bs, pad->collapse_len);
        if (pad->write) {
            qemu_iovec_to_buf(&pad->pre_collapse_qiov, 0,
                              pad->collapse_bounce_buf, pad->collapse_len);
        }
        qemu_iovec_add(&pad->local_qiov,
                       pad->collapse_bounce_buf, pad->collapse_len);
    }

    qemu_iovec_concat_iov(&pad->local_qiov, iov, niov, iov_offset, bytes);

    if (pad->tail) {
        qemu_iovec_add(&pad->local_qiov,
                       pad->buf + pad->buf_len - pad->tail, pad->tail);
    }

    assert(pad->local_qiov.niov == MIN(padded_niov, IOV_MAX));
    return 0;
}

/*
 * bdrv_pad_request
 *
 * Exchange request parameters with padded request if needed. Don't include RMW
 * read of padding, bdrv_padding_rmw_read() should be called separately if
 * needed.
 *
 * @write is true for write requests, false for read requests.
 *
 * Request parameters (@qiov, &qiov_offset, &offset, &bytes) are in-out:
 *  - on function start they represent original request
 *  - on failure or when padding is not needed they are unchanged
 *  - on success when padding is needed they represent padded request
 */
static int bdrv_pad_request(BlockDriverState *bs,
                            QEMUIOVector **qiov, size_t *qiov_offset,
                            int64_t *offset, int64_t *bytes,
                            bool write,
                            BdrvRequestPadding *pad, bool *padded,
                            BdrvRequestFlags *flags)
{
    int ret;
    struct iovec *sliced_iov;
    int sliced_niov;
    size_t sliced_head, sliced_tail;

    /* Should have been checked by the caller already */
    ret = bdrv_check_request32(*offset, *bytes, *qiov, *qiov_offset);
    if (ret < 0) {
        return ret;
    }

    if (!bdrv_init_padding(bs, *offset, *bytes, write, pad)) {
        if (padded) {
            *padded = false;
        }
        return 0;
    }

    /*
     * For prefetching in stream_populate(), no qiov is passed along, because
     * only copy-on-read matters.
     */
    if (*qiov) {
        sliced_iov = qemu_iovec_slice(*qiov, *qiov_offset, *bytes,
                                      &sliced_head, &sliced_tail,
                                      &sliced_niov);

        /* Guaranteed by bdrv_check_request32() */
        assert(*bytes <= SIZE_MAX);
        ret = bdrv_create_padded_qiov(bs, pad, sliced_iov, sliced_niov,
                                      sliced_head, *bytes);
        if (ret < 0) {
            bdrv_padding_finalize(pad);
            return ret;
        }
        *qiov = &pad->local_qiov;
        *qiov_offset = 0;
    }

    *bytes += pad->head + pad->tail;
    *offset -= pad->head;
    if (padded) {
        *padded = true;
    }
    if (flags) {
        /* Can't use optimization hint with bounce buffer */
        *flags &= ~BDRV_REQ_REGISTERED_BUF;
    }

    return 0;
}

int coroutine_fn bdrv_co_preadv(BdrvChild *child,
    int64_t offset, int64_t bytes, QEMUIOVector *qiov,
    BdrvRequestFlags flags)
{
    IO_CODE();
    return bdrv_co_preadv_part(child, offset, bytes, qiov, 0, flags);
}

int coroutine_fn bdrv_co_preadv_part(BdrvChild *child,
    int64_t offset, int64_t bytes,
    QEMUIOVector *qiov, size_t qiov_offset,
    BdrvRequestFlags flags)
{
    BlockDriverState *bs = child->bs;
    BdrvTrackedRequest req;
    BdrvRequestPadding pad;
    int ret;
    IO_CODE();

    trace_bdrv_co_preadv_part(bs, offset, bytes, flags);

    if (!bdrv_co_is_inserted(bs)) {
        return -ENOMEDIUM;
    }

    ret = bdrv_check_request32(offset, bytes, qiov, qiov_offset);
    if (ret < 0) {
        return ret;
    }

    if (bytes == 0 && !QEMU_IS_ALIGNED(offset, bs->bl.request_alignment)) {
        /*
         * Aligning zero request is nonsense. Even if driver has special meaning
         * of zero-length (like qcow2_co_pwritev_compressed_part), we can't pass
         * it to driver due to request_alignment.
         *
         * Still, no reason to return an error if someone do unaligned
         * zero-length read occasionally.
         */
        return 0;
    }

    bdrv_inc_in_flight(bs);

    /* Don't do copy-on-read if we read data before write operation */
    if (qatomic_read(&bs->copy_on_read)) {
        flags |= BDRV_REQ_COPY_ON_READ;
    }

    ret = bdrv_pad_request(bs, &qiov, &qiov_offset, &offset, &bytes, false,
                           &pad, NULL, &flags);
    if (ret < 0) {
        goto fail;
    }

    tracked_request_begin(&req, bs, offset, bytes, BDRV_TRACKED_READ);
    ret = bdrv_aligned_preadv(child, &req, offset, bytes,
                              bs->bl.request_alignment,
                              qiov, qiov_offset, flags);
    tracked_request_end(&req);
    bdrv_padding_finalize(&pad);

fail:
    bdrv_dec_in_flight(bs);

    return ret;
}

static int coroutine_fn GRAPH_RDLOCK
bdrv_co_do_pwrite_zeroes(BlockDriverState *bs, int64_t offset, int64_t bytes,
                         BdrvRequestFlags flags)
{
    BlockDriver *drv = bs->drv;
    QEMUIOVector qiov;
    void *buf = NULL;
    int ret = 0;
    bool need_flush = false;
    int head = 0;
    int tail = 0;

    int64_t max_write_zeroes = MIN_NON_ZERO(bs->bl.max_pwrite_zeroes,
                                            INT64_MAX);
    int alignment = MAX(bs->bl.pwrite_zeroes_alignment,
                        bs->bl.request_alignment);
    int max_transfer = MIN_NON_ZERO(bs->bl.max_transfer, MAX_BOUNCE_BUFFER);

    assert_bdrv_graph_readable();
    bdrv_check_request(offset, bytes, &error_abort);

    if (!drv) {
        return -ENOMEDIUM;
    }

    if ((flags & ~bs->supported_zero_flags) & BDRV_REQ_NO_FALLBACK) {
        return -ENOTSUP;
    }

    /* By definition there is no user buffer so this flag doesn't make sense */
    if (flags & BDRV_REQ_REGISTERED_BUF) {
        return -EINVAL;
    }

    /* Invalidate the cached block-status data range if this write overlaps */
    bdrv_bsc_invalidate_range(bs, offset, bytes);

    assert(alignment % bs->bl.request_alignment == 0);
    head = offset % alignment;
    tail = (offset + bytes) % alignment;
    max_write_zeroes = QEMU_ALIGN_DOWN(max_write_zeroes, alignment);
    assert(max_write_zeroes >= bs->bl.request_alignment);

    while (bytes > 0 && !ret) {
        int64_t num = bytes;

        /* Align request.  Block drivers can expect the "bulk" of the request
         * to be aligned, and that unaligned requests do not cross cluster
         * boundaries.
         */
        if (head) {
            /* Make a small request up to the first aligned sector. For
             * convenience, limit this request to max_transfer even if
             * we don't need to fall back to writes.  */
            num = MIN(MIN(bytes, max_transfer), alignment - head);
            head = (head + num) % alignment;
            assert(num < max_write_zeroes);
        } else if (tail && num > alignment) {
            /* Shorten the request to the last aligned sector.  */
            num -= tail;
        }

        /* limit request size */
        if (num > max_write_zeroes) {
            num = max_write_zeroes;
        }

        ret = -ENOTSUP;
        /* First try the efficient write zeroes operation */
        if (drv->bdrv_co_pwrite_zeroes) {
            ret = drv->bdrv_co_pwrite_zeroes(bs, offset, num,
                                             flags & bs->supported_zero_flags);
            if (ret != -ENOTSUP && (flags & BDRV_REQ_FUA) &&
                !(bs->supported_zero_flags & BDRV_REQ_FUA)) {
                need_flush = true;
            }
        } else {
            assert(!bs->supported_zero_flags);
        }

        if (ret == -ENOTSUP && !(flags & BDRV_REQ_NO_FALLBACK)) {
            /* Fall back to bounce buffer if write zeroes is unsupported */
            BdrvRequestFlags write_flags = flags & ~BDRV_REQ_ZERO_WRITE;

            if ((flags & BDRV_REQ_FUA) &&
                !(bs->supported_write_flags & BDRV_REQ_FUA)) {
                /* No need for bdrv_driver_pwrite() to do a fallback
                 * flush on each chunk; use just one at the end */
                write_flags &= ~BDRV_REQ_FUA;
                need_flush = true;
            }
            num = MIN(num, max_transfer);
            if (buf == NULL) {
                buf = qemu_try_blockalign0(bs, num);
                if (buf == NULL) {
                    ret = -ENOMEM;
                    goto fail;
                }
            }
            qemu_iovec_init_buf(&qiov, buf, num);

            ret = bdrv_driver_pwritev(bs, offset, num, &qiov, 0, write_flags);

            /* Keep bounce buffer around if it is big enough for all
             * all future requests.
             */
            if (num < max_transfer) {
                qemu_vfree(buf);
                buf = NULL;
            }
        }

        offset += num;
        bytes -= num;
    }

fail:
    if (ret == 0 && need_flush) {
        ret = bdrv_co_flush(bs);
    }
    qemu_vfree(buf);
    return ret;
}

static inline int coroutine_fn GRAPH_RDLOCK
bdrv_co_write_req_prepare(BdrvChild *child, int64_t offset, int64_t bytes,
                          BdrvTrackedRequest *req, int flags)
{
    BlockDriverState *bs = child->bs;

    bdrv_check_request(offset, bytes, &error_abort);

    if (bdrv_is_read_only(bs)) {
        return -EPERM;
    }

    assert(!(bs->open_flags & BDRV_O_INACTIVE));
    assert((bs->open_flags & BDRV_O_NO_IO) == 0);
    assert(!(flags & ~BDRV_REQ_MASK));
    assert(!((flags & BDRV_REQ_NO_WAIT) && !(flags & BDRV_REQ_SERIALISING)));

    if (flags & BDRV_REQ_SERIALISING) {
        QEMU_LOCK_GUARD(&bs->reqs_lock);

        tracked_request_set_serialising(req, bdrv_get_cluster_size(bs));

        if ((flags & BDRV_REQ_NO_WAIT) && bdrv_find_conflicting_request(req)) {
            return -EBUSY;
        }

        bdrv_wait_serialising_requests_locked(req);
    } else {
        bdrv_wait_serialising_requests(req);
    }

    assert(req->overlap_offset <= offset);
    assert(offset + bytes <= req->overlap_offset + req->overlap_bytes);
    assert(offset + bytes <= bs->total_sectors * BDRV_SECTOR_SIZE ||
           child->perm & BLK_PERM_RESIZE);

    switch (req->type) {
    case BDRV_TRACKED_WRITE:
    case BDRV_TRACKED_DISCARD:
        if (flags & BDRV_REQ_WRITE_UNCHANGED) {
            assert(child->perm & (BLK_PERM_WRITE_UNCHANGED | BLK_PERM_WRITE));
        } else {
            assert(child->perm & BLK_PERM_WRITE);
        }
        bdrv_write_threshold_check_write(bs, offset, bytes);
        return 0;
    case BDRV_TRACKED_TRUNCATE:
        assert(child->perm & BLK_PERM_RESIZE);
        return 0;
    default:
        abort();
    }
}

static inline void coroutine_fn GRAPH_RDLOCK
bdrv_co_write_req_finish(BdrvChild *child, int64_t offset, int64_t bytes,
                         BdrvTrackedRequest *req, int ret)
{
    int64_t end_sector = DIV_ROUND_UP(offset + bytes, BDRV_SECTOR_SIZE);
    BlockDriverState *bs = child->bs;

    bdrv_check_request(offset, bytes, &error_abort);

    qatomic_inc(&bs->write_gen);

    /*
     * Discard cannot extend the image, but in error handling cases, such as
     * when reverting a qcow2 cluster allocation, the discarded range can pass
     * the end of image file, so we cannot assert about BDRV_TRACKED_DISCARD
     * here. Instead, just skip it, since semantically a discard request
     * beyond EOF cannot expand the image anyway.
     */
    if (ret == 0 &&
        (req->type == BDRV_TRACKED_TRUNCATE ||
         end_sector > bs->total_sectors) &&
        req->type != BDRV_TRACKED_DISCARD) {
        bs->total_sectors = end_sector;
        bdrv_parent_cb_resize(bs);
        bdrv_dirty_bitmap_truncate(bs, end_sector << BDRV_SECTOR_BITS);
    }
    if (req->bytes) {
        switch (req->type) {
        case BDRV_TRACKED_WRITE:
            stat64_max(&bs->wr_highest_offset, offset + bytes);
            /* fall through, to set dirty bits */
        case BDRV_TRACKED_DISCARD:
            bdrv_set_dirty(bs, offset, bytes);
            break;
        default:
            break;
        }
    }
}

/*
 * Forwards an already correctly aligned write request to the BlockDriver,
 * after possibly fragmenting it.
 */
static int coroutine_fn GRAPH_RDLOCK
bdrv_aligned_pwritev(BdrvChild *child, BdrvTrackedRequest *req,
                     int64_t offset, int64_t bytes, int64_t align,
                     QEMUIOVector *qiov, size_t qiov_offset,
                     BdrvRequestFlags flags)
{
    BlockDriverState *bs = child->bs;
    BlockDriver *drv = bs->drv;
    int ret;

    int64_t bytes_remaining = bytes;
    int max_transfer;

    bdrv_check_qiov_request(offset, bytes, qiov, qiov_offset, &error_abort);

    if (!drv) {
        return -ENOMEDIUM;
    }

    if (bdrv_has_readonly_bitmaps(bs)) {
        return -EPERM;
    }

    assert(is_power_of_2(align));
    assert((offset & (align - 1)) == 0);
    assert((bytes & (align - 1)) == 0);
    max_transfer = QEMU_ALIGN_DOWN(MIN_NON_ZERO(bs->bl.max_transfer, INT_MAX),
                                   align);

    ret = bdrv_co_write_req_prepare(child, offset, bytes, req, flags);

    if (!ret && bs->detect_zeroes != BLOCKDEV_DETECT_ZEROES_OPTIONS_OFF &&
        !(flags & BDRV_REQ_ZERO_WRITE) && drv->bdrv_co_pwrite_zeroes &&
        qemu_iovec_is_zero(qiov, qiov_offset, bytes)) {
        flags |= BDRV_REQ_ZERO_WRITE;
        if (bs->detect_zeroes == BLOCKDEV_DETECT_ZEROES_OPTIONS_UNMAP) {
            flags |= BDRV_REQ_MAY_UNMAP;
        }

        /* Can't use optimization hint with bufferless zero write */
        flags &= ~BDRV_REQ_REGISTERED_BUF;
    }

    if (ret < 0) {
        /* Do nothing, write notifier decided to fail this request */
    } else if (flags & BDRV_REQ_ZERO_WRITE) {
        bdrv_co_debug_event(bs, BLKDBG_PWRITEV_ZERO);
        ret = bdrv_co_do_pwrite_zeroes(bs, offset, bytes, flags);
    } else if (flags & BDRV_REQ_WRITE_COMPRESSED) {
        ret = bdrv_driver_pwritev_compressed(bs, offset, bytes,
                                             qiov, qiov_offset);
    } else if (bytes <= max_transfer) {
        bdrv_co_debug_event(bs, BLKDBG_PWRITEV);
        ret = bdrv_driver_pwritev(bs, offset, bytes, qiov, qiov_offset, flags);
    } else {
        bdrv_co_debug_event(bs, BLKDBG_PWRITEV);
        while (bytes_remaining) {
            int num = MIN(bytes_remaining, max_transfer);
            int local_flags = flags;

            assert(num);
            if (num < bytes_remaining && (flags & BDRV_REQ_FUA) &&
                !(bs->supported_write_flags & BDRV_REQ_FUA)) {
                /* If FUA is going to be emulated by flush, we only
                 * need to flush on the last iteration */
                local_flags &= ~BDRV_REQ_FUA;
            }

            ret = bdrv_driver_pwritev(bs, offset + bytes - bytes_remaining,
                                      num, qiov,
                                      qiov_offset + bytes - bytes_remaining,
                                      local_flags);
            if (ret < 0) {
                break;
            }
            bytes_remaining -= num;
        }
    }
    bdrv_co_debug_event(bs, BLKDBG_PWRITEV_DONE);

    if (ret >= 0) {
        ret = 0;
    }
    bdrv_co_write_req_finish(child, offset, bytes, req, ret);

    return ret;
}

static int coroutine_fn GRAPH_RDLOCK
bdrv_co_do_zero_pwritev(BdrvChild *child, int64_t offset, int64_t bytes,
                        BdrvRequestFlags flags, BdrvTrackedRequest *req)
{
    BlockDriverState *bs = child->bs;
    QEMUIOVector local_qiov;
    uint64_t align = bs->bl.request_alignment;
    int ret = 0;
    bool padding;
    BdrvRequestPadding pad;

    /* This flag doesn't make sense for padding or zero writes */
    flags &= ~BDRV_REQ_REGISTERED_BUF;

    padding = bdrv_init_padding(bs, offset, bytes, true, &pad);
    if (padding) {
        assert(!(flags & BDRV_REQ_NO_WAIT));
        bdrv_make_request_serialising(req, align);

        bdrv_padding_rmw_read(child, req, &pad, true);

        if (pad.head || pad.merge_reads) {
            int64_t aligned_offset = offset & ~(align - 1);
            int64_t write_bytes = pad.merge_reads ? pad.buf_len : align;

            qemu_iovec_init_buf(&local_qiov, pad.buf, write_bytes);
            ret = bdrv_aligned_pwritev(child, req, aligned_offset, write_bytes,
                                       align, &local_qiov, 0,
                                       flags & ~BDRV_REQ_ZERO_WRITE);
            if (ret < 0 || pad.merge_reads) {
                /* Error or all work is done */
                goto out;
            }
            offset += write_bytes - pad.head;
            bytes -= write_bytes - pad.head;
        }
    }

    assert(!bytes || (offset & (align - 1)) == 0);
    if (bytes >= align) {
        /* Write the aligned part in the middle. */
        int64_t aligned_bytes = bytes & ~(align - 1);
        ret = bdrv_aligned_pwritev(child, req, offset, aligned_bytes, align,
                                   NULL, 0, flags);
        if (ret < 0) {
            goto out;
        }
        bytes -= aligned_bytes;
        offset += aligned_bytes;
    }

    assert(!bytes || (offset & (align - 1)) == 0);
    if (bytes) {
        assert(align == pad.tail + bytes);

        qemu_iovec_init_buf(&local_qiov, pad.tail_buf, align);
        ret = bdrv_aligned_pwritev(child, req, offset, align, align,
                                   &local_qiov, 0,
                                   flags & ~BDRV_REQ_ZERO_WRITE);
    }

out:
    bdrv_padding_finalize(&pad);

    return ret;
}

/*
 * Handle a write request in coroutine context
 */
int coroutine_fn bdrv_co_pwritev(BdrvChild *child,
    int64_t offset, int64_t bytes, QEMUIOVector *qiov,
    BdrvRequestFlags flags)
{
    IO_CODE();
    return bdrv_co_pwritev_part(child, offset, bytes, qiov, 0, flags);
}

int coroutine_fn bdrv_co_pwritev_part(BdrvChild *child,
    int64_t offset, int64_t bytes, QEMUIOVector *qiov, size_t qiov_offset,
    BdrvRequestFlags flags)
{
    BlockDriverState *bs = child->bs;
    BdrvTrackedRequest req;
    uint64_t align = bs->bl.request_alignment;
    BdrvRequestPadding pad;
    int ret;
    bool padded = false;
    IO_CODE();

    trace_bdrv_co_pwritev_part(child->bs, offset, bytes, flags);

    if (!bdrv_co_is_inserted(bs)) {
        return -ENOMEDIUM;
    }

    if (flags & BDRV_REQ_ZERO_WRITE) {
        ret = bdrv_check_qiov_request(offset, bytes, qiov, qiov_offset, NULL);
    } else {
        ret = bdrv_check_request32(offset, bytes, qiov, qiov_offset);
    }
    if (ret < 0) {
        return ret;
    }

    /* If the request is misaligned then we can't make it efficient */
    if ((flags & BDRV_REQ_NO_FALLBACK) &&
        !QEMU_IS_ALIGNED(offset | bytes, align))
    {
        return -ENOTSUP;
    }

    if (bytes == 0 && !QEMU_IS_ALIGNED(offset, bs->bl.request_alignment)) {
        /*
         * Aligning zero request is nonsense. Even if driver has special meaning
         * of zero-length (like qcow2_co_pwritev_compressed_part), we can't pass
         * it to driver due to request_alignment.
         *
         * Still, no reason to return an error if someone do unaligned
         * zero-length write occasionally.
         */
        return 0;
    }

    if (!(flags & BDRV_REQ_ZERO_WRITE)) {
        /*
         * Pad request for following read-modify-write cycle.
         * bdrv_co_do_zero_pwritev() does aligning by itself, so, we do
         * alignment only if there is no ZERO flag.
         */
        ret = bdrv_pad_request(bs, &qiov, &qiov_offset, &offset, &bytes, true,
                               &pad, &padded, &flags);
        if (ret < 0) {
            return ret;
        }
    }

    bdrv_inc_in_flight(bs);
    tracked_request_begin(&req, bs, offset, bytes, BDRV_TRACKED_WRITE);

    if (flags & BDRV_REQ_ZERO_WRITE) {
        assert(!padded);
        ret = bdrv_co_do_zero_pwritev(child, offset, bytes, flags, &req);
        goto out;
    }

    if (padded) {
        /*
         * Request was unaligned to request_alignment and therefore
         * padded.  We are going to do read-modify-write, and must
         * serialize the request to prevent interactions of the
         * widened region with other transactions.
         */
        assert(!(flags & BDRV_REQ_NO_WAIT));
        bdrv_make_request_serialising(&req, align);
        bdrv_padding_rmw_read(child, &req, &pad, false);
    }

    ret = bdrv_aligned_pwritev(child, &req, offset, bytes, align,
                               qiov, qiov_offset, flags);

    bdrv_padding_finalize(&pad);

out:
    tracked_request_end(&req);
    bdrv_dec_in_flight(bs);

    return ret;
}

int coroutine_fn bdrv_co_pwrite_zeroes(BdrvChild *child, int64_t offset,
                                       int64_t bytes, BdrvRequestFlags flags)
{
    IO_CODE();
    trace_bdrv_co_pwrite_zeroes(child->bs, offset, bytes, flags);
    assert_bdrv_graph_readable();

    if (!(child->bs->open_flags & BDRV_O_UNMAP)) {
        flags &= ~BDRV_REQ_MAY_UNMAP;
    }

    return bdrv_co_pwritev(child, offset, bytes, NULL,
                           BDRV_REQ_ZERO_WRITE | flags);
}

/*
 * Flush ALL BDSes regardless of if they are reachable via a BlkBackend or not.
 */
int bdrv_flush_all(void)
{
    BdrvNextIterator it;
    BlockDriverState *bs = NULL;
    int result = 0;

    GLOBAL_STATE_CODE();
    GRAPH_RDLOCK_GUARD_MAINLOOP();

    /*
     * bdrv queue is managed by record/replay,
     * creating new flush request for stopping
     * the VM may break the determinism
     */
    if (replay_events_enabled()) {
        return result;
    }

    for (bs = bdrv_first(&it); bs; bs = bdrv_next(&it)) {
        int ret = bdrv_flush(bs);
        if (ret < 0 && !result) {
            result = ret;
        }
    }

    return result;
}

/*
 * Returns the allocation status of the specified sectors.
 * Drivers not implementing the functionality are assumed to not support
 * backing files, hence all their sectors are reported as allocated.
 *
 * If 'want_zero' is true, the caller is querying for mapping
 * purposes, with a focus on valid BDRV_BLOCK_OFFSET_VALID, _DATA, and
 * _ZERO where possible; otherwise, the result favors larger 'pnum',
 * with a focus on accurate BDRV_BLOCK_ALLOCATED.
 *
 * If 'offset' is beyond the end of the disk image the return value is
 * BDRV_BLOCK_EOF and 'pnum' is set to 0.
 *
 * 'bytes' is the max value 'pnum' should be set to.  If bytes goes
 * beyond the end of the disk image it will be clamped; if 'pnum' is set to
 * the end of the image, then the returned value will include BDRV_BLOCK_EOF.
 *
 * 'pnum' is set to the number of bytes (including and immediately
 * following the specified offset) that are easily known to be in the
 * same allocated/unallocated state.  Note that a second call starting
 * at the original offset plus returned pnum may have the same status.
 * The returned value is non-zero on success except at end-of-file.
 *
 * Returns negative errno on failure.  Otherwise, if the
 * BDRV_BLOCK_OFFSET_VALID bit is set, 'map' and 'file' (if non-NULL) are
 * set to the host mapping and BDS corresponding to the guest offset.
 */
static int coroutine_fn GRAPH_RDLOCK
bdrv_co_do_block_status(BlockDriverState *bs, bool want_zero,
                        int64_t offset, int64_t bytes,
                        int64_t *pnum, int64_t *map, BlockDriverState **file)
{
    int64_t total_size;
    int64_t n; /* bytes */
    int ret;
    int64_t local_map = 0;
    BlockDriverState *local_file = NULL;
    int64_t aligned_offset, aligned_bytes;
    uint32_t align;
    bool has_filtered_child;

    assert(pnum);
    assert_bdrv_graph_readable();
    *pnum = 0;
    total_size = bdrv_co_getlength(bs);
    if (total_size < 0) {
        ret = total_size;
        goto early_out;
    }

    if (offset >= total_size) {
        ret = BDRV_BLOCK_EOF;
        goto early_out;
    }
    if (!bytes) {
        ret = 0;
        goto early_out;
    }

    n = total_size - offset;
    if (n < bytes) {
        bytes = n;
    }

    /* Must be non-NULL or bdrv_co_getlength() would have failed */
    assert(bs->drv);
    has_filtered_child = bdrv_filter_child(bs);
    if (!bs->drv->bdrv_co_block_status && !has_filtered_child) {
        *pnum = bytes;
        ret = BDRV_BLOCK_DATA | BDRV_BLOCK_ALLOCATED;
        if (offset + bytes == total_size) {
            ret |= BDRV_BLOCK_EOF;
        }
        if (bs->drv->protocol_name) {
            ret |= BDRV_BLOCK_OFFSET_VALID;
            local_map = offset;
            local_file = bs;
        }
        goto early_out;
    }

    bdrv_inc_in_flight(bs);

    /* Round out to request_alignment boundaries */
    align = bs->bl.request_alignment;
    aligned_offset = QEMU_ALIGN_DOWN(offset, align);
    aligned_bytes = ROUND_UP(offset + bytes, align) - aligned_offset;

    if (bs->drv->bdrv_co_block_status) {
        /*
         * Use the block-status cache only for protocol nodes: Format
         * drivers are generally quick to inquire the status, but protocol
         * drivers often need to get information from outside of qemu, so
         * we do not have control over the actual implementation.  There
         * have been cases where inquiring the status took an unreasonably
         * long time, and we can do nothing in qemu to fix it.
         * This is especially problematic for images with large data areas,
         * because finding the few holes in them and giving them special
         * treatment does not gain much performance.  Therefore, we try to
         * cache the last-identified data region.
         *
         * Second, limiting ourselves to protocol nodes allows us to assume
         * the block status for data regions to be DATA | OFFSET_VALID, and
         * that the host offset is the same as the guest offset.
         *
         * Note that it is possible that external writers zero parts of
         * the cached regions without the cache being invalidated, and so
         * we may report zeroes as data.  This is not catastrophic,
         * however, because reporting zeroes as data is fine.
         */
        if (QLIST_EMPTY(&bs->children) &&
            bdrv_bsc_is_data(bs, aligned_offset, pnum))
        {
            ret = BDRV_BLOCK_DATA | BDRV_BLOCK_OFFSET_VALID;
            local_file = bs;
            local_map = aligned_offset;
        } else {
            ret = bs->drv->bdrv_co_block_status(bs, want_zero, aligned_offset,
                                                aligned_bytes, pnum, &local_map,
                                                &local_file);

            /*
             * Note that checking QLIST_EMPTY(&bs->children) is also done when
             * the cache is queried above.  Technically, we do not need to check
             * it here; the worst that can happen is that we fill the cache for
             * non-protocol nodes, and then it is never used.  However, filling
             * the cache requires an RCU update, so double check here to avoid
             * such an update if possible.
             *
             * Check want_zero, because we only want to update the cache when we
             * have accurate information about what is zero and what is data.
             */
            if (want_zero &&
                ret == (BDRV_BLOCK_DATA | BDRV_BLOCK_OFFSET_VALID) &&
                QLIST_EMPTY(&bs->children))
            {
                /*
                 * When a protocol driver reports BLOCK_OFFSET_VALID, the
                 * returned local_map value must be the same as the offset we
                 * have passed (aligned_offset), and local_bs must be the node
                 * itself.
                 * Assert this, because we follow this rule when reading from
                 * the cache (see the `local_file = bs` and
                 * `local_map = aligned_offset` assignments above), and the
                 * result the cache delivers must be the same as the driver
                 * would deliver.
                 */
                assert(local_file == bs);
                assert(local_map == aligned_offset);
                bdrv_bsc_fill(bs, aligned_offset, *pnum);
            }
        }
    } else {
        /* Default code for filters */

        local_file = bdrv_filter_bs(bs);
        assert(local_file);

        *pnum = aligned_bytes;
        local_map = aligned_offset;
        ret = BDRV_BLOCK_RAW | BDRV_BLOCK_OFFSET_VALID;
    }
    if (ret < 0) {
        *pnum = 0;
        goto out;
    }

    /*
     * The driver's result must be a non-zero multiple of request_alignment.
     * Clamp pnum and adjust map to original request.
     */
    assert(*pnum && QEMU_IS_ALIGNED(*pnum, align) &&
           align > offset - aligned_offset);
    if (ret & BDRV_BLOCK_RECURSE) {
        assert(ret & BDRV_BLOCK_DATA);
        assert(ret & BDRV_BLOCK_OFFSET_VALID);
        assert(!(ret & BDRV_BLOCK_ZERO));
    }

    *pnum -= offset - aligned_offset;
    if (*pnum > bytes) {
        *pnum = bytes;
    }
    if (ret & BDRV_BLOCK_OFFSET_VALID) {
        local_map += offset - aligned_offset;
    }

    if (ret & BDRV_BLOCK_RAW) {
        assert(ret & BDRV_BLOCK_OFFSET_VALID && local_file);
        ret = bdrv_co_do_block_status(local_file, want_zero, local_map,
                                      *pnum, pnum, &local_map, &local_file);
        goto out;
    }

    if (ret & (BDRV_BLOCK_DATA | BDRV_BLOCK_ZERO)) {
        ret |= BDRV_BLOCK_ALLOCATED;
    } else if (bs->drv->supports_backing) {
        BlockDriverState *cow_bs = bdrv_cow_bs(bs);

        if (!cow_bs) {
            ret |= BDRV_BLOCK_ZERO;
        } else if (want_zero) {
            int64_t size2 = bdrv_co_getlength(cow_bs);

            if (size2 >= 0 && offset >= size2) {
                ret |= BDRV_BLOCK_ZERO;
            }
        }
    }

    if (want_zero && ret & BDRV_BLOCK_RECURSE &&
        local_file && local_file != bs &&
        (ret & BDRV_BLOCK_DATA) && !(ret & BDRV_BLOCK_ZERO) &&
        (ret & BDRV_BLOCK_OFFSET_VALID)) {
        int64_t file_pnum;
        int ret2;

        ret2 = bdrv_co_do_block_status(local_file, want_zero, local_map,
                                       *pnum, &file_pnum, NULL, NULL);
        if (ret2 >= 0) {
            /* Ignore errors.  This is just providing extra information, it
             * is useful but not necessary.
             */
            if (ret2 & BDRV_BLOCK_EOF &&
                (!file_pnum || ret2 & BDRV_BLOCK_ZERO)) {
                /*
                 * It is valid for the format block driver to read
                 * beyond the end of the underlying file's current
                 * size; such areas read as zero.
                 */
                ret |= BDRV_BLOCK_ZERO;
            } else {
                /* Limit request to the range reported by the protocol driver */
                *pnum = file_pnum;
                ret |= (ret2 & BDRV_BLOCK_ZERO);
            }
        }

        /*
         * Now that the recursive search was done, clear the flag. Otherwise,
         * with more complicated block graphs like snapshot-access ->
         * copy-before-write -> qcow2, where the return value will be propagated
         * further up to a parent bdrv_co_do_block_status() call, both the
         * BDRV_BLOCK_RECURSE and BDRV_BLOCK_ZERO flags would be set, which is
         * not allowed.
         */
        ret &= ~BDRV_BLOCK_RECURSE;
    }

out:
    bdrv_dec_in_flight(bs);
    if (ret >= 0 && offset + *pnum == total_size) {
        ret |= BDRV_BLOCK_EOF;
    }
early_out:
    if (file) {
        *file = local_file;
    }
    if (map) {
        *map = local_map;
    }
    return ret;
}

int coroutine_fn
bdrv_co_common_block_status_above(BlockDriverState *bs,
                                  BlockDriverState *base,
                                  bool include_base,
                                  bool want_zero,
                                  int64_t offset,
                                  int64_t bytes,
                                  int64_t *pnum,
                                  int64_t *map,
                                  BlockDriverState **file,
                                  int *depth)
{
    int ret;
    BlockDriverState *p;
    int64_t eof = 0;
    int dummy;
    IO_CODE();

    assert(!include_base || base); /* Can't include NULL base */
    assert_bdrv_graph_readable();

    if (!depth) {
        depth = &dummy;
    }
    *depth = 0;

    if (!include_base && bs == base) {
        *pnum = bytes;
        return 0;
    }

    ret = bdrv_co_do_block_status(bs, want_zero, offset, bytes, pnum,
                                  map, file);
    ++*depth;
    if (ret < 0 || *pnum == 0 || ret & BDRV_BLOCK_ALLOCATED || bs == base) {
        return ret;
    }

    if (ret & BDRV_BLOCK_EOF) {
        eof = offset + *pnum;
    }

    assert(*pnum <= bytes);
    bytes = *pnum;

    for (p = bdrv_filter_or_cow_bs(bs); include_base || p != base;
         p = bdrv_filter_or_cow_bs(p))
    {
        ret = bdrv_co_do_block_status(p, want_zero, offset, bytes, pnum,
                                      map, file);
        ++*depth;
        if (ret < 0) {
            return ret;
        }
        if (*pnum == 0) {
            /*
             * The top layer deferred to this layer, and because this layer is
             * short, any zeroes that we synthesize beyond EOF behave as if they
             * were allocated at this layer.
             *
             * We don't include BDRV_BLOCK_EOF into ret, as upper layer may be
             * larger. We'll add BDRV_BLOCK_EOF if needed at function end, see
             * below.
             */
            assert(ret & BDRV_BLOCK_EOF);
            *pnum = bytes;
            if (file) {
                *file = p;
            }
            ret = BDRV_BLOCK_ZERO | BDRV_BLOCK_ALLOCATED;
            break;
        }
        if (ret & BDRV_BLOCK_ALLOCATED) {
            /*
             * We've found the node and the status, we must break.
             *
             * Drop BDRV_BLOCK_EOF, as it's not for upper layer, which may be
             * larger. We'll add BDRV_BLOCK_EOF if needed at function end, see
             * below.
             */
            ret &= ~BDRV_BLOCK_EOF;
            break;
        }

        if (p == base) {
            assert(include_base);
            break;
        }

        /*
         * OK, [offset, offset + *pnum) region is unallocated on this layer,
         * let's continue the diving.
         */
        assert(*pnum <= bytes);
        bytes = *pnum;
    }

    if (offset + *pnum == eof) {
        ret |= BDRV_BLOCK_EOF;
    }

    return ret;
}

int coroutine_fn bdrv_co_block_status_above(BlockDriverState *bs,
                                            BlockDriverState *base,
                                            int64_t offset, int64_t bytes,
                                            int64_t *pnum, int64_t *map,
                                            BlockDriverState **file)
{
    IO_CODE();
    return bdrv_co_common_block_status_above(bs, base, false, true, offset,
                                             bytes, pnum, map, file, NULL);
}

int coroutine_fn bdrv_co_block_status(BlockDriverState *bs, int64_t offset,
                                      int64_t bytes, int64_t *pnum,
                                      int64_t *map, BlockDriverState **file)
{
    IO_CODE();
    return bdrv_co_block_status_above(bs, bdrv_filter_or_cow_bs(bs),
                                      offset, bytes, pnum, map, file);
}

/*
 * Check @bs (and its backing chain) to see if the range defined
 * by @offset and @bytes is known to read as zeroes.
 * Return 1 if that is the case, 0 otherwise and -errno on error.
 * This test is meant to be fast rather than accurate so returning 0
 * does not guarantee non-zero data.
 */
int coroutine_fn bdrv_co_is_zero_fast(BlockDriverState *bs, int64_t offset,
                                      int64_t bytes)
{
    int ret;
    int64_t pnum = bytes;
    IO_CODE();

    if (!bytes) {
        return 1;
    }

    ret = bdrv_co_common_block_status_above(bs, NULL, false, false, offset,
                                            bytes, &pnum, NULL, NULL, NULL);

    if (ret < 0) {
        return ret;
    }

    return (pnum == bytes) && (ret & BDRV_BLOCK_ZERO);
}

int coroutine_fn bdrv_co_is_allocated(BlockDriverState *bs, int64_t offset,
                                      int64_t bytes, int64_t *pnum)
{
    int ret;
    int64_t dummy;
    IO_CODE();

    ret = bdrv_co_common_block_status_above(bs, bs, true, false, offset,
                                            bytes, pnum ? pnum : &dummy, NULL,
                                            NULL, NULL);
    if (ret < 0) {
        return ret;
    }
    return !!(ret & BDRV_BLOCK_ALLOCATED);
}

/*
 * Given an image chain: ... -> [BASE] -> [INTER1] -> [INTER2] -> [TOP]
 *
 * Return a positive depth if (a prefix of) the given range is allocated
 * in any image between BASE and TOP (BASE is only included if include_base
 * is set).  Depth 1 is TOP, 2 is the first backing layer, and so forth.
 * BASE can be NULL to check if the given offset is allocated in any
 * image of the chain.  Return 0 otherwise, or negative errno on
 * failure.
 *
 * 'pnum' is set to the number of bytes (including and immediately
 * following the specified offset) that are known to be in the same
 * allocated/unallocated state.  Note that a subsequent call starting
 * at 'offset + *pnum' may return the same allocation status (in other
 * words, the result is not necessarily the maximum possible range);
 * but 'pnum' will only be 0 when end of file is reached.
 */
int coroutine_fn bdrv_co_is_allocated_above(BlockDriverState *bs,
                                            BlockDriverState *base,
                                            bool include_base, int64_t offset,
                                            int64_t bytes, int64_t *pnum)
{
    int depth;
    int ret;
    IO_CODE();

    ret = bdrv_co_common_block_status_above(bs, base, include_base, false,
                                            offset, bytes, pnum, NULL, NULL,
                                            &depth);
    if (ret < 0) {
        return ret;
    }

    if (ret & BDRV_BLOCK_ALLOCATED) {
        return depth;
    }
    return 0;
}

int coroutine_fn
bdrv_co_readv_vmstate(BlockDriverState *bs, QEMUIOVector *qiov, int64_t pos)
{
    BlockDriver *drv = bs->drv;
    BlockDriverState *child_bs = bdrv_primary_bs(bs);
    int ret;
    IO_CODE();
    assert_bdrv_graph_readable();

    ret = bdrv_check_qiov_request(pos, qiov->size, qiov, 0, NULL);
    if (ret < 0) {
        return ret;
    }

    if (!drv) {
        return -ENOMEDIUM;
    }

    bdrv_inc_in_flight(bs);

    if (drv->bdrv_co_load_vmstate) {
        ret = drv->bdrv_co_load_vmstate(bs, qiov, pos);
    } else if (child_bs) {
        ret = bdrv_co_readv_vmstate(child_bs, qiov, pos);
    } else {
        ret = -ENOTSUP;
    }

    bdrv_dec_in_flight(bs);

    return ret;
}

int coroutine_fn
bdrv_co_writev_vmstate(BlockDriverState *bs, QEMUIOVector *qiov, int64_t pos)
{
    BlockDriver *drv = bs->drv;
    BlockDriverState *child_bs = bdrv_primary_bs(bs);
    int ret;
    IO_CODE();
    assert_bdrv_graph_readable();

    ret = bdrv_check_qiov_request(pos, qiov->size, qiov, 0, NULL);
    if (ret < 0) {
        return ret;
    }

    if (!drv) {
        return -ENOMEDIUM;
    }

    bdrv_inc_in_flight(bs);

    if (drv->bdrv_co_save_vmstate) {
        ret = drv->bdrv_co_save_vmstate(bs, qiov, pos);
    } else if (child_bs) {
        ret = bdrv_co_writev_vmstate(child_bs, qiov, pos);
    } else {
        ret = -ENOTSUP;
    }

    bdrv_dec_in_flight(bs);

    return ret;
}

int bdrv_save_vmstate(BlockDriverState *bs, const uint8_t *buf,
                      int64_t pos, int size)
{
    QEMUIOVector qiov = QEMU_IOVEC_INIT_BUF(qiov, buf, size);
    int ret = bdrv_writev_vmstate(bs, &qiov, pos);
    IO_CODE();

    return ret < 0 ? ret : size;
}

int bdrv_load_vmstate(BlockDriverState *bs, uint8_t *buf,
                      int64_t pos, int size)
{
    QEMUIOVector qiov = QEMU_IOVEC_INIT_BUF(qiov, buf, size);
    int ret = bdrv_readv_vmstate(bs, &qiov, pos);
    IO_CODE();

    return ret < 0 ? ret : size;
}

/**************************************************************/
/* async I/Os */

/**
 * Synchronously cancels an acb. Must be called with the BQL held and the acb
 * must be processed with the BQL held too (IOThreads are not allowed).
 *
 * Use bdrv_aio_cancel_async() instead when possible.
 */
void bdrv_aio_cancel(BlockAIOCB *acb)
{
    GLOBAL_STATE_CODE();
    qemu_aio_ref(acb);
    bdrv_aio_cancel_async(acb);
    AIO_WAIT_WHILE_UNLOCKED(NULL, acb->refcnt > 1);
    qemu_aio_unref(acb);
}

/* Async version of aio cancel. The caller is not blocked if the acb implements
 * cancel_async, otherwise we do nothing and let the request normally complete.
 * In either case the completion callback must be called. */
void bdrv_aio_cancel_async(BlockAIOCB *acb)
{
    IO_CODE();
    if (acb->aiocb_info->cancel_async) {
        acb->aiocb_info->cancel_async(acb);
    }
}

/**************************************************************/
/* Coroutine block device emulation */

int coroutine_fn bdrv_co_flush(BlockDriverState *bs)
{
    BdrvChild *primary_child = bdrv_primary_child(bs);
    BdrvChild *child;
    int current_gen;
    int ret = 0;
    IO_CODE();

    assert_bdrv_graph_readable();
    bdrv_inc_in_flight(bs);

    if (!bdrv_co_is_inserted(bs) || bdrv_is_read_only(bs) ||
        bdrv_is_sg(bs)) {
        goto early_exit;
    }

    qemu_mutex_lock(&bs->reqs_lock);
    current_gen = qatomic_read(&bs->write_gen);

    /* Wait until any previous flushes are completed */
    while (bs->active_flush_req) {
        qemu_co_queue_wait(&bs->flush_queue, &bs->reqs_lock);
    }

    /* Flushes reach this point in nondecreasing current_gen order.  */
    bs->active_flush_req = true;
    qemu_mutex_unlock(&bs->reqs_lock);

    /* Write back all layers by calling one driver function */
    if (bs->drv->bdrv_co_flush) {
        ret = bs->drv->bdrv_co_flush(bs);
        goto out;
    }

    /* Write back cached data to the OS even with cache=unsafe */
    BLKDBG_CO_EVENT(primary_child, BLKDBG_FLUSH_TO_OS);
    if (bs->drv->bdrv_co_flush_to_os) {
        ret = bs->drv->bdrv_co_flush_to_os(bs);
        if (ret < 0) {
            goto out;
        }
    }

    /* But don't actually force it to the disk with cache=unsafe */
    if (bs->open_flags & BDRV_O_NO_FLUSH) {
        goto flush_children;
    }

    /* Check if we really need to flush anything */
    if (bs->flushed_gen == current_gen) {
        goto flush_children;
    }

    BLKDBG_CO_EVENT(primary_child, BLKDBG_FLUSH_TO_DISK);
    if (!bs->drv) {
        /* bs->drv->bdrv_co_flush() might have ejected the BDS
         * (even in case of apparent success) */
        ret = -ENOMEDIUM;
        goto out;
    }
    if (bs->drv->bdrv_co_flush_to_disk) {
        ret = bs->drv->bdrv_co_flush_to_disk(bs);
    } else if (bs->drv->bdrv_aio_flush) {
        BlockAIOCB *acb;
        CoroutineIOCompletion co = {
            .coroutine = qemu_coroutine_self(),
        };

        acb = bs->drv->bdrv_aio_flush(bs, bdrv_co_io_em_complete, &co);
        if (acb == NULL) {
            ret = -EIO;
        } else {
            qemu_coroutine_yield();
            ret = co.ret;
        }
    } else {
        /*
         * Some block drivers always operate in either writethrough or unsafe
         * mode and don't support bdrv_flush therefore. Usually qemu doesn't
         * know how the server works (because the behaviour is hardcoded or
         * depends on server-side configuration), so we can't ensure that
         * everything is safe on disk. Returning an error doesn't work because
         * that would break guests even if the server operates in writethrough
         * mode.
         *
         * Let's hope the user knows what he's doing.
         */
        ret = 0;
    }

    if (ret < 0) {
        goto out;
    }

    /* Now flush the underlying protocol.  It will also have BDRV_O_NO_FLUSH
     * in the case of cache=unsafe, so there are no useless flushes.
     */
flush_children:
    ret = 0;
    QLIST_FOREACH(child, &bs->children, next) {
        if (child->perm & (BLK_PERM_WRITE | BLK_PERM_WRITE_UNCHANGED)) {
            int this_child_ret = bdrv_co_flush(child->bs);
            if (!ret) {
                ret = this_child_ret;
            }
        }
    }

out:
    /* Notify any pending flushes that we have completed */
    if (ret == 0) {
        bs->flushed_gen = current_gen;
    }

    qemu_mutex_lock(&bs->reqs_lock);
    bs->active_flush_req = false;
    /* Return value is ignored - it's ok if wait queue is empty */
    qemu_co_queue_next(&bs->flush_queue);
    qemu_mutex_unlock(&bs->reqs_lock);

early_exit:
    bdrv_dec_in_flight(bs);
    return ret;
}

int coroutine_fn bdrv_co_pdiscard(BdrvChild *child, int64_t offset,
                                  int64_t bytes)
{
    BdrvTrackedRequest req;
    int ret;
    int64_t max_pdiscard;
    int head, tail, align;
    BlockDriverState *bs = child->bs;
    IO_CODE();
    assert_bdrv_graph_readable();

    if (!bs || !bs->drv || !bdrv_co_is_inserted(bs)) {
        return -ENOMEDIUM;
    }

    if (bdrv_has_readonly_bitmaps(bs)) {
        return -EPERM;
    }

    ret = bdrv_check_request(offset, bytes, NULL);
    if (ret < 0) {
        return ret;
    }

    /* Do nothing if disabled.  */
    if (!(bs->open_flags & BDRV_O_UNMAP)) {
        return 0;
    }

    if (!bs->drv->bdrv_co_pdiscard && !bs->drv->bdrv_aio_pdiscard) {
        return 0;
    }

    /* Invalidate the cached block-status data range if this discard overlaps */
    bdrv_bsc_invalidate_range(bs, offset, bytes);

    /* Discard is advisory, but some devices track and coalesce
     * unaligned requests, so we must pass everything down rather than
     * round here.  Still, most devices will just silently ignore
     * unaligned requests (by returning -ENOTSUP), so we must fragment
     * the request accordingly.  */
    align = MAX(bs->bl.pdiscard_alignment, bs->bl.request_alignment);
    assert(align % bs->bl.request_alignment == 0);
    head = offset % align;
    tail = (offset + bytes) % align;

    bdrv_inc_in_flight(bs);
    tracked_request_begin(&req, bs, offset, bytes, BDRV_TRACKED_DISCARD);

    ret = bdrv_co_write_req_prepare(child, offset, bytes, &req, 0);
    if (ret < 0) {
        goto out;
    }

    max_pdiscard = QEMU_ALIGN_DOWN(MIN_NON_ZERO(bs->bl.max_pdiscard, INT64_MAX),
                                   align);
    assert(max_pdiscard >= bs->bl.request_alignment);

    while (bytes > 0) {
        int64_t num = bytes;

        if (head) {
            /* Make small requests to get to alignment boundaries. */
            num = MIN(bytes, align - head);
            if (!QEMU_IS_ALIGNED(num, bs->bl.request_alignment)) {
                num %= bs->bl.request_alignment;
            }
            head = (head + num) % align;
            assert(num < max_pdiscard);
        } else if (tail) {
            if (num > align) {
                /* Shorten the request to the last aligned cluster.  */
                num -= tail;
            } else if (!QEMU_IS_ALIGNED(tail, bs->bl.request_alignment) &&
                       tail > bs->bl.request_alignment) {
                tail %= bs->bl.request_alignment;
                num -= tail;
            }
        }
        /* limit request size */
        if (num > max_pdiscard) {
            num = max_pdiscard;
        }

        if (!bs->drv) {
            ret = -ENOMEDIUM;
            goto out;
        }
        if (bs->drv->bdrv_co_pdiscard) {
            ret = bs->drv->bdrv_co_pdiscard(bs, offset, num);
        } else {
            BlockAIOCB *acb;
            CoroutineIOCompletion co = {
                .coroutine = qemu_coroutine_self(),
            };

            acb = bs->drv->bdrv_aio_pdiscard(bs, offset, num,
                                             bdrv_co_io_em_complete, &co);
            if (acb == NULL) {
                ret = -EIO;
                goto out;
            } else {
                qemu_coroutine_yield();
                ret = co.ret;
            }
        }
        if (ret && ret != -ENOTSUP) {
            goto out;
        }

        offset += num;
        bytes -= num;
    }
    ret = 0;
out:
    bdrv_co_write_req_finish(child, req.offset, req.bytes, &req, ret);
    tracked_request_end(&req);
    bdrv_dec_in_flight(bs);
    return ret;
}

int coroutine_fn bdrv_co_ioctl(BlockDriverState *bs, int req, void *buf)
{
    BlockDriver *drv = bs->drv;
    CoroutineIOCompletion co = {
        .coroutine = qemu_coroutine_self(),
    };
    BlockAIOCB *acb;
    IO_CODE();
    assert_bdrv_graph_readable();

    bdrv_inc_in_flight(bs);
    if (!drv || (!drv->bdrv_aio_ioctl && !drv->bdrv_co_ioctl)) {
        co.ret = -ENOTSUP;
        goto out;
    }

    if (drv->bdrv_co_ioctl) {
        co.ret = drv->bdrv_co_ioctl(bs, req, buf);
    } else {
        acb = drv->bdrv_aio_ioctl(bs, req, buf, bdrv_co_io_em_complete, &co);
        if (!acb) {
            co.ret = -ENOTSUP;
            goto out;
        }
        qemu_coroutine_yield();
    }
out:
    bdrv_dec_in_flight(bs);
    return co.ret;
}

int coroutine_fn bdrv_co_zone_report(BlockDriverState *bs, int64_t offset,
                        unsigned int *nr_zones,
                        BlockZoneDescriptor *zones)
{
    BlockDriver *drv = bs->drv;
    CoroutineIOCompletion co = {
            .coroutine = qemu_coroutine_self(),
    };
    IO_CODE();

    bdrv_inc_in_flight(bs);
    if (!drv || !drv->bdrv_co_zone_report || bs->bl.zoned == BLK_Z_NONE) {
        co.ret = -ENOTSUP;
        goto out;
    }
    co.ret = drv->bdrv_co_zone_report(bs, offset, nr_zones, zones);
out:
    bdrv_dec_in_flight(bs);
    return co.ret;
}

int coroutine_fn bdrv_co_zone_mgmt(BlockDriverState *bs, BlockZoneOp op,
        int64_t offset, int64_t len)
{
    BlockDriver *drv = bs->drv;
    CoroutineIOCompletion co = {
            .coroutine = qemu_coroutine_self(),
    };
    IO_CODE();

    bdrv_inc_in_flight(bs);
    if (!drv || !drv->bdrv_co_zone_mgmt || bs->bl.zoned == BLK_Z_NONE) {
        co.ret = -ENOTSUP;
        goto out;
    }
    co.ret = drv->bdrv_co_zone_mgmt(bs, op, offset, len);
out:
    bdrv_dec_in_flight(bs);
    return co.ret;
}

int coroutine_fn bdrv_co_zone_append(BlockDriverState *bs, int64_t *offset,
                        QEMUIOVector *qiov,
                        BdrvRequestFlags flags)
{
    int ret;
    BlockDriver *drv = bs->drv;
    CoroutineIOCompletion co = {
            .coroutine = qemu_coroutine_self(),
    };
    IO_CODE();

    ret = bdrv_check_qiov_request(*offset, qiov->size, qiov, 0, NULL);
    if (ret < 0) {
        return ret;
    }

    bdrv_inc_in_flight(bs);
    if (!drv || !drv->bdrv_co_zone_append || bs->bl.zoned == BLK_Z_NONE) {
        co.ret = -ENOTSUP;
        goto out;
    }
    co.ret = drv->bdrv_co_zone_append(bs, offset, qiov, flags);
out:
    bdrv_dec_in_flight(bs);
    return co.ret;
}

void *qemu_blockalign(BlockDriverState *bs, size_t size)
{
    IO_CODE();
    return qemu_memalign(bdrv_opt_mem_align(bs), size);
}

void *qemu_blockalign0(BlockDriverState *bs, size_t size)
{
    IO_CODE();
    return memset(qemu_blockalign(bs, size), 0, size);
}

void *qemu_try_blockalign(BlockDriverState *bs, size_t size)
{
    size_t align = bdrv_opt_mem_align(bs);
    IO_CODE();

    /* Ensure that NULL is never returned on success */
    assert(align > 0);
    if (size == 0) {
        size = align;
    }

    return qemu_try_memalign(align, size);
}

void *qemu_try_blockalign0(BlockDriverState *bs, size_t size)
{
    void *mem = qemu_try_blockalign(bs, size);
    IO_CODE();

    if (mem) {
        memset(mem, 0, size);
    }

    return mem;
}

/* Helper that undoes bdrv_register_buf() when it fails partway through */
static void GRAPH_RDLOCK
bdrv_register_buf_rollback(BlockDriverState *bs, void *host, size_t size,
                           BdrvChild *final_child)
{
    BdrvChild *child;

    GLOBAL_STATE_CODE();
    assert_bdrv_graph_readable();

    QLIST_FOREACH(child, &bs->children, next) {
        if (child == final_child) {
            break;
        }

        bdrv_unregister_buf(child->bs, host, size);
    }

    if (bs->drv && bs->drv->bdrv_unregister_buf) {
        bs->drv->bdrv_unregister_buf(bs, host, size);
    }
}

bool bdrv_register_buf(BlockDriverState *bs, void *host, size_t size,
                       Error **errp)
{
    BdrvChild *child;

    GLOBAL_STATE_CODE();
    GRAPH_RDLOCK_GUARD_MAINLOOP();

    if (bs->drv && bs->drv->bdrv_register_buf) {
        if (!bs->drv->bdrv_register_buf(bs, host, size, errp)) {
            return false;
        }
    }
    QLIST_FOREACH(child, &bs->children, next) {
        if (!bdrv_register_buf(child->bs, host, size, errp)) {
            bdrv_register_buf_rollback(bs, host, size, child);
            return false;
        }
    }
    return true;
}

void bdrv_unregister_buf(BlockDriverState *bs, void *host, size_t size)
{
    BdrvChild *child;

    GLOBAL_STATE_CODE();
    GRAPH_RDLOCK_GUARD_MAINLOOP();

    if (bs->drv && bs->drv->bdrv_unregister_buf) {
        bs->drv->bdrv_unregister_buf(bs, host, size);
    }
    QLIST_FOREACH(child, &bs->children, next) {
        bdrv_unregister_buf(child->bs, host, size);
    }
}

static int coroutine_fn GRAPH_RDLOCK bdrv_co_copy_range_internal(
        BdrvChild *src, int64_t src_offset, BdrvChild *dst,
        int64_t dst_offset, int64_t bytes,
        BdrvRequestFlags read_flags, BdrvRequestFlags write_flags,
        bool recurse_src)
{
    BdrvTrackedRequest req;
    int ret;
    assert_bdrv_graph_readable();

    /* TODO We can support BDRV_REQ_NO_FALLBACK here */
    assert(!(read_flags & BDRV_REQ_NO_FALLBACK));
    assert(!(write_flags & BDRV_REQ_NO_FALLBACK));
    assert(!(read_flags & BDRV_REQ_NO_WAIT));
    assert(!(write_flags & BDRV_REQ_NO_WAIT));

    if (!dst || !dst->bs || !bdrv_co_is_inserted(dst->bs)) {
        return -ENOMEDIUM;
    }
    ret = bdrv_check_request32(dst_offset, bytes, NULL, 0);
    if (ret) {
        return ret;
    }
    if (write_flags & BDRV_REQ_ZERO_WRITE) {
        return bdrv_co_pwrite_zeroes(dst, dst_offset, bytes, write_flags);
    }

    if (!src || !src->bs || !bdrv_co_is_inserted(src->bs)) {
        return -ENOMEDIUM;
    }
    ret = bdrv_check_request32(src_offset, bytes, NULL, 0);
    if (ret) {
        return ret;
    }

    if (!src->bs->drv->bdrv_co_copy_range_from
        || !dst->bs->drv->bdrv_co_copy_range_to
        || src->bs->encrypted || dst->bs->encrypted) {
        return -ENOTSUP;
    }

    if (recurse_src) {
        bdrv_inc_in_flight(src->bs);
        tracked_request_begin(&req, src->bs, src_offset, bytes,
                              BDRV_TRACKED_READ);

        /* BDRV_REQ_SERIALISING is only for write operation */
        assert(!(read_flags & BDRV_REQ_SERIALISING));
        bdrv_wait_serialising_requests(&req);

        ret = src->bs->drv->bdrv_co_copy_range_from(src->bs,
                                                    src, src_offset,
                                                    dst, dst_offset,
                                                    bytes,
                                                    read_flags, write_flags);

        tracked_request_end(&req);
        bdrv_dec_in_flight(src->bs);
    } else {
        bdrv_inc_in_flight(dst->bs);
        tracked_request_begin(&req, dst->bs, dst_offset, bytes,
                              BDRV_TRACKED_WRITE);
        ret = bdrv_co_write_req_prepare(dst, dst_offset, bytes, &req,
                                        write_flags);
        if (!ret) {
            ret = dst->bs->drv->bdrv_co_copy_range_to(dst->bs,
                                                      src, src_offset,
                                                      dst, dst_offset,
                                                      bytes,
                                                      read_flags, write_flags);
        }
        bdrv_co_write_req_finish(dst, dst_offset, bytes, &req, ret);
        tracked_request_end(&req);
        bdrv_dec_in_flight(dst->bs);
    }

    return ret;
}

/* Copy range from @src to @dst.
 *
 * See the comment of bdrv_co_copy_range for the parameter and return value
 * semantics. */
int coroutine_fn bdrv_co_copy_range_from(BdrvChild *src, int64_t src_offset,
                                         BdrvChild *dst, int64_t dst_offset,
                                         int64_t bytes,
                                         BdrvRequestFlags read_flags,
                                         BdrvRequestFlags write_flags)
{
    IO_CODE();
    assert_bdrv_graph_readable();
    trace_bdrv_co_copy_range_from(src, src_offset, dst, dst_offset, bytes,
                                  read_flags, write_flags);
    return bdrv_co_copy_range_internal(src, src_offset, dst, dst_offset,
                                       bytes, read_flags, write_flags, true);
}

/* Copy range from @src to @dst.
 *
 * See the comment of bdrv_co_copy_range for the parameter and return value
 * semantics. */
int coroutine_fn bdrv_co_copy_range_to(BdrvChild *src, int64_t src_offset,
                                       BdrvChild *dst, int64_t dst_offset,
                                       int64_t bytes,
                                       BdrvRequestFlags read_flags,
                                       BdrvRequestFlags write_flags)
{
    IO_CODE();
    assert_bdrv_graph_readable();
    trace_bdrv_co_copy_range_to(src, src_offset, dst, dst_offset, bytes,
                                read_flags, write_flags);
    return bdrv_co_copy_range_internal(src, src_offset, dst, dst_offset,
                                       bytes, read_flags, write_flags, false);
}

int coroutine_fn bdrv_co_copy_range(BdrvChild *src, int64_t src_offset,
                                    BdrvChild *dst, int64_t dst_offset,
                                    int64_t bytes, BdrvRequestFlags read_flags,
                                    BdrvRequestFlags write_flags)
{
    IO_CODE();
    assert_bdrv_graph_readable();

    return bdrv_co_copy_range_from(src, src_offset,
                                   dst, dst_offset,
                                   bytes, read_flags, write_flags);
}

static void coroutine_fn GRAPH_RDLOCK
bdrv_parent_cb_resize(BlockDriverState *bs)
{
    BdrvChild *c;

    assert_bdrv_graph_readable();

    QLIST_FOREACH(c, &bs->parents, next_parent) {
        if (c->klass->resize) {
            c->klass->resize(c);
        }
    }
}

/**
 * Truncate file to 'offset' bytes (needed only for file protocols)
 *
 * If 'exact' is true, the file must be resized to exactly the given
 * 'offset'.  Otherwise, it is sufficient for the node to be at least
 * 'offset' bytes in length.
 */
int coroutine_fn bdrv_co_truncate(BdrvChild *child, int64_t offset, bool exact,
                                  PreallocMode prealloc, BdrvRequestFlags flags,
                                  Error **errp)
{
    BlockDriverState *bs = child->bs;
    BdrvChild *filtered, *backing;
    BlockDriver *drv = bs->drv;
    BdrvTrackedRequest req;
    int64_t old_size, new_bytes;
    int ret;
    IO_CODE();
    assert_bdrv_graph_readable();

    /* if bs->drv == NULL, bs is closed, so there's nothing to do here */
    if (!drv) {
        error_setg(errp, "No medium inserted");
        return -ENOMEDIUM;
    }
    if (offset < 0) {
        error_setg(errp, "Image size cannot be negative");
        return -EINVAL;
    }

    ret = bdrv_check_request(offset, 0, errp);
    if (ret < 0) {
        return ret;
    }

    old_size = bdrv_co_getlength(bs);
    if (old_size < 0) {
        error_setg_errno(errp, -old_size, "Failed to get old image size");
        return old_size;
    }

    if (bdrv_is_read_only(bs)) {
        error_setg(errp, "Image is read-only");
        return -EACCES;
    }

    if (offset > old_size) {
        new_bytes = offset - old_size;
    } else {
        new_bytes = 0;
    }

    bdrv_inc_in_flight(bs);
    tracked_request_begin(&req, bs, offset - new_bytes, new_bytes,
                          BDRV_TRACKED_TRUNCATE);

    /* If we are growing the image and potentially using preallocation for the
     * new area, we need to make sure that no write requests are made to it
     * concurrently or they might be overwritten by preallocation. */
    if (new_bytes) {
        bdrv_make_request_serialising(&req, 1);
    }
    ret = bdrv_co_write_req_prepare(child, offset - new_bytes, new_bytes, &req,
                                    0);
    if (ret < 0) {
        error_setg_errno(errp, -ret,
                         "Failed to prepare request for truncation");
        goto out;
    }

    filtered = bdrv_filter_child(bs);
    backing = bdrv_cow_child(bs);

    /*
     * If the image has a backing file that is large enough that it would
     * provide data for the new area, we cannot leave it unallocated because
     * then the backing file content would become visible. Instead, zero-fill
     * the new area.
     *
     * Note that if the image has a backing file, but was opened without the
     * backing file, taking care of keeping things consistent with that backing
     * file is the user's responsibility.
     */
    if (new_bytes && backing) {
        int64_t backing_len;

        backing_len = bdrv_co_getlength(backing->bs);
        if (backing_len < 0) {
            ret = backing_len;
            error_setg_errno(errp, -ret, "Could not get backing file size");
            goto out;
        }

        if (backing_len > old_size) {
            flags |= BDRV_REQ_ZERO_WRITE;
        }
    }

    if (drv->bdrv_co_truncate) {
        if (flags & ~bs->supported_truncate_flags) {
            error_setg(errp, "Block driver does not support requested flags");
            ret = -ENOTSUP;
            goto out;
        }
        ret = drv->bdrv_co_truncate(bs, offset, exact, prealloc, flags, errp);
    } else if (filtered) {
        ret = bdrv_co_truncate(filtered, offset, exact, prealloc, flags, errp);
    } else {
        error_setg(errp, "Image format driver does not support resize");
        ret = -ENOTSUP;
        goto out;
    }
    if (ret < 0) {
        goto out;
    }

    ret = bdrv_co_refresh_total_sectors(bs, offset >> BDRV_SECTOR_BITS);
    if (ret < 0) {
        error_setg_errno(errp, -ret, "Could not refresh total sector count");
    } else {
        offset = bs->total_sectors * BDRV_SECTOR_SIZE;
    }
    /*
     * It's possible that truncation succeeded but bdrv_refresh_total_sectors
     * failed, but the latter doesn't affect how we should finish the request.
     * Pass 0 as the last parameter so that dirty bitmaps etc. are handled.
     */
    bdrv_co_write_req_finish(child, offset - new_bytes, new_bytes, &req, 0);

out:
    tracked_request_end(&req);
    bdrv_dec_in_flight(bs);

    return ret;
}

void bdrv_cancel_in_flight(BlockDriverState *bs)
{
    GLOBAL_STATE_CODE();
    GRAPH_RDLOCK_GUARD_MAINLOOP();

    if (!bs || !bs->drv) {
        return;
    }

    if (bs->drv->bdrv_cancel_in_flight) {
        bs->drv->bdrv_cancel_in_flight(bs);
    }
}

int coroutine_fn
bdrv_co_preadv_snapshot(BdrvChild *child, int64_t offset, int64_t bytes,
                        QEMUIOVector *qiov, size_t qiov_offset)
{
    BlockDriverState *bs = child->bs;
    BlockDriver *drv = bs->drv;
    int ret;
    IO_CODE();
    assert_bdrv_graph_readable();

    if (!drv) {
        return -ENOMEDIUM;
    }

    if (!drv->bdrv_co_preadv_snapshot) {
        return -ENOTSUP;
    }

    bdrv_inc_in_flight(bs);
    ret = drv->bdrv_co_preadv_snapshot(bs, offset, bytes, qiov, qiov_offset);
    bdrv_dec_in_flight(bs);

    return ret;
}

int coroutine_fn
bdrv_co_snapshot_block_status(BlockDriverState *bs,
                              bool want_zero, int64_t offset, int64_t bytes,
                              int64_t *pnum, int64_t *map,
                              BlockDriverState **file)
{
    BlockDriver *drv = bs->drv;
    int ret;
    IO_CODE();
    assert_bdrv_graph_readable();

    if (!drv) {
        return -ENOMEDIUM;
    }

    if (!drv->bdrv_co_snapshot_block_status) {
        return -ENOTSUP;
    }

    bdrv_inc_in_flight(bs);
    ret = drv->bdrv_co_snapshot_block_status(bs, want_zero, offset, bytes,
                                             pnum, map, file);
    bdrv_dec_in_flight(bs);

    return ret;
}

int coroutine_fn
bdrv_co_pdiscard_snapshot(BlockDriverState *bs, int64_t offset, int64_t bytes)
{
    BlockDriver *drv = bs->drv;
    int ret;
    IO_CODE();
    assert_bdrv_graph_readable();

    if (!drv) {
        return -ENOMEDIUM;
    }

    if (!drv->bdrv_co_pdiscard_snapshot) {
        return -ENOTSUP;
    }

    bdrv_inc_in_flight(bs);
    ret = drv->bdrv_co_pdiscard_snapshot(bs, offset, bytes);
    bdrv_dec_in_flight(bs);

    return ret;
}
