126f54e9aSMarkus Armbruster /* 226f54e9aSMarkus Armbruster * QEMU Block backends 326f54e9aSMarkus Armbruster * 460cb2fa7SEric Blake * Copyright (C) 2014-2016 Red Hat, Inc. 526f54e9aSMarkus Armbruster * 626f54e9aSMarkus Armbruster * Authors: 726f54e9aSMarkus Armbruster * Markus Armbruster <armbru@redhat.com>, 826f54e9aSMarkus Armbruster * 926f54e9aSMarkus Armbruster * This work is licensed under the terms of the GNU LGPL, version 2.1 1026f54e9aSMarkus Armbruster * or later. See the COPYING.LIB file in the top-level directory. 1126f54e9aSMarkus Armbruster */ 1226f54e9aSMarkus Armbruster 1380c71a24SPeter Maydell #include "qemu/osdep.h" 1426f54e9aSMarkus Armbruster #include "sysemu/block-backend.h" 1526f54e9aSMarkus Armbruster #include "block/block_int.h" 16373340b2SMax Reitz #include "block/blockjob.h" 17281d22d8SMax Reitz #include "block/throttle-groups.h" 1813d4ff07SMarkus Armbruster #include "hw/qdev-core.h" 1918e46a03SMarkus Armbruster #include "sysemu/blockdev.h" 2054d31236SMarkus Armbruster #include "sysemu/runstate.h" 21e4ec5ad4SPavel Dovgalyuk #include "sysemu/sysemu.h" 22e4ec5ad4SPavel Dovgalyuk #include "sysemu/replay.h" 23e688df6bSMarkus Armbruster #include "qapi/error.h" 249af23989SMarkus Armbruster #include "qapi/qapi-events-block.h" 25f348b6d1SVeronia Bahaa #include "qemu/id.h" 26db725815SMarkus Armbruster #include "qemu/main-loop.h" 27922a01a0SMarkus Armbruster #include "qemu/option.h" 281e98fefdSKevin Wolf #include "trace.h" 295f7772c4SFam Zheng #include "migration/misc.h" 30a7f53e26SMarkus Armbruster 31a7f53e26SMarkus Armbruster /* Number of coroutines to reserve per attached device model */ 32a7f53e26SMarkus Armbruster #define COROUTINE_POOL_RESERVATION 64 3326f54e9aSMarkus Armbruster 341bf1cbc9SKevin Wolf #define NOT_DONE 0x7fffffff /* used while emulated sync operation in progress */ 351bf1cbc9SKevin Wolf 364981bdecSMax Reitz static AioContext *blk_aiocb_get_aio_context(BlockAIOCB *acb); 374981bdecSMax Reitz 38d03654eaSStefan Hajnoczi typedef struct BlockBackendAioNotifier { 39d03654eaSStefan Hajnoczi void (*attached_aio_context)(AioContext *new_context, void *opaque); 40d03654eaSStefan Hajnoczi void (*detach_aio_context)(void *opaque); 41d03654eaSStefan Hajnoczi void *opaque; 42d03654eaSStefan Hajnoczi QLIST_ENTRY(BlockBackendAioNotifier) list; 43d03654eaSStefan Hajnoczi } BlockBackendAioNotifier; 44d03654eaSStefan Hajnoczi 4526f54e9aSMarkus Armbruster struct BlockBackend { 4626f54e9aSMarkus Armbruster char *name; 4726f54e9aSMarkus Armbruster int refcnt; 48f21d96d0SKevin Wolf BdrvChild *root; 49d861ab3aSKevin Wolf AioContext *ctx; 5026f8b3a8SMarkus Armbruster DriveInfo *legacy_dinfo; /* null unless created by drive_new() */ 512cf22d6aSMax Reitz QTAILQ_ENTRY(BlockBackend) link; /* for block_backends */ 529492b0b9SMax Reitz QTAILQ_ENTRY(BlockBackend) monitor_link; /* for monitor_block_backends */ 53f2cd875dSKevin Wolf BlockBackendPublic public; 54a7f53e26SMarkus Armbruster 55d09ea2d2SThomas Huth DeviceState *dev; /* attached device model, if any */ 56a7f53e26SMarkus Armbruster const BlockDevOps *dev_ops; 57a7f53e26SMarkus Armbruster void *dev_opaque; 5868e9ec01SMax Reitz 5968e9ec01SMax Reitz /* the block size for which the guest device expects atomicity */ 6068e9ec01SMax Reitz int guest_block_size; 617f0e9da6SMax Reitz 62281d22d8SMax Reitz /* If the BDS tree is removed, some of its options are stored here (which 63281d22d8SMax Reitz * can be used to restore those options in the new BDS on insert) */ 64281d22d8SMax Reitz BlockBackendRootState root_state; 65281d22d8SMax Reitz 66bfd18d1eSKevin Wolf bool enable_write_cache; 67bfd18d1eSKevin Wolf 687f0e9da6SMax Reitz /* I/O stats (display with "info blockstats"). */ 697f0e9da6SMax Reitz BlockAcctStats stats; 70373340b2SMax Reitz 71373340b2SMax Reitz BlockdevOnError on_read_error, on_write_error; 72373340b2SMax Reitz bool iostatus_enabled; 73373340b2SMax Reitz BlockDeviceIoStatus iostatus; 743301f6c6SMax Reitz 75981776b3SKevin Wolf uint64_t perm; 76981776b3SKevin Wolf uint64_t shared_perm; 77d35ff5e6SKevin Wolf bool disable_perm; 78981776b3SKevin Wolf 79980b0f94SKevin Wolf bool allow_aio_context_change; 80c10c9d96SKevin Wolf bool allow_write_beyond_eof; 81c10c9d96SKevin Wolf 823301f6c6SMax Reitz NotifierList remove_bs_notifiers, insert_bs_notifiers; 83d03654eaSStefan Hajnoczi QLIST_HEAD(, BlockBackendAioNotifier) aio_notifiers; 84f4d9cc88SJohn Snow 85f4d9cc88SJohn Snow int quiesce_counter; 86cf312932SKevin Wolf CoQueue queued_requests; 87cf312932SKevin Wolf bool disable_request_queuing; 88cf312932SKevin Wolf 895f7772c4SFam Zheng VMChangeStateEntry *vmsh; 90ca2e2144SFam Zheng bool force_allow_inactivate; 9133f2a757SStefan Hajnoczi 9233f2a757SStefan Hajnoczi /* Number of in-flight aio requests. BlockDriverState also counts 9333f2a757SStefan Hajnoczi * in-flight requests but aio requests can exist even when blk->root is 9433f2a757SStefan Hajnoczi * NULL, so we cannot rely on its counter for that case. 9533f2a757SStefan Hajnoczi * Accessed with atomic ops. 9633f2a757SStefan Hajnoczi */ 9733f2a757SStefan Hajnoczi unsigned int in_flight; 9826f54e9aSMarkus Armbruster }; 9926f54e9aSMarkus Armbruster 100e7f7d676SMax Reitz typedef struct BlockBackendAIOCB { 101e7f7d676SMax Reitz BlockAIOCB common; 1024981bdecSMax Reitz BlockBackend *blk; 103e7f7d676SMax Reitz int ret; 104e7f7d676SMax Reitz } BlockBackendAIOCB; 105e7f7d676SMax Reitz 106e7f7d676SMax Reitz static const AIOCBInfo block_backend_aiocb_info = { 1074981bdecSMax Reitz .get_aio_context = blk_aiocb_get_aio_context, 108e7f7d676SMax Reitz .aiocb_size = sizeof(BlockBackendAIOCB), 109e7f7d676SMax Reitz }; 110e7f7d676SMax Reitz 1118fb3c76cSMarkus Armbruster static void drive_info_del(DriveInfo *dinfo); 1127c8eece4SKevin Wolf static BlockBackend *bdrv_first_blk(BlockDriverState *bs); 1138fb3c76cSMarkus Armbruster 1142cf22d6aSMax Reitz /* All BlockBackends */ 1152cf22d6aSMax Reitz static QTAILQ_HEAD(, BlockBackend) block_backends = 1162cf22d6aSMax Reitz QTAILQ_HEAD_INITIALIZER(block_backends); 1172cf22d6aSMax Reitz 1189492b0b9SMax Reitz /* All BlockBackends referenced by the monitor and which are iterated through by 1199492b0b9SMax Reitz * blk_next() */ 1209492b0b9SMax Reitz static QTAILQ_HEAD(, BlockBackend) monitor_block_backends = 1219492b0b9SMax Reitz QTAILQ_HEAD_INITIALIZER(monitor_block_backends); 12226f54e9aSMarkus Armbruster 1233cdc69d3SMax Reitz static void blk_root_inherit_options(BdrvChildRole role, bool parent_is_format, 124272c02eaSMax Reitz int *child_flags, QDict *child_options, 125f21d96d0SKevin Wolf int parent_flags, QDict *parent_options) 126f21d96d0SKevin Wolf { 127f21d96d0SKevin Wolf /* We're not supposed to call this function for root nodes */ 128f21d96d0SKevin Wolf abort(); 129f21d96d0SKevin Wolf } 130c2066af0SKevin Wolf static void blk_root_drained_begin(BdrvChild *child); 131fe5258a5SKevin Wolf static bool blk_root_drained_poll(BdrvChild *child); 132e037c09cSMax Reitz static void blk_root_drained_end(BdrvChild *child, int *drained_end_counter); 133f21d96d0SKevin Wolf 1345c8cab48SKevin Wolf static void blk_root_change_media(BdrvChild *child, bool load); 1355c8cab48SKevin Wolf static void blk_root_resize(BdrvChild *child); 1365c8cab48SKevin Wolf 13738475269SKevin Wolf static bool blk_root_can_set_aio_ctx(BdrvChild *child, AioContext *ctx, 13838475269SKevin Wolf GSList **ignore, Error **errp); 13938475269SKevin Wolf static void blk_root_set_aio_ctx(BdrvChild *child, AioContext *ctx, 14038475269SKevin Wolf GSList **ignore); 14138475269SKevin Wolf 142b5411555SKevin Wolf static char *blk_root_get_parent_desc(BdrvChild *child) 143b5411555SKevin Wolf { 144b5411555SKevin Wolf BlockBackend *blk = child->opaque; 145b5411555SKevin Wolf char *dev_id; 146b5411555SKevin Wolf 147b5411555SKevin Wolf if (blk->name) { 148b5411555SKevin Wolf return g_strdup(blk->name); 149b5411555SKevin Wolf } 150b5411555SKevin Wolf 151b5411555SKevin Wolf dev_id = blk_get_attached_dev_id(blk); 152b5411555SKevin Wolf if (*dev_id) { 153b5411555SKevin Wolf return dev_id; 154b5411555SKevin Wolf } else { 155b5411555SKevin Wolf /* TODO Callback into the BB owner for something more detailed */ 156b5411555SKevin Wolf g_free(dev_id); 157b5411555SKevin Wolf return g_strdup("a block device"); 158b5411555SKevin Wolf } 159b5411555SKevin Wolf } 160b5411555SKevin Wolf 1614c265bf9SKevin Wolf static const char *blk_root_get_name(BdrvChild *child) 1624c265bf9SKevin Wolf { 1634c265bf9SKevin Wolf return blk_name(child->opaque); 1644c265bf9SKevin Wolf } 1654c265bf9SKevin Wolf 1665f7772c4SFam Zheng static void blk_vm_state_changed(void *opaque, int running, RunState state) 1675f7772c4SFam Zheng { 1685f7772c4SFam Zheng Error *local_err = NULL; 1695f7772c4SFam Zheng BlockBackend *blk = opaque; 1705f7772c4SFam Zheng 1715f7772c4SFam Zheng if (state == RUN_STATE_INMIGRATE) { 1725f7772c4SFam Zheng return; 1735f7772c4SFam Zheng } 1745f7772c4SFam Zheng 1755f7772c4SFam Zheng qemu_del_vm_change_state_handler(blk->vmsh); 1765f7772c4SFam Zheng blk->vmsh = NULL; 1775f7772c4SFam Zheng blk_set_perm(blk, blk->perm, blk->shared_perm, &local_err); 1785f7772c4SFam Zheng if (local_err) { 1795f7772c4SFam Zheng error_report_err(local_err); 1805f7772c4SFam Zheng } 1815f7772c4SFam Zheng } 1825f7772c4SFam Zheng 1834417ab7aSKevin Wolf /* 1844417ab7aSKevin Wolf * Notifies the user of the BlockBackend that migration has completed. qdev 1854417ab7aSKevin Wolf * devices can tighten their permissions in response (specifically revoke 1864417ab7aSKevin Wolf * shared write permissions that we needed for storage migration). 1874417ab7aSKevin Wolf * 1884417ab7aSKevin Wolf * If an error is returned, the VM cannot be allowed to be resumed. 1894417ab7aSKevin Wolf */ 1904417ab7aSKevin Wolf static void blk_root_activate(BdrvChild *child, Error **errp) 1914417ab7aSKevin Wolf { 1924417ab7aSKevin Wolf BlockBackend *blk = child->opaque; 1934417ab7aSKevin Wolf Error *local_err = NULL; 1944417ab7aSKevin Wolf 1954417ab7aSKevin Wolf if (!blk->disable_perm) { 1964417ab7aSKevin Wolf return; 1974417ab7aSKevin Wolf } 1984417ab7aSKevin Wolf 1994417ab7aSKevin Wolf blk->disable_perm = false; 2004417ab7aSKevin Wolf 2015f7772c4SFam Zheng blk_set_perm(blk, blk->perm, BLK_PERM_ALL, &local_err); 2025f7772c4SFam Zheng if (local_err) { 2035f7772c4SFam Zheng error_propagate(errp, local_err); 2045f7772c4SFam Zheng blk->disable_perm = true; 2055f7772c4SFam Zheng return; 2065f7772c4SFam Zheng } 2075f7772c4SFam Zheng 2085f7772c4SFam Zheng if (runstate_check(RUN_STATE_INMIGRATE)) { 2095f7772c4SFam Zheng /* Activation can happen when migration process is still active, for 2105f7772c4SFam Zheng * example when nbd_server_add is called during non-shared storage 2115f7772c4SFam Zheng * migration. Defer the shared_perm update to migration completion. */ 2125f7772c4SFam Zheng if (!blk->vmsh) { 2135f7772c4SFam Zheng blk->vmsh = qemu_add_vm_change_state_handler(blk_vm_state_changed, 2145f7772c4SFam Zheng blk); 2155f7772c4SFam Zheng } 2165f7772c4SFam Zheng return; 2175f7772c4SFam Zheng } 2185f7772c4SFam Zheng 2194417ab7aSKevin Wolf blk_set_perm(blk, blk->perm, blk->shared_perm, &local_err); 2204417ab7aSKevin Wolf if (local_err) { 2214417ab7aSKevin Wolf error_propagate(errp, local_err); 2224417ab7aSKevin Wolf blk->disable_perm = true; 2234417ab7aSKevin Wolf return; 2244417ab7aSKevin Wolf } 2254417ab7aSKevin Wolf } 2264417ab7aSKevin Wolf 227ca2e2144SFam Zheng void blk_set_force_allow_inactivate(BlockBackend *blk) 228ca2e2144SFam Zheng { 229ca2e2144SFam Zheng blk->force_allow_inactivate = true; 230ca2e2144SFam Zheng } 231ca2e2144SFam Zheng 232c16de8f5SFam Zheng static bool blk_can_inactivate(BlockBackend *blk) 233c16de8f5SFam Zheng { 234ca2e2144SFam Zheng /* If it is a guest device, inactivate is ok. */ 235c16de8f5SFam Zheng if (blk->dev || blk_name(blk)[0]) { 236c16de8f5SFam Zheng return true; 237c16de8f5SFam Zheng } 238c16de8f5SFam Zheng 239ca2e2144SFam Zheng /* Inactivating means no more writes to the image can be done, 240ca2e2144SFam Zheng * even if those writes would be changes invisible to the 241ca2e2144SFam Zheng * guest. For block job BBs that satisfy this, we can just allow 242ca2e2144SFam Zheng * it. This is the case for mirror job source, which is required 243ca2e2144SFam Zheng * by libvirt non-shared block migration. */ 244ca2e2144SFam Zheng if (!(blk->perm & (BLK_PERM_WRITE | BLK_PERM_WRITE_UNCHANGED))) { 245ca2e2144SFam Zheng return true; 246ca2e2144SFam Zheng } 247ca2e2144SFam Zheng 248ca2e2144SFam Zheng return blk->force_allow_inactivate; 249c16de8f5SFam Zheng } 250c16de8f5SFam Zheng 251cfa1a572SKevin Wolf static int blk_root_inactivate(BdrvChild *child) 252cfa1a572SKevin Wolf { 253cfa1a572SKevin Wolf BlockBackend *blk = child->opaque; 254cfa1a572SKevin Wolf 255cfa1a572SKevin Wolf if (blk->disable_perm) { 256cfa1a572SKevin Wolf return 0; 257cfa1a572SKevin Wolf } 258cfa1a572SKevin Wolf 259c16de8f5SFam Zheng if (!blk_can_inactivate(blk)) { 260cfa1a572SKevin Wolf return -EPERM; 261cfa1a572SKevin Wolf } 262cfa1a572SKevin Wolf 263cfa1a572SKevin Wolf blk->disable_perm = true; 264cfa1a572SKevin Wolf if (blk->root) { 265cfa1a572SKevin Wolf bdrv_child_try_set_perm(blk->root, 0, BLK_PERM_ALL, &error_abort); 266cfa1a572SKevin Wolf } 267cfa1a572SKevin Wolf 268cfa1a572SKevin Wolf return 0; 269cfa1a572SKevin Wolf } 270cfa1a572SKevin Wolf 271d03654eaSStefan Hajnoczi static void blk_root_attach(BdrvChild *child) 272d03654eaSStefan Hajnoczi { 273d03654eaSStefan Hajnoczi BlockBackend *blk = child->opaque; 274d03654eaSStefan Hajnoczi BlockBackendAioNotifier *notifier; 275d03654eaSStefan Hajnoczi 276d03654eaSStefan Hajnoczi trace_blk_root_attach(child, blk, child->bs); 277d03654eaSStefan Hajnoczi 278d03654eaSStefan Hajnoczi QLIST_FOREACH(notifier, &blk->aio_notifiers, list) { 279d03654eaSStefan Hajnoczi bdrv_add_aio_context_notifier(child->bs, 280d03654eaSStefan Hajnoczi notifier->attached_aio_context, 281d03654eaSStefan Hajnoczi notifier->detach_aio_context, 282d03654eaSStefan Hajnoczi notifier->opaque); 283d03654eaSStefan Hajnoczi } 284d03654eaSStefan Hajnoczi } 285d03654eaSStefan Hajnoczi 286d03654eaSStefan Hajnoczi static void blk_root_detach(BdrvChild *child) 287d03654eaSStefan Hajnoczi { 288d03654eaSStefan Hajnoczi BlockBackend *blk = child->opaque; 289d03654eaSStefan Hajnoczi BlockBackendAioNotifier *notifier; 290d03654eaSStefan Hajnoczi 291d03654eaSStefan Hajnoczi trace_blk_root_detach(child, blk, child->bs); 292d03654eaSStefan Hajnoczi 293d03654eaSStefan Hajnoczi QLIST_FOREACH(notifier, &blk->aio_notifiers, list) { 294d03654eaSStefan Hajnoczi bdrv_remove_aio_context_notifier(child->bs, 295d03654eaSStefan Hajnoczi notifier->attached_aio_context, 296d03654eaSStefan Hajnoczi notifier->detach_aio_context, 297d03654eaSStefan Hajnoczi notifier->opaque); 298d03654eaSStefan Hajnoczi } 299d03654eaSStefan Hajnoczi } 300d03654eaSStefan Hajnoczi 301bd86fb99SMax Reitz static const BdrvChildClass child_root = { 302f21d96d0SKevin Wolf .inherit_options = blk_root_inherit_options, 303c2066af0SKevin Wolf 3045c8cab48SKevin Wolf .change_media = blk_root_change_media, 3055c8cab48SKevin Wolf .resize = blk_root_resize, 3064c265bf9SKevin Wolf .get_name = blk_root_get_name, 307b5411555SKevin Wolf .get_parent_desc = blk_root_get_parent_desc, 3085c8cab48SKevin Wolf 309c2066af0SKevin Wolf .drained_begin = blk_root_drained_begin, 310fe5258a5SKevin Wolf .drained_poll = blk_root_drained_poll, 311c2066af0SKevin Wolf .drained_end = blk_root_drained_end, 3124417ab7aSKevin Wolf 3134417ab7aSKevin Wolf .activate = blk_root_activate, 314cfa1a572SKevin Wolf .inactivate = blk_root_inactivate, 315d03654eaSStefan Hajnoczi 316d03654eaSStefan Hajnoczi .attach = blk_root_attach, 317d03654eaSStefan Hajnoczi .detach = blk_root_detach, 31838475269SKevin Wolf 31938475269SKevin Wolf .can_set_aio_ctx = blk_root_can_set_aio_ctx, 32038475269SKevin Wolf .set_aio_ctx = blk_root_set_aio_ctx, 321f21d96d0SKevin Wolf }; 322f21d96d0SKevin Wolf 32326f54e9aSMarkus Armbruster /* 324efaa7c4eSMax Reitz * Create a new BlockBackend with a reference count of one. 3256d0eb64dSKevin Wolf * 3266d0eb64dSKevin Wolf * @perm is a bitmasks of BLK_PERM_* constants which describes the permissions 3276d0eb64dSKevin Wolf * to request for a block driver node that is attached to this BlockBackend. 3286d0eb64dSKevin Wolf * @shared_perm is a bitmask which describes which permissions may be granted 3296d0eb64dSKevin Wolf * to other users of the attached node. 3306d0eb64dSKevin Wolf * Both sets of permissions can be changed later using blk_set_perm(). 3316d0eb64dSKevin Wolf * 33226f54e9aSMarkus Armbruster * Return the new BlockBackend on success, null on failure. 33326f54e9aSMarkus Armbruster */ 334d861ab3aSKevin Wolf BlockBackend *blk_new(AioContext *ctx, uint64_t perm, uint64_t shared_perm) 33526f54e9aSMarkus Armbruster { 33626f54e9aSMarkus Armbruster BlockBackend *blk; 33726f54e9aSMarkus Armbruster 33826f54e9aSMarkus Armbruster blk = g_new0(BlockBackend, 1); 33926f54e9aSMarkus Armbruster blk->refcnt = 1; 340d861ab3aSKevin Wolf blk->ctx = ctx; 3416d0eb64dSKevin Wolf blk->perm = perm; 3426d0eb64dSKevin Wolf blk->shared_perm = shared_perm; 3430c3169dfSKevin Wolf blk_set_enable_write_cache(blk, true); 3440c3169dfSKevin Wolf 345cb53460bSKevin Wolf blk->on_read_error = BLOCKDEV_ON_ERROR_REPORT; 346cb53460bSKevin Wolf blk->on_write_error = BLOCKDEV_ON_ERROR_ENOSPC; 347cb53460bSKevin Wolf 3489caa6f3dSPaolo Bonzini block_acct_init(&blk->stats); 34927ccdd52SKevin Wolf 350cf312932SKevin Wolf qemu_co_queue_init(&blk->queued_requests); 3513301f6c6SMax Reitz notifier_list_init(&blk->remove_bs_notifiers); 3523301f6c6SMax Reitz notifier_list_init(&blk->insert_bs_notifiers); 353d03654eaSStefan Hajnoczi QLIST_INIT(&blk->aio_notifiers); 35427ccdd52SKevin Wolf 3552cf22d6aSMax Reitz QTAILQ_INSERT_TAIL(&block_backends, blk, link); 35626f54e9aSMarkus Armbruster return blk; 35726f54e9aSMarkus Armbruster } 35826f54e9aSMarkus Armbruster 3597e7d56d9SMarkus Armbruster /* 360a3aeeab5SEric Blake * Create a new BlockBackend connected to an existing BlockDriverState. 361a3aeeab5SEric Blake * 362a3aeeab5SEric Blake * @perm is a bitmasks of BLK_PERM_* constants which describes the 363a3aeeab5SEric Blake * permissions to request for @bs that is attached to this 364a3aeeab5SEric Blake * BlockBackend. @shared_perm is a bitmask which describes which 365a3aeeab5SEric Blake * permissions may be granted to other users of the attached node. 366a3aeeab5SEric Blake * Both sets of permissions can be changed later using blk_set_perm(). 367a3aeeab5SEric Blake * 368a3aeeab5SEric Blake * Return the new BlockBackend on success, null on failure. 369a3aeeab5SEric Blake */ 370a3aeeab5SEric Blake BlockBackend *blk_new_with_bs(BlockDriverState *bs, uint64_t perm, 371a3aeeab5SEric Blake uint64_t shared_perm, Error **errp) 372a3aeeab5SEric Blake { 373a3aeeab5SEric Blake BlockBackend *blk = blk_new(bdrv_get_aio_context(bs), perm, shared_perm); 374a3aeeab5SEric Blake 375a3aeeab5SEric Blake if (blk_insert_bs(blk, bs, errp) < 0) { 376a3aeeab5SEric Blake blk_unref(blk); 377a3aeeab5SEric Blake return NULL; 378a3aeeab5SEric Blake } 379a3aeeab5SEric Blake return blk; 380a3aeeab5SEric Blake } 381a3aeeab5SEric Blake 382a3aeeab5SEric Blake /* 38328eb9b12SMax Reitz * Creates a new BlockBackend, opens a new BlockDriverState, and connects both. 384d861ab3aSKevin Wolf * The new BlockBackend is in the main AioContext. 385ca49a4fdSMax Reitz * 386ca49a4fdSMax Reitz * Just as with bdrv_open(), after having called this function the reference to 387ca49a4fdSMax Reitz * @options belongs to the block layer (even on failure). 388ca49a4fdSMax Reitz * 389ca49a4fdSMax Reitz * TODO: Remove @filename and @flags; it should be possible to specify a whole 390ca49a4fdSMax Reitz * BDS tree just by specifying the @options QDict (or @reference, 391ca49a4fdSMax Reitz * alternatively). At the time of adding this function, this is not possible, 392ca49a4fdSMax Reitz * though, so callers of this function have to be able to specify @filename and 393ca49a4fdSMax Reitz * @flags. 394ca49a4fdSMax Reitz */ 395efaa7c4eSMax Reitz BlockBackend *blk_new_open(const char *filename, const char *reference, 396efaa7c4eSMax Reitz QDict *options, int flags, Error **errp) 397ca49a4fdSMax Reitz { 398ca49a4fdSMax Reitz BlockBackend *blk; 39928eb9b12SMax Reitz BlockDriverState *bs; 4001f4ad7d3SKevin Wolf uint64_t perm = 0; 401ca49a4fdSMax Reitz 402c62d32f5SKevin Wolf /* blk_new_open() is mainly used in .bdrv_create implementations and the 403c62d32f5SKevin Wolf * tools where sharing isn't a concern because the BDS stays private, so we 404c62d32f5SKevin Wolf * just request permission according to the flags. 405c62d32f5SKevin Wolf * 406c62d32f5SKevin Wolf * The exceptions are xen_disk and blockdev_init(); in these cases, the 407c62d32f5SKevin Wolf * caller of blk_new_open() doesn't make use of the permissions, but they 408c62d32f5SKevin Wolf * shouldn't hurt either. We can still share everything here because the 409c62d32f5SKevin Wolf * guest devices will add their own blockers if they can't share. */ 4101f4ad7d3SKevin Wolf if ((flags & BDRV_O_NO_IO) == 0) { 4111f4ad7d3SKevin Wolf perm |= BLK_PERM_CONSISTENT_READ; 412c62d32f5SKevin Wolf if (flags & BDRV_O_RDWR) { 413c62d32f5SKevin Wolf perm |= BLK_PERM_WRITE; 414c62d32f5SKevin Wolf } 4151f4ad7d3SKevin Wolf } 416c62d32f5SKevin Wolf if (flags & BDRV_O_RESIZE) { 417c62d32f5SKevin Wolf perm |= BLK_PERM_RESIZE; 418c62d32f5SKevin Wolf } 419c62d32f5SKevin Wolf 420d861ab3aSKevin Wolf blk = blk_new(qemu_get_aio_context(), perm, BLK_PERM_ALL); 4215b363937SMax Reitz bs = bdrv_open(filename, reference, options, flags, errp); 4225b363937SMax Reitz if (!bs) { 423ca49a4fdSMax Reitz blk_unref(blk); 424ca49a4fdSMax Reitz return NULL; 425ca49a4fdSMax Reitz } 426ca49a4fdSMax Reitz 4271f38f04eSMax Reitz blk->root = bdrv_root_attach_child(bs, "root", &child_root, 4281f38f04eSMax Reitz BDRV_CHILD_FILTERED | BDRV_CHILD_PRIMARY, 4291f38f04eSMax Reitz blk->ctx, perm, BLK_PERM_ALL, blk, errp); 43050bfbe93SFam Zheng if (!blk->root) { 43150bfbe93SFam Zheng blk_unref(blk); 43250bfbe93SFam Zheng return NULL; 43350bfbe93SFam Zheng } 43472e775c7SKevin Wolf 435ca49a4fdSMax Reitz return blk; 436ca49a4fdSMax Reitz } 437ca49a4fdSMax Reitz 43826f54e9aSMarkus Armbruster static void blk_delete(BlockBackend *blk) 43926f54e9aSMarkus Armbruster { 44026f54e9aSMarkus Armbruster assert(!blk->refcnt); 441e5e78550SMax Reitz assert(!blk->name); 442a7f53e26SMarkus Armbruster assert(!blk->dev); 443022cdc9fSManos Pitsidianakis if (blk->public.throttle_group_member.throttle_state) { 4441606e4cfSEric Blake blk_io_limits_disable(blk); 4451606e4cfSEric Blake } 446f21d96d0SKevin Wolf if (blk->root) { 44713855c6bSMax Reitz blk_remove_bs(blk); 4487e7d56d9SMarkus Armbruster } 4495f7772c4SFam Zheng if (blk->vmsh) { 4505f7772c4SFam Zheng qemu_del_vm_change_state_handler(blk->vmsh); 4515f7772c4SFam Zheng blk->vmsh = NULL; 4525f7772c4SFam Zheng } 4533301f6c6SMax Reitz assert(QLIST_EMPTY(&blk->remove_bs_notifiers.notifiers)); 4543301f6c6SMax Reitz assert(QLIST_EMPTY(&blk->insert_bs_notifiers.notifiers)); 455d03654eaSStefan Hajnoczi assert(QLIST_EMPTY(&blk->aio_notifiers)); 4562cf22d6aSMax Reitz QTAILQ_REMOVE(&block_backends, blk, link); 45718e46a03SMarkus Armbruster drive_info_del(blk->legacy_dinfo); 458979e9b03SAlberto Garcia block_acct_cleanup(&blk->stats); 45926f54e9aSMarkus Armbruster g_free(blk); 46026f54e9aSMarkus Armbruster } 46126f54e9aSMarkus Armbruster 4628fb3c76cSMarkus Armbruster static void drive_info_del(DriveInfo *dinfo) 4638fb3c76cSMarkus Armbruster { 4648fb3c76cSMarkus Armbruster if (!dinfo) { 4658fb3c76cSMarkus Armbruster return; 4668fb3c76cSMarkus Armbruster } 4678fb3c76cSMarkus Armbruster qemu_opts_del(dinfo->opts); 4688fb3c76cSMarkus Armbruster g_free(dinfo); 4698fb3c76cSMarkus Armbruster } 4708fb3c76cSMarkus Armbruster 471f636ae85SAlberto Garcia int blk_get_refcnt(BlockBackend *blk) 472f636ae85SAlberto Garcia { 473f636ae85SAlberto Garcia return blk ? blk->refcnt : 0; 474f636ae85SAlberto Garcia } 475f636ae85SAlberto Garcia 47626f54e9aSMarkus Armbruster /* 47726f54e9aSMarkus Armbruster * Increment @blk's reference count. 47826f54e9aSMarkus Armbruster * @blk must not be null. 47926f54e9aSMarkus Armbruster */ 48026f54e9aSMarkus Armbruster void blk_ref(BlockBackend *blk) 48126f54e9aSMarkus Armbruster { 4825ca9d21bSKevin Wolf assert(blk->refcnt > 0); 48326f54e9aSMarkus Armbruster blk->refcnt++; 48426f54e9aSMarkus Armbruster } 48526f54e9aSMarkus Armbruster 48626f54e9aSMarkus Armbruster /* 48726f54e9aSMarkus Armbruster * Decrement @blk's reference count. 48826f54e9aSMarkus Armbruster * If this drops it to zero, destroy @blk. 48926f54e9aSMarkus Armbruster * For convenience, do nothing if @blk is null. 49026f54e9aSMarkus Armbruster */ 49126f54e9aSMarkus Armbruster void blk_unref(BlockBackend *blk) 49226f54e9aSMarkus Armbruster { 49326f54e9aSMarkus Armbruster if (blk) { 49426f54e9aSMarkus Armbruster assert(blk->refcnt > 0); 4955ca9d21bSKevin Wolf if (blk->refcnt > 1) { 4965ca9d21bSKevin Wolf blk->refcnt--; 4975ca9d21bSKevin Wolf } else { 4985ca9d21bSKevin Wolf blk_drain(blk); 4995ca9d21bSKevin Wolf /* blk_drain() cannot resurrect blk, nobody held a reference */ 5005ca9d21bSKevin Wolf assert(blk->refcnt == 1); 5015ca9d21bSKevin Wolf blk->refcnt = 0; 50226f54e9aSMarkus Armbruster blk_delete(blk); 50326f54e9aSMarkus Armbruster } 50426f54e9aSMarkus Armbruster } 50526f54e9aSMarkus Armbruster } 50626f54e9aSMarkus Armbruster 5072cf22d6aSMax Reitz /* 5082cf22d6aSMax Reitz * Behaves similarly to blk_next() but iterates over all BlockBackends, even the 5092cf22d6aSMax Reitz * ones which are hidden (i.e. are not referenced by the monitor). 5102cf22d6aSMax Reitz */ 511a429b9b5SKevin Wolf BlockBackend *blk_all_next(BlockBackend *blk) 5122cf22d6aSMax Reitz { 5132cf22d6aSMax Reitz return blk ? QTAILQ_NEXT(blk, link) 5142cf22d6aSMax Reitz : QTAILQ_FIRST(&block_backends); 5152cf22d6aSMax Reitz } 5162cf22d6aSMax Reitz 517d8da3cefSMax Reitz void blk_remove_all_bs(void) 518d8da3cefSMax Reitz { 51974d1b8fcSMax Reitz BlockBackend *blk = NULL; 520d8da3cefSMax Reitz 5212cf22d6aSMax Reitz while ((blk = blk_all_next(blk)) != NULL) { 522d8da3cefSMax Reitz AioContext *ctx = blk_get_aio_context(blk); 523d8da3cefSMax Reitz 524d8da3cefSMax Reitz aio_context_acquire(ctx); 525f21d96d0SKevin Wolf if (blk->root) { 526d8da3cefSMax Reitz blk_remove_bs(blk); 527d8da3cefSMax Reitz } 528d8da3cefSMax Reitz aio_context_release(ctx); 529d8da3cefSMax Reitz } 530d8da3cefSMax Reitz } 531d8da3cefSMax Reitz 53226f54e9aSMarkus Armbruster /* 5339492b0b9SMax Reitz * Return the monitor-owned BlockBackend after @blk. 53426f54e9aSMarkus Armbruster * If @blk is null, return the first one. 53526f54e9aSMarkus Armbruster * Else, return @blk's next sibling, which may be null. 53626f54e9aSMarkus Armbruster * 53726f54e9aSMarkus Armbruster * To iterate over all BlockBackends, do 53826f54e9aSMarkus Armbruster * for (blk = blk_next(NULL); blk; blk = blk_next(blk)) { 53926f54e9aSMarkus Armbruster * ... 54026f54e9aSMarkus Armbruster * } 54126f54e9aSMarkus Armbruster */ 54226f54e9aSMarkus Armbruster BlockBackend *blk_next(BlockBackend *blk) 54326f54e9aSMarkus Armbruster { 5449492b0b9SMax Reitz return blk ? QTAILQ_NEXT(blk, monitor_link) 5459492b0b9SMax Reitz : QTAILQ_FIRST(&monitor_block_backends); 54626f54e9aSMarkus Armbruster } 54726f54e9aSMarkus Armbruster 5487c8eece4SKevin Wolf /* Iterates over all top-level BlockDriverStates, i.e. BDSs that are owned by 5497c8eece4SKevin Wolf * the monitor or attached to a BlockBackend */ 55088be7b4bSKevin Wolf BlockDriverState *bdrv_next(BdrvNextIterator *it) 5517c8eece4SKevin Wolf { 5525e003f17SMax Reitz BlockDriverState *bs, *old_bs; 5535e003f17SMax Reitz 5545e003f17SMax Reitz /* Must be called from the main loop */ 5555e003f17SMax Reitz assert(qemu_get_current_aio_context() == qemu_get_aio_context()); 556981f4f57SMax Reitz 5577c8eece4SKevin Wolf /* First, return all root nodes of BlockBackends. In order to avoid 5587c8eece4SKevin Wolf * returning a BDS twice when multiple BBs refer to it, we only return it 5597c8eece4SKevin Wolf * if the BB is the first one in the parent list of the BDS. */ 5607c8eece4SKevin Wolf if (it->phase == BDRV_NEXT_BACKEND_ROOTS) { 5615e003f17SMax Reitz BlockBackend *old_blk = it->blk; 5625e003f17SMax Reitz 5635e003f17SMax Reitz old_bs = old_blk ? blk_bs(old_blk) : NULL; 5645e003f17SMax Reitz 565981f4f57SMax Reitz do { 5667c8eece4SKevin Wolf it->blk = blk_all_next(it->blk); 56788be7b4bSKevin Wolf bs = it->blk ? blk_bs(it->blk) : NULL; 56888be7b4bSKevin Wolf } while (it->blk && (bs == NULL || bdrv_first_blk(bs) != it->blk)); 569981f4f57SMax Reitz 5705e003f17SMax Reitz if (it->blk) { 5715e003f17SMax Reitz blk_ref(it->blk); 5725e003f17SMax Reitz } 5735e003f17SMax Reitz blk_unref(old_blk); 5745e003f17SMax Reitz 57588be7b4bSKevin Wolf if (bs) { 5765e003f17SMax Reitz bdrv_ref(bs); 5775e003f17SMax Reitz bdrv_unref(old_bs); 57888be7b4bSKevin Wolf return bs; 5797c8eece4SKevin Wolf } 5807c8eece4SKevin Wolf it->phase = BDRV_NEXT_MONITOR_OWNED; 5815e003f17SMax Reitz } else { 5825e003f17SMax Reitz old_bs = it->bs; 5837c8eece4SKevin Wolf } 5847c8eece4SKevin Wolf 5857c8eece4SKevin Wolf /* Then return the monitor-owned BDSes without a BB attached. Ignore all 5867c8eece4SKevin Wolf * BDSes that are attached to a BlockBackend here; they have been handled 5877c8eece4SKevin Wolf * by the above block already */ 5887c8eece4SKevin Wolf do { 5897c8eece4SKevin Wolf it->bs = bdrv_next_monitor_owned(it->bs); 59088be7b4bSKevin Wolf bs = it->bs; 59188be7b4bSKevin Wolf } while (bs && bdrv_has_blk(bs)); 5927c8eece4SKevin Wolf 5935e003f17SMax Reitz if (bs) { 5945e003f17SMax Reitz bdrv_ref(bs); 5955e003f17SMax Reitz } 5965e003f17SMax Reitz bdrv_unref(old_bs); 5975e003f17SMax Reitz 59888be7b4bSKevin Wolf return bs; 59988be7b4bSKevin Wolf } 60088be7b4bSKevin Wolf 6015e003f17SMax Reitz static void bdrv_next_reset(BdrvNextIterator *it) 60288be7b4bSKevin Wolf { 60388be7b4bSKevin Wolf *it = (BdrvNextIterator) { 60488be7b4bSKevin Wolf .phase = BDRV_NEXT_BACKEND_ROOTS, 60588be7b4bSKevin Wolf }; 6065e003f17SMax Reitz } 60788be7b4bSKevin Wolf 6085e003f17SMax Reitz BlockDriverState *bdrv_first(BdrvNextIterator *it) 6095e003f17SMax Reitz { 6105e003f17SMax Reitz bdrv_next_reset(it); 61188be7b4bSKevin Wolf return bdrv_next(it); 612981f4f57SMax Reitz } 613981f4f57SMax Reitz 6145e003f17SMax Reitz /* Must be called when aborting a bdrv_next() iteration before 6155e003f17SMax Reitz * bdrv_next() returns NULL */ 6165e003f17SMax Reitz void bdrv_next_cleanup(BdrvNextIterator *it) 6175e003f17SMax Reitz { 6185e003f17SMax Reitz /* Must be called from the main loop */ 6195e003f17SMax Reitz assert(qemu_get_current_aio_context() == qemu_get_aio_context()); 6205e003f17SMax Reitz 6215e003f17SMax Reitz if (it->phase == BDRV_NEXT_BACKEND_ROOTS) { 6225e003f17SMax Reitz if (it->blk) { 6235e003f17SMax Reitz bdrv_unref(blk_bs(it->blk)); 6245e003f17SMax Reitz blk_unref(it->blk); 6255e003f17SMax Reitz } 6265e003f17SMax Reitz } else { 6275e003f17SMax Reitz bdrv_unref(it->bs); 6285e003f17SMax Reitz } 6295e003f17SMax Reitz 6305e003f17SMax Reitz bdrv_next_reset(it); 6315e003f17SMax Reitz } 6325e003f17SMax Reitz 633981f4f57SMax Reitz /* 634e5e78550SMax Reitz * Add a BlockBackend into the list of backends referenced by the monitor, with 635e5e78550SMax Reitz * the given @name acting as the handle for the monitor. 636e5e78550SMax Reitz * Strictly for use by blockdev.c. 637e5e78550SMax Reitz * 638e5e78550SMax Reitz * @name must not be null or empty. 639e5e78550SMax Reitz * 640e5e78550SMax Reitz * Returns true on success and false on failure. In the latter case, an Error 641e5e78550SMax Reitz * object is returned through @errp. 642e5e78550SMax Reitz */ 643e5e78550SMax Reitz bool monitor_add_blk(BlockBackend *blk, const char *name, Error **errp) 644e5e78550SMax Reitz { 645e5e78550SMax Reitz assert(!blk->name); 646e5e78550SMax Reitz assert(name && name[0]); 647e5e78550SMax Reitz 648e5e78550SMax Reitz if (!id_wellformed(name)) { 649e5e78550SMax Reitz error_setg(errp, "Invalid device name"); 650e5e78550SMax Reitz return false; 651e5e78550SMax Reitz } 652e5e78550SMax Reitz if (blk_by_name(name)) { 653e5e78550SMax Reitz error_setg(errp, "Device with id '%s' already exists", name); 654e5e78550SMax Reitz return false; 655e5e78550SMax Reitz } 656e5e78550SMax Reitz if (bdrv_find_node(name)) { 657e5e78550SMax Reitz error_setg(errp, 658e5e78550SMax Reitz "Device name '%s' conflicts with an existing node name", 659e5e78550SMax Reitz name); 660e5e78550SMax Reitz return false; 661e5e78550SMax Reitz } 662e5e78550SMax Reitz 663e5e78550SMax Reitz blk->name = g_strdup(name); 664e5e78550SMax Reitz QTAILQ_INSERT_TAIL(&monitor_block_backends, blk, monitor_link); 665e5e78550SMax Reitz return true; 666e5e78550SMax Reitz } 667e5e78550SMax Reitz 668e5e78550SMax Reitz /* 669e5e78550SMax Reitz * Remove a BlockBackend from the list of backends referenced by the monitor. 670e5e78550SMax Reitz * Strictly for use by blockdev.c. 671e5e78550SMax Reitz */ 672e5e78550SMax Reitz void monitor_remove_blk(BlockBackend *blk) 673e5e78550SMax Reitz { 674e5e78550SMax Reitz if (!blk->name) { 675e5e78550SMax Reitz return; 676e5e78550SMax Reitz } 677e5e78550SMax Reitz 678e5e78550SMax Reitz QTAILQ_REMOVE(&monitor_block_backends, blk, monitor_link); 679e5e78550SMax Reitz g_free(blk->name); 680e5e78550SMax Reitz blk->name = NULL; 681e5e78550SMax Reitz } 682e5e78550SMax Reitz 683e5e78550SMax Reitz /* 6847e7d56d9SMarkus Armbruster * Return @blk's name, a non-null string. 685e5e78550SMax Reitz * Returns an empty string iff @blk is not referenced by the monitor. 68626f54e9aSMarkus Armbruster */ 6870731a50fSKrzysztof Kozlowski const char *blk_name(const BlockBackend *blk) 68826f54e9aSMarkus Armbruster { 689e5e78550SMax Reitz return blk->name ?: ""; 69026f54e9aSMarkus Armbruster } 69126f54e9aSMarkus Armbruster 69226f54e9aSMarkus Armbruster /* 69326f54e9aSMarkus Armbruster * Return the BlockBackend with name @name if it exists, else null. 69426f54e9aSMarkus Armbruster * @name must not be null. 69526f54e9aSMarkus Armbruster */ 69626f54e9aSMarkus Armbruster BlockBackend *blk_by_name(const char *name) 69726f54e9aSMarkus Armbruster { 69874d1b8fcSMax Reitz BlockBackend *blk = NULL; 69926f54e9aSMarkus Armbruster 70026f54e9aSMarkus Armbruster assert(name); 70174d1b8fcSMax Reitz while ((blk = blk_next(blk)) != NULL) { 70226f54e9aSMarkus Armbruster if (!strcmp(name, blk->name)) { 70326f54e9aSMarkus Armbruster return blk; 70426f54e9aSMarkus Armbruster } 70526f54e9aSMarkus Armbruster } 70626f54e9aSMarkus Armbruster return NULL; 70726f54e9aSMarkus Armbruster } 7087e7d56d9SMarkus Armbruster 7097e7d56d9SMarkus Armbruster /* 7107e7d56d9SMarkus Armbruster * Return the BlockDriverState attached to @blk if any, else null. 7117e7d56d9SMarkus Armbruster */ 7127e7d56d9SMarkus Armbruster BlockDriverState *blk_bs(BlockBackend *blk) 7137e7d56d9SMarkus Armbruster { 714f21d96d0SKevin Wolf return blk->root ? blk->root->bs : NULL; 7157e7d56d9SMarkus Armbruster } 7167e7d56d9SMarkus Armbruster 7177c8eece4SKevin Wolf static BlockBackend *bdrv_first_blk(BlockDriverState *bs) 718dde33812SKevin Wolf { 719dde33812SKevin Wolf BdrvChild *child; 720dde33812SKevin Wolf QLIST_FOREACH(child, &bs->parents, next_parent) { 721bd86fb99SMax Reitz if (child->klass == &child_root) { 7227c8eece4SKevin Wolf return child->opaque; 723dde33812SKevin Wolf } 724dde33812SKevin Wolf } 725dde33812SKevin Wolf 7267c8eece4SKevin Wolf return NULL; 7277c8eece4SKevin Wolf } 7287c8eece4SKevin Wolf 7297c8eece4SKevin Wolf /* 7307c8eece4SKevin Wolf * Returns true if @bs has an associated BlockBackend. 7317c8eece4SKevin Wolf */ 7327c8eece4SKevin Wolf bool bdrv_has_blk(BlockDriverState *bs) 7337c8eece4SKevin Wolf { 7347c8eece4SKevin Wolf return bdrv_first_blk(bs) != NULL; 735dde33812SKevin Wolf } 736dde33812SKevin Wolf 737dde33812SKevin Wolf /* 738b6c1bae5SKevin Wolf * Returns true if @bs has only BlockBackends as parents. 739b6c1bae5SKevin Wolf */ 740b6c1bae5SKevin Wolf bool bdrv_is_root_node(BlockDriverState *bs) 741b6c1bae5SKevin Wolf { 742b6c1bae5SKevin Wolf BdrvChild *c; 743b6c1bae5SKevin Wolf 744b6c1bae5SKevin Wolf QLIST_FOREACH(c, &bs->parents, next_parent) { 745bd86fb99SMax Reitz if (c->klass != &child_root) { 746b6c1bae5SKevin Wolf return false; 747b6c1bae5SKevin Wolf } 748b6c1bae5SKevin Wolf } 749b6c1bae5SKevin Wolf 750b6c1bae5SKevin Wolf return true; 751b6c1bae5SKevin Wolf } 752b6c1bae5SKevin Wolf 753b6c1bae5SKevin Wolf /* 75418e46a03SMarkus Armbruster * Return @blk's DriveInfo if any, else null. 75518e46a03SMarkus Armbruster */ 75618e46a03SMarkus Armbruster DriveInfo *blk_legacy_dinfo(BlockBackend *blk) 75718e46a03SMarkus Armbruster { 75818e46a03SMarkus Armbruster return blk->legacy_dinfo; 75918e46a03SMarkus Armbruster } 76018e46a03SMarkus Armbruster 76118e46a03SMarkus Armbruster /* 76218e46a03SMarkus Armbruster * Set @blk's DriveInfo to @dinfo, and return it. 76318e46a03SMarkus Armbruster * @blk must not have a DriveInfo set already. 76418e46a03SMarkus Armbruster * No other BlockBackend may have the same DriveInfo set. 76518e46a03SMarkus Armbruster */ 76618e46a03SMarkus Armbruster DriveInfo *blk_set_legacy_dinfo(BlockBackend *blk, DriveInfo *dinfo) 76718e46a03SMarkus Armbruster { 76818e46a03SMarkus Armbruster assert(!blk->legacy_dinfo); 76918e46a03SMarkus Armbruster return blk->legacy_dinfo = dinfo; 77018e46a03SMarkus Armbruster } 77118e46a03SMarkus Armbruster 77218e46a03SMarkus Armbruster /* 77318e46a03SMarkus Armbruster * Return the BlockBackend with DriveInfo @dinfo. 77418e46a03SMarkus Armbruster * It must exist. 77518e46a03SMarkus Armbruster */ 77618e46a03SMarkus Armbruster BlockBackend *blk_by_legacy_dinfo(DriveInfo *dinfo) 77718e46a03SMarkus Armbruster { 77874d1b8fcSMax Reitz BlockBackend *blk = NULL; 77918e46a03SMarkus Armbruster 78074d1b8fcSMax Reitz while ((blk = blk_next(blk)) != NULL) { 78118e46a03SMarkus Armbruster if (blk->legacy_dinfo == dinfo) { 78218e46a03SMarkus Armbruster return blk; 78318e46a03SMarkus Armbruster } 78418e46a03SMarkus Armbruster } 78518e46a03SMarkus Armbruster abort(); 78618e46a03SMarkus Armbruster } 78718e46a03SMarkus Armbruster 78818e46a03SMarkus Armbruster /* 789f2cd875dSKevin Wolf * Returns a pointer to the publicly accessible fields of @blk. 790f2cd875dSKevin Wolf */ 791f2cd875dSKevin Wolf BlockBackendPublic *blk_get_public(BlockBackend *blk) 792f2cd875dSKevin Wolf { 793f2cd875dSKevin Wolf return &blk->public; 794f2cd875dSKevin Wolf } 795f2cd875dSKevin Wolf 796f2cd875dSKevin Wolf /* 797f2cd875dSKevin Wolf * Returns a BlockBackend given the associated @public fields. 798f2cd875dSKevin Wolf */ 799f2cd875dSKevin Wolf BlockBackend *blk_by_public(BlockBackendPublic *public) 800f2cd875dSKevin Wolf { 801f2cd875dSKevin Wolf return container_of(public, BlockBackend, public); 802f2cd875dSKevin Wolf } 803f2cd875dSKevin Wolf 804f2cd875dSKevin Wolf /* 8051c95f7e1SMax Reitz * Disassociates the currently associated BlockDriverState from @blk. 8061c95f7e1SMax Reitz */ 8071c95f7e1SMax Reitz void blk_remove_bs(BlockBackend *blk) 8081c95f7e1SMax Reitz { 809c89bcf3aSAlberto Garcia ThrottleGroupMember *tgm = &blk->public.throttle_group_member; 810632a7735SZhengui BlockDriverState *bs; 811e6cada92SGreg Kurz BdrvChild *root; 812022cdc9fSManos Pitsidianakis 8133301f6c6SMax Reitz notifier_list_notify(&blk->remove_bs_notifiers, blk); 814c89bcf3aSAlberto Garcia if (tgm->throttle_state) { 815632a7735SZhengui bs = blk_bs(blk); 816632a7735SZhengui bdrv_drained_begin(bs); 817c89bcf3aSAlberto Garcia throttle_group_detach_aio_context(tgm); 818c89bcf3aSAlberto Garcia throttle_group_attach_aio_context(tgm, qemu_get_aio_context()); 819632a7735SZhengui bdrv_drained_end(bs); 8207ca7f0f6SKevin Wolf } 8213301f6c6SMax Reitz 8221c95f7e1SMax Reitz blk_update_root_state(blk); 8231c95f7e1SMax Reitz 824f45280cbSGreg Kurz /* bdrv_root_unref_child() will cause blk->root to become stale and may 825f45280cbSGreg Kurz * switch to a completion coroutine later on. Let's drain all I/O here 826f45280cbSGreg Kurz * to avoid that and a potential QEMU crash. 827f45280cbSGreg Kurz */ 828f45280cbSGreg Kurz blk_drain(blk); 829e6cada92SGreg Kurz root = blk->root; 830f21d96d0SKevin Wolf blk->root = NULL; 831e6cada92SGreg Kurz bdrv_root_unref_child(root); 8321c95f7e1SMax Reitz } 8331c95f7e1SMax Reitz 8341c95f7e1SMax Reitz /* 8350c3c36d6SMax Reitz * Associates a new BlockDriverState with @blk. 8360c3c36d6SMax Reitz */ 837d7086422SKevin Wolf int blk_insert_bs(BlockBackend *blk, BlockDriverState *bs, Error **errp) 8380c3c36d6SMax Reitz { 839c89bcf3aSAlberto Garcia ThrottleGroupMember *tgm = &blk->public.throttle_group_member; 840b441dc71SAlberto Garcia bdrv_ref(bs); 8411f38f04eSMax Reitz blk->root = bdrv_root_attach_child(bs, "root", &child_root, 8421f38f04eSMax Reitz BDRV_CHILD_FILTERED | BDRV_CHILD_PRIMARY, 8431f38f04eSMax Reitz blk->ctx, blk->perm, blk->shared_perm, 8441f38f04eSMax Reitz blk, errp); 845d7086422SKevin Wolf if (blk->root == NULL) { 846d7086422SKevin Wolf return -EPERM; 847d7086422SKevin Wolf } 8483301f6c6SMax Reitz 8493301f6c6SMax Reitz notifier_list_notify(&blk->insert_bs_notifiers, blk); 850c89bcf3aSAlberto Garcia if (tgm->throttle_state) { 851c89bcf3aSAlberto Garcia throttle_group_detach_aio_context(tgm); 852c89bcf3aSAlberto Garcia throttle_group_attach_aio_context(tgm, bdrv_get_aio_context(bs)); 8537ca7f0f6SKevin Wolf } 854d7086422SKevin Wolf 855d7086422SKevin Wolf return 0; 8560c3c36d6SMax Reitz } 8570c3c36d6SMax Reitz 858981776b3SKevin Wolf /* 859981776b3SKevin Wolf * Sets the permission bitmasks that the user of the BlockBackend needs. 860981776b3SKevin Wolf */ 861981776b3SKevin Wolf int blk_set_perm(BlockBackend *blk, uint64_t perm, uint64_t shared_perm, 862981776b3SKevin Wolf Error **errp) 863981776b3SKevin Wolf { 864981776b3SKevin Wolf int ret; 865981776b3SKevin Wolf 866d35ff5e6SKevin Wolf if (blk->root && !blk->disable_perm) { 867981776b3SKevin Wolf ret = bdrv_child_try_set_perm(blk->root, perm, shared_perm, errp); 868981776b3SKevin Wolf if (ret < 0) { 869981776b3SKevin Wolf return ret; 870981776b3SKevin Wolf } 871981776b3SKevin Wolf } 872981776b3SKevin Wolf 873981776b3SKevin Wolf blk->perm = perm; 874981776b3SKevin Wolf blk->shared_perm = shared_perm; 875981776b3SKevin Wolf 876981776b3SKevin Wolf return 0; 877981776b3SKevin Wolf } 878981776b3SKevin Wolf 879887354bdSKevin Wolf void blk_get_perm(BlockBackend *blk, uint64_t *perm, uint64_t *shared_perm) 880887354bdSKevin Wolf { 881887354bdSKevin Wolf *perm = blk->perm; 882887354bdSKevin Wolf *shared_perm = blk->shared_perm; 883887354bdSKevin Wolf } 884887354bdSKevin Wolf 885d09ea2d2SThomas Huth /* 886d09ea2d2SThomas Huth * Attach device model @dev to @blk. 887d09ea2d2SThomas Huth * Return 0 on success, -EBUSY when a device model is attached already. 888d09ea2d2SThomas Huth */ 889d09ea2d2SThomas Huth int blk_attach_dev(BlockBackend *blk, DeviceState *dev) 890a7f53e26SMarkus Armbruster { 891a7f53e26SMarkus Armbruster if (blk->dev) { 892a7f53e26SMarkus Armbruster return -EBUSY; 893a7f53e26SMarkus Armbruster } 894d35ff5e6SKevin Wolf 895d35ff5e6SKevin Wolf /* While migration is still incoming, we don't need to apply the 896d35ff5e6SKevin Wolf * permissions of guest device BlockBackends. We might still have a block 897d35ff5e6SKevin Wolf * job or NBD server writing to the image for storage migration. */ 898d35ff5e6SKevin Wolf if (runstate_check(RUN_STATE_INMIGRATE)) { 899d35ff5e6SKevin Wolf blk->disable_perm = true; 900d35ff5e6SKevin Wolf } 901d35ff5e6SKevin Wolf 90284ebe375SMarkus Armbruster blk_ref(blk); 903a7f53e26SMarkus Armbruster blk->dev = dev; 904373340b2SMax Reitz blk_iostatus_reset(blk); 905d35ff5e6SKevin Wolf 906a7f53e26SMarkus Armbruster return 0; 907a7f53e26SMarkus Armbruster } 908a7f53e26SMarkus Armbruster 909a7f53e26SMarkus Armbruster /* 910a7f53e26SMarkus Armbruster * Detach device model @dev from @blk. 911a7f53e26SMarkus Armbruster * @dev must be currently attached to @blk. 912a7f53e26SMarkus Armbruster */ 913d09ea2d2SThomas Huth void blk_detach_dev(BlockBackend *blk, DeviceState *dev) 914a7f53e26SMarkus Armbruster { 915a7f53e26SMarkus Armbruster assert(blk->dev == dev); 916a7f53e26SMarkus Armbruster blk->dev = NULL; 917a7f53e26SMarkus Armbruster blk->dev_ops = NULL; 918a7f53e26SMarkus Armbruster blk->dev_opaque = NULL; 91968e9ec01SMax Reitz blk->guest_block_size = 512; 920981776b3SKevin Wolf blk_set_perm(blk, 0, BLK_PERM_ALL, &error_abort); 92184ebe375SMarkus Armbruster blk_unref(blk); 922a7f53e26SMarkus Armbruster } 923a7f53e26SMarkus Armbruster 924a7f53e26SMarkus Armbruster /* 925a7f53e26SMarkus Armbruster * Return the device model attached to @blk if any, else null. 926a7f53e26SMarkus Armbruster */ 927d09ea2d2SThomas Huth DeviceState *blk_get_attached_dev(BlockBackend *blk) 928a7f53e26SMarkus Armbruster { 929a7f53e26SMarkus Armbruster return blk->dev; 930a7f53e26SMarkus Armbruster } 931a7f53e26SMarkus Armbruster 9322d76e724SKevin Wolf /* Return the qdev ID, or if no ID is assigned the QOM path, of the block 9332d76e724SKevin Wolf * device attached to the BlockBackend. */ 93477beef83SKevin Wolf char *blk_get_attached_dev_id(BlockBackend *blk) 9352d76e724SKevin Wolf { 936d09ea2d2SThomas Huth DeviceState *dev = blk->dev; 9372d76e724SKevin Wolf 9382d76e724SKevin Wolf if (!dev) { 9392d76e724SKevin Wolf return g_strdup(""); 9402d76e724SKevin Wolf } else if (dev->id) { 9412d76e724SKevin Wolf return g_strdup(dev->id); 9422d76e724SKevin Wolf } 943602414d1SLiam Merwick 944602414d1SLiam Merwick return object_get_canonical_path(OBJECT(dev)) ?: g_strdup(""); 9452d76e724SKevin Wolf } 9462d76e724SKevin Wolf 947a7f53e26SMarkus Armbruster /* 9481c89e1faSKevin Wolf * Return the BlockBackend which has the device model @dev attached if it 9491c89e1faSKevin Wolf * exists, else null. 9501c89e1faSKevin Wolf * 9511c89e1faSKevin Wolf * @dev must not be null. 9521c89e1faSKevin Wolf */ 9531c89e1faSKevin Wolf BlockBackend *blk_by_dev(void *dev) 9541c89e1faSKevin Wolf { 9551c89e1faSKevin Wolf BlockBackend *blk = NULL; 9561c89e1faSKevin Wolf 9571c89e1faSKevin Wolf assert(dev != NULL); 9581c89e1faSKevin Wolf while ((blk = blk_all_next(blk)) != NULL) { 9591c89e1faSKevin Wolf if (blk->dev == dev) { 9601c89e1faSKevin Wolf return blk; 9611c89e1faSKevin Wolf } 9621c89e1faSKevin Wolf } 9631c89e1faSKevin Wolf return NULL; 9641c89e1faSKevin Wolf } 9651c89e1faSKevin Wolf 9661c89e1faSKevin Wolf /* 967a7f53e26SMarkus Armbruster * Set @blk's device model callbacks to @ops. 968a7f53e26SMarkus Armbruster * @opaque is the opaque argument to pass to the callbacks. 969a7f53e26SMarkus Armbruster * This is for use by device models. 970a7f53e26SMarkus Armbruster */ 971a7f53e26SMarkus Armbruster void blk_set_dev_ops(BlockBackend *blk, const BlockDevOps *ops, 972a7f53e26SMarkus Armbruster void *opaque) 973a7f53e26SMarkus Armbruster { 974a7f53e26SMarkus Armbruster blk->dev_ops = ops; 975a7f53e26SMarkus Armbruster blk->dev_opaque = opaque; 976f4d9cc88SJohn Snow 977f4d9cc88SJohn Snow /* Are we currently quiesced? Should we enforce this right now? */ 978f4d9cc88SJohn Snow if (blk->quiesce_counter && ops->drained_begin) { 979f4d9cc88SJohn Snow ops->drained_begin(opaque); 980f4d9cc88SJohn Snow } 981a7f53e26SMarkus Armbruster } 982a7f53e26SMarkus Armbruster 983a7f53e26SMarkus Armbruster /* 984a7f53e26SMarkus Armbruster * Notify @blk's attached device model of media change. 98539829a01SKevin Wolf * 98639829a01SKevin Wolf * If @load is true, notify of media load. This action can fail, meaning that 98739829a01SKevin Wolf * the medium cannot be loaded. @errp is set then. 98839829a01SKevin Wolf * 98939829a01SKevin Wolf * If @load is false, notify of media eject. This can never fail. 99039829a01SKevin Wolf * 991a7f53e26SMarkus Armbruster * Also send DEVICE_TRAY_MOVED events as appropriate. 992a7f53e26SMarkus Armbruster */ 99339829a01SKevin Wolf void blk_dev_change_media_cb(BlockBackend *blk, bool load, Error **errp) 994a7f53e26SMarkus Armbruster { 995a7f53e26SMarkus Armbruster if (blk->dev_ops && blk->dev_ops->change_media_cb) { 996f1f57066SMax Reitz bool tray_was_open, tray_is_open; 99739829a01SKevin Wolf Error *local_err = NULL; 998a7f53e26SMarkus Armbruster 999f1f57066SMax Reitz tray_was_open = blk_dev_is_tray_open(blk); 100039829a01SKevin Wolf blk->dev_ops->change_media_cb(blk->dev_opaque, load, &local_err); 100139829a01SKevin Wolf if (local_err) { 100239829a01SKevin Wolf assert(load == true); 100339829a01SKevin Wolf error_propagate(errp, local_err); 100439829a01SKevin Wolf return; 100539829a01SKevin Wolf } 1006f1f57066SMax Reitz tray_is_open = blk_dev_is_tray_open(blk); 1007f1f57066SMax Reitz 1008f1f57066SMax Reitz if (tray_was_open != tray_is_open) { 10092d76e724SKevin Wolf char *id = blk_get_attached_dev_id(blk); 10103ab72385SPeter Xu qapi_event_send_device_tray_moved(blk_name(blk), id, tray_is_open); 10112d76e724SKevin Wolf g_free(id); 1012a7f53e26SMarkus Armbruster } 1013a7f53e26SMarkus Armbruster } 1014a7f53e26SMarkus Armbruster } 1015a7f53e26SMarkus Armbruster 10165c8cab48SKevin Wolf static void blk_root_change_media(BdrvChild *child, bool load) 10175c8cab48SKevin Wolf { 101839829a01SKevin Wolf blk_dev_change_media_cb(child->opaque, load, NULL); 10195c8cab48SKevin Wolf } 10205c8cab48SKevin Wolf 1021a7f53e26SMarkus Armbruster /* 1022a7f53e26SMarkus Armbruster * Does @blk's attached device model have removable media? 1023a7f53e26SMarkus Armbruster * %true if no device model is attached. 1024a7f53e26SMarkus Armbruster */ 1025a7f53e26SMarkus Armbruster bool blk_dev_has_removable_media(BlockBackend *blk) 1026a7f53e26SMarkus Armbruster { 1027a7f53e26SMarkus Armbruster return !blk->dev || (blk->dev_ops && blk->dev_ops->change_media_cb); 1028a7f53e26SMarkus Armbruster } 1029a7f53e26SMarkus Armbruster 1030a7f53e26SMarkus Armbruster /* 10318f3a73bcSMax Reitz * Does @blk's attached device model have a tray? 10328f3a73bcSMax Reitz */ 10338f3a73bcSMax Reitz bool blk_dev_has_tray(BlockBackend *blk) 10348f3a73bcSMax Reitz { 10358f3a73bcSMax Reitz return blk->dev_ops && blk->dev_ops->is_tray_open; 10368f3a73bcSMax Reitz } 10378f3a73bcSMax Reitz 10388f3a73bcSMax Reitz /* 1039a7f53e26SMarkus Armbruster * Notify @blk's attached device model of a media eject request. 1040a7f53e26SMarkus Armbruster * If @force is true, the medium is about to be yanked out forcefully. 1041a7f53e26SMarkus Armbruster */ 1042a7f53e26SMarkus Armbruster void blk_dev_eject_request(BlockBackend *blk, bool force) 1043a7f53e26SMarkus Armbruster { 1044a7f53e26SMarkus Armbruster if (blk->dev_ops && blk->dev_ops->eject_request_cb) { 1045a7f53e26SMarkus Armbruster blk->dev_ops->eject_request_cb(blk->dev_opaque, force); 1046a7f53e26SMarkus Armbruster } 1047a7f53e26SMarkus Armbruster } 1048a7f53e26SMarkus Armbruster 1049a7f53e26SMarkus Armbruster /* 1050a7f53e26SMarkus Armbruster * Does @blk's attached device model have a tray, and is it open? 1051a7f53e26SMarkus Armbruster */ 1052a7f53e26SMarkus Armbruster bool blk_dev_is_tray_open(BlockBackend *blk) 1053a7f53e26SMarkus Armbruster { 10548f3a73bcSMax Reitz if (blk_dev_has_tray(blk)) { 1055a7f53e26SMarkus Armbruster return blk->dev_ops->is_tray_open(blk->dev_opaque); 1056a7f53e26SMarkus Armbruster } 1057a7f53e26SMarkus Armbruster return false; 1058a7f53e26SMarkus Armbruster } 1059a7f53e26SMarkus Armbruster 1060a7f53e26SMarkus Armbruster /* 1061a7f53e26SMarkus Armbruster * Does @blk's attached device model have the medium locked? 1062a7f53e26SMarkus Armbruster * %false if the device model has no such lock. 1063a7f53e26SMarkus Armbruster */ 1064a7f53e26SMarkus Armbruster bool blk_dev_is_medium_locked(BlockBackend *blk) 1065a7f53e26SMarkus Armbruster { 1066a7f53e26SMarkus Armbruster if (blk->dev_ops && blk->dev_ops->is_medium_locked) { 1067a7f53e26SMarkus Armbruster return blk->dev_ops->is_medium_locked(blk->dev_opaque); 1068a7f53e26SMarkus Armbruster } 1069a7f53e26SMarkus Armbruster return false; 1070a7f53e26SMarkus Armbruster } 1071a7f53e26SMarkus Armbruster 1072a7f53e26SMarkus Armbruster /* 1073a7f53e26SMarkus Armbruster * Notify @blk's attached device model of a backend size change. 1074a7f53e26SMarkus Armbruster */ 10755c8cab48SKevin Wolf static void blk_root_resize(BdrvChild *child) 1076a7f53e26SMarkus Armbruster { 10775c8cab48SKevin Wolf BlockBackend *blk = child->opaque; 10785c8cab48SKevin Wolf 1079a7f53e26SMarkus Armbruster if (blk->dev_ops && blk->dev_ops->resize_cb) { 1080a7f53e26SMarkus Armbruster blk->dev_ops->resize_cb(blk->dev_opaque); 1081a7f53e26SMarkus Armbruster } 1082a7f53e26SMarkus Armbruster } 1083a7f53e26SMarkus Armbruster 10844be74634SMarkus Armbruster void blk_iostatus_enable(BlockBackend *blk) 10854be74634SMarkus Armbruster { 1086373340b2SMax Reitz blk->iostatus_enabled = true; 1087373340b2SMax Reitz blk->iostatus = BLOCK_DEVICE_IO_STATUS_OK; 1088373340b2SMax Reitz } 1089373340b2SMax Reitz 1090373340b2SMax Reitz /* The I/O status is only enabled if the drive explicitly 1091373340b2SMax Reitz * enables it _and_ the VM is configured to stop on errors */ 1092373340b2SMax Reitz bool blk_iostatus_is_enabled(const BlockBackend *blk) 1093373340b2SMax Reitz { 1094373340b2SMax Reitz return (blk->iostatus_enabled && 1095373340b2SMax Reitz (blk->on_write_error == BLOCKDEV_ON_ERROR_ENOSPC || 1096373340b2SMax Reitz blk->on_write_error == BLOCKDEV_ON_ERROR_STOP || 1097373340b2SMax Reitz blk->on_read_error == BLOCKDEV_ON_ERROR_STOP)); 1098373340b2SMax Reitz } 1099373340b2SMax Reitz 1100373340b2SMax Reitz BlockDeviceIoStatus blk_iostatus(const BlockBackend *blk) 1101373340b2SMax Reitz { 1102373340b2SMax Reitz return blk->iostatus; 1103373340b2SMax Reitz } 1104373340b2SMax Reitz 1105373340b2SMax Reitz void blk_iostatus_disable(BlockBackend *blk) 1106373340b2SMax Reitz { 1107373340b2SMax Reitz blk->iostatus_enabled = false; 1108373340b2SMax Reitz } 1109373340b2SMax Reitz 1110373340b2SMax Reitz void blk_iostatus_reset(BlockBackend *blk) 1111373340b2SMax Reitz { 1112373340b2SMax Reitz if (blk_iostatus_is_enabled(blk)) { 1113373340b2SMax Reitz blk->iostatus = BLOCK_DEVICE_IO_STATUS_OK; 1114373340b2SMax Reitz } 1115373340b2SMax Reitz } 1116373340b2SMax Reitz 1117373340b2SMax Reitz void blk_iostatus_set_err(BlockBackend *blk, int error) 1118373340b2SMax Reitz { 1119373340b2SMax Reitz assert(blk_iostatus_is_enabled(blk)); 1120373340b2SMax Reitz if (blk->iostatus == BLOCK_DEVICE_IO_STATUS_OK) { 1121373340b2SMax Reitz blk->iostatus = error == ENOSPC ? BLOCK_DEVICE_IO_STATUS_NOSPACE : 1122373340b2SMax Reitz BLOCK_DEVICE_IO_STATUS_FAILED; 1123373340b2SMax Reitz } 11244be74634SMarkus Armbruster } 11254be74634SMarkus Armbruster 1126c10c9d96SKevin Wolf void blk_set_allow_write_beyond_eof(BlockBackend *blk, bool allow) 1127c10c9d96SKevin Wolf { 1128c10c9d96SKevin Wolf blk->allow_write_beyond_eof = allow; 1129c10c9d96SKevin Wolf } 1130c10c9d96SKevin Wolf 1131980b0f94SKevin Wolf void blk_set_allow_aio_context_change(BlockBackend *blk, bool allow) 1132980b0f94SKevin Wolf { 1133980b0f94SKevin Wolf blk->allow_aio_context_change = allow; 1134980b0f94SKevin Wolf } 1135980b0f94SKevin Wolf 1136cf312932SKevin Wolf void blk_set_disable_request_queuing(BlockBackend *blk, bool disable) 1137cf312932SKevin Wolf { 1138cf312932SKevin Wolf blk->disable_request_queuing = disable; 1139cf312932SKevin Wolf } 1140cf312932SKevin Wolf 1141e7f7d676SMax Reitz static int blk_check_byte_request(BlockBackend *blk, int64_t offset, 1142e7f7d676SMax Reitz size_t size) 1143e7f7d676SMax Reitz { 1144e7f7d676SMax Reitz int64_t len; 1145e7f7d676SMax Reitz 1146e7f7d676SMax Reitz if (size > INT_MAX) { 1147e7f7d676SMax Reitz return -EIO; 1148e7f7d676SMax Reitz } 1149e7f7d676SMax Reitz 1150c09ba36cSMax Reitz if (!blk_is_available(blk)) { 1151e7f7d676SMax Reitz return -ENOMEDIUM; 1152e7f7d676SMax Reitz } 1153e7f7d676SMax Reitz 1154c10c9d96SKevin Wolf if (offset < 0) { 1155c10c9d96SKevin Wolf return -EIO; 1156c10c9d96SKevin Wolf } 1157c10c9d96SKevin Wolf 1158c10c9d96SKevin Wolf if (!blk->allow_write_beyond_eof) { 1159e7f7d676SMax Reitz len = blk_getlength(blk); 1160e7f7d676SMax Reitz if (len < 0) { 1161e7f7d676SMax Reitz return len; 1162e7f7d676SMax Reitz } 1163e7f7d676SMax Reitz 1164e7f7d676SMax Reitz if (offset > len || len - offset < size) { 1165e7f7d676SMax Reitz return -EIO; 1166e7f7d676SMax Reitz } 1167c10c9d96SKevin Wolf } 1168e7f7d676SMax Reitz 1169e7f7d676SMax Reitz return 0; 1170e7f7d676SMax Reitz } 1171e7f7d676SMax Reitz 11727f16476fSKevin Wolf /* To be called between exactly one pair of blk_inc/dec_in_flight() */ 1173cf312932SKevin Wolf static void coroutine_fn blk_wait_while_drained(BlockBackend *blk) 1174cf312932SKevin Wolf { 11757f16476fSKevin Wolf assert(blk->in_flight > 0); 11767f16476fSKevin Wolf 1177cf312932SKevin Wolf if (blk->quiesce_counter && !blk->disable_request_queuing) { 11787f16476fSKevin Wolf blk_dec_in_flight(blk); 1179cf312932SKevin Wolf qemu_co_queue_wait(&blk->queued_requests, NULL); 11807f16476fSKevin Wolf blk_inc_in_flight(blk); 1181cf312932SKevin Wolf } 1182cf312932SKevin Wolf } 1183cf312932SKevin Wolf 1184fbb92b67SKevin Wolf /* To be called between exactly one pair of blk_inc/dec_in_flight() */ 1185fbb92b67SKevin Wolf static int coroutine_fn 1186fbb92b67SKevin Wolf blk_do_preadv(BlockBackend *blk, int64_t offset, unsigned int bytes, 1187fbb92b67SKevin Wolf QEMUIOVector *qiov, BdrvRequestFlags flags) 11884be74634SMarkus Armbruster { 11891e98fefdSKevin Wolf int ret; 1190cf312932SKevin Wolf BlockDriverState *bs; 11911e98fefdSKevin Wolf 1192cf312932SKevin Wolf blk_wait_while_drained(blk); 1193cf312932SKevin Wolf 1194cf312932SKevin Wolf /* Call blk_bs() only after waiting, the graph may have changed */ 1195cf312932SKevin Wolf bs = blk_bs(blk); 119699723548SPaolo Bonzini trace_blk_co_preadv(blk, bs, offset, bytes, flags); 11971e98fefdSKevin Wolf 11981e98fefdSKevin Wolf ret = blk_check_byte_request(blk, offset, bytes); 1199e7f7d676SMax Reitz if (ret < 0) { 1200e7f7d676SMax Reitz return ret; 1201e7f7d676SMax Reitz } 1202e7f7d676SMax Reitz 120399723548SPaolo Bonzini bdrv_inc_in_flight(bs); 120499723548SPaolo Bonzini 1205441565b2SKevin Wolf /* throttling disk I/O */ 1206022cdc9fSManos Pitsidianakis if (blk->public.throttle_group_member.throttle_state) { 1207022cdc9fSManos Pitsidianakis throttle_group_co_io_limits_intercept(&blk->public.throttle_group_member, 1208022cdc9fSManos Pitsidianakis bytes, false); 1209441565b2SKevin Wolf } 1210441565b2SKevin Wolf 121199723548SPaolo Bonzini ret = bdrv_co_preadv(blk->root, offset, bytes, qiov, flags); 121299723548SPaolo Bonzini bdrv_dec_in_flight(bs); 121399723548SPaolo Bonzini return ret; 12141bf1cbc9SKevin Wolf } 12151bf1cbc9SKevin Wolf 1216fbb92b67SKevin Wolf int coroutine_fn blk_co_preadv(BlockBackend *blk, int64_t offset, 1217fbb92b67SKevin Wolf unsigned int bytes, QEMUIOVector *qiov, 1218fbb92b67SKevin Wolf BdrvRequestFlags flags) 1219fbb92b67SKevin Wolf { 1220fbb92b67SKevin Wolf int ret; 1221fbb92b67SKevin Wolf 1222fbb92b67SKevin Wolf blk_inc_in_flight(blk); 1223fbb92b67SKevin Wolf ret = blk_do_preadv(blk, offset, bytes, qiov, flags); 1224fbb92b67SKevin Wolf blk_dec_in_flight(blk); 1225fbb92b67SKevin Wolf 1226fbb92b67SKevin Wolf return ret; 1227fbb92b67SKevin Wolf } 1228fbb92b67SKevin Wolf 1229fbb92b67SKevin Wolf /* To be called between exactly one pair of blk_inc/dec_in_flight() */ 1230fbb92b67SKevin Wolf static int coroutine_fn 1231fbb92b67SKevin Wolf blk_do_pwritev_part(BlockBackend *blk, int64_t offset, unsigned int bytes, 1232b3016864SVladimir Sementsov-Ogievskiy QEMUIOVector *qiov, size_t qiov_offset, 1233a8823a3bSKevin Wolf BdrvRequestFlags flags) 1234a8823a3bSKevin Wolf { 1235bfd18d1eSKevin Wolf int ret; 1236cf312932SKevin Wolf BlockDriverState *bs; 1237bfd18d1eSKevin Wolf 1238cf312932SKevin Wolf blk_wait_while_drained(blk); 1239cf312932SKevin Wolf 1240cf312932SKevin Wolf /* Call blk_bs() only after waiting, the graph may have changed */ 1241cf312932SKevin Wolf bs = blk_bs(blk); 124299723548SPaolo Bonzini trace_blk_co_pwritev(blk, bs, offset, bytes, flags); 12431e98fefdSKevin Wolf 1244bfd18d1eSKevin Wolf ret = blk_check_byte_request(blk, offset, bytes); 1245a8823a3bSKevin Wolf if (ret < 0) { 1246a8823a3bSKevin Wolf return ret; 1247a8823a3bSKevin Wolf } 1248a8823a3bSKevin Wolf 124999723548SPaolo Bonzini bdrv_inc_in_flight(bs); 1250441565b2SKevin Wolf /* throttling disk I/O */ 1251022cdc9fSManos Pitsidianakis if (blk->public.throttle_group_member.throttle_state) { 1252022cdc9fSManos Pitsidianakis throttle_group_co_io_limits_intercept(&blk->public.throttle_group_member, 1253022cdc9fSManos Pitsidianakis bytes, true); 1254441565b2SKevin Wolf } 1255441565b2SKevin Wolf 1256bfd18d1eSKevin Wolf if (!blk->enable_write_cache) { 1257bfd18d1eSKevin Wolf flags |= BDRV_REQ_FUA; 1258bfd18d1eSKevin Wolf } 1259bfd18d1eSKevin Wolf 1260b3016864SVladimir Sementsov-Ogievskiy ret = bdrv_co_pwritev_part(blk->root, offset, bytes, qiov, qiov_offset, 1261b3016864SVladimir Sementsov-Ogievskiy flags); 126299723548SPaolo Bonzini bdrv_dec_in_flight(bs); 126399723548SPaolo Bonzini return ret; 1264a8823a3bSKevin Wolf } 1265a8823a3bSKevin Wolf 1266fbb92b67SKevin Wolf int coroutine_fn blk_co_pwritev_part(BlockBackend *blk, int64_t offset, 1267fbb92b67SKevin Wolf unsigned int bytes, 1268fbb92b67SKevin Wolf QEMUIOVector *qiov, size_t qiov_offset, 1269fbb92b67SKevin Wolf BdrvRequestFlags flags) 1270fbb92b67SKevin Wolf { 1271fbb92b67SKevin Wolf int ret; 1272fbb92b67SKevin Wolf 1273fbb92b67SKevin Wolf blk_inc_in_flight(blk); 1274fbb92b67SKevin Wolf ret = blk_do_pwritev_part(blk, offset, bytes, qiov, qiov_offset, flags); 1275fbb92b67SKevin Wolf blk_dec_in_flight(blk); 1276fbb92b67SKevin Wolf 1277fbb92b67SKevin Wolf return ret; 1278fbb92b67SKevin Wolf } 1279fbb92b67SKevin Wolf 1280b3016864SVladimir Sementsov-Ogievskiy int coroutine_fn blk_co_pwritev(BlockBackend *blk, int64_t offset, 1281b3016864SVladimir Sementsov-Ogievskiy unsigned int bytes, QEMUIOVector *qiov, 1282b3016864SVladimir Sementsov-Ogievskiy BdrvRequestFlags flags) 1283b3016864SVladimir Sementsov-Ogievskiy { 1284b3016864SVladimir Sementsov-Ogievskiy return blk_co_pwritev_part(blk, offset, bytes, qiov, 0, flags); 1285b3016864SVladimir Sementsov-Ogievskiy } 1286b3016864SVladimir Sementsov-Ogievskiy 12871bf1cbc9SKevin Wolf typedef struct BlkRwCo { 12881bf1cbc9SKevin Wolf BlockBackend *blk; 12891bf1cbc9SKevin Wolf int64_t offset; 1290c060332cSDeepa Srinivasan void *iobuf; 12911bf1cbc9SKevin Wolf int ret; 12921bf1cbc9SKevin Wolf BdrvRequestFlags flags; 12931bf1cbc9SKevin Wolf } BlkRwCo; 12941bf1cbc9SKevin Wolf 12951bf1cbc9SKevin Wolf static void blk_read_entry(void *opaque) 12961bf1cbc9SKevin Wolf { 12971bf1cbc9SKevin Wolf BlkRwCo *rwco = opaque; 1298c060332cSDeepa Srinivasan QEMUIOVector *qiov = rwco->iobuf; 12991bf1cbc9SKevin Wolf 1300fbb92b67SKevin Wolf rwco->ret = blk_do_preadv(rwco->blk, rwco->offset, qiov->size, 1301c060332cSDeepa Srinivasan qiov, rwco->flags); 13024720cbeeSKevin Wolf aio_wait_kick(); 13031bf1cbc9SKevin Wolf } 13041bf1cbc9SKevin Wolf 1305a8823a3bSKevin Wolf static void blk_write_entry(void *opaque) 1306a8823a3bSKevin Wolf { 1307a8823a3bSKevin Wolf BlkRwCo *rwco = opaque; 1308c060332cSDeepa Srinivasan QEMUIOVector *qiov = rwco->iobuf; 1309a8823a3bSKevin Wolf 1310fbb92b67SKevin Wolf rwco->ret = blk_do_pwritev_part(rwco->blk, rwco->offset, qiov->size, 1311fbb92b67SKevin Wolf qiov, 0, rwco->flags); 13124720cbeeSKevin Wolf aio_wait_kick(); 1313a8823a3bSKevin Wolf } 1314a8823a3bSKevin Wolf 1315a55d3fbaSKevin Wolf static int blk_prw(BlockBackend *blk, int64_t offset, uint8_t *buf, 1316a55d3fbaSKevin Wolf int64_t bytes, CoroutineEntry co_entry, 1317fc1453cdSKevin Wolf BdrvRequestFlags flags) 13181bf1cbc9SKevin Wolf { 1319ae5a9592SVladimir Sementsov-Ogievskiy QEMUIOVector qiov = QEMU_IOVEC_INIT_BUF(qiov, buf, bytes); 1320ae5a9592SVladimir Sementsov-Ogievskiy BlkRwCo rwco = { 13211bf1cbc9SKevin Wolf .blk = blk, 1322a55d3fbaSKevin Wolf .offset = offset, 1323c060332cSDeepa Srinivasan .iobuf = &qiov, 1324fc1453cdSKevin Wolf .flags = flags, 13251bf1cbc9SKevin Wolf .ret = NOT_DONE, 13261bf1cbc9SKevin Wolf }; 13271bf1cbc9SKevin Wolf 1328fbb92b67SKevin Wolf blk_inc_in_flight(blk); 132935f106e6SPaolo Bonzini if (qemu_in_coroutine()) { 133035f106e6SPaolo Bonzini /* Fast-path if already in coroutine context */ 133135f106e6SPaolo Bonzini co_entry(&rwco); 133235f106e6SPaolo Bonzini } else { 133335f106e6SPaolo Bonzini Coroutine *co = qemu_coroutine_create(co_entry, &rwco); 1334e92f0e19SFam Zheng bdrv_coroutine_enter(blk_bs(blk), co); 133588b062c2SPaolo Bonzini BDRV_POLL_WHILE(blk_bs(blk), rwco.ret == NOT_DONE); 133635f106e6SPaolo Bonzini } 1337fbb92b67SKevin Wolf blk_dec_in_flight(blk); 13381bf1cbc9SKevin Wolf 13391bf1cbc9SKevin Wolf return rwco.ret; 13404be74634SMarkus Armbruster } 13414be74634SMarkus Armbruster 1342d004bd52SEric Blake int blk_pwrite_zeroes(BlockBackend *blk, int64_t offset, 1343f5a5ca79SManos Pitsidianakis int bytes, BdrvRequestFlags flags) 13440df89e8eSKevin Wolf { 1345f5a5ca79SManos Pitsidianakis return blk_prw(blk, offset, NULL, bytes, blk_write_entry, 134616aaf975SKevin Wolf flags | BDRV_REQ_ZERO_WRITE); 13470df89e8eSKevin Wolf } 13480df89e8eSKevin Wolf 1349720ff280SKevin Wolf int blk_make_zero(BlockBackend *blk, BdrvRequestFlags flags) 1350720ff280SKevin Wolf { 1351720ff280SKevin Wolf return bdrv_make_zero(blk->root, flags); 1352720ff280SKevin Wolf } 1353720ff280SKevin Wolf 1354c90e2a9cSKevin Wolf void blk_inc_in_flight(BlockBackend *blk) 135533f2a757SStefan Hajnoczi { 135633f2a757SStefan Hajnoczi atomic_inc(&blk->in_flight); 135733f2a757SStefan Hajnoczi } 135833f2a757SStefan Hajnoczi 1359c90e2a9cSKevin Wolf void blk_dec_in_flight(BlockBackend *blk) 136033f2a757SStefan Hajnoczi { 136133f2a757SStefan Hajnoczi atomic_dec(&blk->in_flight); 1362cfe29d82SKevin Wolf aio_wait_kick(); 136333f2a757SStefan Hajnoczi } 136433f2a757SStefan Hajnoczi 1365e7f7d676SMax Reitz static void error_callback_bh(void *opaque) 1366e7f7d676SMax Reitz { 1367e7f7d676SMax Reitz struct BlockBackendAIOCB *acb = opaque; 136899723548SPaolo Bonzini 136933f2a757SStefan Hajnoczi blk_dec_in_flight(acb->blk); 1370e7f7d676SMax Reitz acb->common.cb(acb->common.opaque, acb->ret); 1371e7f7d676SMax Reitz qemu_aio_unref(acb); 1372e7f7d676SMax Reitz } 1373e7f7d676SMax Reitz 1374ca78ecfaSPeter Lieven BlockAIOCB *blk_abort_aio_request(BlockBackend *blk, 1375ca78ecfaSPeter Lieven BlockCompletionFunc *cb, 1376e7f7d676SMax Reitz void *opaque, int ret) 1377e7f7d676SMax Reitz { 1378e7f7d676SMax Reitz struct BlockBackendAIOCB *acb; 1379e7f7d676SMax Reitz 138033f2a757SStefan Hajnoczi blk_inc_in_flight(blk); 1381e7f7d676SMax Reitz acb = blk_aio_get(&block_backend_aiocb_info, blk, cb, opaque); 13824981bdecSMax Reitz acb->blk = blk; 1383e7f7d676SMax Reitz acb->ret = ret; 1384e7f7d676SMax Reitz 1385e4ec5ad4SPavel Dovgalyuk replay_bh_schedule_oneshot_event(blk_get_aio_context(blk), 1386e4ec5ad4SPavel Dovgalyuk error_callback_bh, acb); 1387e7f7d676SMax Reitz return &acb->common; 1388e7f7d676SMax Reitz } 1389e7f7d676SMax Reitz 139057d6a428SKevin Wolf typedef struct BlkAioEmAIOCB { 139157d6a428SKevin Wolf BlockAIOCB common; 139257d6a428SKevin Wolf BlkRwCo rwco; 13937fa84cd8SKevin Wolf int bytes; 139457d6a428SKevin Wolf bool has_returned; 139557d6a428SKevin Wolf } BlkAioEmAIOCB; 139657d6a428SKevin Wolf 13971d719ddcSStefan Hajnoczi static AioContext *blk_aio_em_aiocb_get_aio_context(BlockAIOCB *acb_) 13981d719ddcSStefan Hajnoczi { 13991d719ddcSStefan Hajnoczi BlkAioEmAIOCB *acb = container_of(acb_, BlkAioEmAIOCB, common); 14001d719ddcSStefan Hajnoczi 14011d719ddcSStefan Hajnoczi return blk_get_aio_context(acb->rwco.blk); 14021d719ddcSStefan Hajnoczi } 14031d719ddcSStefan Hajnoczi 140457d6a428SKevin Wolf static const AIOCBInfo blk_aio_em_aiocb_info = { 140557d6a428SKevin Wolf .aiocb_size = sizeof(BlkAioEmAIOCB), 14061d719ddcSStefan Hajnoczi .get_aio_context = blk_aio_em_aiocb_get_aio_context, 140757d6a428SKevin Wolf }; 140857d6a428SKevin Wolf 140957d6a428SKevin Wolf static void blk_aio_complete(BlkAioEmAIOCB *acb) 141057d6a428SKevin Wolf { 141157d6a428SKevin Wolf if (acb->has_returned) { 141257d6a428SKevin Wolf acb->common.cb(acb->common.opaque, acb->rwco.ret); 141346aaf2a5SKevin Wolf blk_dec_in_flight(acb->rwco.blk); 141457d6a428SKevin Wolf qemu_aio_unref(acb); 141557d6a428SKevin Wolf } 141657d6a428SKevin Wolf } 141757d6a428SKevin Wolf 141857d6a428SKevin Wolf static void blk_aio_complete_bh(void *opaque) 141957d6a428SKevin Wolf { 1420fffb6e12SPaolo Bonzini BlkAioEmAIOCB *acb = opaque; 1421fffb6e12SPaolo Bonzini assert(acb->has_returned); 1422fffb6e12SPaolo Bonzini blk_aio_complete(acb); 142357d6a428SKevin Wolf } 142457d6a428SKevin Wolf 14257fa84cd8SKevin Wolf static BlockAIOCB *blk_aio_prwv(BlockBackend *blk, int64_t offset, int bytes, 1426c060332cSDeepa Srinivasan void *iobuf, CoroutineEntry co_entry, 142757d6a428SKevin Wolf BdrvRequestFlags flags, 142857d6a428SKevin Wolf BlockCompletionFunc *cb, void *opaque) 142957d6a428SKevin Wolf { 143057d6a428SKevin Wolf BlkAioEmAIOCB *acb; 143157d6a428SKevin Wolf Coroutine *co; 143257d6a428SKevin Wolf 143333f2a757SStefan Hajnoczi blk_inc_in_flight(blk); 143457d6a428SKevin Wolf acb = blk_aio_get(&blk_aio_em_aiocb_info, blk, cb, opaque); 143557d6a428SKevin Wolf acb->rwco = (BlkRwCo) { 143657d6a428SKevin Wolf .blk = blk, 143757d6a428SKevin Wolf .offset = offset, 1438c060332cSDeepa Srinivasan .iobuf = iobuf, 143957d6a428SKevin Wolf .flags = flags, 144057d6a428SKevin Wolf .ret = NOT_DONE, 144157d6a428SKevin Wolf }; 14427fa84cd8SKevin Wolf acb->bytes = bytes; 144357d6a428SKevin Wolf acb->has_returned = false; 144457d6a428SKevin Wolf 14450b8b8753SPaolo Bonzini co = qemu_coroutine_create(co_entry, acb); 1446e92f0e19SFam Zheng bdrv_coroutine_enter(blk_bs(blk), co); 144757d6a428SKevin Wolf 144857d6a428SKevin Wolf acb->has_returned = true; 144957d6a428SKevin Wolf if (acb->rwco.ret != NOT_DONE) { 1450e4ec5ad4SPavel Dovgalyuk replay_bh_schedule_oneshot_event(blk_get_aio_context(blk), 1451fffb6e12SPaolo Bonzini blk_aio_complete_bh, acb); 145257d6a428SKevin Wolf } 145357d6a428SKevin Wolf 145457d6a428SKevin Wolf return &acb->common; 145557d6a428SKevin Wolf } 145657d6a428SKevin Wolf 145757d6a428SKevin Wolf static void blk_aio_read_entry(void *opaque) 145857d6a428SKevin Wolf { 145957d6a428SKevin Wolf BlkAioEmAIOCB *acb = opaque; 146057d6a428SKevin Wolf BlkRwCo *rwco = &acb->rwco; 1461c060332cSDeepa Srinivasan QEMUIOVector *qiov = rwco->iobuf; 146257d6a428SKevin Wolf 1463c060332cSDeepa Srinivasan assert(qiov->size == acb->bytes); 1464fbb92b67SKevin Wolf rwco->ret = blk_do_preadv(rwco->blk, rwco->offset, acb->bytes, 1465c060332cSDeepa Srinivasan qiov, rwco->flags); 146657d6a428SKevin Wolf blk_aio_complete(acb); 146757d6a428SKevin Wolf } 146857d6a428SKevin Wolf 146957d6a428SKevin Wolf static void blk_aio_write_entry(void *opaque) 147057d6a428SKevin Wolf { 147157d6a428SKevin Wolf BlkAioEmAIOCB *acb = opaque; 147257d6a428SKevin Wolf BlkRwCo *rwco = &acb->rwco; 1473c060332cSDeepa Srinivasan QEMUIOVector *qiov = rwco->iobuf; 147457d6a428SKevin Wolf 1475c060332cSDeepa Srinivasan assert(!qiov || qiov->size == acb->bytes); 1476fbb92b67SKevin Wolf rwco->ret = blk_do_pwritev_part(rwco->blk, rwco->offset, acb->bytes, 1477fbb92b67SKevin Wolf qiov, 0, rwco->flags); 147857d6a428SKevin Wolf blk_aio_complete(acb); 147957d6a428SKevin Wolf } 148057d6a428SKevin Wolf 1481d004bd52SEric Blake BlockAIOCB *blk_aio_pwrite_zeroes(BlockBackend *blk, int64_t offset, 1482983a1600SEric Blake int count, BdrvRequestFlags flags, 14834be74634SMarkus Armbruster BlockCompletionFunc *cb, void *opaque) 14844be74634SMarkus Armbruster { 1485983a1600SEric Blake return blk_aio_prwv(blk, offset, count, NULL, blk_aio_write_entry, 1486983a1600SEric Blake flags | BDRV_REQ_ZERO_WRITE, cb, opaque); 14874be74634SMarkus Armbruster } 14884be74634SMarkus Armbruster 14894be74634SMarkus Armbruster int blk_pread(BlockBackend *blk, int64_t offset, void *buf, int count) 14904be74634SMarkus Armbruster { 1491a55d3fbaSKevin Wolf int ret = blk_prw(blk, offset, buf, count, blk_read_entry, 0); 1492e7f7d676SMax Reitz if (ret < 0) { 1493e7f7d676SMax Reitz return ret; 1494e7f7d676SMax Reitz } 1495a55d3fbaSKevin Wolf return count; 14964be74634SMarkus Armbruster } 14974be74634SMarkus Armbruster 14988341f00dSEric Blake int blk_pwrite(BlockBackend *blk, int64_t offset, const void *buf, int count, 14998341f00dSEric Blake BdrvRequestFlags flags) 15004be74634SMarkus Armbruster { 15018341f00dSEric Blake int ret = blk_prw(blk, offset, (void *) buf, count, blk_write_entry, 15028341f00dSEric Blake flags); 1503e7f7d676SMax Reitz if (ret < 0) { 1504e7f7d676SMax Reitz return ret; 1505e7f7d676SMax Reitz } 1506a55d3fbaSKevin Wolf return count; 15074be74634SMarkus Armbruster } 15084be74634SMarkus Armbruster 15094be74634SMarkus Armbruster int64_t blk_getlength(BlockBackend *blk) 15104be74634SMarkus Armbruster { 1511c09ba36cSMax Reitz if (!blk_is_available(blk)) { 1512c09ba36cSMax Reitz return -ENOMEDIUM; 1513c09ba36cSMax Reitz } 1514c09ba36cSMax Reitz 1515f21d96d0SKevin Wolf return bdrv_getlength(blk_bs(blk)); 15164be74634SMarkus Armbruster } 15174be74634SMarkus Armbruster 15184be74634SMarkus Armbruster void blk_get_geometry(BlockBackend *blk, uint64_t *nb_sectors_ptr) 15194be74634SMarkus Armbruster { 1520f21d96d0SKevin Wolf if (!blk_bs(blk)) { 1521a46fc9c9SMax Reitz *nb_sectors_ptr = 0; 1522a46fc9c9SMax Reitz } else { 1523f21d96d0SKevin Wolf bdrv_get_geometry(blk_bs(blk), nb_sectors_ptr); 15244be74634SMarkus Armbruster } 1525a46fc9c9SMax Reitz } 15264be74634SMarkus Armbruster 15271ef01253SMax Reitz int64_t blk_nb_sectors(BlockBackend *blk) 15281ef01253SMax Reitz { 1529c09ba36cSMax Reitz if (!blk_is_available(blk)) { 1530c09ba36cSMax Reitz return -ENOMEDIUM; 1531c09ba36cSMax Reitz } 1532c09ba36cSMax Reitz 1533f21d96d0SKevin Wolf return bdrv_nb_sectors(blk_bs(blk)); 15341ef01253SMax Reitz } 15351ef01253SMax Reitz 153660cb2fa7SEric Blake BlockAIOCB *blk_aio_preadv(BlockBackend *blk, int64_t offset, 153760cb2fa7SEric Blake QEMUIOVector *qiov, BdrvRequestFlags flags, 153860cb2fa7SEric Blake BlockCompletionFunc *cb, void *opaque) 153960cb2fa7SEric Blake { 154060cb2fa7SEric Blake return blk_aio_prwv(blk, offset, qiov->size, qiov, 154160cb2fa7SEric Blake blk_aio_read_entry, flags, cb, opaque); 154260cb2fa7SEric Blake } 154360cb2fa7SEric Blake 154460cb2fa7SEric Blake BlockAIOCB *blk_aio_pwritev(BlockBackend *blk, int64_t offset, 154560cb2fa7SEric Blake QEMUIOVector *qiov, BdrvRequestFlags flags, 154660cb2fa7SEric Blake BlockCompletionFunc *cb, void *opaque) 154760cb2fa7SEric Blake { 154860cb2fa7SEric Blake return blk_aio_prwv(blk, offset, qiov->size, qiov, 154960cb2fa7SEric Blake blk_aio_write_entry, flags, cb, opaque); 155060cb2fa7SEric Blake } 155160cb2fa7SEric Blake 15524be74634SMarkus Armbruster void blk_aio_cancel(BlockAIOCB *acb) 15534be74634SMarkus Armbruster { 15544be74634SMarkus Armbruster bdrv_aio_cancel(acb); 15554be74634SMarkus Armbruster } 15564be74634SMarkus Armbruster 15574be74634SMarkus Armbruster void blk_aio_cancel_async(BlockAIOCB *acb) 15584be74634SMarkus Armbruster { 15594be74634SMarkus Armbruster bdrv_aio_cancel_async(acb); 15604be74634SMarkus Armbruster } 15614be74634SMarkus Armbruster 1562fbb92b67SKevin Wolf /* To be called between exactly one pair of blk_inc/dec_in_flight() */ 1563fbb92b67SKevin Wolf static int coroutine_fn 1564fbb92b67SKevin Wolf blk_do_ioctl(BlockBackend *blk, unsigned long int req, void *buf) 15654be74634SMarkus Armbruster { 1566cf312932SKevin Wolf blk_wait_while_drained(blk); 1567cf312932SKevin Wolf 1568c09ba36cSMax Reitz if (!blk_is_available(blk)) { 1569c09ba36cSMax Reitz return -ENOMEDIUM; 1570c09ba36cSMax Reitz } 1571c09ba36cSMax Reitz 157248af776aSKevin Wolf return bdrv_co_ioctl(blk_bs(blk), req, buf); 157348af776aSKevin Wolf } 157448af776aSKevin Wolf 157548af776aSKevin Wolf static void blk_ioctl_entry(void *opaque) 157648af776aSKevin Wolf { 157748af776aSKevin Wolf BlkRwCo *rwco = opaque; 1578c060332cSDeepa Srinivasan QEMUIOVector *qiov = rwco->iobuf; 1579c060332cSDeepa Srinivasan 1580fbb92b67SKevin Wolf rwco->ret = blk_do_ioctl(rwco->blk, rwco->offset, qiov->iov[0].iov_base); 15814720cbeeSKevin Wolf aio_wait_kick(); 158248af776aSKevin Wolf } 158348af776aSKevin Wolf 158448af776aSKevin Wolf int blk_ioctl(BlockBackend *blk, unsigned long int req, void *buf) 158548af776aSKevin Wolf { 158648af776aSKevin Wolf return blk_prw(blk, req, buf, 0, blk_ioctl_entry, 0); 158748af776aSKevin Wolf } 158848af776aSKevin Wolf 158948af776aSKevin Wolf static void blk_aio_ioctl_entry(void *opaque) 159048af776aSKevin Wolf { 159148af776aSKevin Wolf BlkAioEmAIOCB *acb = opaque; 159248af776aSKevin Wolf BlkRwCo *rwco = &acb->rwco; 159348af776aSKevin Wolf 1594fbb92b67SKevin Wolf rwco->ret = blk_do_ioctl(rwco->blk, rwco->offset, rwco->iobuf); 1595c060332cSDeepa Srinivasan 159648af776aSKevin Wolf blk_aio_complete(acb); 15974be74634SMarkus Armbruster } 15984be74634SMarkus Armbruster 15994be74634SMarkus Armbruster BlockAIOCB *blk_aio_ioctl(BlockBackend *blk, unsigned long int req, void *buf, 16004be74634SMarkus Armbruster BlockCompletionFunc *cb, void *opaque) 16014be74634SMarkus Armbruster { 1602c060332cSDeepa Srinivasan return blk_aio_prwv(blk, req, 0, buf, blk_aio_ioctl_entry, 0, cb, opaque); 16034be74634SMarkus Armbruster } 16044be74634SMarkus Armbruster 1605fbb92b67SKevin Wolf /* To be called between exactly one pair of blk_inc/dec_in_flight() */ 1606fbb92b67SKevin Wolf static int coroutine_fn 1607fbb92b67SKevin Wolf blk_do_pdiscard(BlockBackend *blk, int64_t offset, int bytes) 16082bb0dce7SMax Reitz { 1609cf312932SKevin Wolf int ret; 1610cf312932SKevin Wolf 1611cf312932SKevin Wolf blk_wait_while_drained(blk); 1612cf312932SKevin Wolf 1613cf312932SKevin Wolf ret = blk_check_byte_request(blk, offset, bytes); 1614e7f7d676SMax Reitz if (ret < 0) { 1615e7f7d676SMax Reitz return ret; 1616e7f7d676SMax Reitz } 1617e7f7d676SMax Reitz 16180b9fd3f4SFam Zheng return bdrv_co_pdiscard(blk->root, offset, bytes); 16192bb0dce7SMax Reitz } 16202bb0dce7SMax Reitz 1621564806c5SKevin Wolf static void blk_aio_pdiscard_entry(void *opaque) 1622564806c5SKevin Wolf { 1623564806c5SKevin Wolf BlkAioEmAIOCB *acb = opaque; 1624564806c5SKevin Wolf BlkRwCo *rwco = &acb->rwco; 1625564806c5SKevin Wolf 1626fbb92b67SKevin Wolf rwco->ret = blk_do_pdiscard(rwco->blk, rwco->offset, acb->bytes); 1627564806c5SKevin Wolf blk_aio_complete(acb); 1628564806c5SKevin Wolf } 1629564806c5SKevin Wolf 1630564806c5SKevin Wolf BlockAIOCB *blk_aio_pdiscard(BlockBackend *blk, 1631564806c5SKevin Wolf int64_t offset, int bytes, 1632564806c5SKevin Wolf BlockCompletionFunc *cb, void *opaque) 1633564806c5SKevin Wolf { 1634564806c5SKevin Wolf return blk_aio_prwv(blk, offset, bytes, NULL, blk_aio_pdiscard_entry, 0, 1635564806c5SKevin Wolf cb, opaque); 1636564806c5SKevin Wolf } 1637564806c5SKevin Wolf 1638fbb92b67SKevin Wolf int coroutine_fn blk_co_pdiscard(BlockBackend *blk, int64_t offset, int bytes) 1639fbb92b67SKevin Wolf { 1640fbb92b67SKevin Wolf int ret; 1641fbb92b67SKevin Wolf 1642fbb92b67SKevin Wolf blk_inc_in_flight(blk); 1643fbb92b67SKevin Wolf ret = blk_do_pdiscard(blk, offset, bytes); 1644fbb92b67SKevin Wolf blk_dec_in_flight(blk); 1645fbb92b67SKevin Wolf 1646fbb92b67SKevin Wolf return ret; 1647fbb92b67SKevin Wolf } 1648fbb92b67SKevin Wolf 1649564806c5SKevin Wolf static void blk_pdiscard_entry(void *opaque) 1650564806c5SKevin Wolf { 1651564806c5SKevin Wolf BlkRwCo *rwco = opaque; 1652564806c5SKevin Wolf QEMUIOVector *qiov = rwco->iobuf; 1653564806c5SKevin Wolf 1654fbb92b67SKevin Wolf rwco->ret = blk_do_pdiscard(rwco->blk, rwco->offset, qiov->size); 1655564806c5SKevin Wolf aio_wait_kick(); 1656564806c5SKevin Wolf } 1657564806c5SKevin Wolf 1658564806c5SKevin Wolf int blk_pdiscard(BlockBackend *blk, int64_t offset, int bytes) 1659564806c5SKevin Wolf { 1660564806c5SKevin Wolf return blk_prw(blk, offset, NULL, bytes, blk_pdiscard_entry, 0); 1661564806c5SKevin Wolf } 1662564806c5SKevin Wolf 1663fbb92b67SKevin Wolf /* To be called between exactly one pair of blk_inc/dec_in_flight() */ 1664fbb92b67SKevin Wolf static int coroutine_fn blk_do_flush(BlockBackend *blk) 16652bb0dce7SMax Reitz { 1666cf312932SKevin Wolf blk_wait_while_drained(blk); 1667cf312932SKevin Wolf 1668c09ba36cSMax Reitz if (!blk_is_available(blk)) { 1669c09ba36cSMax Reitz return -ENOMEDIUM; 1670c09ba36cSMax Reitz } 1671c09ba36cSMax Reitz 1672f21d96d0SKevin Wolf return bdrv_co_flush(blk_bs(blk)); 16732bb0dce7SMax Reitz } 16742bb0dce7SMax Reitz 1675564806c5SKevin Wolf static void blk_aio_flush_entry(void *opaque) 1676564806c5SKevin Wolf { 1677564806c5SKevin Wolf BlkAioEmAIOCB *acb = opaque; 1678564806c5SKevin Wolf BlkRwCo *rwco = &acb->rwco; 1679564806c5SKevin Wolf 1680fbb92b67SKevin Wolf rwco->ret = blk_do_flush(rwco->blk); 1681564806c5SKevin Wolf blk_aio_complete(acb); 1682564806c5SKevin Wolf } 1683564806c5SKevin Wolf 1684564806c5SKevin Wolf BlockAIOCB *blk_aio_flush(BlockBackend *blk, 1685564806c5SKevin Wolf BlockCompletionFunc *cb, void *opaque) 1686564806c5SKevin Wolf { 1687564806c5SKevin Wolf return blk_aio_prwv(blk, 0, 0, NULL, blk_aio_flush_entry, 0, cb, opaque); 1688564806c5SKevin Wolf } 1689564806c5SKevin Wolf 1690fbb92b67SKevin Wolf int coroutine_fn blk_co_flush(BlockBackend *blk) 1691fbb92b67SKevin Wolf { 1692fbb92b67SKevin Wolf int ret; 1693fbb92b67SKevin Wolf 1694fbb92b67SKevin Wolf blk_inc_in_flight(blk); 1695fbb92b67SKevin Wolf ret = blk_do_flush(blk); 1696fbb92b67SKevin Wolf blk_dec_in_flight(blk); 1697fbb92b67SKevin Wolf 1698fbb92b67SKevin Wolf return ret; 1699fbb92b67SKevin Wolf } 1700fbb92b67SKevin Wolf 1701be07a889SKevin Wolf static void blk_flush_entry(void *opaque) 17024be74634SMarkus Armbruster { 1703be07a889SKevin Wolf BlkRwCo *rwco = opaque; 1704fbb92b67SKevin Wolf rwco->ret = blk_do_flush(rwco->blk); 17054720cbeeSKevin Wolf aio_wait_kick(); 1706c09ba36cSMax Reitz } 1707c09ba36cSMax Reitz 1708be07a889SKevin Wolf int blk_flush(BlockBackend *blk) 1709be07a889SKevin Wolf { 1710be07a889SKevin Wolf return blk_prw(blk, 0, NULL, 0, blk_flush_entry, 0); 17114be74634SMarkus Armbruster } 17124be74634SMarkus Armbruster 171397b0385aSAlexander Yarygin void blk_drain(BlockBackend *blk) 171497b0385aSAlexander Yarygin { 171533f2a757SStefan Hajnoczi BlockDriverState *bs = blk_bs(blk); 171633f2a757SStefan Hajnoczi 171733f2a757SStefan Hajnoczi if (bs) { 171833f2a757SStefan Hajnoczi bdrv_drained_begin(bs); 171933f2a757SStefan Hajnoczi } 172033f2a757SStefan Hajnoczi 172133f2a757SStefan Hajnoczi /* We may have -ENOMEDIUM completions in flight */ 1722cfe29d82SKevin Wolf AIO_WAIT_WHILE(blk_get_aio_context(blk), 172333f2a757SStefan Hajnoczi atomic_mb_read(&blk->in_flight) > 0); 172433f2a757SStefan Hajnoczi 172533f2a757SStefan Hajnoczi if (bs) { 172633f2a757SStefan Hajnoczi bdrv_drained_end(bs); 172797b0385aSAlexander Yarygin } 1728a46fc9c9SMax Reitz } 172997b0385aSAlexander Yarygin 17304be74634SMarkus Armbruster void blk_drain_all(void) 17314be74634SMarkus Armbruster { 173233f2a757SStefan Hajnoczi BlockBackend *blk = NULL; 173333f2a757SStefan Hajnoczi 173433f2a757SStefan Hajnoczi bdrv_drain_all_begin(); 173533f2a757SStefan Hajnoczi 173633f2a757SStefan Hajnoczi while ((blk = blk_all_next(blk)) != NULL) { 173733f2a757SStefan Hajnoczi AioContext *ctx = blk_get_aio_context(blk); 173833f2a757SStefan Hajnoczi 173933f2a757SStefan Hajnoczi aio_context_acquire(ctx); 174033f2a757SStefan Hajnoczi 174133f2a757SStefan Hajnoczi /* We may have -ENOMEDIUM completions in flight */ 1742cfe29d82SKevin Wolf AIO_WAIT_WHILE(ctx, atomic_mb_read(&blk->in_flight) > 0); 174333f2a757SStefan Hajnoczi 174433f2a757SStefan Hajnoczi aio_context_release(ctx); 174533f2a757SStefan Hajnoczi } 174633f2a757SStefan Hajnoczi 174733f2a757SStefan Hajnoczi bdrv_drain_all_end(); 17484be74634SMarkus Armbruster } 17494be74634SMarkus Armbruster 1750373340b2SMax Reitz void blk_set_on_error(BlockBackend *blk, BlockdevOnError on_read_error, 1751373340b2SMax Reitz BlockdevOnError on_write_error) 1752373340b2SMax Reitz { 1753373340b2SMax Reitz blk->on_read_error = on_read_error; 1754373340b2SMax Reitz blk->on_write_error = on_write_error; 1755373340b2SMax Reitz } 1756373340b2SMax Reitz 17574be74634SMarkus Armbruster BlockdevOnError blk_get_on_error(BlockBackend *blk, bool is_read) 17584be74634SMarkus Armbruster { 1759373340b2SMax Reitz return is_read ? blk->on_read_error : blk->on_write_error; 17604be74634SMarkus Armbruster } 17614be74634SMarkus Armbruster 17624be74634SMarkus Armbruster BlockErrorAction blk_get_error_action(BlockBackend *blk, bool is_read, 17634be74634SMarkus Armbruster int error) 17644be74634SMarkus Armbruster { 1765373340b2SMax Reitz BlockdevOnError on_err = blk_get_on_error(blk, is_read); 1766373340b2SMax Reitz 1767373340b2SMax Reitz switch (on_err) { 1768373340b2SMax Reitz case BLOCKDEV_ON_ERROR_ENOSPC: 1769373340b2SMax Reitz return (error == ENOSPC) ? 1770373340b2SMax Reitz BLOCK_ERROR_ACTION_STOP : BLOCK_ERROR_ACTION_REPORT; 1771373340b2SMax Reitz case BLOCKDEV_ON_ERROR_STOP: 1772373340b2SMax Reitz return BLOCK_ERROR_ACTION_STOP; 1773373340b2SMax Reitz case BLOCKDEV_ON_ERROR_REPORT: 1774373340b2SMax Reitz return BLOCK_ERROR_ACTION_REPORT; 1775373340b2SMax Reitz case BLOCKDEV_ON_ERROR_IGNORE: 1776373340b2SMax Reitz return BLOCK_ERROR_ACTION_IGNORE; 17778c398252SKevin Wolf case BLOCKDEV_ON_ERROR_AUTO: 1778373340b2SMax Reitz default: 1779373340b2SMax Reitz abort(); 1780373340b2SMax Reitz } 17814be74634SMarkus Armbruster } 17824be74634SMarkus Armbruster 1783373340b2SMax Reitz static void send_qmp_error_event(BlockBackend *blk, 1784373340b2SMax Reitz BlockErrorAction action, 1785373340b2SMax Reitz bool is_read, int error) 1786373340b2SMax Reitz { 1787373340b2SMax Reitz IoOperationType optype; 1788bfe1a14cSKevin Wolf BlockDriverState *bs = blk_bs(blk); 1789373340b2SMax Reitz 1790373340b2SMax Reitz optype = is_read ? IO_OPERATION_TYPE_READ : IO_OPERATION_TYPE_WRITE; 1791bfe1a14cSKevin Wolf qapi_event_send_block_io_error(blk_name(blk), !!bs, 1792bfe1a14cSKevin Wolf bs ? bdrv_get_node_name(bs) : NULL, optype, 17932bf7e10fSKevin Wolf action, blk_iostatus_is_enabled(blk), 17943ab72385SPeter Xu error == ENOSPC, strerror(error)); 1795373340b2SMax Reitz } 1796373340b2SMax Reitz 1797373340b2SMax Reitz /* This is done by device models because, while the block layer knows 1798373340b2SMax Reitz * about the error, it does not know whether an operation comes from 1799373340b2SMax Reitz * the device or the block layer (from a job, for example). 1800373340b2SMax Reitz */ 18014be74634SMarkus Armbruster void blk_error_action(BlockBackend *blk, BlockErrorAction action, 18024be74634SMarkus Armbruster bool is_read, int error) 18034be74634SMarkus Armbruster { 1804373340b2SMax Reitz assert(error >= 0); 1805373340b2SMax Reitz 1806373340b2SMax Reitz if (action == BLOCK_ERROR_ACTION_STOP) { 1807373340b2SMax Reitz /* First set the iostatus, so that "info block" returns an iostatus 1808373340b2SMax Reitz * that matches the events raised so far (an additional error iostatus 1809373340b2SMax Reitz * is fine, but not a lost one). 1810373340b2SMax Reitz */ 1811373340b2SMax Reitz blk_iostatus_set_err(blk, error); 1812373340b2SMax Reitz 1813373340b2SMax Reitz /* Then raise the request to stop the VM and the event. 1814373340b2SMax Reitz * qemu_system_vmstop_request_prepare has two effects. First, 1815373340b2SMax Reitz * it ensures that the STOP event always comes after the 1816373340b2SMax Reitz * BLOCK_IO_ERROR event. Second, it ensures that even if management 1817373340b2SMax Reitz * can observe the STOP event and do a "cont" before the STOP 1818373340b2SMax Reitz * event is issued, the VM will not stop. In this case, vm_start() 1819373340b2SMax Reitz * also ensures that the STOP/RESUME pair of events is emitted. 1820373340b2SMax Reitz */ 1821373340b2SMax Reitz qemu_system_vmstop_request_prepare(); 1822373340b2SMax Reitz send_qmp_error_event(blk, action, is_read, error); 1823373340b2SMax Reitz qemu_system_vmstop_request(RUN_STATE_IO_ERROR); 1824373340b2SMax Reitz } else { 1825373340b2SMax Reitz send_qmp_error_event(blk, action, is_read, error); 1826373340b2SMax Reitz } 18274be74634SMarkus Armbruster } 18284be74634SMarkus Armbruster 182996710565SLi Qiang bool blk_is_read_only(BlockBackend *blk) 18304be74634SMarkus Armbruster { 1831f21d96d0SKevin Wolf BlockDriverState *bs = blk_bs(blk); 1832f21d96d0SKevin Wolf 1833f21d96d0SKevin Wolf if (bs) { 1834f21d96d0SKevin Wolf return bdrv_is_read_only(bs); 1835061959e8SMax Reitz } else { 1836061959e8SMax Reitz return blk->root_state.read_only; 1837061959e8SMax Reitz } 18384be74634SMarkus Armbruster } 18394be74634SMarkus Armbruster 184096710565SLi Qiang bool blk_is_sg(BlockBackend *blk) 18414be74634SMarkus Armbruster { 1842f21d96d0SKevin Wolf BlockDriverState *bs = blk_bs(blk); 1843f21d96d0SKevin Wolf 1844f21d96d0SKevin Wolf if (!bs) { 184596710565SLi Qiang return false; 1846a46fc9c9SMax Reitz } 1847a46fc9c9SMax Reitz 1848f21d96d0SKevin Wolf return bdrv_is_sg(bs); 18494be74634SMarkus Armbruster } 18504be74634SMarkus Armbruster 185196710565SLi Qiang bool blk_enable_write_cache(BlockBackend *blk) 18524be74634SMarkus Armbruster { 1853bfd18d1eSKevin Wolf return blk->enable_write_cache; 18544be74634SMarkus Armbruster } 18554be74634SMarkus Armbruster 18564be74634SMarkus Armbruster void blk_set_enable_write_cache(BlockBackend *blk, bool wce) 18574be74634SMarkus Armbruster { 1858bfd18d1eSKevin Wolf blk->enable_write_cache = wce; 18594be74634SMarkus Armbruster } 18604be74634SMarkus Armbruster 18612bb0dce7SMax Reitz void blk_invalidate_cache(BlockBackend *blk, Error **errp) 18622bb0dce7SMax Reitz { 1863f21d96d0SKevin Wolf BlockDriverState *bs = blk_bs(blk); 1864f21d96d0SKevin Wolf 1865f21d96d0SKevin Wolf if (!bs) { 1866c09ba36cSMax Reitz error_setg(errp, "Device '%s' has no medium", blk->name); 1867c09ba36cSMax Reitz return; 1868c09ba36cSMax Reitz } 1869c09ba36cSMax Reitz 1870f21d96d0SKevin Wolf bdrv_invalidate_cache(bs, errp); 18712bb0dce7SMax Reitz } 18722bb0dce7SMax Reitz 1873e031f750SMax Reitz bool blk_is_inserted(BlockBackend *blk) 18744be74634SMarkus Armbruster { 1875f21d96d0SKevin Wolf BlockDriverState *bs = blk_bs(blk); 1876f21d96d0SKevin Wolf 1877f21d96d0SKevin Wolf return bs && bdrv_is_inserted(bs); 1878db0284f8SMax Reitz } 1879db0284f8SMax Reitz 1880db0284f8SMax Reitz bool blk_is_available(BlockBackend *blk) 1881db0284f8SMax Reitz { 1882db0284f8SMax Reitz return blk_is_inserted(blk) && !blk_dev_is_tray_open(blk); 18834be74634SMarkus Armbruster } 18844be74634SMarkus Armbruster 18854be74634SMarkus Armbruster void blk_lock_medium(BlockBackend *blk, bool locked) 18864be74634SMarkus Armbruster { 1887f21d96d0SKevin Wolf BlockDriverState *bs = blk_bs(blk); 1888f21d96d0SKevin Wolf 1889f21d96d0SKevin Wolf if (bs) { 1890f21d96d0SKevin Wolf bdrv_lock_medium(bs, locked); 18914be74634SMarkus Armbruster } 1892a46fc9c9SMax Reitz } 18934be74634SMarkus Armbruster 18944be74634SMarkus Armbruster void blk_eject(BlockBackend *blk, bool eject_flag) 18954be74634SMarkus Armbruster { 1896f21d96d0SKevin Wolf BlockDriverState *bs = blk_bs(blk); 18972d76e724SKevin Wolf char *id; 18982d76e724SKevin Wolf 1899f21d96d0SKevin Wolf if (bs) { 1900f21d96d0SKevin Wolf bdrv_eject(bs, eject_flag); 1901c47ee043SJohn Snow } 19022d76e724SKevin Wolf 1903c47ee043SJohn Snow /* Whether or not we ejected on the backend, 1904c47ee043SJohn Snow * the frontend experienced a tray event. */ 19052d76e724SKevin Wolf id = blk_get_attached_dev_id(blk); 19062d76e724SKevin Wolf qapi_event_send_device_tray_moved(blk_name(blk), id, 19073ab72385SPeter Xu eject_flag); 19082d76e724SKevin Wolf g_free(id); 1909a46fc9c9SMax Reitz } 19104be74634SMarkus Armbruster 19114be74634SMarkus Armbruster int blk_get_flags(BlockBackend *blk) 19124be74634SMarkus Armbruster { 1913f21d96d0SKevin Wolf BlockDriverState *bs = blk_bs(blk); 1914f21d96d0SKevin Wolf 1915f21d96d0SKevin Wolf if (bs) { 1916f21d96d0SKevin Wolf return bdrv_get_flags(bs); 1917061959e8SMax Reitz } else { 1918061959e8SMax Reitz return blk->root_state.open_flags; 1919061959e8SMax Reitz } 19204be74634SMarkus Armbruster } 19214be74634SMarkus Armbruster 19224841211eSEric Blake /* Returns the minimum request alignment, in bytes; guaranteed nonzero */ 19234841211eSEric Blake uint32_t blk_get_request_alignment(BlockBackend *blk) 19244841211eSEric Blake { 19254841211eSEric Blake BlockDriverState *bs = blk_bs(blk); 19264841211eSEric Blake return bs ? bs->bl.request_alignment : BDRV_SECTOR_SIZE; 19274841211eSEric Blake } 19284841211eSEric Blake 19295def6b80SEric Blake /* Returns the maximum transfer length, in bytes; guaranteed nonzero */ 19305def6b80SEric Blake uint32_t blk_get_max_transfer(BlockBackend *blk) 1931454057b7SPeter Lieven { 1932f21d96d0SKevin Wolf BlockDriverState *bs = blk_bs(blk); 19335def6b80SEric Blake uint32_t max = 0; 1934f21d96d0SKevin Wolf 1935f21d96d0SKevin Wolf if (bs) { 19365def6b80SEric Blake max = bs->bl.max_transfer; 1937a46fc9c9SMax Reitz } 19385def6b80SEric Blake return MIN_NON_ZERO(max, INT_MAX); 1939454057b7SPeter Lieven } 1940454057b7SPeter Lieven 1941648296e0SStefan Hajnoczi int blk_get_max_iov(BlockBackend *blk) 1942648296e0SStefan Hajnoczi { 1943f21d96d0SKevin Wolf return blk->root->bs->bl.max_iov; 1944648296e0SStefan Hajnoczi } 1945648296e0SStefan Hajnoczi 19464be74634SMarkus Armbruster void blk_set_guest_block_size(BlockBackend *blk, int align) 19474be74634SMarkus Armbruster { 194868e9ec01SMax Reitz blk->guest_block_size = align; 19494be74634SMarkus Armbruster } 19504be74634SMarkus Armbruster 1951f1c17521SPaolo Bonzini void *blk_try_blockalign(BlockBackend *blk, size_t size) 1952f1c17521SPaolo Bonzini { 1953f21d96d0SKevin Wolf return qemu_try_blockalign(blk ? blk_bs(blk) : NULL, size); 1954f1c17521SPaolo Bonzini } 1955f1c17521SPaolo Bonzini 19564be74634SMarkus Armbruster void *blk_blockalign(BlockBackend *blk, size_t size) 19574be74634SMarkus Armbruster { 1958f21d96d0SKevin Wolf return qemu_blockalign(blk ? blk_bs(blk) : NULL, size); 19594be74634SMarkus Armbruster } 19604be74634SMarkus Armbruster 19614be74634SMarkus Armbruster bool blk_op_is_blocked(BlockBackend *blk, BlockOpType op, Error **errp) 19624be74634SMarkus Armbruster { 1963f21d96d0SKevin Wolf BlockDriverState *bs = blk_bs(blk); 1964f21d96d0SKevin Wolf 1965f21d96d0SKevin Wolf if (!bs) { 1966a46fc9c9SMax Reitz return false; 1967a46fc9c9SMax Reitz } 1968a46fc9c9SMax Reitz 1969f21d96d0SKevin Wolf return bdrv_op_is_blocked(bs, op, errp); 19704be74634SMarkus Armbruster } 19714be74634SMarkus Armbruster 19724be74634SMarkus Armbruster void blk_op_unblock(BlockBackend *blk, BlockOpType op, Error *reason) 19734be74634SMarkus Armbruster { 1974f21d96d0SKevin Wolf BlockDriverState *bs = blk_bs(blk); 1975f21d96d0SKevin Wolf 1976f21d96d0SKevin Wolf if (bs) { 1977f21d96d0SKevin Wolf bdrv_op_unblock(bs, op, reason); 19784be74634SMarkus Armbruster } 1979a46fc9c9SMax Reitz } 19804be74634SMarkus Armbruster 19814be74634SMarkus Armbruster void blk_op_block_all(BlockBackend *blk, Error *reason) 19824be74634SMarkus Armbruster { 1983f21d96d0SKevin Wolf BlockDriverState *bs = blk_bs(blk); 1984f21d96d0SKevin Wolf 1985f21d96d0SKevin Wolf if (bs) { 1986f21d96d0SKevin Wolf bdrv_op_block_all(bs, reason); 19874be74634SMarkus Armbruster } 1988a46fc9c9SMax Reitz } 19894be74634SMarkus Armbruster 19904be74634SMarkus Armbruster void blk_op_unblock_all(BlockBackend *blk, Error *reason) 19914be74634SMarkus Armbruster { 1992f21d96d0SKevin Wolf BlockDriverState *bs = blk_bs(blk); 1993f21d96d0SKevin Wolf 1994f21d96d0SKevin Wolf if (bs) { 1995f21d96d0SKevin Wolf bdrv_op_unblock_all(bs, reason); 19964be74634SMarkus Armbruster } 1997a46fc9c9SMax Reitz } 19984be74634SMarkus Armbruster 19994be74634SMarkus Armbruster AioContext *blk_get_aio_context(BlockBackend *blk) 20004be74634SMarkus Armbruster { 2001d861ab3aSKevin Wolf BlockDriverState *bs = blk_bs(blk); 2002d861ab3aSKevin Wolf 2003d861ab3aSKevin Wolf if (bs) { 2004132ada80SKevin Wolf AioContext *ctx = bdrv_get_aio_context(blk_bs(blk)); 2005132ada80SKevin Wolf assert(ctx == blk->ctx); 20064981bdecSMax Reitz } 20074981bdecSMax Reitz 2008d861ab3aSKevin Wolf return blk->ctx; 2009d861ab3aSKevin Wolf } 2010d861ab3aSKevin Wolf 20114981bdecSMax Reitz static AioContext *blk_aiocb_get_aio_context(BlockAIOCB *acb) 20124981bdecSMax Reitz { 20134981bdecSMax Reitz BlockBackendAIOCB *blk_acb = DO_UPCAST(BlockBackendAIOCB, common, acb); 20144981bdecSMax Reitz return blk_get_aio_context(blk_acb->blk); 20154be74634SMarkus Armbruster } 20164be74634SMarkus Armbruster 201797896a48SKevin Wolf static int blk_do_set_aio_context(BlockBackend *blk, AioContext *new_context, 201897896a48SKevin Wolf bool update_root_node, Error **errp) 20194be74634SMarkus Armbruster { 2020f21d96d0SKevin Wolf BlockDriverState *bs = blk_bs(blk); 2021c61791fcSManos Pitsidianakis ThrottleGroupMember *tgm = &blk->public.throttle_group_member; 202297896a48SKevin Wolf int ret; 2023f21d96d0SKevin Wolf 2024f21d96d0SKevin Wolf if (bs) { 202597896a48SKevin Wolf if (update_root_node) { 202697896a48SKevin Wolf ret = bdrv_child_try_set_aio_context(bs, new_context, blk->root, 202797896a48SKevin Wolf errp); 202897896a48SKevin Wolf if (ret < 0) { 202997896a48SKevin Wolf return ret; 203097896a48SKevin Wolf } 203197896a48SKevin Wolf } 2032c61791fcSManos Pitsidianakis if (tgm->throttle_state) { 2033dc868fb0SStefan Hajnoczi bdrv_drained_begin(bs); 2034c61791fcSManos Pitsidianakis throttle_group_detach_aio_context(tgm); 2035c61791fcSManos Pitsidianakis throttle_group_attach_aio_context(tgm, new_context); 2036dc868fb0SStefan Hajnoczi bdrv_drained_end(bs); 20377ca7f0f6SKevin Wolf } 203838475269SKevin Wolf } 203938475269SKevin Wolf 2040d861ab3aSKevin Wolf blk->ctx = new_context; 204197896a48SKevin Wolf return 0; 204297896a48SKevin Wolf } 204397896a48SKevin Wolf 204497896a48SKevin Wolf int blk_set_aio_context(BlockBackend *blk, AioContext *new_context, 204597896a48SKevin Wolf Error **errp) 204638475269SKevin Wolf { 204797896a48SKevin Wolf return blk_do_set_aio_context(blk, new_context, true, errp); 204838475269SKevin Wolf } 204938475269SKevin Wolf 205038475269SKevin Wolf static bool blk_root_can_set_aio_ctx(BdrvChild *child, AioContext *ctx, 205138475269SKevin Wolf GSList **ignore, Error **errp) 205238475269SKevin Wolf { 205338475269SKevin Wolf BlockBackend *blk = child->opaque; 205438475269SKevin Wolf 2055980b0f94SKevin Wolf if (blk->allow_aio_context_change) { 2056980b0f94SKevin Wolf return true; 2057980b0f94SKevin Wolf } 2058980b0f94SKevin Wolf 205938475269SKevin Wolf /* Only manually created BlockBackends that are not attached to anything 206038475269SKevin Wolf * can change their AioContext without updating their user. */ 206138475269SKevin Wolf if (!blk->name || blk->dev) { 206238475269SKevin Wolf /* TODO Add BB name/QOM path */ 206338475269SKevin Wolf error_setg(errp, "Cannot change iothread of active block backend"); 206438475269SKevin Wolf return false; 206538475269SKevin Wolf } 206638475269SKevin Wolf 206738475269SKevin Wolf return true; 206838475269SKevin Wolf } 206938475269SKevin Wolf 207038475269SKevin Wolf static void blk_root_set_aio_ctx(BdrvChild *child, AioContext *ctx, 207138475269SKevin Wolf GSList **ignore) 207238475269SKevin Wolf { 207338475269SKevin Wolf BlockBackend *blk = child->opaque; 207497896a48SKevin Wolf blk_do_set_aio_context(blk, ctx, false, &error_abort); 207538475269SKevin Wolf } 20764be74634SMarkus Armbruster 20772019ba0aSMax Reitz void blk_add_aio_context_notifier(BlockBackend *blk, 20782019ba0aSMax Reitz void (*attached_aio_context)(AioContext *new_context, void *opaque), 20792019ba0aSMax Reitz void (*detach_aio_context)(void *opaque), void *opaque) 20802019ba0aSMax Reitz { 2081d03654eaSStefan Hajnoczi BlockBackendAioNotifier *notifier; 2082f21d96d0SKevin Wolf BlockDriverState *bs = blk_bs(blk); 2083f21d96d0SKevin Wolf 2084d03654eaSStefan Hajnoczi notifier = g_new(BlockBackendAioNotifier, 1); 2085d03654eaSStefan Hajnoczi notifier->attached_aio_context = attached_aio_context; 2086d03654eaSStefan Hajnoczi notifier->detach_aio_context = detach_aio_context; 2087d03654eaSStefan Hajnoczi notifier->opaque = opaque; 2088d03654eaSStefan Hajnoczi QLIST_INSERT_HEAD(&blk->aio_notifiers, notifier, list); 2089d03654eaSStefan Hajnoczi 2090f21d96d0SKevin Wolf if (bs) { 2091f21d96d0SKevin Wolf bdrv_add_aio_context_notifier(bs, attached_aio_context, 20922019ba0aSMax Reitz detach_aio_context, opaque); 20932019ba0aSMax Reitz } 2094a46fc9c9SMax Reitz } 20952019ba0aSMax Reitz 20962019ba0aSMax Reitz void blk_remove_aio_context_notifier(BlockBackend *blk, 20972019ba0aSMax Reitz void (*attached_aio_context)(AioContext *, 20982019ba0aSMax Reitz void *), 20992019ba0aSMax Reitz void (*detach_aio_context)(void *), 21002019ba0aSMax Reitz void *opaque) 21012019ba0aSMax Reitz { 2102d03654eaSStefan Hajnoczi BlockBackendAioNotifier *notifier; 2103f21d96d0SKevin Wolf BlockDriverState *bs = blk_bs(blk); 2104f21d96d0SKevin Wolf 2105f21d96d0SKevin Wolf if (bs) { 2106f21d96d0SKevin Wolf bdrv_remove_aio_context_notifier(bs, attached_aio_context, 21072019ba0aSMax Reitz detach_aio_context, opaque); 21082019ba0aSMax Reitz } 2109d03654eaSStefan Hajnoczi 2110d03654eaSStefan Hajnoczi QLIST_FOREACH(notifier, &blk->aio_notifiers, list) { 2111d03654eaSStefan Hajnoczi if (notifier->attached_aio_context == attached_aio_context && 2112d03654eaSStefan Hajnoczi notifier->detach_aio_context == detach_aio_context && 2113d03654eaSStefan Hajnoczi notifier->opaque == opaque) { 2114d03654eaSStefan Hajnoczi QLIST_REMOVE(notifier, list); 2115d03654eaSStefan Hajnoczi g_free(notifier); 2116d03654eaSStefan Hajnoczi return; 2117d03654eaSStefan Hajnoczi } 2118d03654eaSStefan Hajnoczi } 2119d03654eaSStefan Hajnoczi 2120d03654eaSStefan Hajnoczi abort(); 2121a46fc9c9SMax Reitz } 21222019ba0aSMax Reitz 21233301f6c6SMax Reitz void blk_add_remove_bs_notifier(BlockBackend *blk, Notifier *notify) 21243301f6c6SMax Reitz { 21253301f6c6SMax Reitz notifier_list_add(&blk->remove_bs_notifiers, notify); 21263301f6c6SMax Reitz } 21273301f6c6SMax Reitz 21283301f6c6SMax Reitz void blk_add_insert_bs_notifier(BlockBackend *blk, Notifier *notify) 21293301f6c6SMax Reitz { 21303301f6c6SMax Reitz notifier_list_add(&blk->insert_bs_notifiers, notify); 21313301f6c6SMax Reitz } 21323301f6c6SMax Reitz 21334be74634SMarkus Armbruster void blk_io_plug(BlockBackend *blk) 21344be74634SMarkus Armbruster { 2135f21d96d0SKevin Wolf BlockDriverState *bs = blk_bs(blk); 2136f21d96d0SKevin Wolf 2137f21d96d0SKevin Wolf if (bs) { 2138f21d96d0SKevin Wolf bdrv_io_plug(bs); 21394be74634SMarkus Armbruster } 2140a46fc9c9SMax Reitz } 21414be74634SMarkus Armbruster 21424be74634SMarkus Armbruster void blk_io_unplug(BlockBackend *blk) 21434be74634SMarkus Armbruster { 2144f21d96d0SKevin Wolf BlockDriverState *bs = blk_bs(blk); 2145f21d96d0SKevin Wolf 2146f21d96d0SKevin Wolf if (bs) { 2147f21d96d0SKevin Wolf bdrv_io_unplug(bs); 21484be74634SMarkus Armbruster } 2149a46fc9c9SMax Reitz } 21504be74634SMarkus Armbruster 21514be74634SMarkus Armbruster BlockAcctStats *blk_get_stats(BlockBackend *blk) 21524be74634SMarkus Armbruster { 21537f0e9da6SMax Reitz return &blk->stats; 21544be74634SMarkus Armbruster } 21554be74634SMarkus Armbruster 21564be74634SMarkus Armbruster void *blk_aio_get(const AIOCBInfo *aiocb_info, BlockBackend *blk, 21574be74634SMarkus Armbruster BlockCompletionFunc *cb, void *opaque) 21584be74634SMarkus Armbruster { 21594be74634SMarkus Armbruster return qemu_aio_get(aiocb_info, blk_bs(blk), cb, opaque); 21604be74634SMarkus Armbruster } 21611ef01253SMax Reitz 2162d004bd52SEric Blake int coroutine_fn blk_co_pwrite_zeroes(BlockBackend *blk, int64_t offset, 2163f5a5ca79SManos Pitsidianakis int bytes, BdrvRequestFlags flags) 21641ef01253SMax Reitz { 2165f5a5ca79SManos Pitsidianakis return blk_co_pwritev(blk, offset, bytes, NULL, 216616aaf975SKevin Wolf flags | BDRV_REQ_ZERO_WRITE); 21671ef01253SMax Reitz } 21681ef01253SMax Reitz 2169fe5c1355SPavel Butsykin int blk_pwrite_compressed(BlockBackend *blk, int64_t offset, const void *buf, 2170fe5c1355SPavel Butsykin int count) 21711ef01253SMax Reitz { 217235fadca8SPavel Butsykin return blk_prw(blk, offset, (void *) buf, count, blk_write_entry, 217335fadca8SPavel Butsykin BDRV_REQ_WRITE_COMPRESSED); 21741ef01253SMax Reitz } 21751ef01253SMax Reitz 2176c80d8b06SMax Reitz int blk_truncate(BlockBackend *blk, int64_t offset, bool exact, 21778c6242b6SKevin Wolf PreallocMode prealloc, BdrvRequestFlags flags, Error **errp) 21781ef01253SMax Reitz { 2179c09ba36cSMax Reitz if (!blk_is_available(blk)) { 2180ed3d2ec9SMax Reitz error_setg(errp, "No medium inserted"); 2181c09ba36cSMax Reitz return -ENOMEDIUM; 2182c09ba36cSMax Reitz } 2183c09ba36cSMax Reitz 21848c6242b6SKevin Wolf return bdrv_truncate(blk->root, offset, exact, prealloc, flags, errp); 21851ef01253SMax Reitz } 21861ef01253SMax Reitz 21871ef01253SMax Reitz int blk_save_vmstate(BlockBackend *blk, const uint8_t *buf, 21881ef01253SMax Reitz int64_t pos, int size) 21891ef01253SMax Reitz { 2190bfd18d1eSKevin Wolf int ret; 2191bfd18d1eSKevin Wolf 2192c09ba36cSMax Reitz if (!blk_is_available(blk)) { 2193c09ba36cSMax Reitz return -ENOMEDIUM; 2194c09ba36cSMax Reitz } 2195c09ba36cSMax Reitz 2196bfd18d1eSKevin Wolf ret = bdrv_save_vmstate(blk_bs(blk), buf, pos, size); 2197bfd18d1eSKevin Wolf if (ret < 0) { 2198bfd18d1eSKevin Wolf return ret; 2199bfd18d1eSKevin Wolf } 2200bfd18d1eSKevin Wolf 2201bfd18d1eSKevin Wolf if (ret == size && !blk->enable_write_cache) { 2202bfd18d1eSKevin Wolf ret = bdrv_flush(blk_bs(blk)); 2203bfd18d1eSKevin Wolf } 2204bfd18d1eSKevin Wolf 2205bfd18d1eSKevin Wolf return ret < 0 ? ret : size; 22061ef01253SMax Reitz } 22071ef01253SMax Reitz 22081ef01253SMax Reitz int blk_load_vmstate(BlockBackend *blk, uint8_t *buf, int64_t pos, int size) 22091ef01253SMax Reitz { 2210c09ba36cSMax Reitz if (!blk_is_available(blk)) { 2211c09ba36cSMax Reitz return -ENOMEDIUM; 2212c09ba36cSMax Reitz } 2213c09ba36cSMax Reitz 2214f21d96d0SKevin Wolf return bdrv_load_vmstate(blk_bs(blk), buf, pos, size); 22151ef01253SMax Reitz } 2216f0272c4dSEkaterina Tumanova 2217f0272c4dSEkaterina Tumanova int blk_probe_blocksizes(BlockBackend *blk, BlockSizes *bsz) 2218f0272c4dSEkaterina Tumanova { 2219c09ba36cSMax Reitz if (!blk_is_available(blk)) { 2220c09ba36cSMax Reitz return -ENOMEDIUM; 2221c09ba36cSMax Reitz } 2222c09ba36cSMax Reitz 2223f21d96d0SKevin Wolf return bdrv_probe_blocksizes(blk_bs(blk), bsz); 2224f0272c4dSEkaterina Tumanova } 2225f0272c4dSEkaterina Tumanova 2226f0272c4dSEkaterina Tumanova int blk_probe_geometry(BlockBackend *blk, HDGeometry *geo) 2227f0272c4dSEkaterina Tumanova { 2228c09ba36cSMax Reitz if (!blk_is_available(blk)) { 2229c09ba36cSMax Reitz return -ENOMEDIUM; 2230c09ba36cSMax Reitz } 2231c09ba36cSMax Reitz 2232f21d96d0SKevin Wolf return bdrv_probe_geometry(blk_bs(blk), geo); 2233f0272c4dSEkaterina Tumanova } 2234281d22d8SMax Reitz 2235281d22d8SMax Reitz /* 2236281d22d8SMax Reitz * Updates the BlockBackendRootState object with data from the currently 2237281d22d8SMax Reitz * attached BlockDriverState. 2238281d22d8SMax Reitz */ 2239281d22d8SMax Reitz void blk_update_root_state(BlockBackend *blk) 2240281d22d8SMax Reitz { 2241f21d96d0SKevin Wolf assert(blk->root); 2242281d22d8SMax Reitz 2243f21d96d0SKevin Wolf blk->root_state.open_flags = blk->root->bs->open_flags; 2244f21d96d0SKevin Wolf blk->root_state.read_only = blk->root->bs->read_only; 2245f21d96d0SKevin Wolf blk->root_state.detect_zeroes = blk->root->bs->detect_zeroes; 2246281d22d8SMax Reitz } 2247281d22d8SMax Reitz 224838cb18f5SMax Reitz /* 2249b85114f8SKevin Wolf * Returns the detect-zeroes setting to be used for bdrv_open() of a 2250b85114f8SKevin Wolf * BlockDriverState which is supposed to inherit the root state. 225138cb18f5SMax Reitz */ 2252b85114f8SKevin Wolf bool blk_get_detect_zeroes_from_root_state(BlockBackend *blk) 225338cb18f5SMax Reitz { 2254b85114f8SKevin Wolf return blk->root_state.detect_zeroes; 225538cb18f5SMax Reitz } 225638cb18f5SMax Reitz 225738cb18f5SMax Reitz /* 225838cb18f5SMax Reitz * Returns the flags to be used for bdrv_open() of a BlockDriverState which is 225938cb18f5SMax Reitz * supposed to inherit the root state. 226038cb18f5SMax Reitz */ 226138cb18f5SMax Reitz int blk_get_open_flags_from_root_state(BlockBackend *blk) 226238cb18f5SMax Reitz { 226338cb18f5SMax Reitz int bs_flags; 226438cb18f5SMax Reitz 226538cb18f5SMax Reitz bs_flags = blk->root_state.read_only ? 0 : BDRV_O_RDWR; 226638cb18f5SMax Reitz bs_flags |= blk->root_state.open_flags & ~BDRV_O_RDWR; 226738cb18f5SMax Reitz 226838cb18f5SMax Reitz return bs_flags; 226938cb18f5SMax Reitz } 227038cb18f5SMax Reitz 2271281d22d8SMax Reitz BlockBackendRootState *blk_get_root_state(BlockBackend *blk) 2272281d22d8SMax Reitz { 2273281d22d8SMax Reitz return &blk->root_state; 2274281d22d8SMax Reitz } 22751393f212SMax Reitz 22761393f212SMax Reitz int blk_commit_all(void) 22771393f212SMax Reitz { 2278fe1a9cbcSMax Reitz BlockBackend *blk = NULL; 2279fe1a9cbcSMax Reitz 2280fe1a9cbcSMax Reitz while ((blk = blk_all_next(blk)) != NULL) { 2281fe1a9cbcSMax Reitz AioContext *aio_context = blk_get_aio_context(blk); 2282*9a71b9deSMax Reitz BlockDriverState *unfiltered_bs = bdrv_skip_filters(blk_bs(blk)); 2283fe1a9cbcSMax Reitz 2284fe1a9cbcSMax Reitz aio_context_acquire(aio_context); 2285*9a71b9deSMax Reitz if (blk_is_inserted(blk) && bdrv_cow_child(unfiltered_bs)) { 2286*9a71b9deSMax Reitz int ret; 2287*9a71b9deSMax Reitz 2288*9a71b9deSMax Reitz ret = bdrv_commit(unfiltered_bs); 2289fe1a9cbcSMax Reitz if (ret < 0) { 2290fe1a9cbcSMax Reitz aio_context_release(aio_context); 2291fe1a9cbcSMax Reitz return ret; 2292fe1a9cbcSMax Reitz } 2293fe1a9cbcSMax Reitz } 2294fe1a9cbcSMax Reitz aio_context_release(aio_context); 2295fe1a9cbcSMax Reitz } 2296fe1a9cbcSMax Reitz return 0; 2297fe1a9cbcSMax Reitz } 2298fe1a9cbcSMax Reitz 229997148076SKevin Wolf 230097148076SKevin Wolf /* throttling disk I/O limits */ 230197148076SKevin Wolf void blk_set_io_limits(BlockBackend *blk, ThrottleConfig *cfg) 230297148076SKevin Wolf { 2303022cdc9fSManos Pitsidianakis throttle_group_config(&blk->public.throttle_group_member, cfg); 230497148076SKevin Wolf } 230597148076SKevin Wolf 230697148076SKevin Wolf void blk_io_limits_disable(BlockBackend *blk) 230797148076SKevin Wolf { 230848bf7ea8SAlberto Garcia BlockDriverState *bs = blk_bs(blk); 230948bf7ea8SAlberto Garcia ThrottleGroupMember *tgm = &blk->public.throttle_group_member; 231048bf7ea8SAlberto Garcia assert(tgm->throttle_state); 231148bf7ea8SAlberto Garcia if (bs) { 231248bf7ea8SAlberto Garcia bdrv_drained_begin(bs); 231348bf7ea8SAlberto Garcia } 231448bf7ea8SAlberto Garcia throttle_group_unregister_tgm(tgm); 231548bf7ea8SAlberto Garcia if (bs) { 231648bf7ea8SAlberto Garcia bdrv_drained_end(bs); 231748bf7ea8SAlberto Garcia } 231897148076SKevin Wolf } 231997148076SKevin Wolf 232097148076SKevin Wolf /* should be called before blk_set_io_limits if a limit is set */ 232197148076SKevin Wolf void blk_io_limits_enable(BlockBackend *blk, const char *group) 232297148076SKevin Wolf { 2323022cdc9fSManos Pitsidianakis assert(!blk->public.throttle_group_member.throttle_state); 2324c61791fcSManos Pitsidianakis throttle_group_register_tgm(&blk->public.throttle_group_member, 2325c61791fcSManos Pitsidianakis group, blk_get_aio_context(blk)); 232697148076SKevin Wolf } 232797148076SKevin Wolf 232897148076SKevin Wolf void blk_io_limits_update_group(BlockBackend *blk, const char *group) 232997148076SKevin Wolf { 233097148076SKevin Wolf /* this BB is not part of any group */ 2331022cdc9fSManos Pitsidianakis if (!blk->public.throttle_group_member.throttle_state) { 233297148076SKevin Wolf return; 233397148076SKevin Wolf } 233497148076SKevin Wolf 233597148076SKevin Wolf /* this BB is a part of the same group than the one we want */ 2336022cdc9fSManos Pitsidianakis if (!g_strcmp0(throttle_group_get_name(&blk->public.throttle_group_member), 2337022cdc9fSManos Pitsidianakis group)) { 233897148076SKevin Wolf return; 233997148076SKevin Wolf } 234097148076SKevin Wolf 234197148076SKevin Wolf /* need to change the group this bs belong to */ 234297148076SKevin Wolf blk_io_limits_disable(blk); 234397148076SKevin Wolf blk_io_limits_enable(blk, group); 234497148076SKevin Wolf } 2345c2066af0SKevin Wolf 2346c2066af0SKevin Wolf static void blk_root_drained_begin(BdrvChild *child) 2347c2066af0SKevin Wolf { 2348c2066af0SKevin Wolf BlockBackend *blk = child->opaque; 2349c2066af0SKevin Wolf 2350f4d9cc88SJohn Snow if (++blk->quiesce_counter == 1) { 2351f4d9cc88SJohn Snow if (blk->dev_ops && blk->dev_ops->drained_begin) { 2352f4d9cc88SJohn Snow blk->dev_ops->drained_begin(blk->dev_opaque); 2353f4d9cc88SJohn Snow } 2354f4d9cc88SJohn Snow } 2355f4d9cc88SJohn Snow 235636fe1331SKevin Wolf /* Note that blk->root may not be accessible here yet if we are just 235736fe1331SKevin Wolf * attaching to a BlockDriverState that is drained. Use child instead. */ 235836fe1331SKevin Wolf 2359022cdc9fSManos Pitsidianakis if (atomic_fetch_inc(&blk->public.throttle_group_member.io_limits_disabled) == 0) { 2360022cdc9fSManos Pitsidianakis throttle_group_restart_tgm(&blk->public.throttle_group_member); 2361c2066af0SKevin Wolf } 2362c2066af0SKevin Wolf } 2363c2066af0SKevin Wolf 2364fe5258a5SKevin Wolf static bool blk_root_drained_poll(BdrvChild *child) 2365fe5258a5SKevin Wolf { 2366fe5258a5SKevin Wolf BlockBackend *blk = child->opaque; 2367fe5258a5SKevin Wolf assert(blk->quiesce_counter); 2368fe5258a5SKevin Wolf return !!blk->in_flight; 2369fe5258a5SKevin Wolf } 2370fe5258a5SKevin Wolf 2371e037c09cSMax Reitz static void blk_root_drained_end(BdrvChild *child, int *drained_end_counter) 2372c2066af0SKevin Wolf { 2373c2066af0SKevin Wolf BlockBackend *blk = child->opaque; 2374f4d9cc88SJohn Snow assert(blk->quiesce_counter); 2375c2066af0SKevin Wolf 2376022cdc9fSManos Pitsidianakis assert(blk->public.throttle_group_member.io_limits_disabled); 2377022cdc9fSManos Pitsidianakis atomic_dec(&blk->public.throttle_group_member.io_limits_disabled); 2378f4d9cc88SJohn Snow 2379f4d9cc88SJohn Snow if (--blk->quiesce_counter == 0) { 2380f4d9cc88SJohn Snow if (blk->dev_ops && blk->dev_ops->drained_end) { 2381f4d9cc88SJohn Snow blk->dev_ops->drained_end(blk->dev_opaque); 2382f4d9cc88SJohn Snow } 2383cf312932SKevin Wolf while (qemu_co_enter_next(&blk->queued_requests, NULL)) { 2384cf312932SKevin Wolf /* Resume all queued requests */ 2385cf312932SKevin Wolf } 2386f4d9cc88SJohn Snow } 2387c2066af0SKevin Wolf } 238823d0ba93SFam Zheng 238923d0ba93SFam Zheng void blk_register_buf(BlockBackend *blk, void *host, size_t size) 239023d0ba93SFam Zheng { 239123d0ba93SFam Zheng bdrv_register_buf(blk_bs(blk), host, size); 239223d0ba93SFam Zheng } 239323d0ba93SFam Zheng 239423d0ba93SFam Zheng void blk_unregister_buf(BlockBackend *blk, void *host) 239523d0ba93SFam Zheng { 239623d0ba93SFam Zheng bdrv_unregister_buf(blk_bs(blk), host); 239723d0ba93SFam Zheng } 2398b5679fa4SFam Zheng 2399b5679fa4SFam Zheng int coroutine_fn blk_co_copy_range(BlockBackend *blk_in, int64_t off_in, 2400b5679fa4SFam Zheng BlockBackend *blk_out, int64_t off_out, 240167b51fb9SVladimir Sementsov-Ogievskiy int bytes, BdrvRequestFlags read_flags, 240267b51fb9SVladimir Sementsov-Ogievskiy BdrvRequestFlags write_flags) 2403b5679fa4SFam Zheng { 2404b5679fa4SFam Zheng int r; 2405b5679fa4SFam Zheng r = blk_check_byte_request(blk_in, off_in, bytes); 2406b5679fa4SFam Zheng if (r) { 2407b5679fa4SFam Zheng return r; 2408b5679fa4SFam Zheng } 2409b5679fa4SFam Zheng r = blk_check_byte_request(blk_out, off_out, bytes); 2410b5679fa4SFam Zheng if (r) { 2411b5679fa4SFam Zheng return r; 2412b5679fa4SFam Zheng } 2413b5679fa4SFam Zheng return bdrv_co_copy_range(blk_in->root, off_in, 2414b5679fa4SFam Zheng blk_out->root, off_out, 241567b51fb9SVladimir Sementsov-Ogievskiy bytes, read_flags, write_flags); 2416b5679fa4SFam Zheng } 24175d3b4e99SVladimir Sementsov-Ogievskiy 24185d3b4e99SVladimir Sementsov-Ogievskiy const BdrvChild *blk_root(BlockBackend *blk) 24195d3b4e99SVladimir Sementsov-Ogievskiy { 24205d3b4e99SVladimir Sementsov-Ogievskiy return blk->root; 24215d3b4e99SVladimir Sementsov-Ogievskiy } 24222b7bbdbdSMax Reitz 24232b7bbdbdSMax Reitz int blk_make_empty(BlockBackend *blk, Error **errp) 24242b7bbdbdSMax Reitz { 24252b7bbdbdSMax Reitz if (!blk_is_available(blk)) { 24262b7bbdbdSMax Reitz error_setg(errp, "No medium inserted"); 24272b7bbdbdSMax Reitz return -ENOMEDIUM; 24282b7bbdbdSMax Reitz } 24292b7bbdbdSMax Reitz 24302b7bbdbdSMax Reitz return bdrv_make_empty(blk->root, errp); 24312b7bbdbdSMax Reitz } 2432