/*
 * QEMU Block backends
 *
 * Copyright (C) 2014-2016 Red Hat, Inc.
 *
 * Authors:
 *  Markus Armbruster <armbru@redhat.com>,
 *
 * This work is licensed under the terms of the GNU LGPL, version 2.1
 * or later.  See the COPYING.LIB file in the top-level directory.
 */

#include "qemu/osdep.h"
#include "sysemu/block-backend.h"
#include "block/block_int.h"
#include "block/blockjob.h"
#include "block/coroutines.h"
#include "block/throttle-groups.h"
#include "hw/qdev-core.h"
#include "sysemu/blockdev.h"
#include "sysemu/runstate.h"
#include "sysemu/replay.h"
#include "qapi/error.h"
#include "qapi/qapi-events-block.h"
#include "qemu/id.h"
#include "qemu/main-loop.h"
#include "qemu/option.h"
#include "trace.h"
#include "migration/misc.h"

/* Number of coroutines to reserve per attached device model */
#define COROUTINE_POOL_RESERVATION 64

#define NOT_DONE 0x7fffffff /* used while emulated sync operation in progress */

static AioContext *blk_aiocb_get_aio_context(BlockAIOCB *acb);

typedef struct BlockBackendAioNotifier {
    void (*attached_aio_context)(AioContext *new_context, void *opaque);
    void (*detach_aio_context)(void *opaque);
    void *opaque;
    QLIST_ENTRY(BlockBackendAioNotifier) list;
} BlockBackendAioNotifier;

struct BlockBackend {
    char *name;
    int refcnt;
    BdrvChild *root;
    AioContext *ctx;
    DriveInfo *legacy_dinfo;    /* null unless created by drive_new() */
    QTAILQ_ENTRY(BlockBackend) link;         /* for block_backends */
    QTAILQ_ENTRY(BlockBackend) monitor_link; /* for monitor_block_backends */
    BlockBackendPublic public;

    DeviceState *dev;           /* attached device model, if any */
    const BlockDevOps *dev_ops;
    void *dev_opaque;

    /* If the BDS tree is removed, some of its options are stored here (which
     * can be used to restore those options in the new BDS on insert) */
    BlockBackendRootState root_state;

    bool enable_write_cache;

    /* I/O stats (display with "info blockstats"). */
    BlockAcctStats stats;

    BlockdevOnError on_read_error, on_write_error;
    bool iostatus_enabled;
    BlockDeviceIoStatus iostatus;

    uint64_t perm;
    uint64_t shared_perm;
    bool disable_perm;

    bool allow_aio_context_change;
    bool allow_write_beyond_eof;

    /* Protected by BQL */
    NotifierList remove_bs_notifiers, insert_bs_notifiers;
    QLIST_HEAD(, BlockBackendAioNotifier) aio_notifiers;

    int quiesce_counter; /* atomic: written under BQL, read by other threads */
    QemuMutex queued_requests_lock; /* protects queued_requests */
    CoQueue queued_requests;
    bool disable_request_queuing; /* atomic */

    VMChangeStateEntry *vmsh;
    bool force_allow_inactivate;

    /* Number of in-flight aio requests.  BlockDriverState also counts
     * in-flight requests but aio requests can exist even when blk->root is
     * NULL, so we cannot rely on its counter for that case.
     * Accessed with atomic ops.
     */
    unsigned int in_flight;
};

typedef struct BlockBackendAIOCB {
    BlockAIOCB common;
    BlockBackend *blk;
    int ret;
} BlockBackendAIOCB;

static const AIOCBInfo block_backend_aiocb_info = {
    .get_aio_context = blk_aiocb_get_aio_context,
    .aiocb_size = sizeof(BlockBackendAIOCB),
};

static void drive_info_del(DriveInfo *dinfo);
static BlockBackend *bdrv_first_blk(BlockDriverState *bs);

/* All BlockBackends. Protected by BQL. */
static QTAILQ_HEAD(, BlockBackend) block_backends =
    QTAILQ_HEAD_INITIALIZER(block_backends);

/*
 * All BlockBackends referenced by the monitor and which are iterated through by
 * blk_next(). Protected by BQL.
 */
static QTAILQ_HEAD(, BlockBackend) monitor_block_backends =
    QTAILQ_HEAD_INITIALIZER(monitor_block_backends);

static int coroutine_mixed_fn GRAPH_RDLOCK
blk_set_perm_locked(BlockBackend *blk, uint64_t perm, uint64_t shared_perm,
                    Error **errp);

static void blk_root_inherit_options(BdrvChildRole role, bool parent_is_format,
                                     int *child_flags, QDict *child_options,
                                     int parent_flags, QDict *parent_options)
{
    /* We're not supposed to call this function for root nodes */
    abort();
}
static void blk_root_drained_begin(BdrvChild *child);
static bool blk_root_drained_poll(BdrvChild *child);
static void blk_root_drained_end(BdrvChild *child);

static void blk_root_change_media(BdrvChild *child, bool load);
static void blk_root_resize(BdrvChild *child);

static bool blk_root_change_aio_ctx(BdrvChild *child, AioContext *ctx,
                                    GHashTable *visited, Transaction *tran,
                                    Error **errp);

static char *blk_root_get_parent_desc(BdrvChild *child)
{
    BlockBackend *blk = child->opaque;
    g_autofree char *dev_id = NULL;

    if (blk->name) {
        return g_strdup_printf("block device '%s'", blk->name);
    }

    dev_id = blk_get_attached_dev_id(blk);
    if (*dev_id) {
        return g_strdup_printf("block device '%s'", dev_id);
    } else {
        /* TODO Callback into the BB owner for something more detailed */
        return g_strdup("an unnamed block device");
    }
}

static const char *blk_root_get_name(BdrvChild *child)
{
    return blk_name(child->opaque);
}

static void blk_vm_state_changed(void *opaque, bool running, RunState state)
{
    Error *local_err = NULL;
    BlockBackend *blk = opaque;

    if (state == RUN_STATE_INMIGRATE) {
        return;
    }

    qemu_del_vm_change_state_handler(blk->vmsh);
    blk->vmsh = NULL;
    blk_set_perm(blk, blk->perm, blk->shared_perm, &local_err);
    if (local_err) {
        error_report_err(local_err);
    }
}

/*
 * Notifies the user of the BlockBackend that migration has completed. qdev
 * devices can tighten their permissions in response (specifically revoke
 * shared write permissions that we needed for storage migration).
 *
 * If an error is returned, the VM cannot be allowed to be resumed.
 */
static void GRAPH_RDLOCK blk_root_activate(BdrvChild *child, Error **errp)
{
    BlockBackend *blk = child->opaque;
    Error *local_err = NULL;
    uint64_t saved_shared_perm;

    if (!blk->disable_perm) {
        return;
    }

    blk->disable_perm = false;

    /*
     * blk->shared_perm contains the permissions we want to share once
     * migration is really completely done.  For now, we need to share
     * all; but we also need to retain blk->shared_perm, which is
     * overwritten by a successful blk_set_perm() call.  Save it and
     * restore it below.
     */
    saved_shared_perm = blk->shared_perm;

    blk_set_perm_locked(blk, blk->perm, BLK_PERM_ALL, &local_err);
    if (local_err) {
        error_propagate(errp, local_err);
        blk->disable_perm = true;
        return;
    }
    blk->shared_perm = saved_shared_perm;

    if (runstate_check(RUN_STATE_INMIGRATE)) {
        /* Activation can happen when migration process is still active, for
         * example when nbd_server_add is called during non-shared storage
         * migration. Defer the shared_perm update to migration completion. */
        if (!blk->vmsh) {
            blk->vmsh = qemu_add_vm_change_state_handler(blk_vm_state_changed,
                                                         blk);
        }
        return;
    }

    blk_set_perm_locked(blk, blk->perm, blk->shared_perm, &local_err);
    if (local_err) {
        error_propagate(errp, local_err);
        blk->disable_perm = true;
        return;
    }
}

void blk_set_force_allow_inactivate(BlockBackend *blk)
{
    GLOBAL_STATE_CODE();
    blk->force_allow_inactivate = true;
}

static bool blk_can_inactivate(BlockBackend *blk)
{
    /* If it is a guest device, inactivate is ok. */
    if (blk->dev || blk_name(blk)[0]) {
        return true;
    }

    /* Inactivating means no more writes to the image can be done,
     * even if those writes would be changes invisible to the
     * guest.  For block job BBs that satisfy this, we can just allow
     * it.  This is the case for mirror job source, which is required
     * by libvirt non-shared block migration. */
    if (!(blk->perm & (BLK_PERM_WRITE | BLK_PERM_WRITE_UNCHANGED))) {
        return true;
    }

    return blk->force_allow_inactivate;
}

static int GRAPH_RDLOCK blk_root_inactivate(BdrvChild *child)
{
    BlockBackend *blk = child->opaque;

    if (blk->disable_perm) {
        return 0;
    }

    if (!blk_can_inactivate(blk)) {
        return -EPERM;
    }

    blk->disable_perm = true;
    if (blk->root) {
        bdrv_child_try_set_perm(blk->root, 0, BLK_PERM_ALL, &error_abort);
    }

    return 0;
}

static void blk_root_attach(BdrvChild *child)
{
    BlockBackend *blk = child->opaque;
    BlockBackendAioNotifier *notifier;

    trace_blk_root_attach(child, blk, child->bs);

    QLIST_FOREACH(notifier, &blk->aio_notifiers, list) {
        bdrv_add_aio_context_notifier(child->bs,
                notifier->attached_aio_context,
                notifier->detach_aio_context,
                notifier->opaque);
    }
}

static void blk_root_detach(BdrvChild *child)
{
    BlockBackend *blk = child->opaque;
    BlockBackendAioNotifier *notifier;

    trace_blk_root_detach(child, blk, child->bs);

    QLIST_FOREACH(notifier, &blk->aio_notifiers, list) {
        bdrv_remove_aio_context_notifier(child->bs,
                notifier->attached_aio_context,
                notifier->detach_aio_context,
                notifier->opaque);
    }
}

static AioContext *blk_root_get_parent_aio_context(BdrvChild *c)
{
    BlockBackend *blk = c->opaque;
    IO_CODE();

    return blk_get_aio_context(blk);
}

static const BdrvChildClass child_root = {
    .inherit_options    = blk_root_inherit_options,

    .change_media       = blk_root_change_media,
    .resize             = blk_root_resize,
    .get_name           = blk_root_get_name,
    .get_parent_desc    = blk_root_get_parent_desc,

    .drained_begin      = blk_root_drained_begin,
    .drained_poll       = blk_root_drained_poll,
    .drained_end        = blk_root_drained_end,

    .activate           = blk_root_activate,
    .inactivate         = blk_root_inactivate,

    .attach             = blk_root_attach,
    .detach             = blk_root_detach,

    .change_aio_ctx     = blk_root_change_aio_ctx,

    .get_parent_aio_context = blk_root_get_parent_aio_context,
};

/*
 * Create a new BlockBackend with a reference count of one.
 *
 * @perm is a bitmasks of BLK_PERM_* constants which describes the permissions
 * to request for a block driver node that is attached to this BlockBackend.
 * @shared_perm is a bitmask which describes which permissions may be granted
 * to other users of the attached node.
 * Both sets of permissions can be changed later using blk_set_perm().
 *
 * Return the new BlockBackend on success, null on failure.
 */
BlockBackend *blk_new(AioContext *ctx, uint64_t perm, uint64_t shared_perm)
{
    BlockBackend *blk;

    GLOBAL_STATE_CODE();

    blk = g_new0(BlockBackend, 1);
    blk->refcnt = 1;
    blk->ctx = ctx;
    blk->perm = perm;
    blk->shared_perm = shared_perm;
    blk_set_enable_write_cache(blk, true);

    blk->on_read_error = BLOCKDEV_ON_ERROR_REPORT;
    blk->on_write_error = BLOCKDEV_ON_ERROR_ENOSPC;

    block_acct_init(&blk->stats);

    qemu_mutex_init(&blk->queued_requests_lock);
    qemu_co_queue_init(&blk->queued_requests);
    notifier_list_init(&blk->remove_bs_notifiers);
    notifier_list_init(&blk->insert_bs_notifiers);
    QLIST_INIT(&blk->aio_notifiers);

    QTAILQ_INSERT_TAIL(&block_backends, blk, link);
    return blk;
}

/*
 * Create a new BlockBackend connected to an existing BlockDriverState.
 *
 * @perm is a bitmasks of BLK_PERM_* constants which describes the
 * permissions to request for @bs that is attached to this
 * BlockBackend.  @shared_perm is a bitmask which describes which
 * permissions may be granted to other users of the attached node.
 * Both sets of permissions can be changed later using blk_set_perm().
 *
 * Return the new BlockBackend on success, null on failure.
 *
 * Callers must hold the AioContext lock of @bs.
 */
BlockBackend *blk_new_with_bs(BlockDriverState *bs, uint64_t perm,
                              uint64_t shared_perm, Error **errp)
{
    BlockBackend *blk = blk_new(bdrv_get_aio_context(bs), perm, shared_perm);

    GLOBAL_STATE_CODE();

    if (blk_insert_bs(blk, bs, errp) < 0) {
        blk_unref(blk);
        return NULL;
    }
    return blk;
}

/*
 * Creates a new BlockBackend, opens a new BlockDriverState, and connects both.
 * By default, the new BlockBackend is in the main AioContext, but if the
 * parameters connect it with any existing node in a different AioContext, it
 * may end up there instead.
 *
 * Just as with bdrv_open(), after having called this function the reference to
 * @options belongs to the block layer (even on failure).
 *
 * Called without holding an AioContext lock.
 *
 * TODO: Remove @filename and @flags; it should be possible to specify a whole
 * BDS tree just by specifying the @options QDict (or @reference,
 * alternatively). At the time of adding this function, this is not possible,
 * though, so callers of this function have to be able to specify @filename and
 * @flags.
 */
BlockBackend *blk_new_open(const char *filename, const char *reference,
                           QDict *options, int flags, Error **errp)
{
    BlockBackend *blk;
    BlockDriverState *bs;
    AioContext *ctx;
    uint64_t perm = 0;
    uint64_t shared = BLK_PERM_ALL;

    GLOBAL_STATE_CODE();

    /*
     * blk_new_open() is mainly used in .bdrv_create implementations and the
     * tools where sharing isn't a major concern because the BDS stays private
     * and the file is generally not supposed to be used by a second process,
     * so we just request permission according to the flags.
     *
     * The exceptions are xen_disk and blockdev_init(); in these cases, the
     * caller of blk_new_open() doesn't make use of the permissions, but they
     * shouldn't hurt either. We can still share everything here because the
     * guest devices will add their own blockers if they can't share.
     */
    if ((flags & BDRV_O_NO_IO) == 0) {
        perm |= BLK_PERM_CONSISTENT_READ;
        if (flags & BDRV_O_RDWR) {
            perm |= BLK_PERM_WRITE;
        }
    }
    if (flags & BDRV_O_RESIZE) {
        perm |= BLK_PERM_RESIZE;
    }
    if (flags & BDRV_O_NO_SHARE) {
        shared = BLK_PERM_CONSISTENT_READ | BLK_PERM_WRITE_UNCHANGED;
    }

    aio_context_acquire(qemu_get_aio_context());
    bs = bdrv_open(filename, reference, options, flags, errp);
    aio_context_release(qemu_get_aio_context());
    if (!bs) {
        return NULL;
    }

    /* bdrv_open() could have moved bs to a different AioContext */
    ctx = bdrv_get_aio_context(bs);
    blk = blk_new(bdrv_get_aio_context(bs), perm, shared);
    blk->perm = perm;
    blk->shared_perm = shared;

    aio_context_acquire(ctx);
    blk_insert_bs(blk, bs, errp);
    bdrv_unref(bs);
    aio_context_release(ctx);

    if (!blk->root) {
        blk_unref(blk);
        return NULL;
    }

    return blk;
}

static void blk_delete(BlockBackend *blk)
{
    assert(!blk->refcnt);
    assert(!blk->name);
    assert(!blk->dev);
    if (blk->public.throttle_group_member.throttle_state) {
        blk_io_limits_disable(blk);
    }
    if (blk->root) {
        blk_remove_bs(blk);
    }
    if (blk->vmsh) {
        qemu_del_vm_change_state_handler(blk->vmsh);
        blk->vmsh = NULL;
    }
    assert(QLIST_EMPTY(&blk->remove_bs_notifiers.notifiers));
    assert(QLIST_EMPTY(&blk->insert_bs_notifiers.notifiers));
    assert(QLIST_EMPTY(&blk->aio_notifiers));
    assert(qemu_co_queue_empty(&blk->queued_requests));
    qemu_mutex_destroy(&blk->queued_requests_lock);
    QTAILQ_REMOVE(&block_backends, blk, link);
    drive_info_del(blk->legacy_dinfo);
    block_acct_cleanup(&blk->stats);
    g_free(blk);
}

static void drive_info_del(DriveInfo *dinfo)
{
    if (!dinfo) {
        return;
    }
    qemu_opts_del(dinfo->opts);
    g_free(dinfo);
}

int blk_get_refcnt(BlockBackend *blk)
{
    GLOBAL_STATE_CODE();
    return blk ? blk->refcnt : 0;
}

/*
 * Increment @blk's reference count.
 * @blk must not be null.
 */
void blk_ref(BlockBackend *blk)
{
    assert(blk->refcnt > 0);
    GLOBAL_STATE_CODE();
    blk->refcnt++;
}

/*
 * Decrement @blk's reference count.
 * If this drops it to zero, destroy @blk.
 * For convenience, do nothing if @blk is null.
 */
void blk_unref(BlockBackend *blk)
{
    GLOBAL_STATE_CODE();
    if (blk) {
        assert(blk->refcnt > 0);
        if (blk->refcnt > 1) {
            blk->refcnt--;
        } else {
            blk_drain(blk);
            /* blk_drain() cannot resurrect blk, nobody held a reference */
            assert(blk->refcnt == 1);
            blk->refcnt = 0;
            blk_delete(blk);
        }
    }
}

/*
 * Behaves similarly to blk_next() but iterates over all BlockBackends, even the
 * ones which are hidden (i.e. are not referenced by the monitor).
 */
BlockBackend *blk_all_next(BlockBackend *blk)
{
    GLOBAL_STATE_CODE();
    return blk ? QTAILQ_NEXT(blk, link)
               : QTAILQ_FIRST(&block_backends);
}

void blk_remove_all_bs(void)
{
    BlockBackend *blk = NULL;

    GLOBAL_STATE_CODE();

    while ((blk = blk_all_next(blk)) != NULL) {
        AioContext *ctx = blk_get_aio_context(blk);

        aio_context_acquire(ctx);
        if (blk->root) {
            blk_remove_bs(blk);
        }
        aio_context_release(ctx);
    }
}

/*
 * Return the monitor-owned BlockBackend after @blk.
 * If @blk is null, return the first one.
 * Else, return @blk's next sibling, which may be null.
 *
 * To iterate over all BlockBackends, do
 * for (blk = blk_next(NULL); blk; blk = blk_next(blk)) {
 *     ...
 * }
 */
BlockBackend *blk_next(BlockBackend *blk)
{
    GLOBAL_STATE_CODE();
    return blk ? QTAILQ_NEXT(blk, monitor_link)
               : QTAILQ_FIRST(&monitor_block_backends);
}

/* Iterates over all top-level BlockDriverStates, i.e. BDSs that are owned by
 * the monitor or attached to a BlockBackend */
BlockDriverState *bdrv_next(BdrvNextIterator *it)
{
    BlockDriverState *bs, *old_bs;

    /* Must be called from the main loop */
    assert(qemu_get_current_aio_context() == qemu_get_aio_context());

    /* First, return all root nodes of BlockBackends. In order to avoid
     * returning a BDS twice when multiple BBs refer to it, we only return it
     * if the BB is the first one in the parent list of the BDS. */
    if (it->phase == BDRV_NEXT_BACKEND_ROOTS) {
        BlockBackend *old_blk = it->blk;

        old_bs = old_blk ? blk_bs(old_blk) : NULL;

        do {
            it->blk = blk_all_next(it->blk);
            bs = it->blk ? blk_bs(it->blk) : NULL;
        } while (it->blk && (bs == NULL || bdrv_first_blk(bs) != it->blk));

        if (it->blk) {
            blk_ref(it->blk);
        }
        blk_unref(old_blk);

        if (bs) {
            bdrv_ref(bs);
            bdrv_unref(old_bs);
            return bs;
        }
        it->phase = BDRV_NEXT_MONITOR_OWNED;
    } else {
        old_bs = it->bs;
    }

    /* Then return the monitor-owned BDSes without a BB attached. Ignore all
     * BDSes that are attached to a BlockBackend here; they have been handled
     * by the above block already */
    do {
        it->bs = bdrv_next_monitor_owned(it->bs);
        bs = it->bs;
    } while (bs && bdrv_has_blk(bs));

    if (bs) {
        bdrv_ref(bs);
    }
    bdrv_unref(old_bs);

    return bs;
}

static void bdrv_next_reset(BdrvNextIterator *it)
{
    *it = (BdrvNextIterator) {
        .phase = BDRV_NEXT_BACKEND_ROOTS,
    };
}

BlockDriverState *bdrv_first(BdrvNextIterator *it)
{
    GLOBAL_STATE_CODE();
    bdrv_next_reset(it);
    return bdrv_next(it);
}

/* Must be called when aborting a bdrv_next() iteration before
 * bdrv_next() returns NULL */
void bdrv_next_cleanup(BdrvNextIterator *it)
{
    /* Must be called from the main loop */
    assert(qemu_get_current_aio_context() == qemu_get_aio_context());

    if (it->phase == BDRV_NEXT_BACKEND_ROOTS) {
        if (it->blk) {
            bdrv_unref(blk_bs(it->blk));
            blk_unref(it->blk);
        }
    } else {
        bdrv_unref(it->bs);
    }

    bdrv_next_reset(it);
}

/*
 * Add a BlockBackend into the list of backends referenced by the monitor, with
 * the given @name acting as the handle for the monitor.
 * Strictly for use by blockdev.c.
 *
 * @name must not be null or empty.
 *
 * Returns true on success and false on failure. In the latter case, an Error
 * object is returned through @errp.
 */
bool monitor_add_blk(BlockBackend *blk, const char *name, Error **errp)
{
    assert(!blk->name);
    assert(name && name[0]);
    GLOBAL_STATE_CODE();

    if (!id_wellformed(name)) {
        error_setg(errp, "Invalid device name");
        return false;
    }
    if (blk_by_name(name)) {
        error_setg(errp, "Device with id '%s' already exists", name);
        return false;
    }
    if (bdrv_find_node(name)) {
        error_setg(errp,
                   "Device name '%s' conflicts with an existing node name",
                   name);
        return false;
    }

    blk->name = g_strdup(name);
    QTAILQ_INSERT_TAIL(&monitor_block_backends, blk, monitor_link);
    return true;
}

/*
 * Remove a BlockBackend from the list of backends referenced by the monitor.
 * Strictly for use by blockdev.c.
 */
void monitor_remove_blk(BlockBackend *blk)
{
    GLOBAL_STATE_CODE();

    if (!blk->name) {
        return;
    }

    QTAILQ_REMOVE(&monitor_block_backends, blk, monitor_link);
    g_free(blk->name);
    blk->name = NULL;
}

/*
 * Return @blk's name, a non-null string.
 * Returns an empty string iff @blk is not referenced by the monitor.
 */
const char *blk_name(const BlockBackend *blk)
{
    IO_CODE();
    return blk->name ?: "";
}

/*
 * Return the BlockBackend with name @name if it exists, else null.
 * @name must not be null.
 */
BlockBackend *blk_by_name(const char *name)
{
    BlockBackend *blk = NULL;

    GLOBAL_STATE_CODE();
    assert(name);
    while ((blk = blk_next(blk)) != NULL) {
        if (!strcmp(name, blk->name)) {
            return blk;
        }
    }
    return NULL;
}

/*
 * Return the BlockDriverState attached to @blk if any, else null.
 */
BlockDriverState *blk_bs(BlockBackend *blk)
{
    IO_CODE();
    return blk->root ? blk->root->bs : NULL;
}

static BlockBackend *bdrv_first_blk(BlockDriverState *bs)
{
    BdrvChild *child;

    GLOBAL_STATE_CODE();

    QLIST_FOREACH(child, &bs->parents, next_parent) {
        if (child->klass == &child_root) {
            return child->opaque;
        }
    }

    return NULL;
}

/*
 * Returns true if @bs has an associated BlockBackend.
 */
bool bdrv_has_blk(BlockDriverState *bs)
{
    GLOBAL_STATE_CODE();
    return bdrv_first_blk(bs) != NULL;
}

/*
 * Returns true if @bs has only BlockBackends as parents.
 */
bool bdrv_is_root_node(BlockDriverState *bs)
{
    BdrvChild *c;

    GLOBAL_STATE_CODE();
    QLIST_FOREACH(c, &bs->parents, next_parent) {
        if (c->klass != &child_root) {
            return false;
        }
    }

    return true;
}

/*
 * Return @blk's DriveInfo if any, else null.
 */
DriveInfo *blk_legacy_dinfo(BlockBackend *blk)
{
    GLOBAL_STATE_CODE();
    return blk->legacy_dinfo;
}

/*
 * Set @blk's DriveInfo to @dinfo, and return it.
 * @blk must not have a DriveInfo set already.
 * No other BlockBackend may have the same DriveInfo set.
 */
DriveInfo *blk_set_legacy_dinfo(BlockBackend *blk, DriveInfo *dinfo)
{
    assert(!blk->legacy_dinfo);
    GLOBAL_STATE_CODE();
    return blk->legacy_dinfo = dinfo;
}

/*
 * Return the BlockBackend with DriveInfo @dinfo.
 * It must exist.
 */
BlockBackend *blk_by_legacy_dinfo(DriveInfo *dinfo)
{
    BlockBackend *blk = NULL;
    GLOBAL_STATE_CODE();

    while ((blk = blk_next(blk)) != NULL) {
        if (blk->legacy_dinfo == dinfo) {
            return blk;
        }
    }
    abort();
}

/*
 * Returns a pointer to the publicly accessible fields of @blk.
 */
BlockBackendPublic *blk_get_public(BlockBackend *blk)
{
    GLOBAL_STATE_CODE();
    return &blk->public;
}

/*
 * Returns a BlockBackend given the associated @public fields.
 */
BlockBackend *blk_by_public(BlockBackendPublic *public)
{
    GLOBAL_STATE_CODE();
    return container_of(public, BlockBackend, public);
}

/*
 * Disassociates the currently associated BlockDriverState from @blk.
 */
void blk_remove_bs(BlockBackend *blk)
{
    ThrottleGroupMember *tgm = &blk->public.throttle_group_member;
    BdrvChild *root;

    GLOBAL_STATE_CODE();

    notifier_list_notify(&blk->remove_bs_notifiers, blk);
    if (tgm->throttle_state) {
        BlockDriverState *bs = blk_bs(blk);

        /*
         * Take a ref in case blk_bs() changes across bdrv_drained_begin(), for
         * example, if a temporary filter node is removed by a blockjob.
         */
        bdrv_ref(bs);
        bdrv_drained_begin(bs);
        throttle_group_detach_aio_context(tgm);
        throttle_group_attach_aio_context(tgm, qemu_get_aio_context());
        bdrv_drained_end(bs);
        bdrv_unref(bs);
    }

    blk_update_root_state(blk);

    /* bdrv_root_unref_child() will cause blk->root to become stale and may
     * switch to a completion coroutine later on. Let's drain all I/O here
     * to avoid that and a potential QEMU crash.
     */
    blk_drain(blk);
    root = blk->root;
    blk->root = NULL;

    bdrv_graph_wrlock(NULL);
    bdrv_root_unref_child(root);
    bdrv_graph_wrunlock();
}

/*
 * Associates a new BlockDriverState with @blk.
 *
 * Callers must hold the AioContext lock of @bs.
 */
int blk_insert_bs(BlockBackend *blk, BlockDriverState *bs, Error **errp)
{
    ThrottleGroupMember *tgm = &blk->public.throttle_group_member;
    GLOBAL_STATE_CODE();
    bdrv_ref(bs);
    blk->root = bdrv_root_attach_child(bs, "root", &child_root,
                                       BDRV_CHILD_FILTERED | BDRV_CHILD_PRIMARY,
                                       blk->perm, blk->shared_perm,
                                       blk, errp);
    if (blk->root == NULL) {
        return -EPERM;
    }

    notifier_list_notify(&blk->insert_bs_notifiers, blk);
    if (tgm->throttle_state) {
        throttle_group_detach_aio_context(tgm);
        throttle_group_attach_aio_context(tgm, bdrv_get_aio_context(bs));
    }

    return 0;
}

/*
 * Change BlockDriverState associated with @blk.
 */
int blk_replace_bs(BlockBackend *blk, BlockDriverState *new_bs, Error **errp)
{
    GLOBAL_STATE_CODE();
    return bdrv_replace_child_bs(blk->root, new_bs, errp);
}

/*
 * Sets the permission bitmasks that the user of the BlockBackend needs.
 */
static int coroutine_mixed_fn GRAPH_RDLOCK
blk_set_perm_locked(BlockBackend *blk, uint64_t perm, uint64_t shared_perm,
                    Error **errp)
{
    int ret;
    GLOBAL_STATE_CODE();

    if (blk->root && !blk->disable_perm) {
        ret = bdrv_child_try_set_perm(blk->root, perm, shared_perm, errp);
        if (ret < 0) {
            return ret;
        }
    }

    blk->perm = perm;
    blk->shared_perm = shared_perm;

    return 0;
}

int blk_set_perm(BlockBackend *blk, uint64_t perm, uint64_t shared_perm,
                 Error **errp)
{
    GLOBAL_STATE_CODE();
    GRAPH_RDLOCK_GUARD_MAINLOOP();

    return blk_set_perm_locked(blk, perm, shared_perm, errp);
}

void blk_get_perm(BlockBackend *blk, uint64_t *perm, uint64_t *shared_perm)
{
    GLOBAL_STATE_CODE();
    *perm = blk->perm;
    *shared_perm = blk->shared_perm;
}

/*
 * Attach device model @dev to @blk.
 * Return 0 on success, -EBUSY when a device model is attached already.
 */
int blk_attach_dev(BlockBackend *blk, DeviceState *dev)
{
    GLOBAL_STATE_CODE();
    if (blk->dev) {
        return -EBUSY;
    }

    /* While migration is still incoming, we don't need to apply the
     * permissions of guest device BlockBackends. We might still have a block
     * job or NBD server writing to the image for storage migration. */
    if (runstate_check(RUN_STATE_INMIGRATE)) {
        blk->disable_perm = true;
    }

    blk_ref(blk);
    blk->dev = dev;
    blk_iostatus_reset(blk);

    return 0;
}

/*
 * Detach device model @dev from @blk.
 * @dev must be currently attached to @blk.
 */
void blk_detach_dev(BlockBackend *blk, DeviceState *dev)
{
    assert(blk->dev == dev);
    GLOBAL_STATE_CODE();
    blk->dev = NULL;
    blk->dev_ops = NULL;
    blk->dev_opaque = NULL;
    blk_set_perm(blk, 0, BLK_PERM_ALL, &error_abort);
    blk_unref(blk);
}

/*
 * Return the device model attached to @blk if any, else null.
 */
DeviceState *blk_get_attached_dev(BlockBackend *blk)
{
    GLOBAL_STATE_CODE();
    return blk->dev;
}

/* Return the qdev ID, or if no ID is assigned the QOM path, of the block
 * device attached to the BlockBackend. */
char *blk_get_attached_dev_id(BlockBackend *blk)
{
    DeviceState *dev = blk->dev;
    IO_CODE();

    if (!dev) {
        return g_strdup("");
    } else if (dev->id) {
        return g_strdup(dev->id);
    }

    return object_get_canonical_path(OBJECT(dev)) ?: g_strdup("");
}

/*
 * Return the BlockBackend which has the device model @dev attached if it
 * exists, else null.
 *
 * @dev must not be null.
 */
BlockBackend *blk_by_dev(void *dev)
{
    BlockBackend *blk = NULL;

    GLOBAL_STATE_CODE();

    assert(dev != NULL);
    while ((blk = blk_all_next(blk)) != NULL) {
        if (blk->dev == dev) {
            return blk;
        }
    }
    return NULL;
}

/*
 * Set @blk's device model callbacks to @ops.
 * @opaque is the opaque argument to pass to the callbacks.
 * This is for use by device models.
 */
void blk_set_dev_ops(BlockBackend *blk, const BlockDevOps *ops,
                     void *opaque)
{
    GLOBAL_STATE_CODE();
    blk->dev_ops = ops;
    blk->dev_opaque = opaque;

    /* Are we currently quiesced? Should we enforce this right now? */
    if (qatomic_read(&blk->quiesce_counter) && ops && ops->drained_begin) {
        ops->drained_begin(opaque);
    }
}

/*
 * Notify @blk's attached device model of media change.
 *
 * If @load is true, notify of media load. This action can fail, meaning that
 * the medium cannot be loaded. @errp is set then.
 *
 * If @load is false, notify of media eject. This can never fail.
 *
 * Also send DEVICE_TRAY_MOVED events as appropriate.
 */
void blk_dev_change_media_cb(BlockBackend *blk, bool load, Error **errp)
{
    GLOBAL_STATE_CODE();
    if (blk->dev_ops && blk->dev_ops->change_media_cb) {
        bool tray_was_open, tray_is_open;
        Error *local_err = NULL;

        tray_was_open = blk_dev_is_tray_open(blk);
        blk->dev_ops->change_media_cb(blk->dev_opaque, load, &local_err);
        if (local_err) {
            assert(load == true);
            error_propagate(errp, local_err);
            return;
        }
        tray_is_open = blk_dev_is_tray_open(blk);

        if (tray_was_open != tray_is_open) {
            char *id = blk_get_attached_dev_id(blk);
            qapi_event_send_device_tray_moved(blk_name(blk), id, tray_is_open);
            g_free(id);
        }
    }
}

static void blk_root_change_media(BdrvChild *child, bool load)
{
    blk_dev_change_media_cb(child->opaque, load, NULL);
}

/*
 * Does @blk's attached device model have removable media?
 * %true if no device model is attached.
 */
bool blk_dev_has_removable_media(BlockBackend *blk)
{
    GLOBAL_STATE_CODE();
    return !blk->dev || (blk->dev_ops && blk->dev_ops->change_media_cb);
}

/*
 * Does @blk's attached device model have a tray?
 */
bool blk_dev_has_tray(BlockBackend *blk)
{
    IO_CODE();
    return blk->dev_ops && blk->dev_ops->is_tray_open;
}

/*
 * Notify @blk's attached device model of a media eject request.
 * If @force is true, the medium is about to be yanked out forcefully.
 */
void blk_dev_eject_request(BlockBackend *blk, bool force)
{
    GLOBAL_STATE_CODE();
    if (blk->dev_ops && blk->dev_ops->eject_request_cb) {
        blk->dev_ops->eject_request_cb(blk->dev_opaque, force);
    }
}

/*
 * Does @blk's attached device model have a tray, and is it open?
 */
bool blk_dev_is_tray_open(BlockBackend *blk)
{
    IO_CODE();
    if (blk_dev_has_tray(blk)) {
        return blk->dev_ops->is_tray_open(blk->dev_opaque);
    }
    return false;
}

/*
 * Does @blk's attached device model have the medium locked?
 * %false if the device model has no such lock.
 */
bool blk_dev_is_medium_locked(BlockBackend *blk)
{
    GLOBAL_STATE_CODE();
    if (blk->dev_ops && blk->dev_ops->is_medium_locked) {
        return blk->dev_ops->is_medium_locked(blk->dev_opaque);
    }
    return false;
}

/*
 * Notify @blk's attached device model of a backend size change.
 */
static void blk_root_resize(BdrvChild *child)
{
    BlockBackend *blk = child->opaque;

    if (blk->dev_ops && blk->dev_ops->resize_cb) {
        blk->dev_ops->resize_cb(blk->dev_opaque);
    }
}

void blk_iostatus_enable(BlockBackend *blk)
{
    GLOBAL_STATE_CODE();
    blk->iostatus_enabled = true;
    blk->iostatus = BLOCK_DEVICE_IO_STATUS_OK;
}

/* The I/O status is only enabled if the drive explicitly
 * enables it _and_ the VM is configured to stop on errors */
bool blk_iostatus_is_enabled(const BlockBackend *blk)
{
    IO_CODE();
    return (blk->iostatus_enabled &&
           (blk->on_write_error == BLOCKDEV_ON_ERROR_ENOSPC ||
            blk->on_write_error == BLOCKDEV_ON_ERROR_STOP   ||
            blk->on_read_error == BLOCKDEV_ON_ERROR_STOP));
}

BlockDeviceIoStatus blk_iostatus(const BlockBackend *blk)
{
    GLOBAL_STATE_CODE();
    return blk->iostatus;
}

void blk_iostatus_disable(BlockBackend *blk)
{
    GLOBAL_STATE_CODE();
    blk->iostatus_enabled = false;
}

void blk_iostatus_reset(BlockBackend *blk)
{
    GLOBAL_STATE_CODE();
    if (blk_iostatus_is_enabled(blk)) {
        blk->iostatus = BLOCK_DEVICE_IO_STATUS_OK;
    }
}

void blk_iostatus_set_err(BlockBackend *blk, int error)
{
    IO_CODE();
    assert(blk_iostatus_is_enabled(blk));
    if (blk->iostatus == BLOCK_DEVICE_IO_STATUS_OK) {
        blk->iostatus = error == ENOSPC ? BLOCK_DEVICE_IO_STATUS_NOSPACE :
                                          BLOCK_DEVICE_IO_STATUS_FAILED;
    }
}

void blk_set_allow_write_beyond_eof(BlockBackend *blk, bool allow)
{
    IO_CODE();
    blk->allow_write_beyond_eof = allow;
}

void blk_set_allow_aio_context_change(BlockBackend *blk, bool allow)
{
    IO_CODE();
    blk->allow_aio_context_change = allow;
}

void blk_set_disable_request_queuing(BlockBackend *blk, bool disable)
{
    IO_CODE();
    qatomic_set(&blk->disable_request_queuing, disable);
}

static int coroutine_fn GRAPH_RDLOCK
blk_check_byte_request(BlockBackend *blk, int64_t offset, int64_t bytes)
{
    int64_t len;

    if (bytes < 0) {
        return -EIO;
    }

    if (!blk_co_is_available(blk)) {
        return -ENOMEDIUM;
    }

    if (offset < 0) {
        return -EIO;
    }

    if (!blk->allow_write_beyond_eof) {
        len = bdrv_co_getlength(blk_bs(blk));
        if (len < 0) {
            return len;
        }

        if (offset > len || len - offset < bytes) {
            return -EIO;
        }
    }

    return 0;
}

/* Are we currently in a drained section? */
bool blk_in_drain(BlockBackend *blk)
{
    GLOBAL_STATE_CODE(); /* change to IO_OR_GS_CODE(), if necessary */
    return qatomic_read(&blk->quiesce_counter);
}

/* To be called between exactly one pair of blk_inc/dec_in_flight() */
static void coroutine_fn blk_wait_while_drained(BlockBackend *blk)
{
    assert(blk->in_flight > 0);

    if (qatomic_read(&blk->quiesce_counter) &&
        !qatomic_read(&blk->disable_request_queuing)) {
        /*
         * Take lock before decrementing in flight counter so main loop thread
         * waits for us to enqueue ourselves before it can leave the drained
         * section.
         */
        qemu_mutex_lock(&blk->queued_requests_lock);
        blk_dec_in_flight(blk);
        qemu_co_queue_wait(&blk->queued_requests, &blk->queued_requests_lock);
        blk_inc_in_flight(blk);
        qemu_mutex_unlock(&blk->queued_requests_lock);
    }
}

/* To be called between exactly one pair of blk_inc/dec_in_flight() */
static int coroutine_fn
blk_co_do_preadv_part(BlockBackend *blk, int64_t offset, int64_t bytes,
                      QEMUIOVector *qiov, size_t qiov_offset,
                      BdrvRequestFlags flags)
{
    int ret;
    BlockDriverState *bs;
    IO_CODE();

    blk_wait_while_drained(blk);
    GRAPH_RDLOCK_GUARD();

    /* Call blk_bs() only after waiting, the graph may have changed */
    bs = blk_bs(blk);
    trace_blk_co_preadv(blk, bs, offset, bytes, flags);

    ret = blk_check_byte_request(blk, offset, bytes);
    if (ret < 0) {
        return ret;
    }

    bdrv_inc_in_flight(bs);

    /* throttling disk I/O */
    if (blk->public.throttle_group_member.throttle_state) {
        throttle_group_co_io_limits_intercept(&blk->public.throttle_group_member,
                bytes, false);
    }

    ret = bdrv_co_preadv_part(blk->root, offset, bytes, qiov, qiov_offset,
                              flags);
    bdrv_dec_in_flight(bs);
    return ret;
}

int coroutine_fn blk_co_pread(BlockBackend *blk, int64_t offset, int64_t bytes,
                              void *buf, BdrvRequestFlags flags)
{
    QEMUIOVector qiov = QEMU_IOVEC_INIT_BUF(qiov, buf, bytes);
    IO_OR_GS_CODE();

    assert(bytes <= SIZE_MAX);

    return blk_co_preadv(blk, offset, bytes, &qiov, flags);
}

int coroutine_fn blk_co_preadv(BlockBackend *blk, int64_t offset,
                               int64_t bytes, QEMUIOVector *qiov,
                               BdrvRequestFlags flags)
{
    int ret;
    IO_OR_GS_CODE();

    blk_inc_in_flight(blk);
    ret = blk_co_do_preadv_part(blk, offset, bytes, qiov, 0, flags);
    blk_dec_in_flight(blk);

    return ret;
}

int coroutine_fn blk_co_preadv_part(BlockBackend *blk, int64_t offset,
                                    int64_t bytes, QEMUIOVector *qiov,
                                    size_t qiov_offset, BdrvRequestFlags flags)
{
    int ret;
    IO_OR_GS_CODE();

    blk_inc_in_flight(blk);
    ret = blk_co_do_preadv_part(blk, offset, bytes, qiov, qiov_offset, flags);
    blk_dec_in_flight(blk);

    return ret;
}

/* To be called between exactly one pair of blk_inc/dec_in_flight() */
static int coroutine_fn
blk_co_do_pwritev_part(BlockBackend *blk, int64_t offset, int64_t bytes,
                       QEMUIOVector *qiov, size_t qiov_offset,
                       BdrvRequestFlags flags)
{
    int ret;
    BlockDriverState *bs;
    IO_CODE();

    blk_wait_while_drained(blk);
    GRAPH_RDLOCK_GUARD();

    /* Call blk_bs() only after waiting, the graph may have changed */
    bs = blk_bs(blk);
    trace_blk_co_pwritev(blk, bs, offset, bytes, flags);

    ret = blk_check_byte_request(blk, offset, bytes);
    if (ret < 0) {
        return ret;
    }

    bdrv_inc_in_flight(bs);
    /* throttling disk I/O */
    if (blk->public.throttle_group_member.throttle_state) {
        throttle_group_co_io_limits_intercept(&blk->public.throttle_group_member,
                bytes, true);
    }

    if (!blk->enable_write_cache) {
        flags |= BDRV_REQ_FUA;
    }

    ret = bdrv_co_pwritev_part(blk->root, offset, bytes, qiov, qiov_offset,
                               flags);
    bdrv_dec_in_flight(bs);
    return ret;
}

int coroutine_fn blk_co_pwritev_part(BlockBackend *blk, int64_t offset,
                                     int64_t bytes,
                                     QEMUIOVector *qiov, size_t qiov_offset,
                                     BdrvRequestFlags flags)
{
    int ret;
    IO_OR_GS_CODE();

    blk_inc_in_flight(blk);
    ret = blk_co_do_pwritev_part(blk, offset, bytes, qiov, qiov_offset, flags);
    blk_dec_in_flight(blk);

    return ret;
}

int coroutine_fn blk_co_pwrite(BlockBackend *blk, int64_t offset, int64_t bytes,
                               const void *buf, BdrvRequestFlags flags)
{
    QEMUIOVector qiov = QEMU_IOVEC_INIT_BUF(qiov, buf, bytes);
    IO_OR_GS_CODE();

    assert(bytes <= SIZE_MAX);

    return blk_co_pwritev(blk, offset, bytes, &qiov, flags);
}

int coroutine_fn blk_co_pwritev(BlockBackend *blk, int64_t offset,
                                int64_t bytes, QEMUIOVector *qiov,
                                BdrvRequestFlags flags)
{
    IO_OR_GS_CODE();
    return blk_co_pwritev_part(blk, offset, bytes, qiov, 0, flags);
}

int coroutine_fn blk_co_block_status_above(BlockBackend *blk,
                                           BlockDriverState *base,
                                           int64_t offset, int64_t bytes,
                                           int64_t *pnum, int64_t *map,
                                           BlockDriverState **file)
{
    IO_CODE();
    GRAPH_RDLOCK_GUARD();
    return bdrv_co_block_status_above(blk_bs(blk), base, offset, bytes, pnum,
                                      map, file);
}

int coroutine_fn blk_co_is_allocated_above(BlockBackend *blk,
                                           BlockDriverState *base,
                                           bool include_base, int64_t offset,
                                           int64_t bytes, int64_t *pnum)
{
    IO_CODE();
    GRAPH_RDLOCK_GUARD();
    return bdrv_co_is_allocated_above(blk_bs(blk), base, include_base, offset,
                                      bytes, pnum);
}

typedef struct BlkRwCo {
    BlockBackend *blk;
    int64_t offset;
    void *iobuf;
    int ret;
    BdrvRequestFlags flags;
} BlkRwCo;

int blk_make_zero(BlockBackend *blk, BdrvRequestFlags flags)
{
    GLOBAL_STATE_CODE();
    return bdrv_make_zero(blk->root, flags);
}

void blk_inc_in_flight(BlockBackend *blk)
{
    IO_CODE();
    qatomic_inc(&blk->in_flight);
}

void blk_dec_in_flight(BlockBackend *blk)
{
    IO_CODE();
    qatomic_dec(&blk->in_flight);
    aio_wait_kick();
}

static void error_callback_bh(void *opaque)
{
    struct BlockBackendAIOCB *acb = opaque;

    blk_dec_in_flight(acb->blk);
    acb->common.cb(acb->common.opaque, acb->ret);
    qemu_aio_unref(acb);
}

BlockAIOCB *blk_abort_aio_request(BlockBackend *blk,
                                  BlockCompletionFunc *cb,
                                  void *opaque, int ret)
{
    struct BlockBackendAIOCB *acb;
    IO_CODE();

    blk_inc_in_flight(blk);
    acb = blk_aio_get(&block_backend_aiocb_info, blk, cb, opaque);
    acb->blk = blk;
    acb->ret = ret;

    replay_bh_schedule_oneshot_event(blk_get_aio_context(blk),
                                     error_callback_bh, acb);
    return &acb->common;
}

typedef struct BlkAioEmAIOCB {
    BlockAIOCB common;
    BlkRwCo rwco;
    int64_t bytes;
    bool has_returned;
} BlkAioEmAIOCB;

static AioContext *blk_aio_em_aiocb_get_aio_context(BlockAIOCB *acb_)
{
    BlkAioEmAIOCB *acb = container_of(acb_, BlkAioEmAIOCB, common);

    return blk_get_aio_context(acb->rwco.blk);
}

static const AIOCBInfo blk_aio_em_aiocb_info = {
    .aiocb_size         = sizeof(BlkAioEmAIOCB),
    .get_aio_context    = blk_aio_em_aiocb_get_aio_context,
};

static void blk_aio_complete(BlkAioEmAIOCB *acb)
{
    if (acb->has_returned) {
        acb->common.cb(acb->common.opaque, acb->rwco.ret);
        blk_dec_in_flight(acb->rwco.blk);
        qemu_aio_unref(acb);
    }
}

static void blk_aio_complete_bh(void *opaque)
{
    BlkAioEmAIOCB *acb = opaque;
    assert(acb->has_returned);
    blk_aio_complete(acb);
}

static BlockAIOCB *blk_aio_prwv(BlockBackend *blk, int64_t offset,
                                int64_t bytes,
                                void *iobuf, CoroutineEntry co_entry,
                                BdrvRequestFlags flags,
                                BlockCompletionFunc *cb, void *opaque)
{
    BlkAioEmAIOCB *acb;
    Coroutine *co;

    blk_inc_in_flight(blk);
    acb = blk_aio_get(&blk_aio_em_aiocb_info, blk, cb, opaque);
    acb->rwco = (BlkRwCo) {
        .blk    = blk,
        .offset = offset,
        .iobuf  = iobuf,
        .flags  = flags,
        .ret    = NOT_DONE,
    };
    acb->bytes = bytes;
    acb->has_returned = false;

    co = qemu_coroutine_create(co_entry, acb);
    aio_co_enter(blk_get_aio_context(blk), co);

    acb->has_returned = true;
    if (acb->rwco.ret != NOT_DONE) {
        replay_bh_schedule_oneshot_event(blk_get_aio_context(blk),
                                         blk_aio_complete_bh, acb);
    }

    return &acb->common;
}

static void coroutine_fn blk_aio_read_entry(void *opaque)
{
    BlkAioEmAIOCB *acb = opaque;
    BlkRwCo *rwco = &acb->rwco;
    QEMUIOVector *qiov = rwco->iobuf;

    assert(qiov->size == acb->bytes);
    rwco->ret = blk_co_do_preadv_part(rwco->blk, rwco->offset, acb->bytes, qiov,
                                      0, rwco->flags);
    blk_aio_complete(acb);
}

static void coroutine_fn blk_aio_write_entry(void *opaque)
{
    BlkAioEmAIOCB *acb = opaque;
    BlkRwCo *rwco = &acb->rwco;
    QEMUIOVector *qiov = rwco->iobuf;

    assert(!qiov || qiov->size == acb->bytes);
    rwco->ret = blk_co_do_pwritev_part(rwco->blk, rwco->offset, acb->bytes,
                                       qiov, 0, rwco->flags);
    blk_aio_complete(acb);
}

BlockAIOCB *blk_aio_pwrite_zeroes(BlockBackend *blk, int64_t offset,
                                  int64_t bytes, BdrvRequestFlags flags,
                                  BlockCompletionFunc *cb, void *opaque)
{
    IO_CODE();
    return blk_aio_prwv(blk, offset, bytes, NULL, blk_aio_write_entry,
                        flags | BDRV_REQ_ZERO_WRITE, cb, opaque);
}

int64_t coroutine_fn blk_co_getlength(BlockBackend *blk)
{
    IO_CODE();
    GRAPH_RDLOCK_GUARD();

    if (!blk_co_is_available(blk)) {
        return -ENOMEDIUM;
    }

    return bdrv_co_getlength(blk_bs(blk));
}

int64_t coroutine_fn blk_co_nb_sectors(BlockBackend *blk)
{
    BlockDriverState *bs = blk_bs(blk);

    IO_CODE();
    GRAPH_RDLOCK_GUARD();

    if (!bs) {
        return -ENOMEDIUM;
    } else {
        return bdrv_co_nb_sectors(bs);
    }
}

/*
 * This wrapper is written by hand because this function is in the hot I/O path,
 * via blk_get_geometry.
 */
int64_t coroutine_mixed_fn blk_nb_sectors(BlockBackend *blk)
{
    BlockDriverState *bs = blk_bs(blk);

    IO_CODE();

    if (!bs) {
        return -ENOMEDIUM;
    } else {
        return bdrv_nb_sectors(bs);
    }
}

/* return 0 as number of sectors if no device present or error */
void coroutine_fn blk_co_get_geometry(BlockBackend *blk,
                                      uint64_t *nb_sectors_ptr)
{
    int64_t ret = blk_co_nb_sectors(blk);
    *nb_sectors_ptr = ret < 0 ? 0 : ret;
}

/*
 * This wrapper is written by hand because this function is in the hot I/O path.
 */
void coroutine_mixed_fn blk_get_geometry(BlockBackend *blk,
                                         uint64_t *nb_sectors_ptr)
{
    int64_t ret = blk_nb_sectors(blk);
    *nb_sectors_ptr = ret < 0 ? 0 : ret;
}

BlockAIOCB *blk_aio_preadv(BlockBackend *blk, int64_t offset,
                           QEMUIOVector *qiov, BdrvRequestFlags flags,
                           BlockCompletionFunc *cb, void *opaque)
{
    IO_CODE();
    assert((uint64_t)qiov->size <= INT64_MAX);
    return blk_aio_prwv(blk, offset, qiov->size, qiov,
                        blk_aio_read_entry, flags, cb, opaque);
}

BlockAIOCB *blk_aio_pwritev(BlockBackend *blk, int64_t offset,
                            QEMUIOVector *qiov, BdrvRequestFlags flags,
                            BlockCompletionFunc *cb, void *opaque)
{
    IO_CODE();
    assert((uint64_t)qiov->size <= INT64_MAX);
    return blk_aio_prwv(blk, offset, qiov->size, qiov,
                        blk_aio_write_entry, flags, cb, opaque);
}

void blk_aio_cancel(BlockAIOCB *acb)
{
    GLOBAL_STATE_CODE();
    bdrv_aio_cancel(acb);
}

void blk_aio_cancel_async(BlockAIOCB *acb)
{
    IO_CODE();
    bdrv_aio_cancel_async(acb);
}

/* To be called between exactly one pair of blk_inc/dec_in_flight() */
static int coroutine_fn
blk_co_do_ioctl(BlockBackend *blk, unsigned long int req, void *buf)
{
    IO_CODE();

    blk_wait_while_drained(blk);
    GRAPH_RDLOCK_GUARD();

    if (!blk_co_is_available(blk)) {
        return -ENOMEDIUM;
    }

    return bdrv_co_ioctl(blk_bs(blk), req, buf);
}

int coroutine_fn blk_co_ioctl(BlockBackend *blk, unsigned long int req,
                              void *buf)
{
    int ret;
    IO_OR_GS_CODE();

    blk_inc_in_flight(blk);
    ret = blk_co_do_ioctl(blk, req, buf);
    blk_dec_in_flight(blk);

    return ret;
}

static void coroutine_fn blk_aio_ioctl_entry(void *opaque)
{
    BlkAioEmAIOCB *acb = opaque;
    BlkRwCo *rwco = &acb->rwco;

    rwco->ret = blk_co_do_ioctl(rwco->blk, rwco->offset, rwco->iobuf);

    blk_aio_complete(acb);
}

BlockAIOCB *blk_aio_ioctl(BlockBackend *blk, unsigned long int req, void *buf,
                          BlockCompletionFunc *cb, void *opaque)
{
    IO_CODE();
    return blk_aio_prwv(blk, req, 0, buf, blk_aio_ioctl_entry, 0, cb, opaque);
}

/* To be called between exactly one pair of blk_inc/dec_in_flight() */
static int coroutine_fn
blk_co_do_pdiscard(BlockBackend *blk, int64_t offset, int64_t bytes)
{
    int ret;
    IO_CODE();

    blk_wait_while_drained(blk);
    GRAPH_RDLOCK_GUARD();

    ret = blk_check_byte_request(blk, offset, bytes);
    if (ret < 0) {
        return ret;
    }

    return bdrv_co_pdiscard(blk->root, offset, bytes);
}

static void coroutine_fn blk_aio_pdiscard_entry(void *opaque)
{
    BlkAioEmAIOCB *acb = opaque;
    BlkRwCo *rwco = &acb->rwco;

    rwco->ret = blk_co_do_pdiscard(rwco->blk, rwco->offset, acb->bytes);
    blk_aio_complete(acb);
}

BlockAIOCB *blk_aio_pdiscard(BlockBackend *blk,
                             int64_t offset, int64_t bytes,
                             BlockCompletionFunc *cb, void *opaque)
{
    IO_CODE();
    return blk_aio_prwv(blk, offset, bytes, NULL, blk_aio_pdiscard_entry, 0,
                        cb, opaque);
}

int coroutine_fn blk_co_pdiscard(BlockBackend *blk, int64_t offset,
                                 int64_t bytes)
{
    int ret;
    IO_OR_GS_CODE();

    blk_inc_in_flight(blk);
    ret = blk_co_do_pdiscard(blk, offset, bytes);
    blk_dec_in_flight(blk);

    return ret;
}

/* To be called between exactly one pair of blk_inc/dec_in_flight() */
static int coroutine_fn blk_co_do_flush(BlockBackend *blk)
{
    IO_CODE();
    blk_wait_while_drained(blk);
    GRAPH_RDLOCK_GUARD();

    if (!blk_co_is_available(blk)) {
        return -ENOMEDIUM;
    }

    return bdrv_co_flush(blk_bs(blk));
}

static void coroutine_fn blk_aio_flush_entry(void *opaque)
{
    BlkAioEmAIOCB *acb = opaque;
    BlkRwCo *rwco = &acb->rwco;

    rwco->ret = blk_co_do_flush(rwco->blk);
    blk_aio_complete(acb);
}

BlockAIOCB *blk_aio_flush(BlockBackend *blk,
                          BlockCompletionFunc *cb, void *opaque)
{
    IO_CODE();
    return blk_aio_prwv(blk, 0, 0, NULL, blk_aio_flush_entry, 0, cb, opaque);
}

int coroutine_fn blk_co_flush(BlockBackend *blk)
{
    int ret;
    IO_OR_GS_CODE();

    blk_inc_in_flight(blk);
    ret = blk_co_do_flush(blk);
    blk_dec_in_flight(blk);

    return ret;
}

static void coroutine_fn blk_aio_zone_report_entry(void *opaque)
{
    BlkAioEmAIOCB *acb = opaque;
    BlkRwCo *rwco = &acb->rwco;

    rwco->ret = blk_co_zone_report(rwco->blk, rwco->offset,
                                   (unsigned int*)(uintptr_t)acb->bytes,
                                   rwco->iobuf);
    blk_aio_complete(acb);
}

BlockAIOCB *blk_aio_zone_report(BlockBackend *blk, int64_t offset,
                                unsigned int *nr_zones,
                                BlockZoneDescriptor  *zones,
                                BlockCompletionFunc *cb, void *opaque)
{
    BlkAioEmAIOCB *acb;
    Coroutine *co;
    IO_CODE();

    blk_inc_in_flight(blk);
    acb = blk_aio_get(&blk_aio_em_aiocb_info, blk, cb, opaque);
    acb->rwco = (BlkRwCo) {
        .blk    = blk,
        .offset = offset,
        .iobuf  = zones,
        .ret    = NOT_DONE,
    };
    acb->bytes = (int64_t)(uintptr_t)nr_zones,
    acb->has_returned = false;

    co = qemu_coroutine_create(blk_aio_zone_report_entry, acb);
    aio_co_enter(blk_get_aio_context(blk), co);

    acb->has_returned = true;
    if (acb->rwco.ret != NOT_DONE) {
        replay_bh_schedule_oneshot_event(blk_get_aio_context(blk),
                                         blk_aio_complete_bh, acb);
    }

    return &acb->common;
}

static void coroutine_fn blk_aio_zone_mgmt_entry(void *opaque)
{
    BlkAioEmAIOCB *acb = opaque;
    BlkRwCo *rwco = &acb->rwco;

    rwco->ret = blk_co_zone_mgmt(rwco->blk,
                                 (BlockZoneOp)(uintptr_t)rwco->iobuf,
                                 rwco->offset, acb->bytes);
    blk_aio_complete(acb);
}

BlockAIOCB *blk_aio_zone_mgmt(BlockBackend *blk, BlockZoneOp op,
                              int64_t offset, int64_t len,
                              BlockCompletionFunc *cb, void *opaque) {
    BlkAioEmAIOCB *acb;
    Coroutine *co;
    IO_CODE();

    blk_inc_in_flight(blk);
    acb = blk_aio_get(&blk_aio_em_aiocb_info, blk, cb, opaque);
    acb->rwco = (BlkRwCo) {
        .blk    = blk,
        .offset = offset,
        .iobuf  = (void *)(uintptr_t)op,
        .ret    = NOT_DONE,
    };
    acb->bytes = len;
    acb->has_returned = false;

    co = qemu_coroutine_create(blk_aio_zone_mgmt_entry, acb);
    aio_co_enter(blk_get_aio_context(blk), co);

    acb->has_returned = true;
    if (acb->rwco.ret != NOT_DONE) {
        replay_bh_schedule_oneshot_event(blk_get_aio_context(blk),
                                         blk_aio_complete_bh, acb);
    }

    return &acb->common;
}

static void coroutine_fn blk_aio_zone_append_entry(void *opaque)
{
    BlkAioEmAIOCB *acb = opaque;
    BlkRwCo *rwco = &acb->rwco;

    rwco->ret = blk_co_zone_append(rwco->blk, (int64_t *)(uintptr_t)acb->bytes,
                                   rwco->iobuf, rwco->flags);
    blk_aio_complete(acb);
}

BlockAIOCB *blk_aio_zone_append(BlockBackend *blk, int64_t *offset,
                                QEMUIOVector *qiov, BdrvRequestFlags flags,
                                BlockCompletionFunc *cb, void *opaque) {
    BlkAioEmAIOCB *acb;
    Coroutine *co;
    IO_CODE();

    blk_inc_in_flight(blk);
    acb = blk_aio_get(&blk_aio_em_aiocb_info, blk, cb, opaque);
    acb->rwco = (BlkRwCo) {
        .blk    = blk,
        .ret    = NOT_DONE,
        .flags  = flags,
        .iobuf  = qiov,
    };
    acb->bytes = (int64_t)(uintptr_t)offset;
    acb->has_returned = false;

    co = qemu_coroutine_create(blk_aio_zone_append_entry, acb);
    aio_co_enter(blk_get_aio_context(blk), co);
    acb->has_returned = true;
    if (acb->rwco.ret != NOT_DONE) {
        replay_bh_schedule_oneshot_event(blk_get_aio_context(blk),
                                         blk_aio_complete_bh, acb);
    }

    return &acb->common;
}

/*
 * Send a zone_report command.
 * offset is a byte offset from the start of the device. No alignment
 * required for offset.
 * nr_zones represents IN maximum and OUT actual.
 */
int coroutine_fn blk_co_zone_report(BlockBackend *blk, int64_t offset,
                                    unsigned int *nr_zones,
                                    BlockZoneDescriptor *zones)
{
    int ret;
    IO_CODE();

    blk_inc_in_flight(blk); /* increase before waiting */
    blk_wait_while_drained(blk);
    GRAPH_RDLOCK_GUARD();
    if (!blk_is_available(blk)) {
        blk_dec_in_flight(blk);
        return -ENOMEDIUM;
    }
    ret = bdrv_co_zone_report(blk_bs(blk), offset, nr_zones, zones);
    blk_dec_in_flight(blk);
    return ret;
}

/*
 * Send a zone_management command.
 * op is the zone operation;
 * offset is the byte offset from the start of the zoned device;
 * len is the maximum number of bytes the command should operate on. It
 * should be aligned with the device zone size.
 */
int coroutine_fn blk_co_zone_mgmt(BlockBackend *blk, BlockZoneOp op,
        int64_t offset, int64_t len)
{
    int ret;
    IO_CODE();

    blk_inc_in_flight(blk);
    blk_wait_while_drained(blk);
    GRAPH_RDLOCK_GUARD();

    ret = blk_check_byte_request(blk, offset, len);
    if (ret < 0) {
        blk_dec_in_flight(blk);
        return ret;
    }

    ret = bdrv_co_zone_mgmt(blk_bs(blk), op, offset, len);
    blk_dec_in_flight(blk);
    return ret;
}

/*
 * Send a zone_append command.
 */
int coroutine_fn blk_co_zone_append(BlockBackend *blk, int64_t *offset,
        QEMUIOVector *qiov, BdrvRequestFlags flags)
{
    int ret;
    IO_CODE();

    blk_inc_in_flight(blk);
    blk_wait_while_drained(blk);
    GRAPH_RDLOCK_GUARD();
    if (!blk_is_available(blk)) {
        blk_dec_in_flight(blk);
        return -ENOMEDIUM;
    }

    ret = bdrv_co_zone_append(blk_bs(blk), offset, qiov, flags);
    blk_dec_in_flight(blk);
    return ret;
}

void blk_drain(BlockBackend *blk)
{
    BlockDriverState *bs = blk_bs(blk);
    GLOBAL_STATE_CODE();

    if (bs) {
        bdrv_ref(bs);
        bdrv_drained_begin(bs);
    }

    /* We may have -ENOMEDIUM completions in flight */
    AIO_WAIT_WHILE(blk_get_aio_context(blk),
                   qatomic_read(&blk->in_flight) > 0);

    if (bs) {
        bdrv_drained_end(bs);
        bdrv_unref(bs);
    }
}

void blk_drain_all(void)
{
    BlockBackend *blk = NULL;

    GLOBAL_STATE_CODE();

    bdrv_drain_all_begin();

    while ((blk = blk_all_next(blk)) != NULL) {
        /* We may have -ENOMEDIUM completions in flight */
        AIO_WAIT_WHILE_UNLOCKED(NULL, qatomic_read(&blk->in_flight) > 0);
    }

    bdrv_drain_all_end();
}

void blk_set_on_error(BlockBackend *blk, BlockdevOnError on_read_error,
                      BlockdevOnError on_write_error)
{
    GLOBAL_STATE_CODE();
    blk->on_read_error = on_read_error;
    blk->on_write_error = on_write_error;
}

BlockdevOnError blk_get_on_error(BlockBackend *blk, bool is_read)
{
    IO_CODE();
    return is_read ? blk->on_read_error : blk->on_write_error;
}

BlockErrorAction blk_get_error_action(BlockBackend *blk, bool is_read,
                                      int error)
{
    BlockdevOnError on_err = blk_get_on_error(blk, is_read);
    IO_CODE();

    switch (on_err) {
    case BLOCKDEV_ON_ERROR_ENOSPC:
        return (error == ENOSPC) ?
               BLOCK_ERROR_ACTION_STOP : BLOCK_ERROR_ACTION_REPORT;
    case BLOCKDEV_ON_ERROR_STOP:
        return BLOCK_ERROR_ACTION_STOP;
    case BLOCKDEV_ON_ERROR_REPORT:
        return BLOCK_ERROR_ACTION_REPORT;
    case BLOCKDEV_ON_ERROR_IGNORE:
        return BLOCK_ERROR_ACTION_IGNORE;
    case BLOCKDEV_ON_ERROR_AUTO:
    default:
        abort();
    }
}

static void send_qmp_error_event(BlockBackend *blk,
                                 BlockErrorAction action,
                                 bool is_read, int error)
{
    IoOperationType optype;
    BlockDriverState *bs = blk_bs(blk);

    optype = is_read ? IO_OPERATION_TYPE_READ : IO_OPERATION_TYPE_WRITE;
    qapi_event_send_block_io_error(blk_name(blk),
                                   bs ? bdrv_get_node_name(bs) : NULL, optype,
                                   action, blk_iostatus_is_enabled(blk),
                                   error == ENOSPC, strerror(error));
}

/* This is done by device models because, while the block layer knows
 * about the error, it does not know whether an operation comes from
 * the device or the block layer (from a job, for example).
 */
void blk_error_action(BlockBackend *blk, BlockErrorAction action,
                      bool is_read, int error)
{
    assert(error >= 0);
    IO_CODE();

    if (action == BLOCK_ERROR_ACTION_STOP) {
        /* First set the iostatus, so that "info block" returns an iostatus
         * that matches the events raised so far (an additional error iostatus
         * is fine, but not a lost one).
         */
        blk_iostatus_set_err(blk, error);

        /* Then raise the request to stop the VM and the event.
         * qemu_system_vmstop_request_prepare has two effects.  First,
         * it ensures that the STOP event always comes after the
         * BLOCK_IO_ERROR event.  Second, it ensures that even if management
         * can observe the STOP event and do a "cont" before the STOP
         * event is issued, the VM will not stop.  In this case, vm_start()
         * also ensures that the STOP/RESUME pair of events is emitted.
         */
        qemu_system_vmstop_request_prepare();
        send_qmp_error_event(blk, action, is_read, error);
        qemu_system_vmstop_request(RUN_STATE_IO_ERROR);
    } else {
        send_qmp_error_event(blk, action, is_read, error);
    }
}

/*
 * Returns true if the BlockBackend can support taking write permissions
 * (because its root node is not read-only).
 */
bool blk_supports_write_perm(BlockBackend *blk)
{
    BlockDriverState *bs = blk_bs(blk);
    GLOBAL_STATE_CODE();

    if (bs) {
        return !bdrv_is_read_only(bs);
    } else {
        return blk->root_state.open_flags & BDRV_O_RDWR;
    }
}

/*
 * Returns true if the BlockBackend can be written to in its current
 * configuration (i.e. if write permission have been requested)
 */
bool blk_is_writable(BlockBackend *blk)
{
    IO_CODE();
    return blk->perm & BLK_PERM_WRITE;
}

bool blk_is_sg(BlockBackend *blk)
{
    BlockDriverState *bs = blk_bs(blk);
    GLOBAL_STATE_CODE();

    if (!bs) {
        return false;
    }

    return bdrv_is_sg(bs);
}

bool blk_enable_write_cache(BlockBackend *blk)
{
    IO_CODE();
    return blk->enable_write_cache;
}

void blk_set_enable_write_cache(BlockBackend *blk, bool wce)
{
    IO_CODE();
    blk->enable_write_cache = wce;
}

void blk_activate(BlockBackend *blk, Error **errp)
{
    BlockDriverState *bs = blk_bs(blk);
    GLOBAL_STATE_CODE();

    if (!bs) {
        error_setg(errp, "Device '%s' has no medium", blk->name);
        return;
    }

    /*
     * Migration code can call this function in coroutine context, so leave
     * coroutine context if necessary.
     */
    if (qemu_in_coroutine()) {
        bdrv_co_activate(bs, errp);
    } else {
        bdrv_activate(bs, errp);
    }
}

bool coroutine_fn blk_co_is_inserted(BlockBackend *blk)
{
    BlockDriverState *bs = blk_bs(blk);
    IO_CODE();
    assert_bdrv_graph_readable();

    return bs && bdrv_co_is_inserted(bs);
}

bool coroutine_fn blk_co_is_available(BlockBackend *blk)
{
    IO_CODE();
    return blk_co_is_inserted(blk) && !blk_dev_is_tray_open(blk);
}

void coroutine_fn blk_co_lock_medium(BlockBackend *blk, bool locked)
{
    BlockDriverState *bs = blk_bs(blk);
    IO_CODE();
    GRAPH_RDLOCK_GUARD();

    if (bs) {
        bdrv_co_lock_medium(bs, locked);
    }
}

void coroutine_fn blk_co_eject(BlockBackend *blk, bool eject_flag)
{
    BlockDriverState *bs = blk_bs(blk);
    char *id;
    IO_CODE();
    GRAPH_RDLOCK_GUARD();

    if (bs) {
        bdrv_co_eject(bs, eject_flag);
    }

    /* Whether or not we ejected on the backend,
     * the frontend experienced a tray event. */
    id = blk_get_attached_dev_id(blk);
    qapi_event_send_device_tray_moved(blk_name(blk), id,
                                      eject_flag);
    g_free(id);
}

int blk_get_flags(BlockBackend *blk)
{
    BlockDriverState *bs = blk_bs(blk);
    GLOBAL_STATE_CODE();

    if (bs) {
        return bdrv_get_flags(bs);
    } else {
        return blk->root_state.open_flags;
    }
}

/* Returns the minimum request alignment, in bytes; guaranteed nonzero */
uint32_t blk_get_request_alignment(BlockBackend *blk)
{
    BlockDriverState *bs = blk_bs(blk);
    IO_CODE();
    return bs ? bs->bl.request_alignment : BDRV_SECTOR_SIZE;
}

/* Returns the maximum hardware transfer length, in bytes; guaranteed nonzero */
uint64_t blk_get_max_hw_transfer(BlockBackend *blk)
{
    BlockDriverState *bs = blk_bs(blk);
    uint64_t max = INT_MAX;
    IO_CODE();

    if (bs) {
        max = MIN_NON_ZERO(max, bs->bl.max_hw_transfer);
        max = MIN_NON_ZERO(max, bs->bl.max_transfer);
    }
    return ROUND_DOWN(max, blk_get_request_alignment(blk));
}

/* Returns the maximum transfer length, in bytes; guaranteed nonzero */
uint32_t blk_get_max_transfer(BlockBackend *blk)
{
    BlockDriverState *bs = blk_bs(blk);
    uint32_t max = INT_MAX;
    IO_CODE();

    if (bs) {
        max = MIN_NON_ZERO(max, bs->bl.max_transfer);
    }
    return ROUND_DOWN(max, blk_get_request_alignment(blk));
}

int blk_get_max_hw_iov(BlockBackend *blk)
{
    IO_CODE();
    return MIN_NON_ZERO(blk->root->bs->bl.max_hw_iov,
                        blk->root->bs->bl.max_iov);
}

int blk_get_max_iov(BlockBackend *blk)
{
    IO_CODE();
    return blk->root->bs->bl.max_iov;
}

void *blk_try_blockalign(BlockBackend *blk, size_t size)
{
    IO_CODE();
    return qemu_try_blockalign(blk ? blk_bs(blk) : NULL, size);
}

void *blk_blockalign(BlockBackend *blk, size_t size)
{
    IO_CODE();
    return qemu_blockalign(blk ? blk_bs(blk) : NULL, size);
}

bool blk_op_is_blocked(BlockBackend *blk, BlockOpType op, Error **errp)
{
    BlockDriverState *bs = blk_bs(blk);
    GLOBAL_STATE_CODE();

    if (!bs) {
        return false;
    }

    return bdrv_op_is_blocked(bs, op, errp);
}

void blk_op_unblock(BlockBackend *blk, BlockOpType op, Error *reason)
{
    BlockDriverState *bs = blk_bs(blk);
    GLOBAL_STATE_CODE();

    if (bs) {
        bdrv_op_unblock(bs, op, reason);
    }
}

void blk_op_block_all(BlockBackend *blk, Error *reason)
{
    BlockDriverState *bs = blk_bs(blk);
    GLOBAL_STATE_CODE();

    if (bs) {
        bdrv_op_block_all(bs, reason);
    }
}

void blk_op_unblock_all(BlockBackend *blk, Error *reason)
{
    BlockDriverState *bs = blk_bs(blk);
    GLOBAL_STATE_CODE();

    if (bs) {
        bdrv_op_unblock_all(bs, reason);
    }
}

AioContext *blk_get_aio_context(BlockBackend *blk)
{
    BlockDriverState *bs;
    IO_CODE();

    if (!blk) {
        return qemu_get_aio_context();
    }

    bs = blk_bs(blk);
    if (bs) {
        AioContext *ctx = bdrv_get_aio_context(blk_bs(blk));
        assert(ctx == blk->ctx);
    }

    return blk->ctx;
}

static AioContext *blk_aiocb_get_aio_context(BlockAIOCB *acb)
{
    BlockBackendAIOCB *blk_acb = DO_UPCAST(BlockBackendAIOCB, common, acb);
    return blk_get_aio_context(blk_acb->blk);
}

int blk_set_aio_context(BlockBackend *blk, AioContext *new_context,
                        Error **errp)
{
    bool old_allow_change;
    BlockDriverState *bs = blk_bs(blk);
    int ret;

    GLOBAL_STATE_CODE();

    if (!bs) {
        blk->ctx = new_context;
        return 0;
    }

    bdrv_ref(bs);

    old_allow_change = blk->allow_aio_context_change;
    blk->allow_aio_context_change = true;

    ret = bdrv_try_change_aio_context(bs, new_context, NULL, errp);

    blk->allow_aio_context_change = old_allow_change;

    bdrv_unref(bs);
    return ret;
}

typedef struct BdrvStateBlkRootContext {
    AioContext *new_ctx;
    BlockBackend *blk;
} BdrvStateBlkRootContext;

static void blk_root_set_aio_ctx_commit(void *opaque)
{
    BdrvStateBlkRootContext *s = opaque;
    BlockBackend *blk = s->blk;
    AioContext *new_context = s->new_ctx;
    ThrottleGroupMember *tgm = &blk->public.throttle_group_member;

    blk->ctx = new_context;
    if (tgm->throttle_state) {
        throttle_group_detach_aio_context(tgm);
        throttle_group_attach_aio_context(tgm, new_context);
    }
}

static TransactionActionDrv set_blk_root_context = {
    .commit = blk_root_set_aio_ctx_commit,
    .clean = g_free,
};

static bool blk_root_change_aio_ctx(BdrvChild *child, AioContext *ctx,
                                    GHashTable *visited, Transaction *tran,
                                    Error **errp)
{
    BlockBackend *blk = child->opaque;
    BdrvStateBlkRootContext *s;

    if (!blk->allow_aio_context_change) {
        /*
         * Manually created BlockBackends (those with a name) that are not
         * attached to anything can change their AioContext without updating
         * their user; return an error for others.
         */
        if (!blk->name || blk->dev) {
            /* TODO Add BB name/QOM path */
            error_setg(errp, "Cannot change iothread of active block backend");
            return false;
        }
    }

    s = g_new(BdrvStateBlkRootContext, 1);
    *s = (BdrvStateBlkRootContext) {
        .new_ctx = ctx,
        .blk = blk,
    };

    tran_add(tran, &set_blk_root_context, s);
    return true;
}

void blk_add_aio_context_notifier(BlockBackend *blk,
        void (*attached_aio_context)(AioContext *new_context, void *opaque),
        void (*detach_aio_context)(void *opaque), void *opaque)
{
    BlockBackendAioNotifier *notifier;
    BlockDriverState *bs = blk_bs(blk);
    GLOBAL_STATE_CODE();

    notifier = g_new(BlockBackendAioNotifier, 1);
    notifier->attached_aio_context = attached_aio_context;
    notifier->detach_aio_context = detach_aio_context;
    notifier->opaque = opaque;
    QLIST_INSERT_HEAD(&blk->aio_notifiers, notifier, list);

    if (bs) {
        bdrv_add_aio_context_notifier(bs, attached_aio_context,
                                      detach_aio_context, opaque);
    }
}

void blk_remove_aio_context_notifier(BlockBackend *blk,
                                     void (*attached_aio_context)(AioContext *,
                                                                  void *),
                                     void (*detach_aio_context)(void *),
                                     void *opaque)
{
    BlockBackendAioNotifier *notifier;
    BlockDriverState *bs = blk_bs(blk);

    GLOBAL_STATE_CODE();

    if (bs) {
        bdrv_remove_aio_context_notifier(bs, attached_aio_context,
                                         detach_aio_context, opaque);
    }

    QLIST_FOREACH(notifier, &blk->aio_notifiers, list) {
        if (notifier->attached_aio_context == attached_aio_context &&
            notifier->detach_aio_context == detach_aio_context &&
            notifier->opaque == opaque) {
            QLIST_REMOVE(notifier, list);
            g_free(notifier);
            return;
        }
    }

    abort();
}

void blk_add_remove_bs_notifier(BlockBackend *blk, Notifier *notify)
{
    GLOBAL_STATE_CODE();
    notifier_list_add(&blk->remove_bs_notifiers, notify);
}

void blk_add_insert_bs_notifier(BlockBackend *blk, Notifier *notify)
{
    GLOBAL_STATE_CODE();
    notifier_list_add(&blk->insert_bs_notifiers, notify);
}

BlockAcctStats *blk_get_stats(BlockBackend *blk)
{
    IO_CODE();
    return &blk->stats;
}

void *blk_aio_get(const AIOCBInfo *aiocb_info, BlockBackend *blk,
                  BlockCompletionFunc *cb, void *opaque)
{
    IO_CODE();
    return qemu_aio_get(aiocb_info, blk_bs(blk), cb, opaque);
}

int coroutine_fn blk_co_pwrite_zeroes(BlockBackend *blk, int64_t offset,
                                      int64_t bytes, BdrvRequestFlags flags)
{
    IO_OR_GS_CODE();
    return blk_co_pwritev(blk, offset, bytes, NULL,
                          flags | BDRV_REQ_ZERO_WRITE);
}

int coroutine_fn blk_co_pwrite_compressed(BlockBackend *blk, int64_t offset,
                                          int64_t bytes, const void *buf)
{
    QEMUIOVector qiov = QEMU_IOVEC_INIT_BUF(qiov, buf, bytes);
    IO_OR_GS_CODE();
    return blk_co_pwritev_part(blk, offset, bytes, &qiov, 0,
                               BDRV_REQ_WRITE_COMPRESSED);
}

int coroutine_fn blk_co_truncate(BlockBackend *blk, int64_t offset, bool exact,
                                 PreallocMode prealloc, BdrvRequestFlags flags,
                                 Error **errp)
{
    IO_OR_GS_CODE();
    GRAPH_RDLOCK_GUARD();
    if (!blk_co_is_available(blk)) {
        error_setg(errp, "No medium inserted");
        return -ENOMEDIUM;
    }

    return bdrv_co_truncate(blk->root, offset, exact, prealloc, flags, errp);
}

int blk_save_vmstate(BlockBackend *blk, const uint8_t *buf,
                     int64_t pos, int size)
{
    int ret;
    GLOBAL_STATE_CODE();

    if (!blk_is_available(blk)) {
        return -ENOMEDIUM;
    }

    ret = bdrv_save_vmstate(blk_bs(blk), buf, pos, size);
    if (ret < 0) {
        return ret;
    }

    if (ret == size && !blk->enable_write_cache) {
        ret = bdrv_flush(blk_bs(blk));
    }

    return ret < 0 ? ret : size;
}

int blk_load_vmstate(BlockBackend *blk, uint8_t *buf, int64_t pos, int size)
{
    GLOBAL_STATE_CODE();
    if (!blk_is_available(blk)) {
        return -ENOMEDIUM;
    }

    return bdrv_load_vmstate(blk_bs(blk), buf, pos, size);
}

int blk_probe_blocksizes(BlockBackend *blk, BlockSizes *bsz)
{
    GLOBAL_STATE_CODE();
    if (!blk_is_available(blk)) {
        return -ENOMEDIUM;
    }

    return bdrv_probe_blocksizes(blk_bs(blk), bsz);
}

int blk_probe_geometry(BlockBackend *blk, HDGeometry *geo)
{
    GLOBAL_STATE_CODE();
    if (!blk_is_available(blk)) {
        return -ENOMEDIUM;
    }

    return bdrv_probe_geometry(blk_bs(blk), geo);
}

/*
 * Updates the BlockBackendRootState object with data from the currently
 * attached BlockDriverState.
 */
void blk_update_root_state(BlockBackend *blk)
{
    GLOBAL_STATE_CODE();
    assert(blk->root);

    blk->root_state.open_flags    = blk->root->bs->open_flags;
    blk->root_state.detect_zeroes = blk->root->bs->detect_zeroes;
}

/*
 * Returns the detect-zeroes setting to be used for bdrv_open() of a
 * BlockDriverState which is supposed to inherit the root state.
 */
bool blk_get_detect_zeroes_from_root_state(BlockBackend *blk)
{
    GLOBAL_STATE_CODE();
    return blk->root_state.detect_zeroes;
}

/*
 * Returns the flags to be used for bdrv_open() of a BlockDriverState which is
 * supposed to inherit the root state.
 */
int blk_get_open_flags_from_root_state(BlockBackend *blk)
{
    GLOBAL_STATE_CODE();
    return blk->root_state.open_flags;
}

BlockBackendRootState *blk_get_root_state(BlockBackend *blk)
{
    GLOBAL_STATE_CODE();
    return &blk->root_state;
}

int blk_commit_all(void)
{
    BlockBackend *blk = NULL;
    GLOBAL_STATE_CODE();

    while ((blk = blk_all_next(blk)) != NULL) {
        AioContext *aio_context = blk_get_aio_context(blk);
        BlockDriverState *unfiltered_bs = bdrv_skip_filters(blk_bs(blk));

        aio_context_acquire(aio_context);
        if (blk_is_inserted(blk) && bdrv_cow_child(unfiltered_bs)) {
            int ret;

            ret = bdrv_commit(unfiltered_bs);
            if (ret < 0) {
                aio_context_release(aio_context);
                return ret;
            }
        }
        aio_context_release(aio_context);
    }
    return 0;
}


/* throttling disk I/O limits */
void blk_set_io_limits(BlockBackend *blk, ThrottleConfig *cfg)
{
    GLOBAL_STATE_CODE();
    throttle_group_config(&blk->public.throttle_group_member, cfg);
}

void blk_io_limits_disable(BlockBackend *blk)
{
    BlockDriverState *bs = blk_bs(blk);
    ThrottleGroupMember *tgm = &blk->public.throttle_group_member;
    assert(tgm->throttle_state);
    GLOBAL_STATE_CODE();
    if (bs) {
        bdrv_ref(bs);
        bdrv_drained_begin(bs);
    }
    throttle_group_unregister_tgm(tgm);
    if (bs) {
        bdrv_drained_end(bs);
        bdrv_unref(bs);
    }
}

/* should be called before blk_set_io_limits if a limit is set */
void blk_io_limits_enable(BlockBackend *blk, const char *group)
{
    assert(!blk->public.throttle_group_member.throttle_state);
    GLOBAL_STATE_CODE();
    throttle_group_register_tgm(&blk->public.throttle_group_member,
                                group, blk_get_aio_context(blk));
}

void blk_io_limits_update_group(BlockBackend *blk, const char *group)
{
    GLOBAL_STATE_CODE();
    /* this BB is not part of any group */
    if (!blk->public.throttle_group_member.throttle_state) {
        return;
    }

    /* this BB is a part of the same group than the one we want */
    if (!g_strcmp0(throttle_group_get_name(&blk->public.throttle_group_member),
                group)) {
        return;
    }

    /* need to change the group this bs belong to */
    blk_io_limits_disable(blk);
    blk_io_limits_enable(blk, group);
}

static void blk_root_drained_begin(BdrvChild *child)
{
    BlockBackend *blk = child->opaque;
    ThrottleGroupMember *tgm = &blk->public.throttle_group_member;

    if (qatomic_fetch_inc(&blk->quiesce_counter) == 0) {
        if (blk->dev_ops && blk->dev_ops->drained_begin) {
            blk->dev_ops->drained_begin(blk->dev_opaque);
        }
    }

    /* Note that blk->root may not be accessible here yet if we are just
     * attaching to a BlockDriverState that is drained. Use child instead. */

    if (qatomic_fetch_inc(&tgm->io_limits_disabled) == 0) {
        throttle_group_restart_tgm(tgm);
    }
}

static bool blk_root_drained_poll(BdrvChild *child)
{
    BlockBackend *blk = child->opaque;
    bool busy = false;
    assert(qatomic_read(&blk->quiesce_counter));

    if (blk->dev_ops && blk->dev_ops->drained_poll) {
        busy = blk->dev_ops->drained_poll(blk->dev_opaque);
    }
    return busy || !!blk->in_flight;
}

static void blk_root_drained_end(BdrvChild *child)
{
    BlockBackend *blk = child->opaque;
    assert(qatomic_read(&blk->quiesce_counter));

    assert(blk->public.throttle_group_member.io_limits_disabled);
    qatomic_dec(&blk->public.throttle_group_member.io_limits_disabled);

    if (qatomic_fetch_dec(&blk->quiesce_counter) == 1) {
        if (blk->dev_ops && blk->dev_ops->drained_end) {
            blk->dev_ops->drained_end(blk->dev_opaque);
        }
        qemu_mutex_lock(&blk->queued_requests_lock);
        while (qemu_co_enter_next(&blk->queued_requests,
                                  &blk->queued_requests_lock)) {
            /* Resume all queued requests */
        }
        qemu_mutex_unlock(&blk->queued_requests_lock);
    }
}

bool blk_register_buf(BlockBackend *blk, void *host, size_t size, Error **errp)
{
    BlockDriverState *bs = blk_bs(blk);

    GLOBAL_STATE_CODE();

    if (bs) {
        return bdrv_register_buf(bs, host, size, errp);
    }
    return true;
}

void blk_unregister_buf(BlockBackend *blk, void *host, size_t size)
{
    BlockDriverState *bs = blk_bs(blk);

    GLOBAL_STATE_CODE();

    if (bs) {
        bdrv_unregister_buf(bs, host, size);
    }
}

int coroutine_fn blk_co_copy_range(BlockBackend *blk_in, int64_t off_in,
                                   BlockBackend *blk_out, int64_t off_out,
                                   int64_t bytes, BdrvRequestFlags read_flags,
                                   BdrvRequestFlags write_flags)
{
    int r;
    IO_CODE();
    GRAPH_RDLOCK_GUARD();

    r = blk_check_byte_request(blk_in, off_in, bytes);
    if (r) {
        return r;
    }
    r = blk_check_byte_request(blk_out, off_out, bytes);
    if (r) {
        return r;
    }

    return bdrv_co_copy_range(blk_in->root, off_in,
                              blk_out->root, off_out,
                              bytes, read_flags, write_flags);
}

const BdrvChild *blk_root(BlockBackend *blk)
{
    GLOBAL_STATE_CODE();
    return blk->root;
}

int blk_make_empty(BlockBackend *blk, Error **errp)
{
    GLOBAL_STATE_CODE();
    if (!blk_is_available(blk)) {
        error_setg(errp, "No medium inserted");
        return -ENOMEDIUM;
    }

    return bdrv_make_empty(blk->root, errp);
}
