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 123f21d96d0SKevin Wolf static void blk_root_inherit_options(int *child_flags, QDict *child_options, 124f21d96d0SKevin Wolf int parent_flags, QDict *parent_options) 125f21d96d0SKevin Wolf { 126f21d96d0SKevin Wolf /* We're not supposed to call this function for root nodes */ 127f21d96d0SKevin Wolf abort(); 128f21d96d0SKevin Wolf } 129c2066af0SKevin Wolf static void blk_root_drained_begin(BdrvChild *child); 130fe5258a5SKevin Wolf static bool blk_root_drained_poll(BdrvChild *child); 131e037c09cSMax Reitz static void blk_root_drained_end(BdrvChild *child, int *drained_end_counter); 132f21d96d0SKevin Wolf 1335c8cab48SKevin Wolf static void blk_root_change_media(BdrvChild *child, bool load); 1345c8cab48SKevin Wolf static void blk_root_resize(BdrvChild *child); 1355c8cab48SKevin Wolf 13638475269SKevin Wolf static bool blk_root_can_set_aio_ctx(BdrvChild *child, AioContext *ctx, 13738475269SKevin Wolf GSList **ignore, Error **errp); 13838475269SKevin Wolf static void blk_root_set_aio_ctx(BdrvChild *child, AioContext *ctx, 13938475269SKevin Wolf GSList **ignore); 14038475269SKevin Wolf 141b5411555SKevin Wolf static char *blk_root_get_parent_desc(BdrvChild *child) 142b5411555SKevin Wolf { 143b5411555SKevin Wolf BlockBackend *blk = child->opaque; 144b5411555SKevin Wolf char *dev_id; 145b5411555SKevin Wolf 146b5411555SKevin Wolf if (blk->name) { 147b5411555SKevin Wolf return g_strdup(blk->name); 148b5411555SKevin Wolf } 149b5411555SKevin Wolf 150b5411555SKevin Wolf dev_id = blk_get_attached_dev_id(blk); 151b5411555SKevin Wolf if (*dev_id) { 152b5411555SKevin Wolf return dev_id; 153b5411555SKevin Wolf } else { 154b5411555SKevin Wolf /* TODO Callback into the BB owner for something more detailed */ 155b5411555SKevin Wolf g_free(dev_id); 156b5411555SKevin Wolf return g_strdup("a block device"); 157b5411555SKevin Wolf } 158b5411555SKevin Wolf } 159b5411555SKevin Wolf 1604c265bf9SKevin Wolf static const char *blk_root_get_name(BdrvChild *child) 1614c265bf9SKevin Wolf { 1624c265bf9SKevin Wolf return blk_name(child->opaque); 1634c265bf9SKevin Wolf } 1644c265bf9SKevin Wolf 1655f7772c4SFam Zheng static void blk_vm_state_changed(void *opaque, int running, RunState state) 1665f7772c4SFam Zheng { 1675f7772c4SFam Zheng Error *local_err = NULL; 1685f7772c4SFam Zheng BlockBackend *blk = opaque; 1695f7772c4SFam Zheng 1705f7772c4SFam Zheng if (state == RUN_STATE_INMIGRATE) { 1715f7772c4SFam Zheng return; 1725f7772c4SFam Zheng } 1735f7772c4SFam Zheng 1745f7772c4SFam Zheng qemu_del_vm_change_state_handler(blk->vmsh); 1755f7772c4SFam Zheng blk->vmsh = NULL; 1765f7772c4SFam Zheng blk_set_perm(blk, blk->perm, blk->shared_perm, &local_err); 1775f7772c4SFam Zheng if (local_err) { 1785f7772c4SFam Zheng error_report_err(local_err); 1795f7772c4SFam Zheng } 1805f7772c4SFam Zheng } 1815f7772c4SFam Zheng 1824417ab7aSKevin Wolf /* 1834417ab7aSKevin Wolf * Notifies the user of the BlockBackend that migration has completed. qdev 1844417ab7aSKevin Wolf * devices can tighten their permissions in response (specifically revoke 1854417ab7aSKevin Wolf * shared write permissions that we needed for storage migration). 1864417ab7aSKevin Wolf * 1874417ab7aSKevin Wolf * If an error is returned, the VM cannot be allowed to be resumed. 1884417ab7aSKevin Wolf */ 1894417ab7aSKevin Wolf static void blk_root_activate(BdrvChild *child, Error **errp) 1904417ab7aSKevin Wolf { 1914417ab7aSKevin Wolf BlockBackend *blk = child->opaque; 1924417ab7aSKevin Wolf Error *local_err = NULL; 1934417ab7aSKevin Wolf 1944417ab7aSKevin Wolf if (!blk->disable_perm) { 1954417ab7aSKevin Wolf return; 1964417ab7aSKevin Wolf } 1974417ab7aSKevin Wolf 1984417ab7aSKevin Wolf blk->disable_perm = false; 1994417ab7aSKevin Wolf 2005f7772c4SFam Zheng blk_set_perm(blk, blk->perm, BLK_PERM_ALL, &local_err); 2015f7772c4SFam Zheng if (local_err) { 2025f7772c4SFam Zheng error_propagate(errp, local_err); 2035f7772c4SFam Zheng blk->disable_perm = true; 2045f7772c4SFam Zheng return; 2055f7772c4SFam Zheng } 2065f7772c4SFam Zheng 2075f7772c4SFam Zheng if (runstate_check(RUN_STATE_INMIGRATE)) { 2085f7772c4SFam Zheng /* Activation can happen when migration process is still active, for 2095f7772c4SFam Zheng * example when nbd_server_add is called during non-shared storage 2105f7772c4SFam Zheng * migration. Defer the shared_perm update to migration completion. */ 2115f7772c4SFam Zheng if (!blk->vmsh) { 2125f7772c4SFam Zheng blk->vmsh = qemu_add_vm_change_state_handler(blk_vm_state_changed, 2135f7772c4SFam Zheng blk); 2145f7772c4SFam Zheng } 2155f7772c4SFam Zheng return; 2165f7772c4SFam Zheng } 2175f7772c4SFam Zheng 2184417ab7aSKevin Wolf blk_set_perm(blk, blk->perm, blk->shared_perm, &local_err); 2194417ab7aSKevin Wolf if (local_err) { 2204417ab7aSKevin Wolf error_propagate(errp, local_err); 2214417ab7aSKevin Wolf blk->disable_perm = true; 2224417ab7aSKevin Wolf return; 2234417ab7aSKevin Wolf } 2244417ab7aSKevin Wolf } 2254417ab7aSKevin Wolf 226ca2e2144SFam Zheng void blk_set_force_allow_inactivate(BlockBackend *blk) 227ca2e2144SFam Zheng { 228ca2e2144SFam Zheng blk->force_allow_inactivate = true; 229ca2e2144SFam Zheng } 230ca2e2144SFam Zheng 231c16de8f5SFam Zheng static bool blk_can_inactivate(BlockBackend *blk) 232c16de8f5SFam Zheng { 233ca2e2144SFam Zheng /* If it is a guest device, inactivate is ok. */ 234c16de8f5SFam Zheng if (blk->dev || blk_name(blk)[0]) { 235c16de8f5SFam Zheng return true; 236c16de8f5SFam Zheng } 237c16de8f5SFam Zheng 238ca2e2144SFam Zheng /* Inactivating means no more writes to the image can be done, 239ca2e2144SFam Zheng * even if those writes would be changes invisible to the 240ca2e2144SFam Zheng * guest. For block job BBs that satisfy this, we can just allow 241ca2e2144SFam Zheng * it. This is the case for mirror job source, which is required 242ca2e2144SFam Zheng * by libvirt non-shared block migration. */ 243ca2e2144SFam Zheng if (!(blk->perm & (BLK_PERM_WRITE | BLK_PERM_WRITE_UNCHANGED))) { 244ca2e2144SFam Zheng return true; 245ca2e2144SFam Zheng } 246ca2e2144SFam Zheng 247ca2e2144SFam Zheng return blk->force_allow_inactivate; 248c16de8f5SFam Zheng } 249c16de8f5SFam Zheng 250cfa1a572SKevin Wolf static int blk_root_inactivate(BdrvChild *child) 251cfa1a572SKevin Wolf { 252cfa1a572SKevin Wolf BlockBackend *blk = child->opaque; 253cfa1a572SKevin Wolf 254cfa1a572SKevin Wolf if (blk->disable_perm) { 255cfa1a572SKevin Wolf return 0; 256cfa1a572SKevin Wolf } 257cfa1a572SKevin Wolf 258c16de8f5SFam Zheng if (!blk_can_inactivate(blk)) { 259cfa1a572SKevin Wolf return -EPERM; 260cfa1a572SKevin Wolf } 261cfa1a572SKevin Wolf 262cfa1a572SKevin Wolf blk->disable_perm = true; 263cfa1a572SKevin Wolf if (blk->root) { 264cfa1a572SKevin Wolf bdrv_child_try_set_perm(blk->root, 0, BLK_PERM_ALL, &error_abort); 265cfa1a572SKevin Wolf } 266cfa1a572SKevin Wolf 267cfa1a572SKevin Wolf return 0; 268cfa1a572SKevin Wolf } 269cfa1a572SKevin Wolf 270d03654eaSStefan Hajnoczi static void blk_root_attach(BdrvChild *child) 271d03654eaSStefan Hajnoczi { 272d03654eaSStefan Hajnoczi BlockBackend *blk = child->opaque; 273d03654eaSStefan Hajnoczi BlockBackendAioNotifier *notifier; 274d03654eaSStefan Hajnoczi 275d03654eaSStefan Hajnoczi trace_blk_root_attach(child, blk, child->bs); 276d03654eaSStefan Hajnoczi 277d03654eaSStefan Hajnoczi QLIST_FOREACH(notifier, &blk->aio_notifiers, list) { 278d03654eaSStefan Hajnoczi bdrv_add_aio_context_notifier(child->bs, 279d03654eaSStefan Hajnoczi notifier->attached_aio_context, 280d03654eaSStefan Hajnoczi notifier->detach_aio_context, 281d03654eaSStefan Hajnoczi notifier->opaque); 282d03654eaSStefan Hajnoczi } 283d03654eaSStefan Hajnoczi } 284d03654eaSStefan Hajnoczi 285d03654eaSStefan Hajnoczi static void blk_root_detach(BdrvChild *child) 286d03654eaSStefan Hajnoczi { 287d03654eaSStefan Hajnoczi BlockBackend *blk = child->opaque; 288d03654eaSStefan Hajnoczi BlockBackendAioNotifier *notifier; 289d03654eaSStefan Hajnoczi 290d03654eaSStefan Hajnoczi trace_blk_root_detach(child, blk, child->bs); 291d03654eaSStefan Hajnoczi 292d03654eaSStefan Hajnoczi QLIST_FOREACH(notifier, &blk->aio_notifiers, list) { 293d03654eaSStefan Hajnoczi bdrv_remove_aio_context_notifier(child->bs, 294d03654eaSStefan Hajnoczi notifier->attached_aio_context, 295d03654eaSStefan Hajnoczi notifier->detach_aio_context, 296d03654eaSStefan Hajnoczi notifier->opaque); 297d03654eaSStefan Hajnoczi } 298d03654eaSStefan Hajnoczi } 299d03654eaSStefan Hajnoczi 300f21d96d0SKevin Wolf static const BdrvChildRole child_root = { 301f21d96d0SKevin Wolf .inherit_options = blk_root_inherit_options, 302c2066af0SKevin Wolf 3035c8cab48SKevin Wolf .change_media = blk_root_change_media, 3045c8cab48SKevin Wolf .resize = blk_root_resize, 3054c265bf9SKevin Wolf .get_name = blk_root_get_name, 306b5411555SKevin Wolf .get_parent_desc = blk_root_get_parent_desc, 3075c8cab48SKevin Wolf 308c2066af0SKevin Wolf .drained_begin = blk_root_drained_begin, 309fe5258a5SKevin Wolf .drained_poll = blk_root_drained_poll, 310c2066af0SKevin Wolf .drained_end = blk_root_drained_end, 3114417ab7aSKevin Wolf 3124417ab7aSKevin Wolf .activate = blk_root_activate, 313cfa1a572SKevin Wolf .inactivate = blk_root_inactivate, 314d03654eaSStefan Hajnoczi 315d03654eaSStefan Hajnoczi .attach = blk_root_attach, 316d03654eaSStefan Hajnoczi .detach = blk_root_detach, 31738475269SKevin Wolf 31838475269SKevin Wolf .can_set_aio_ctx = blk_root_can_set_aio_ctx, 31938475269SKevin Wolf .set_aio_ctx = blk_root_set_aio_ctx, 320f21d96d0SKevin Wolf }; 321f21d96d0SKevin Wolf 32226f54e9aSMarkus Armbruster /* 323efaa7c4eSMax Reitz * Create a new BlockBackend with a reference count of one. 3246d0eb64dSKevin Wolf * 3256d0eb64dSKevin Wolf * @perm is a bitmasks of BLK_PERM_* constants which describes the permissions 3266d0eb64dSKevin Wolf * to request for a block driver node that is attached to this BlockBackend. 3276d0eb64dSKevin Wolf * @shared_perm is a bitmask which describes which permissions may be granted 3286d0eb64dSKevin Wolf * to other users of the attached node. 3296d0eb64dSKevin Wolf * Both sets of permissions can be changed later using blk_set_perm(). 3306d0eb64dSKevin Wolf * 33126f54e9aSMarkus Armbruster * Return the new BlockBackend on success, null on failure. 33226f54e9aSMarkus Armbruster */ 333d861ab3aSKevin Wolf BlockBackend *blk_new(AioContext *ctx, uint64_t perm, uint64_t shared_perm) 33426f54e9aSMarkus Armbruster { 33526f54e9aSMarkus Armbruster BlockBackend *blk; 33626f54e9aSMarkus Armbruster 33726f54e9aSMarkus Armbruster blk = g_new0(BlockBackend, 1); 33826f54e9aSMarkus Armbruster blk->refcnt = 1; 339d861ab3aSKevin Wolf blk->ctx = ctx; 3406d0eb64dSKevin Wolf blk->perm = perm; 3416d0eb64dSKevin Wolf blk->shared_perm = shared_perm; 3420c3169dfSKevin Wolf blk_set_enable_write_cache(blk, true); 3430c3169dfSKevin Wolf 344cb53460bSKevin Wolf blk->on_read_error = BLOCKDEV_ON_ERROR_REPORT; 345cb53460bSKevin Wolf blk->on_write_error = BLOCKDEV_ON_ERROR_ENOSPC; 346cb53460bSKevin Wolf 3479caa6f3dSPaolo Bonzini block_acct_init(&blk->stats); 34827ccdd52SKevin Wolf 349cf312932SKevin Wolf qemu_co_queue_init(&blk->queued_requests); 3503301f6c6SMax Reitz notifier_list_init(&blk->remove_bs_notifiers); 3513301f6c6SMax Reitz notifier_list_init(&blk->insert_bs_notifiers); 352d03654eaSStefan Hajnoczi QLIST_INIT(&blk->aio_notifiers); 35327ccdd52SKevin Wolf 3542cf22d6aSMax Reitz QTAILQ_INSERT_TAIL(&block_backends, blk, link); 35526f54e9aSMarkus Armbruster return blk; 35626f54e9aSMarkus Armbruster } 35726f54e9aSMarkus Armbruster 3587e7d56d9SMarkus Armbruster /* 35928eb9b12SMax Reitz * Creates a new BlockBackend, opens a new BlockDriverState, and connects both. 360d861ab3aSKevin Wolf * The new BlockBackend is in the main AioContext. 361ca49a4fdSMax Reitz * 362ca49a4fdSMax Reitz * Just as with bdrv_open(), after having called this function the reference to 363ca49a4fdSMax Reitz * @options belongs to the block layer (even on failure). 364ca49a4fdSMax Reitz * 365ca49a4fdSMax Reitz * TODO: Remove @filename and @flags; it should be possible to specify a whole 366ca49a4fdSMax Reitz * BDS tree just by specifying the @options QDict (or @reference, 367ca49a4fdSMax Reitz * alternatively). At the time of adding this function, this is not possible, 368ca49a4fdSMax Reitz * though, so callers of this function have to be able to specify @filename and 369ca49a4fdSMax Reitz * @flags. 370ca49a4fdSMax Reitz */ 371efaa7c4eSMax Reitz BlockBackend *blk_new_open(const char *filename, const char *reference, 372efaa7c4eSMax Reitz QDict *options, int flags, Error **errp) 373ca49a4fdSMax Reitz { 374ca49a4fdSMax Reitz BlockBackend *blk; 37528eb9b12SMax Reitz BlockDriverState *bs; 3761f4ad7d3SKevin Wolf uint64_t perm = 0; 377ca49a4fdSMax Reitz 378c62d32f5SKevin Wolf /* blk_new_open() is mainly used in .bdrv_create implementations and the 379c62d32f5SKevin Wolf * tools where sharing isn't a concern because the BDS stays private, so we 380c62d32f5SKevin Wolf * just request permission according to the flags. 381c62d32f5SKevin Wolf * 382c62d32f5SKevin Wolf * The exceptions are xen_disk and blockdev_init(); in these cases, the 383c62d32f5SKevin Wolf * caller of blk_new_open() doesn't make use of the permissions, but they 384c62d32f5SKevin Wolf * shouldn't hurt either. We can still share everything here because the 385c62d32f5SKevin Wolf * guest devices will add their own blockers if they can't share. */ 3861f4ad7d3SKevin Wolf if ((flags & BDRV_O_NO_IO) == 0) { 3871f4ad7d3SKevin Wolf perm |= BLK_PERM_CONSISTENT_READ; 388c62d32f5SKevin Wolf if (flags & BDRV_O_RDWR) { 389c62d32f5SKevin Wolf perm |= BLK_PERM_WRITE; 390c62d32f5SKevin Wolf } 3911f4ad7d3SKevin Wolf } 392c62d32f5SKevin Wolf if (flags & BDRV_O_RESIZE) { 393c62d32f5SKevin Wolf perm |= BLK_PERM_RESIZE; 394c62d32f5SKevin Wolf } 395c62d32f5SKevin Wolf 396d861ab3aSKevin Wolf blk = blk_new(qemu_get_aio_context(), perm, BLK_PERM_ALL); 3975b363937SMax Reitz bs = bdrv_open(filename, reference, options, flags, errp); 3985b363937SMax Reitz if (!bs) { 399ca49a4fdSMax Reitz blk_unref(blk); 400ca49a4fdSMax Reitz return NULL; 401ca49a4fdSMax Reitz } 402ca49a4fdSMax Reitz 403132ada80SKevin Wolf blk->root = bdrv_root_attach_child(bs, "root", &child_root, blk->ctx, 40450bfbe93SFam Zheng perm, BLK_PERM_ALL, blk, errp); 40550bfbe93SFam Zheng if (!blk->root) { 40650bfbe93SFam Zheng blk_unref(blk); 40750bfbe93SFam Zheng return NULL; 40850bfbe93SFam Zheng } 40972e775c7SKevin Wolf 410ca49a4fdSMax Reitz return blk; 411ca49a4fdSMax Reitz } 412ca49a4fdSMax Reitz 41326f54e9aSMarkus Armbruster static void blk_delete(BlockBackend *blk) 41426f54e9aSMarkus Armbruster { 41526f54e9aSMarkus Armbruster assert(!blk->refcnt); 416e5e78550SMax Reitz assert(!blk->name); 417a7f53e26SMarkus Armbruster assert(!blk->dev); 418022cdc9fSManos Pitsidianakis if (blk->public.throttle_group_member.throttle_state) { 4191606e4cfSEric Blake blk_io_limits_disable(blk); 4201606e4cfSEric Blake } 421f21d96d0SKevin Wolf if (blk->root) { 42213855c6bSMax Reitz blk_remove_bs(blk); 4237e7d56d9SMarkus Armbruster } 4245f7772c4SFam Zheng if (blk->vmsh) { 4255f7772c4SFam Zheng qemu_del_vm_change_state_handler(blk->vmsh); 4265f7772c4SFam Zheng blk->vmsh = NULL; 4275f7772c4SFam Zheng } 4283301f6c6SMax Reitz assert(QLIST_EMPTY(&blk->remove_bs_notifiers.notifiers)); 4293301f6c6SMax Reitz assert(QLIST_EMPTY(&blk->insert_bs_notifiers.notifiers)); 430d03654eaSStefan Hajnoczi assert(QLIST_EMPTY(&blk->aio_notifiers)); 4312cf22d6aSMax Reitz QTAILQ_REMOVE(&block_backends, blk, link); 43218e46a03SMarkus Armbruster drive_info_del(blk->legacy_dinfo); 433979e9b03SAlberto Garcia block_acct_cleanup(&blk->stats); 43426f54e9aSMarkus Armbruster g_free(blk); 43526f54e9aSMarkus Armbruster } 43626f54e9aSMarkus Armbruster 4378fb3c76cSMarkus Armbruster static void drive_info_del(DriveInfo *dinfo) 4388fb3c76cSMarkus Armbruster { 4398fb3c76cSMarkus Armbruster if (!dinfo) { 4408fb3c76cSMarkus Armbruster return; 4418fb3c76cSMarkus Armbruster } 4428fb3c76cSMarkus Armbruster qemu_opts_del(dinfo->opts); 4438fb3c76cSMarkus Armbruster g_free(dinfo); 4448fb3c76cSMarkus Armbruster } 4458fb3c76cSMarkus Armbruster 446f636ae85SAlberto Garcia int blk_get_refcnt(BlockBackend *blk) 447f636ae85SAlberto Garcia { 448f636ae85SAlberto Garcia return blk ? blk->refcnt : 0; 449f636ae85SAlberto Garcia } 450f636ae85SAlberto Garcia 45126f54e9aSMarkus Armbruster /* 45226f54e9aSMarkus Armbruster * Increment @blk's reference count. 45326f54e9aSMarkus Armbruster * @blk must not be null. 45426f54e9aSMarkus Armbruster */ 45526f54e9aSMarkus Armbruster void blk_ref(BlockBackend *blk) 45626f54e9aSMarkus Armbruster { 4575ca9d21bSKevin Wolf assert(blk->refcnt > 0); 45826f54e9aSMarkus Armbruster blk->refcnt++; 45926f54e9aSMarkus Armbruster } 46026f54e9aSMarkus Armbruster 46126f54e9aSMarkus Armbruster /* 46226f54e9aSMarkus Armbruster * Decrement @blk's reference count. 46326f54e9aSMarkus Armbruster * If this drops it to zero, destroy @blk. 46426f54e9aSMarkus Armbruster * For convenience, do nothing if @blk is null. 46526f54e9aSMarkus Armbruster */ 46626f54e9aSMarkus Armbruster void blk_unref(BlockBackend *blk) 46726f54e9aSMarkus Armbruster { 46826f54e9aSMarkus Armbruster if (blk) { 46926f54e9aSMarkus Armbruster assert(blk->refcnt > 0); 4705ca9d21bSKevin Wolf if (blk->refcnt > 1) { 4715ca9d21bSKevin Wolf blk->refcnt--; 4725ca9d21bSKevin Wolf } else { 4735ca9d21bSKevin Wolf blk_drain(blk); 4745ca9d21bSKevin Wolf /* blk_drain() cannot resurrect blk, nobody held a reference */ 4755ca9d21bSKevin Wolf assert(blk->refcnt == 1); 4765ca9d21bSKevin Wolf blk->refcnt = 0; 47726f54e9aSMarkus Armbruster blk_delete(blk); 47826f54e9aSMarkus Armbruster } 47926f54e9aSMarkus Armbruster } 48026f54e9aSMarkus Armbruster } 48126f54e9aSMarkus Armbruster 4822cf22d6aSMax Reitz /* 4832cf22d6aSMax Reitz * Behaves similarly to blk_next() but iterates over all BlockBackends, even the 4842cf22d6aSMax Reitz * ones which are hidden (i.e. are not referenced by the monitor). 4852cf22d6aSMax Reitz */ 486a429b9b5SKevin Wolf BlockBackend *blk_all_next(BlockBackend *blk) 4872cf22d6aSMax Reitz { 4882cf22d6aSMax Reitz return blk ? QTAILQ_NEXT(blk, link) 4892cf22d6aSMax Reitz : QTAILQ_FIRST(&block_backends); 4902cf22d6aSMax Reitz } 4912cf22d6aSMax Reitz 492d8da3cefSMax Reitz void blk_remove_all_bs(void) 493d8da3cefSMax Reitz { 49474d1b8fcSMax Reitz BlockBackend *blk = NULL; 495d8da3cefSMax Reitz 4962cf22d6aSMax Reitz while ((blk = blk_all_next(blk)) != NULL) { 497d8da3cefSMax Reitz AioContext *ctx = blk_get_aio_context(blk); 498d8da3cefSMax Reitz 499d8da3cefSMax Reitz aio_context_acquire(ctx); 500f21d96d0SKevin Wolf if (blk->root) { 501d8da3cefSMax Reitz blk_remove_bs(blk); 502d8da3cefSMax Reitz } 503d8da3cefSMax Reitz aio_context_release(ctx); 504d8da3cefSMax Reitz } 505d8da3cefSMax Reitz } 506d8da3cefSMax Reitz 50726f54e9aSMarkus Armbruster /* 5089492b0b9SMax Reitz * Return the monitor-owned BlockBackend after @blk. 50926f54e9aSMarkus Armbruster * If @blk is null, return the first one. 51026f54e9aSMarkus Armbruster * Else, return @blk's next sibling, which may be null. 51126f54e9aSMarkus Armbruster * 51226f54e9aSMarkus Armbruster * To iterate over all BlockBackends, do 51326f54e9aSMarkus Armbruster * for (blk = blk_next(NULL); blk; blk = blk_next(blk)) { 51426f54e9aSMarkus Armbruster * ... 51526f54e9aSMarkus Armbruster * } 51626f54e9aSMarkus Armbruster */ 51726f54e9aSMarkus Armbruster BlockBackend *blk_next(BlockBackend *blk) 51826f54e9aSMarkus Armbruster { 5199492b0b9SMax Reitz return blk ? QTAILQ_NEXT(blk, monitor_link) 5209492b0b9SMax Reitz : QTAILQ_FIRST(&monitor_block_backends); 52126f54e9aSMarkus Armbruster } 52226f54e9aSMarkus Armbruster 5237c8eece4SKevin Wolf /* Iterates over all top-level BlockDriverStates, i.e. BDSs that are owned by 5247c8eece4SKevin Wolf * the monitor or attached to a BlockBackend */ 52588be7b4bSKevin Wolf BlockDriverState *bdrv_next(BdrvNextIterator *it) 5267c8eece4SKevin Wolf { 5275e003f17SMax Reitz BlockDriverState *bs, *old_bs; 5285e003f17SMax Reitz 5295e003f17SMax Reitz /* Must be called from the main loop */ 5305e003f17SMax Reitz assert(qemu_get_current_aio_context() == qemu_get_aio_context()); 531981f4f57SMax Reitz 5327c8eece4SKevin Wolf /* First, return all root nodes of BlockBackends. In order to avoid 5337c8eece4SKevin Wolf * returning a BDS twice when multiple BBs refer to it, we only return it 5347c8eece4SKevin Wolf * if the BB is the first one in the parent list of the BDS. */ 5357c8eece4SKevin Wolf if (it->phase == BDRV_NEXT_BACKEND_ROOTS) { 5365e003f17SMax Reitz BlockBackend *old_blk = it->blk; 5375e003f17SMax Reitz 5385e003f17SMax Reitz old_bs = old_blk ? blk_bs(old_blk) : NULL; 5395e003f17SMax Reitz 540981f4f57SMax Reitz do { 5417c8eece4SKevin Wolf it->blk = blk_all_next(it->blk); 54288be7b4bSKevin Wolf bs = it->blk ? blk_bs(it->blk) : NULL; 54388be7b4bSKevin Wolf } while (it->blk && (bs == NULL || bdrv_first_blk(bs) != it->blk)); 544981f4f57SMax Reitz 5455e003f17SMax Reitz if (it->blk) { 5465e003f17SMax Reitz blk_ref(it->blk); 5475e003f17SMax Reitz } 5485e003f17SMax Reitz blk_unref(old_blk); 5495e003f17SMax Reitz 55088be7b4bSKevin Wolf if (bs) { 5515e003f17SMax Reitz bdrv_ref(bs); 5525e003f17SMax Reitz bdrv_unref(old_bs); 55388be7b4bSKevin Wolf return bs; 5547c8eece4SKevin Wolf } 5557c8eece4SKevin Wolf it->phase = BDRV_NEXT_MONITOR_OWNED; 5565e003f17SMax Reitz } else { 5575e003f17SMax Reitz old_bs = it->bs; 5587c8eece4SKevin Wolf } 5597c8eece4SKevin Wolf 5607c8eece4SKevin Wolf /* Then return the monitor-owned BDSes without a BB attached. Ignore all 5617c8eece4SKevin Wolf * BDSes that are attached to a BlockBackend here; they have been handled 5627c8eece4SKevin Wolf * by the above block already */ 5637c8eece4SKevin Wolf do { 5647c8eece4SKevin Wolf it->bs = bdrv_next_monitor_owned(it->bs); 56588be7b4bSKevin Wolf bs = it->bs; 56688be7b4bSKevin Wolf } while (bs && bdrv_has_blk(bs)); 5677c8eece4SKevin Wolf 5685e003f17SMax Reitz if (bs) { 5695e003f17SMax Reitz bdrv_ref(bs); 5705e003f17SMax Reitz } 5715e003f17SMax Reitz bdrv_unref(old_bs); 5725e003f17SMax Reitz 57388be7b4bSKevin Wolf return bs; 57488be7b4bSKevin Wolf } 57588be7b4bSKevin Wolf 5765e003f17SMax Reitz static void bdrv_next_reset(BdrvNextIterator *it) 57788be7b4bSKevin Wolf { 57888be7b4bSKevin Wolf *it = (BdrvNextIterator) { 57988be7b4bSKevin Wolf .phase = BDRV_NEXT_BACKEND_ROOTS, 58088be7b4bSKevin Wolf }; 5815e003f17SMax Reitz } 58288be7b4bSKevin Wolf 5835e003f17SMax Reitz BlockDriverState *bdrv_first(BdrvNextIterator *it) 5845e003f17SMax Reitz { 5855e003f17SMax Reitz bdrv_next_reset(it); 58688be7b4bSKevin Wolf return bdrv_next(it); 587981f4f57SMax Reitz } 588981f4f57SMax Reitz 5895e003f17SMax Reitz /* Must be called when aborting a bdrv_next() iteration before 5905e003f17SMax Reitz * bdrv_next() returns NULL */ 5915e003f17SMax Reitz void bdrv_next_cleanup(BdrvNextIterator *it) 5925e003f17SMax Reitz { 5935e003f17SMax Reitz /* Must be called from the main loop */ 5945e003f17SMax Reitz assert(qemu_get_current_aio_context() == qemu_get_aio_context()); 5955e003f17SMax Reitz 5965e003f17SMax Reitz if (it->phase == BDRV_NEXT_BACKEND_ROOTS) { 5975e003f17SMax Reitz if (it->blk) { 5985e003f17SMax Reitz bdrv_unref(blk_bs(it->blk)); 5995e003f17SMax Reitz blk_unref(it->blk); 6005e003f17SMax Reitz } 6015e003f17SMax Reitz } else { 6025e003f17SMax Reitz bdrv_unref(it->bs); 6035e003f17SMax Reitz } 6045e003f17SMax Reitz 6055e003f17SMax Reitz bdrv_next_reset(it); 6065e003f17SMax Reitz } 6075e003f17SMax Reitz 608981f4f57SMax Reitz /* 609e5e78550SMax Reitz * Add a BlockBackend into the list of backends referenced by the monitor, with 610e5e78550SMax Reitz * the given @name acting as the handle for the monitor. 611e5e78550SMax Reitz * Strictly for use by blockdev.c. 612e5e78550SMax Reitz * 613e5e78550SMax Reitz * @name must not be null or empty. 614e5e78550SMax Reitz * 615e5e78550SMax Reitz * Returns true on success and false on failure. In the latter case, an Error 616e5e78550SMax Reitz * object is returned through @errp. 617e5e78550SMax Reitz */ 618e5e78550SMax Reitz bool monitor_add_blk(BlockBackend *blk, const char *name, Error **errp) 619e5e78550SMax Reitz { 620e5e78550SMax Reitz assert(!blk->name); 621e5e78550SMax Reitz assert(name && name[0]); 622e5e78550SMax Reitz 623e5e78550SMax Reitz if (!id_wellformed(name)) { 624e5e78550SMax Reitz error_setg(errp, "Invalid device name"); 625e5e78550SMax Reitz return false; 626e5e78550SMax Reitz } 627e5e78550SMax Reitz if (blk_by_name(name)) { 628e5e78550SMax Reitz error_setg(errp, "Device with id '%s' already exists", name); 629e5e78550SMax Reitz return false; 630e5e78550SMax Reitz } 631e5e78550SMax Reitz if (bdrv_find_node(name)) { 632e5e78550SMax Reitz error_setg(errp, 633e5e78550SMax Reitz "Device name '%s' conflicts with an existing node name", 634e5e78550SMax Reitz name); 635e5e78550SMax Reitz return false; 636e5e78550SMax Reitz } 637e5e78550SMax Reitz 638e5e78550SMax Reitz blk->name = g_strdup(name); 639e5e78550SMax Reitz QTAILQ_INSERT_TAIL(&monitor_block_backends, blk, monitor_link); 640e5e78550SMax Reitz return true; 641e5e78550SMax Reitz } 642e5e78550SMax Reitz 643e5e78550SMax Reitz /* 644e5e78550SMax Reitz * Remove a BlockBackend from the list of backends referenced by the monitor. 645e5e78550SMax Reitz * Strictly for use by blockdev.c. 646e5e78550SMax Reitz */ 647e5e78550SMax Reitz void monitor_remove_blk(BlockBackend *blk) 648e5e78550SMax Reitz { 649e5e78550SMax Reitz if (!blk->name) { 650e5e78550SMax Reitz return; 651e5e78550SMax Reitz } 652e5e78550SMax Reitz 653e5e78550SMax Reitz QTAILQ_REMOVE(&monitor_block_backends, blk, monitor_link); 654e5e78550SMax Reitz g_free(blk->name); 655e5e78550SMax Reitz blk->name = NULL; 656e5e78550SMax Reitz } 657e5e78550SMax Reitz 658e5e78550SMax Reitz /* 6597e7d56d9SMarkus Armbruster * Return @blk's name, a non-null string. 660e5e78550SMax Reitz * Returns an empty string iff @blk is not referenced by the monitor. 66126f54e9aSMarkus Armbruster */ 6620731a50fSKrzysztof Kozlowski const char *blk_name(const BlockBackend *blk) 66326f54e9aSMarkus Armbruster { 664e5e78550SMax Reitz return blk->name ?: ""; 66526f54e9aSMarkus Armbruster } 66626f54e9aSMarkus Armbruster 66726f54e9aSMarkus Armbruster /* 66826f54e9aSMarkus Armbruster * Return the BlockBackend with name @name if it exists, else null. 66926f54e9aSMarkus Armbruster * @name must not be null. 67026f54e9aSMarkus Armbruster */ 67126f54e9aSMarkus Armbruster BlockBackend *blk_by_name(const char *name) 67226f54e9aSMarkus Armbruster { 67374d1b8fcSMax Reitz BlockBackend *blk = NULL; 67426f54e9aSMarkus Armbruster 67526f54e9aSMarkus Armbruster assert(name); 67674d1b8fcSMax Reitz while ((blk = blk_next(blk)) != NULL) { 67726f54e9aSMarkus Armbruster if (!strcmp(name, blk->name)) { 67826f54e9aSMarkus Armbruster return blk; 67926f54e9aSMarkus Armbruster } 68026f54e9aSMarkus Armbruster } 68126f54e9aSMarkus Armbruster return NULL; 68226f54e9aSMarkus Armbruster } 6837e7d56d9SMarkus Armbruster 6847e7d56d9SMarkus Armbruster /* 6857e7d56d9SMarkus Armbruster * Return the BlockDriverState attached to @blk if any, else null. 6867e7d56d9SMarkus Armbruster */ 6877e7d56d9SMarkus Armbruster BlockDriverState *blk_bs(BlockBackend *blk) 6887e7d56d9SMarkus Armbruster { 689f21d96d0SKevin Wolf return blk->root ? blk->root->bs : NULL; 6907e7d56d9SMarkus Armbruster } 6917e7d56d9SMarkus Armbruster 6927c8eece4SKevin Wolf static BlockBackend *bdrv_first_blk(BlockDriverState *bs) 693dde33812SKevin Wolf { 694dde33812SKevin Wolf BdrvChild *child; 695dde33812SKevin Wolf QLIST_FOREACH(child, &bs->parents, next_parent) { 696dde33812SKevin Wolf if (child->role == &child_root) { 6977c8eece4SKevin Wolf return child->opaque; 698dde33812SKevin Wolf } 699dde33812SKevin Wolf } 700dde33812SKevin Wolf 7017c8eece4SKevin Wolf return NULL; 7027c8eece4SKevin Wolf } 7037c8eece4SKevin Wolf 7047c8eece4SKevin Wolf /* 7057c8eece4SKevin Wolf * Returns true if @bs has an associated BlockBackend. 7067c8eece4SKevin Wolf */ 7077c8eece4SKevin Wolf bool bdrv_has_blk(BlockDriverState *bs) 7087c8eece4SKevin Wolf { 7097c8eece4SKevin Wolf return bdrv_first_blk(bs) != NULL; 710dde33812SKevin Wolf } 711dde33812SKevin Wolf 712dde33812SKevin Wolf /* 713b6c1bae5SKevin Wolf * Returns true if @bs has only BlockBackends as parents. 714b6c1bae5SKevin Wolf */ 715b6c1bae5SKevin Wolf bool bdrv_is_root_node(BlockDriverState *bs) 716b6c1bae5SKevin Wolf { 717b6c1bae5SKevin Wolf BdrvChild *c; 718b6c1bae5SKevin Wolf 719b6c1bae5SKevin Wolf QLIST_FOREACH(c, &bs->parents, next_parent) { 720b6c1bae5SKevin Wolf if (c->role != &child_root) { 721b6c1bae5SKevin Wolf return false; 722b6c1bae5SKevin Wolf } 723b6c1bae5SKevin Wolf } 724b6c1bae5SKevin Wolf 725b6c1bae5SKevin Wolf return true; 726b6c1bae5SKevin Wolf } 727b6c1bae5SKevin Wolf 728b6c1bae5SKevin Wolf /* 72918e46a03SMarkus Armbruster * Return @blk's DriveInfo if any, else null. 73018e46a03SMarkus Armbruster */ 73118e46a03SMarkus Armbruster DriveInfo *blk_legacy_dinfo(BlockBackend *blk) 73218e46a03SMarkus Armbruster { 73318e46a03SMarkus Armbruster return blk->legacy_dinfo; 73418e46a03SMarkus Armbruster } 73518e46a03SMarkus Armbruster 73618e46a03SMarkus Armbruster /* 73718e46a03SMarkus Armbruster * Set @blk's DriveInfo to @dinfo, and return it. 73818e46a03SMarkus Armbruster * @blk must not have a DriveInfo set already. 73918e46a03SMarkus Armbruster * No other BlockBackend may have the same DriveInfo set. 74018e46a03SMarkus Armbruster */ 74118e46a03SMarkus Armbruster DriveInfo *blk_set_legacy_dinfo(BlockBackend *blk, DriveInfo *dinfo) 74218e46a03SMarkus Armbruster { 74318e46a03SMarkus Armbruster assert(!blk->legacy_dinfo); 74418e46a03SMarkus Armbruster return blk->legacy_dinfo = dinfo; 74518e46a03SMarkus Armbruster } 74618e46a03SMarkus Armbruster 74718e46a03SMarkus Armbruster /* 74818e46a03SMarkus Armbruster * Return the BlockBackend with DriveInfo @dinfo. 74918e46a03SMarkus Armbruster * It must exist. 75018e46a03SMarkus Armbruster */ 75118e46a03SMarkus Armbruster BlockBackend *blk_by_legacy_dinfo(DriveInfo *dinfo) 75218e46a03SMarkus Armbruster { 75374d1b8fcSMax Reitz BlockBackend *blk = NULL; 75418e46a03SMarkus Armbruster 75574d1b8fcSMax Reitz while ((blk = blk_next(blk)) != NULL) { 75618e46a03SMarkus Armbruster if (blk->legacy_dinfo == dinfo) { 75718e46a03SMarkus Armbruster return blk; 75818e46a03SMarkus Armbruster } 75918e46a03SMarkus Armbruster } 76018e46a03SMarkus Armbruster abort(); 76118e46a03SMarkus Armbruster } 76218e46a03SMarkus Armbruster 76318e46a03SMarkus Armbruster /* 764f2cd875dSKevin Wolf * Returns a pointer to the publicly accessible fields of @blk. 765f2cd875dSKevin Wolf */ 766f2cd875dSKevin Wolf BlockBackendPublic *blk_get_public(BlockBackend *blk) 767f2cd875dSKevin Wolf { 768f2cd875dSKevin Wolf return &blk->public; 769f2cd875dSKevin Wolf } 770f2cd875dSKevin Wolf 771f2cd875dSKevin Wolf /* 772f2cd875dSKevin Wolf * Returns a BlockBackend given the associated @public fields. 773f2cd875dSKevin Wolf */ 774f2cd875dSKevin Wolf BlockBackend *blk_by_public(BlockBackendPublic *public) 775f2cd875dSKevin Wolf { 776f2cd875dSKevin Wolf return container_of(public, BlockBackend, public); 777f2cd875dSKevin Wolf } 778f2cd875dSKevin Wolf 779f2cd875dSKevin Wolf /* 7801c95f7e1SMax Reitz * Disassociates the currently associated BlockDriverState from @blk. 7811c95f7e1SMax Reitz */ 7821c95f7e1SMax Reitz void blk_remove_bs(BlockBackend *blk) 7831c95f7e1SMax Reitz { 784c89bcf3aSAlberto Garcia ThrottleGroupMember *tgm = &blk->public.throttle_group_member; 785632a7735SZhengui BlockDriverState *bs; 786022cdc9fSManos Pitsidianakis 7873301f6c6SMax Reitz notifier_list_notify(&blk->remove_bs_notifiers, blk); 788c89bcf3aSAlberto Garcia if (tgm->throttle_state) { 789632a7735SZhengui bs = blk_bs(blk); 790632a7735SZhengui bdrv_drained_begin(bs); 791c89bcf3aSAlberto Garcia throttle_group_detach_aio_context(tgm); 792c89bcf3aSAlberto Garcia throttle_group_attach_aio_context(tgm, qemu_get_aio_context()); 793632a7735SZhengui bdrv_drained_end(bs); 7947ca7f0f6SKevin Wolf } 7953301f6c6SMax Reitz 7961c95f7e1SMax Reitz blk_update_root_state(blk); 7971c95f7e1SMax Reitz 798f45280cbSGreg Kurz /* bdrv_root_unref_child() will cause blk->root to become stale and may 799f45280cbSGreg Kurz * switch to a completion coroutine later on. Let's drain all I/O here 800f45280cbSGreg Kurz * to avoid that and a potential QEMU crash. 801f45280cbSGreg Kurz */ 802f45280cbSGreg Kurz blk_drain(blk); 803f21d96d0SKevin Wolf bdrv_root_unref_child(blk->root); 804f21d96d0SKevin Wolf blk->root = NULL; 8051c95f7e1SMax Reitz } 8061c95f7e1SMax Reitz 8071c95f7e1SMax Reitz /* 8080c3c36d6SMax Reitz * Associates a new BlockDriverState with @blk. 8090c3c36d6SMax Reitz */ 810d7086422SKevin Wolf int blk_insert_bs(BlockBackend *blk, BlockDriverState *bs, Error **errp) 8110c3c36d6SMax Reitz { 812c89bcf3aSAlberto Garcia ThrottleGroupMember *tgm = &blk->public.throttle_group_member; 813b441dc71SAlberto Garcia bdrv_ref(bs); 814132ada80SKevin Wolf blk->root = bdrv_root_attach_child(bs, "root", &child_root, blk->ctx, 815d7086422SKevin Wolf blk->perm, blk->shared_perm, blk, errp); 816d7086422SKevin Wolf if (blk->root == NULL) { 817d7086422SKevin Wolf return -EPERM; 818d7086422SKevin Wolf } 8193301f6c6SMax Reitz 8203301f6c6SMax Reitz notifier_list_notify(&blk->insert_bs_notifiers, blk); 821c89bcf3aSAlberto Garcia if (tgm->throttle_state) { 822c89bcf3aSAlberto Garcia throttle_group_detach_aio_context(tgm); 823c89bcf3aSAlberto Garcia throttle_group_attach_aio_context(tgm, bdrv_get_aio_context(bs)); 8247ca7f0f6SKevin Wolf } 825d7086422SKevin Wolf 826d7086422SKevin Wolf return 0; 8270c3c36d6SMax Reitz } 8280c3c36d6SMax Reitz 829981776b3SKevin Wolf /* 830981776b3SKevin Wolf * Sets the permission bitmasks that the user of the BlockBackend needs. 831981776b3SKevin Wolf */ 832981776b3SKevin Wolf int blk_set_perm(BlockBackend *blk, uint64_t perm, uint64_t shared_perm, 833981776b3SKevin Wolf Error **errp) 834981776b3SKevin Wolf { 835981776b3SKevin Wolf int ret; 836981776b3SKevin Wolf 837d35ff5e6SKevin Wolf if (blk->root && !blk->disable_perm) { 838981776b3SKevin Wolf ret = bdrv_child_try_set_perm(blk->root, perm, shared_perm, errp); 839981776b3SKevin Wolf if (ret < 0) { 840981776b3SKevin Wolf return ret; 841981776b3SKevin Wolf } 842981776b3SKevin Wolf } 843981776b3SKevin Wolf 844981776b3SKevin Wolf blk->perm = perm; 845981776b3SKevin Wolf blk->shared_perm = shared_perm; 846981776b3SKevin Wolf 847981776b3SKevin Wolf return 0; 848981776b3SKevin Wolf } 849981776b3SKevin Wolf 850887354bdSKevin Wolf void blk_get_perm(BlockBackend *blk, uint64_t *perm, uint64_t *shared_perm) 851887354bdSKevin Wolf { 852887354bdSKevin Wolf *perm = blk->perm; 853887354bdSKevin Wolf *shared_perm = blk->shared_perm; 854887354bdSKevin Wolf } 855887354bdSKevin Wolf 856d09ea2d2SThomas Huth /* 857d09ea2d2SThomas Huth * Attach device model @dev to @blk. 858d09ea2d2SThomas Huth * Return 0 on success, -EBUSY when a device model is attached already. 859d09ea2d2SThomas Huth */ 860d09ea2d2SThomas Huth int blk_attach_dev(BlockBackend *blk, DeviceState *dev) 861a7f53e26SMarkus Armbruster { 862a7f53e26SMarkus Armbruster if (blk->dev) { 863a7f53e26SMarkus Armbruster return -EBUSY; 864a7f53e26SMarkus Armbruster } 865d35ff5e6SKevin Wolf 866d35ff5e6SKevin Wolf /* While migration is still incoming, we don't need to apply the 867d35ff5e6SKevin Wolf * permissions of guest device BlockBackends. We might still have a block 868d35ff5e6SKevin Wolf * job or NBD server writing to the image for storage migration. */ 869d35ff5e6SKevin Wolf if (runstate_check(RUN_STATE_INMIGRATE)) { 870d35ff5e6SKevin Wolf blk->disable_perm = true; 871d35ff5e6SKevin Wolf } 872d35ff5e6SKevin Wolf 87384ebe375SMarkus Armbruster blk_ref(blk); 874a7f53e26SMarkus Armbruster blk->dev = dev; 875373340b2SMax Reitz blk_iostatus_reset(blk); 876d35ff5e6SKevin Wolf 877a7f53e26SMarkus Armbruster return 0; 878a7f53e26SMarkus Armbruster } 879a7f53e26SMarkus Armbruster 880a7f53e26SMarkus Armbruster /* 881a7f53e26SMarkus Armbruster * Detach device model @dev from @blk. 882a7f53e26SMarkus Armbruster * @dev must be currently attached to @blk. 883a7f53e26SMarkus Armbruster */ 884d09ea2d2SThomas Huth void blk_detach_dev(BlockBackend *blk, DeviceState *dev) 885a7f53e26SMarkus Armbruster { 886a7f53e26SMarkus Armbruster assert(blk->dev == dev); 887a7f53e26SMarkus Armbruster blk->dev = NULL; 888a7f53e26SMarkus Armbruster blk->dev_ops = NULL; 889a7f53e26SMarkus Armbruster blk->dev_opaque = NULL; 89068e9ec01SMax Reitz blk->guest_block_size = 512; 891981776b3SKevin Wolf blk_set_perm(blk, 0, BLK_PERM_ALL, &error_abort); 89284ebe375SMarkus Armbruster blk_unref(blk); 893a7f53e26SMarkus Armbruster } 894a7f53e26SMarkus Armbruster 895a7f53e26SMarkus Armbruster /* 896a7f53e26SMarkus Armbruster * Return the device model attached to @blk if any, else null. 897a7f53e26SMarkus Armbruster */ 898d09ea2d2SThomas Huth DeviceState *blk_get_attached_dev(BlockBackend *blk) 899a7f53e26SMarkus Armbruster { 900a7f53e26SMarkus Armbruster return blk->dev; 901a7f53e26SMarkus Armbruster } 902a7f53e26SMarkus Armbruster 9032d76e724SKevin Wolf /* Return the qdev ID, or if no ID is assigned the QOM path, of the block 9042d76e724SKevin Wolf * device attached to the BlockBackend. */ 90577beef83SKevin Wolf char *blk_get_attached_dev_id(BlockBackend *blk) 9062d76e724SKevin Wolf { 907d09ea2d2SThomas Huth DeviceState *dev = blk->dev; 9082d76e724SKevin Wolf 9092d76e724SKevin Wolf if (!dev) { 9102d76e724SKevin Wolf return g_strdup(""); 9112d76e724SKevin Wolf } else if (dev->id) { 9122d76e724SKevin Wolf return g_strdup(dev->id); 9132d76e724SKevin Wolf } 914602414d1SLiam Merwick 915602414d1SLiam Merwick return object_get_canonical_path(OBJECT(dev)) ?: g_strdup(""); 9162d76e724SKevin Wolf } 9172d76e724SKevin Wolf 918a7f53e26SMarkus Armbruster /* 9191c89e1faSKevin Wolf * Return the BlockBackend which has the device model @dev attached if it 9201c89e1faSKevin Wolf * exists, else null. 9211c89e1faSKevin Wolf * 9221c89e1faSKevin Wolf * @dev must not be null. 9231c89e1faSKevin Wolf */ 9241c89e1faSKevin Wolf BlockBackend *blk_by_dev(void *dev) 9251c89e1faSKevin Wolf { 9261c89e1faSKevin Wolf BlockBackend *blk = NULL; 9271c89e1faSKevin Wolf 9281c89e1faSKevin Wolf assert(dev != NULL); 9291c89e1faSKevin Wolf while ((blk = blk_all_next(blk)) != NULL) { 9301c89e1faSKevin Wolf if (blk->dev == dev) { 9311c89e1faSKevin Wolf return blk; 9321c89e1faSKevin Wolf } 9331c89e1faSKevin Wolf } 9341c89e1faSKevin Wolf return NULL; 9351c89e1faSKevin Wolf } 9361c89e1faSKevin Wolf 9371c89e1faSKevin Wolf /* 938a7f53e26SMarkus Armbruster * Set @blk's device model callbacks to @ops. 939a7f53e26SMarkus Armbruster * @opaque is the opaque argument to pass to the callbacks. 940a7f53e26SMarkus Armbruster * This is for use by device models. 941a7f53e26SMarkus Armbruster */ 942a7f53e26SMarkus Armbruster void blk_set_dev_ops(BlockBackend *blk, const BlockDevOps *ops, 943a7f53e26SMarkus Armbruster void *opaque) 944a7f53e26SMarkus Armbruster { 945a7f53e26SMarkus Armbruster blk->dev_ops = ops; 946a7f53e26SMarkus Armbruster blk->dev_opaque = opaque; 947f4d9cc88SJohn Snow 948f4d9cc88SJohn Snow /* Are we currently quiesced? Should we enforce this right now? */ 949f4d9cc88SJohn Snow if (blk->quiesce_counter && ops->drained_begin) { 950f4d9cc88SJohn Snow ops->drained_begin(opaque); 951f4d9cc88SJohn Snow } 952a7f53e26SMarkus Armbruster } 953a7f53e26SMarkus Armbruster 954a7f53e26SMarkus Armbruster /* 955a7f53e26SMarkus Armbruster * Notify @blk's attached device model of media change. 95639829a01SKevin Wolf * 95739829a01SKevin Wolf * If @load is true, notify of media load. This action can fail, meaning that 95839829a01SKevin Wolf * the medium cannot be loaded. @errp is set then. 95939829a01SKevin Wolf * 96039829a01SKevin Wolf * If @load is false, notify of media eject. This can never fail. 96139829a01SKevin Wolf * 962a7f53e26SMarkus Armbruster * Also send DEVICE_TRAY_MOVED events as appropriate. 963a7f53e26SMarkus Armbruster */ 96439829a01SKevin Wolf void blk_dev_change_media_cb(BlockBackend *blk, bool load, Error **errp) 965a7f53e26SMarkus Armbruster { 966a7f53e26SMarkus Armbruster if (blk->dev_ops && blk->dev_ops->change_media_cb) { 967f1f57066SMax Reitz bool tray_was_open, tray_is_open; 96839829a01SKevin Wolf Error *local_err = NULL; 969a7f53e26SMarkus Armbruster 970f1f57066SMax Reitz tray_was_open = blk_dev_is_tray_open(blk); 97139829a01SKevin Wolf blk->dev_ops->change_media_cb(blk->dev_opaque, load, &local_err); 97239829a01SKevin Wolf if (local_err) { 97339829a01SKevin Wolf assert(load == true); 97439829a01SKevin Wolf error_propagate(errp, local_err); 97539829a01SKevin Wolf return; 97639829a01SKevin Wolf } 977f1f57066SMax Reitz tray_is_open = blk_dev_is_tray_open(blk); 978f1f57066SMax Reitz 979f1f57066SMax Reitz if (tray_was_open != tray_is_open) { 9802d76e724SKevin Wolf char *id = blk_get_attached_dev_id(blk); 9813ab72385SPeter Xu qapi_event_send_device_tray_moved(blk_name(blk), id, tray_is_open); 9822d76e724SKevin Wolf g_free(id); 983a7f53e26SMarkus Armbruster } 984a7f53e26SMarkus Armbruster } 985a7f53e26SMarkus Armbruster } 986a7f53e26SMarkus Armbruster 9875c8cab48SKevin Wolf static void blk_root_change_media(BdrvChild *child, bool load) 9885c8cab48SKevin Wolf { 98939829a01SKevin Wolf blk_dev_change_media_cb(child->opaque, load, NULL); 9905c8cab48SKevin Wolf } 9915c8cab48SKevin Wolf 992a7f53e26SMarkus Armbruster /* 993a7f53e26SMarkus Armbruster * Does @blk's attached device model have removable media? 994a7f53e26SMarkus Armbruster * %true if no device model is attached. 995a7f53e26SMarkus Armbruster */ 996a7f53e26SMarkus Armbruster bool blk_dev_has_removable_media(BlockBackend *blk) 997a7f53e26SMarkus Armbruster { 998a7f53e26SMarkus Armbruster return !blk->dev || (blk->dev_ops && blk->dev_ops->change_media_cb); 999a7f53e26SMarkus Armbruster } 1000a7f53e26SMarkus Armbruster 1001a7f53e26SMarkus Armbruster /* 10028f3a73bcSMax Reitz * Does @blk's attached device model have a tray? 10038f3a73bcSMax Reitz */ 10048f3a73bcSMax Reitz bool blk_dev_has_tray(BlockBackend *blk) 10058f3a73bcSMax Reitz { 10068f3a73bcSMax Reitz return blk->dev_ops && blk->dev_ops->is_tray_open; 10078f3a73bcSMax Reitz } 10088f3a73bcSMax Reitz 10098f3a73bcSMax Reitz /* 1010a7f53e26SMarkus Armbruster * Notify @blk's attached device model of a media eject request. 1011a7f53e26SMarkus Armbruster * If @force is true, the medium is about to be yanked out forcefully. 1012a7f53e26SMarkus Armbruster */ 1013a7f53e26SMarkus Armbruster void blk_dev_eject_request(BlockBackend *blk, bool force) 1014a7f53e26SMarkus Armbruster { 1015a7f53e26SMarkus Armbruster if (blk->dev_ops && blk->dev_ops->eject_request_cb) { 1016a7f53e26SMarkus Armbruster blk->dev_ops->eject_request_cb(blk->dev_opaque, force); 1017a7f53e26SMarkus Armbruster } 1018a7f53e26SMarkus Armbruster } 1019a7f53e26SMarkus Armbruster 1020a7f53e26SMarkus Armbruster /* 1021a7f53e26SMarkus Armbruster * Does @blk's attached device model have a tray, and is it open? 1022a7f53e26SMarkus Armbruster */ 1023a7f53e26SMarkus Armbruster bool blk_dev_is_tray_open(BlockBackend *blk) 1024a7f53e26SMarkus Armbruster { 10258f3a73bcSMax Reitz if (blk_dev_has_tray(blk)) { 1026a7f53e26SMarkus Armbruster return blk->dev_ops->is_tray_open(blk->dev_opaque); 1027a7f53e26SMarkus Armbruster } 1028a7f53e26SMarkus Armbruster return false; 1029a7f53e26SMarkus Armbruster } 1030a7f53e26SMarkus Armbruster 1031a7f53e26SMarkus Armbruster /* 1032a7f53e26SMarkus Armbruster * Does @blk's attached device model have the medium locked? 1033a7f53e26SMarkus Armbruster * %false if the device model has no such lock. 1034a7f53e26SMarkus Armbruster */ 1035a7f53e26SMarkus Armbruster bool blk_dev_is_medium_locked(BlockBackend *blk) 1036a7f53e26SMarkus Armbruster { 1037a7f53e26SMarkus Armbruster if (blk->dev_ops && blk->dev_ops->is_medium_locked) { 1038a7f53e26SMarkus Armbruster return blk->dev_ops->is_medium_locked(blk->dev_opaque); 1039a7f53e26SMarkus Armbruster } 1040a7f53e26SMarkus Armbruster return false; 1041a7f53e26SMarkus Armbruster } 1042a7f53e26SMarkus Armbruster 1043a7f53e26SMarkus Armbruster /* 1044a7f53e26SMarkus Armbruster * Notify @blk's attached device model of a backend size change. 1045a7f53e26SMarkus Armbruster */ 10465c8cab48SKevin Wolf static void blk_root_resize(BdrvChild *child) 1047a7f53e26SMarkus Armbruster { 10485c8cab48SKevin Wolf BlockBackend *blk = child->opaque; 10495c8cab48SKevin Wolf 1050a7f53e26SMarkus Armbruster if (blk->dev_ops && blk->dev_ops->resize_cb) { 1051a7f53e26SMarkus Armbruster blk->dev_ops->resize_cb(blk->dev_opaque); 1052a7f53e26SMarkus Armbruster } 1053a7f53e26SMarkus Armbruster } 1054a7f53e26SMarkus Armbruster 10554be74634SMarkus Armbruster void blk_iostatus_enable(BlockBackend *blk) 10564be74634SMarkus Armbruster { 1057373340b2SMax Reitz blk->iostatus_enabled = true; 1058373340b2SMax Reitz blk->iostatus = BLOCK_DEVICE_IO_STATUS_OK; 1059373340b2SMax Reitz } 1060373340b2SMax Reitz 1061373340b2SMax Reitz /* The I/O status is only enabled if the drive explicitly 1062373340b2SMax Reitz * enables it _and_ the VM is configured to stop on errors */ 1063373340b2SMax Reitz bool blk_iostatus_is_enabled(const BlockBackend *blk) 1064373340b2SMax Reitz { 1065373340b2SMax Reitz return (blk->iostatus_enabled && 1066373340b2SMax Reitz (blk->on_write_error == BLOCKDEV_ON_ERROR_ENOSPC || 1067373340b2SMax Reitz blk->on_write_error == BLOCKDEV_ON_ERROR_STOP || 1068373340b2SMax Reitz blk->on_read_error == BLOCKDEV_ON_ERROR_STOP)); 1069373340b2SMax Reitz } 1070373340b2SMax Reitz 1071373340b2SMax Reitz BlockDeviceIoStatus blk_iostatus(const BlockBackend *blk) 1072373340b2SMax Reitz { 1073373340b2SMax Reitz return blk->iostatus; 1074373340b2SMax Reitz } 1075373340b2SMax Reitz 1076373340b2SMax Reitz void blk_iostatus_disable(BlockBackend *blk) 1077373340b2SMax Reitz { 1078373340b2SMax Reitz blk->iostatus_enabled = false; 1079373340b2SMax Reitz } 1080373340b2SMax Reitz 1081373340b2SMax Reitz void blk_iostatus_reset(BlockBackend *blk) 1082373340b2SMax Reitz { 1083373340b2SMax Reitz if (blk_iostatus_is_enabled(blk)) { 1084373340b2SMax Reitz blk->iostatus = BLOCK_DEVICE_IO_STATUS_OK; 1085373340b2SMax Reitz } 1086373340b2SMax Reitz } 1087373340b2SMax Reitz 1088373340b2SMax Reitz void blk_iostatus_set_err(BlockBackend *blk, int error) 1089373340b2SMax Reitz { 1090373340b2SMax Reitz assert(blk_iostatus_is_enabled(blk)); 1091373340b2SMax Reitz if (blk->iostatus == BLOCK_DEVICE_IO_STATUS_OK) { 1092373340b2SMax Reitz blk->iostatus = error == ENOSPC ? BLOCK_DEVICE_IO_STATUS_NOSPACE : 1093373340b2SMax Reitz BLOCK_DEVICE_IO_STATUS_FAILED; 1094373340b2SMax Reitz } 10954be74634SMarkus Armbruster } 10964be74634SMarkus Armbruster 1097c10c9d96SKevin Wolf void blk_set_allow_write_beyond_eof(BlockBackend *blk, bool allow) 1098c10c9d96SKevin Wolf { 1099c10c9d96SKevin Wolf blk->allow_write_beyond_eof = allow; 1100c10c9d96SKevin Wolf } 1101c10c9d96SKevin Wolf 1102980b0f94SKevin Wolf void blk_set_allow_aio_context_change(BlockBackend *blk, bool allow) 1103980b0f94SKevin Wolf { 1104980b0f94SKevin Wolf blk->allow_aio_context_change = allow; 1105980b0f94SKevin Wolf } 1106980b0f94SKevin Wolf 1107cf312932SKevin Wolf void blk_set_disable_request_queuing(BlockBackend *blk, bool disable) 1108cf312932SKevin Wolf { 1109cf312932SKevin Wolf blk->disable_request_queuing = disable; 1110cf312932SKevin Wolf } 1111cf312932SKevin Wolf 1112e7f7d676SMax Reitz static int blk_check_byte_request(BlockBackend *blk, int64_t offset, 1113e7f7d676SMax Reitz size_t size) 1114e7f7d676SMax Reitz { 1115e7f7d676SMax Reitz int64_t len; 1116e7f7d676SMax Reitz 1117e7f7d676SMax Reitz if (size > INT_MAX) { 1118e7f7d676SMax Reitz return -EIO; 1119e7f7d676SMax Reitz } 1120e7f7d676SMax Reitz 1121c09ba36cSMax Reitz if (!blk_is_available(blk)) { 1122e7f7d676SMax Reitz return -ENOMEDIUM; 1123e7f7d676SMax Reitz } 1124e7f7d676SMax Reitz 1125c10c9d96SKevin Wolf if (offset < 0) { 1126c10c9d96SKevin Wolf return -EIO; 1127c10c9d96SKevin Wolf } 1128c10c9d96SKevin Wolf 1129c10c9d96SKevin Wolf if (!blk->allow_write_beyond_eof) { 1130e7f7d676SMax Reitz len = blk_getlength(blk); 1131e7f7d676SMax Reitz if (len < 0) { 1132e7f7d676SMax Reitz return len; 1133e7f7d676SMax Reitz } 1134e7f7d676SMax Reitz 1135e7f7d676SMax Reitz if (offset > len || len - offset < size) { 1136e7f7d676SMax Reitz return -EIO; 1137e7f7d676SMax Reitz } 1138c10c9d96SKevin Wolf } 1139e7f7d676SMax Reitz 1140e7f7d676SMax Reitz return 0; 1141e7f7d676SMax Reitz } 1142e7f7d676SMax Reitz 11437f16476fSKevin Wolf /* To be called between exactly one pair of blk_inc/dec_in_flight() */ 1144cf312932SKevin Wolf static void coroutine_fn blk_wait_while_drained(BlockBackend *blk) 1145cf312932SKevin Wolf { 11467f16476fSKevin Wolf assert(blk->in_flight > 0); 11477f16476fSKevin Wolf 1148cf312932SKevin Wolf if (blk->quiesce_counter && !blk->disable_request_queuing) { 11497f16476fSKevin Wolf blk_dec_in_flight(blk); 1150cf312932SKevin Wolf qemu_co_queue_wait(&blk->queued_requests, NULL); 11517f16476fSKevin Wolf blk_inc_in_flight(blk); 1152cf312932SKevin Wolf } 1153cf312932SKevin Wolf } 1154cf312932SKevin Wolf 1155fbb92b67SKevin Wolf /* To be called between exactly one pair of blk_inc/dec_in_flight() */ 1156fbb92b67SKevin Wolf static int coroutine_fn 1157fbb92b67SKevin Wolf blk_do_preadv(BlockBackend *blk, int64_t offset, unsigned int bytes, 1158fbb92b67SKevin Wolf QEMUIOVector *qiov, BdrvRequestFlags flags) 11594be74634SMarkus Armbruster { 11601e98fefdSKevin Wolf int ret; 1161cf312932SKevin Wolf BlockDriverState *bs; 11621e98fefdSKevin Wolf 1163cf312932SKevin Wolf blk_wait_while_drained(blk); 1164cf312932SKevin Wolf 1165cf312932SKevin Wolf /* Call blk_bs() only after waiting, the graph may have changed */ 1166cf312932SKevin Wolf bs = blk_bs(blk); 116799723548SPaolo Bonzini trace_blk_co_preadv(blk, bs, offset, bytes, flags); 11681e98fefdSKevin Wolf 11691e98fefdSKevin Wolf ret = blk_check_byte_request(blk, offset, bytes); 1170e7f7d676SMax Reitz if (ret < 0) { 1171e7f7d676SMax Reitz return ret; 1172e7f7d676SMax Reitz } 1173e7f7d676SMax Reitz 117499723548SPaolo Bonzini bdrv_inc_in_flight(bs); 117599723548SPaolo Bonzini 1176441565b2SKevin Wolf /* throttling disk I/O */ 1177022cdc9fSManos Pitsidianakis if (blk->public.throttle_group_member.throttle_state) { 1178022cdc9fSManos Pitsidianakis throttle_group_co_io_limits_intercept(&blk->public.throttle_group_member, 1179022cdc9fSManos Pitsidianakis bytes, false); 1180441565b2SKevin Wolf } 1181441565b2SKevin Wolf 118299723548SPaolo Bonzini ret = bdrv_co_preadv(blk->root, offset, bytes, qiov, flags); 118399723548SPaolo Bonzini bdrv_dec_in_flight(bs); 118499723548SPaolo Bonzini return ret; 11851bf1cbc9SKevin Wolf } 11861bf1cbc9SKevin Wolf 1187fbb92b67SKevin Wolf int coroutine_fn blk_co_preadv(BlockBackend *blk, int64_t offset, 1188fbb92b67SKevin Wolf unsigned int bytes, QEMUIOVector *qiov, 1189fbb92b67SKevin Wolf BdrvRequestFlags flags) 1190fbb92b67SKevin Wolf { 1191fbb92b67SKevin Wolf int ret; 1192fbb92b67SKevin Wolf 1193fbb92b67SKevin Wolf blk_inc_in_flight(blk); 1194fbb92b67SKevin Wolf ret = blk_do_preadv(blk, offset, bytes, qiov, flags); 1195fbb92b67SKevin Wolf blk_dec_in_flight(blk); 1196fbb92b67SKevin Wolf 1197fbb92b67SKevin Wolf return ret; 1198fbb92b67SKevin Wolf } 1199fbb92b67SKevin Wolf 1200fbb92b67SKevin Wolf /* To be called between exactly one pair of blk_inc/dec_in_flight() */ 1201fbb92b67SKevin Wolf static int coroutine_fn 1202fbb92b67SKevin Wolf blk_do_pwritev_part(BlockBackend *blk, int64_t offset, unsigned int bytes, 1203b3016864SVladimir Sementsov-Ogievskiy QEMUIOVector *qiov, size_t qiov_offset, 1204a8823a3bSKevin Wolf BdrvRequestFlags flags) 1205a8823a3bSKevin Wolf { 1206bfd18d1eSKevin Wolf int ret; 1207cf312932SKevin Wolf BlockDriverState *bs; 1208bfd18d1eSKevin Wolf 1209cf312932SKevin Wolf blk_wait_while_drained(blk); 1210cf312932SKevin Wolf 1211cf312932SKevin Wolf /* Call blk_bs() only after waiting, the graph may have changed */ 1212cf312932SKevin Wolf bs = blk_bs(blk); 121399723548SPaolo Bonzini trace_blk_co_pwritev(blk, bs, offset, bytes, flags); 12141e98fefdSKevin Wolf 1215bfd18d1eSKevin Wolf ret = blk_check_byte_request(blk, offset, bytes); 1216a8823a3bSKevin Wolf if (ret < 0) { 1217a8823a3bSKevin Wolf return ret; 1218a8823a3bSKevin Wolf } 1219a8823a3bSKevin Wolf 122099723548SPaolo Bonzini bdrv_inc_in_flight(bs); 1221441565b2SKevin Wolf /* throttling disk I/O */ 1222022cdc9fSManos Pitsidianakis if (blk->public.throttle_group_member.throttle_state) { 1223022cdc9fSManos Pitsidianakis throttle_group_co_io_limits_intercept(&blk->public.throttle_group_member, 1224022cdc9fSManos Pitsidianakis bytes, true); 1225441565b2SKevin Wolf } 1226441565b2SKevin Wolf 1227bfd18d1eSKevin Wolf if (!blk->enable_write_cache) { 1228bfd18d1eSKevin Wolf flags |= BDRV_REQ_FUA; 1229bfd18d1eSKevin Wolf } 1230bfd18d1eSKevin Wolf 1231b3016864SVladimir Sementsov-Ogievskiy ret = bdrv_co_pwritev_part(blk->root, offset, bytes, qiov, qiov_offset, 1232b3016864SVladimir Sementsov-Ogievskiy flags); 123399723548SPaolo Bonzini bdrv_dec_in_flight(bs); 123499723548SPaolo Bonzini return ret; 1235a8823a3bSKevin Wolf } 1236a8823a3bSKevin Wolf 1237fbb92b67SKevin Wolf int coroutine_fn blk_co_pwritev_part(BlockBackend *blk, int64_t offset, 1238fbb92b67SKevin Wolf unsigned int bytes, 1239fbb92b67SKevin Wolf QEMUIOVector *qiov, size_t qiov_offset, 1240fbb92b67SKevin Wolf BdrvRequestFlags flags) 1241fbb92b67SKevin Wolf { 1242fbb92b67SKevin Wolf int ret; 1243fbb92b67SKevin Wolf 1244fbb92b67SKevin Wolf blk_inc_in_flight(blk); 1245fbb92b67SKevin Wolf ret = blk_do_pwritev_part(blk, offset, bytes, qiov, qiov_offset, flags); 1246fbb92b67SKevin Wolf blk_dec_in_flight(blk); 1247fbb92b67SKevin Wolf 1248fbb92b67SKevin Wolf return ret; 1249fbb92b67SKevin Wolf } 1250fbb92b67SKevin Wolf 1251b3016864SVladimir Sementsov-Ogievskiy int coroutine_fn blk_co_pwritev(BlockBackend *blk, int64_t offset, 1252b3016864SVladimir Sementsov-Ogievskiy unsigned int bytes, QEMUIOVector *qiov, 1253b3016864SVladimir Sementsov-Ogievskiy BdrvRequestFlags flags) 1254b3016864SVladimir Sementsov-Ogievskiy { 1255b3016864SVladimir Sementsov-Ogievskiy return blk_co_pwritev_part(blk, offset, bytes, qiov, 0, flags); 1256b3016864SVladimir Sementsov-Ogievskiy } 1257b3016864SVladimir Sementsov-Ogievskiy 12581bf1cbc9SKevin Wolf typedef struct BlkRwCo { 12591bf1cbc9SKevin Wolf BlockBackend *blk; 12601bf1cbc9SKevin Wolf int64_t offset; 1261c060332cSDeepa Srinivasan void *iobuf; 12621bf1cbc9SKevin Wolf int ret; 12631bf1cbc9SKevin Wolf BdrvRequestFlags flags; 12641bf1cbc9SKevin Wolf } BlkRwCo; 12651bf1cbc9SKevin Wolf 12661bf1cbc9SKevin Wolf static void blk_read_entry(void *opaque) 12671bf1cbc9SKevin Wolf { 12681bf1cbc9SKevin Wolf BlkRwCo *rwco = opaque; 1269c060332cSDeepa Srinivasan QEMUIOVector *qiov = rwco->iobuf; 12701bf1cbc9SKevin Wolf 1271fbb92b67SKevin Wolf rwco->ret = blk_do_preadv(rwco->blk, rwco->offset, qiov->size, 1272c060332cSDeepa Srinivasan qiov, rwco->flags); 12734720cbeeSKevin Wolf aio_wait_kick(); 12741bf1cbc9SKevin Wolf } 12751bf1cbc9SKevin Wolf 1276a8823a3bSKevin Wolf static void blk_write_entry(void *opaque) 1277a8823a3bSKevin Wolf { 1278a8823a3bSKevin Wolf BlkRwCo *rwco = opaque; 1279c060332cSDeepa Srinivasan QEMUIOVector *qiov = rwco->iobuf; 1280a8823a3bSKevin Wolf 1281fbb92b67SKevin Wolf rwco->ret = blk_do_pwritev_part(rwco->blk, rwco->offset, qiov->size, 1282fbb92b67SKevin Wolf qiov, 0, rwco->flags); 12834720cbeeSKevin Wolf aio_wait_kick(); 1284a8823a3bSKevin Wolf } 1285a8823a3bSKevin Wolf 1286a55d3fbaSKevin Wolf static int blk_prw(BlockBackend *blk, int64_t offset, uint8_t *buf, 1287a55d3fbaSKevin Wolf int64_t bytes, CoroutineEntry co_entry, 1288fc1453cdSKevin Wolf BdrvRequestFlags flags) 12891bf1cbc9SKevin Wolf { 1290ae5a9592SVladimir Sementsov-Ogievskiy QEMUIOVector qiov = QEMU_IOVEC_INIT_BUF(qiov, buf, bytes); 1291ae5a9592SVladimir Sementsov-Ogievskiy BlkRwCo rwco = { 12921bf1cbc9SKevin Wolf .blk = blk, 1293a55d3fbaSKevin Wolf .offset = offset, 1294c060332cSDeepa Srinivasan .iobuf = &qiov, 1295fc1453cdSKevin Wolf .flags = flags, 12961bf1cbc9SKevin Wolf .ret = NOT_DONE, 12971bf1cbc9SKevin Wolf }; 12981bf1cbc9SKevin Wolf 1299fbb92b67SKevin Wolf blk_inc_in_flight(blk); 130035f106e6SPaolo Bonzini if (qemu_in_coroutine()) { 130135f106e6SPaolo Bonzini /* Fast-path if already in coroutine context */ 130235f106e6SPaolo Bonzini co_entry(&rwco); 130335f106e6SPaolo Bonzini } else { 130435f106e6SPaolo Bonzini Coroutine *co = qemu_coroutine_create(co_entry, &rwco); 1305e92f0e19SFam Zheng bdrv_coroutine_enter(blk_bs(blk), co); 130688b062c2SPaolo Bonzini BDRV_POLL_WHILE(blk_bs(blk), rwco.ret == NOT_DONE); 130735f106e6SPaolo Bonzini } 1308fbb92b67SKevin Wolf blk_dec_in_flight(blk); 13091bf1cbc9SKevin Wolf 13101bf1cbc9SKevin Wolf return rwco.ret; 13114be74634SMarkus Armbruster } 13124be74634SMarkus Armbruster 1313d004bd52SEric Blake int blk_pwrite_zeroes(BlockBackend *blk, int64_t offset, 1314f5a5ca79SManos Pitsidianakis int bytes, BdrvRequestFlags flags) 13150df89e8eSKevin Wolf { 1316f5a5ca79SManos Pitsidianakis return blk_prw(blk, offset, NULL, bytes, blk_write_entry, 131716aaf975SKevin Wolf flags | BDRV_REQ_ZERO_WRITE); 13180df89e8eSKevin Wolf } 13190df89e8eSKevin Wolf 1320720ff280SKevin Wolf int blk_make_zero(BlockBackend *blk, BdrvRequestFlags flags) 1321720ff280SKevin Wolf { 1322720ff280SKevin Wolf return bdrv_make_zero(blk->root, flags); 1323720ff280SKevin Wolf } 1324720ff280SKevin Wolf 1325c90e2a9cSKevin Wolf void blk_inc_in_flight(BlockBackend *blk) 132633f2a757SStefan Hajnoczi { 132733f2a757SStefan Hajnoczi atomic_inc(&blk->in_flight); 132833f2a757SStefan Hajnoczi } 132933f2a757SStefan Hajnoczi 1330c90e2a9cSKevin Wolf void blk_dec_in_flight(BlockBackend *blk) 133133f2a757SStefan Hajnoczi { 133233f2a757SStefan Hajnoczi atomic_dec(&blk->in_flight); 1333cfe29d82SKevin Wolf aio_wait_kick(); 133433f2a757SStefan Hajnoczi } 133533f2a757SStefan Hajnoczi 1336e7f7d676SMax Reitz static void error_callback_bh(void *opaque) 1337e7f7d676SMax Reitz { 1338e7f7d676SMax Reitz struct BlockBackendAIOCB *acb = opaque; 133999723548SPaolo Bonzini 134033f2a757SStefan Hajnoczi blk_dec_in_flight(acb->blk); 1341e7f7d676SMax Reitz acb->common.cb(acb->common.opaque, acb->ret); 1342e7f7d676SMax Reitz qemu_aio_unref(acb); 1343e7f7d676SMax Reitz } 1344e7f7d676SMax Reitz 1345ca78ecfaSPeter Lieven BlockAIOCB *blk_abort_aio_request(BlockBackend *blk, 1346ca78ecfaSPeter Lieven BlockCompletionFunc *cb, 1347e7f7d676SMax Reitz void *opaque, int ret) 1348e7f7d676SMax Reitz { 1349e7f7d676SMax Reitz struct BlockBackendAIOCB *acb; 1350e7f7d676SMax Reitz 135133f2a757SStefan Hajnoczi blk_inc_in_flight(blk); 1352e7f7d676SMax Reitz acb = blk_aio_get(&block_backend_aiocb_info, blk, cb, opaque); 13534981bdecSMax Reitz acb->blk = blk; 1354e7f7d676SMax Reitz acb->ret = ret; 1355e7f7d676SMax Reitz 1356e4ec5ad4SPavel Dovgalyuk replay_bh_schedule_oneshot_event(blk_get_aio_context(blk), 1357e4ec5ad4SPavel Dovgalyuk error_callback_bh, acb); 1358e7f7d676SMax Reitz return &acb->common; 1359e7f7d676SMax Reitz } 1360e7f7d676SMax Reitz 136157d6a428SKevin Wolf typedef struct BlkAioEmAIOCB { 136257d6a428SKevin Wolf BlockAIOCB common; 136357d6a428SKevin Wolf BlkRwCo rwco; 13647fa84cd8SKevin Wolf int bytes; 136557d6a428SKevin Wolf bool has_returned; 136657d6a428SKevin Wolf } BlkAioEmAIOCB; 136757d6a428SKevin Wolf 136857d6a428SKevin Wolf static const AIOCBInfo blk_aio_em_aiocb_info = { 136957d6a428SKevin Wolf .aiocb_size = sizeof(BlkAioEmAIOCB), 137057d6a428SKevin Wolf }; 137157d6a428SKevin Wolf 137257d6a428SKevin Wolf static void blk_aio_complete(BlkAioEmAIOCB *acb) 137357d6a428SKevin Wolf { 137457d6a428SKevin Wolf if (acb->has_returned) { 137557d6a428SKevin Wolf acb->common.cb(acb->common.opaque, acb->rwco.ret); 137646aaf2a5SKevin Wolf blk_dec_in_flight(acb->rwco.blk); 137757d6a428SKevin Wolf qemu_aio_unref(acb); 137857d6a428SKevin Wolf } 137957d6a428SKevin Wolf } 138057d6a428SKevin Wolf 138157d6a428SKevin Wolf static void blk_aio_complete_bh(void *opaque) 138257d6a428SKevin Wolf { 1383fffb6e12SPaolo Bonzini BlkAioEmAIOCB *acb = opaque; 1384fffb6e12SPaolo Bonzini assert(acb->has_returned); 1385fffb6e12SPaolo Bonzini blk_aio_complete(acb); 138657d6a428SKevin Wolf } 138757d6a428SKevin Wolf 13887fa84cd8SKevin Wolf static BlockAIOCB *blk_aio_prwv(BlockBackend *blk, int64_t offset, int bytes, 1389c060332cSDeepa Srinivasan void *iobuf, CoroutineEntry co_entry, 139057d6a428SKevin Wolf BdrvRequestFlags flags, 139157d6a428SKevin Wolf BlockCompletionFunc *cb, void *opaque) 139257d6a428SKevin Wolf { 139357d6a428SKevin Wolf BlkAioEmAIOCB *acb; 139457d6a428SKevin Wolf Coroutine *co; 139557d6a428SKevin Wolf 139633f2a757SStefan Hajnoczi blk_inc_in_flight(blk); 139757d6a428SKevin Wolf acb = blk_aio_get(&blk_aio_em_aiocb_info, blk, cb, opaque); 139857d6a428SKevin Wolf acb->rwco = (BlkRwCo) { 139957d6a428SKevin Wolf .blk = blk, 140057d6a428SKevin Wolf .offset = offset, 1401c060332cSDeepa Srinivasan .iobuf = iobuf, 140257d6a428SKevin Wolf .flags = flags, 140357d6a428SKevin Wolf .ret = NOT_DONE, 140457d6a428SKevin Wolf }; 14057fa84cd8SKevin Wolf acb->bytes = bytes; 140657d6a428SKevin Wolf acb->has_returned = false; 140757d6a428SKevin Wolf 14080b8b8753SPaolo Bonzini co = qemu_coroutine_create(co_entry, acb); 1409e92f0e19SFam Zheng bdrv_coroutine_enter(blk_bs(blk), co); 141057d6a428SKevin Wolf 141157d6a428SKevin Wolf acb->has_returned = true; 141257d6a428SKevin Wolf if (acb->rwco.ret != NOT_DONE) { 1413e4ec5ad4SPavel Dovgalyuk replay_bh_schedule_oneshot_event(blk_get_aio_context(blk), 1414fffb6e12SPaolo Bonzini blk_aio_complete_bh, acb); 141557d6a428SKevin Wolf } 141657d6a428SKevin Wolf 141757d6a428SKevin Wolf return &acb->common; 141857d6a428SKevin Wolf } 141957d6a428SKevin Wolf 142057d6a428SKevin Wolf static void blk_aio_read_entry(void *opaque) 142157d6a428SKevin Wolf { 142257d6a428SKevin Wolf BlkAioEmAIOCB *acb = opaque; 142357d6a428SKevin Wolf BlkRwCo *rwco = &acb->rwco; 1424c060332cSDeepa Srinivasan QEMUIOVector *qiov = rwco->iobuf; 142557d6a428SKevin Wolf 1426c060332cSDeepa Srinivasan assert(qiov->size == acb->bytes); 1427fbb92b67SKevin Wolf rwco->ret = blk_do_preadv(rwco->blk, rwco->offset, acb->bytes, 1428c060332cSDeepa Srinivasan qiov, rwco->flags); 142957d6a428SKevin Wolf blk_aio_complete(acb); 143057d6a428SKevin Wolf } 143157d6a428SKevin Wolf 143257d6a428SKevin Wolf static void blk_aio_write_entry(void *opaque) 143357d6a428SKevin Wolf { 143457d6a428SKevin Wolf BlkAioEmAIOCB *acb = opaque; 143557d6a428SKevin Wolf BlkRwCo *rwco = &acb->rwco; 1436c060332cSDeepa Srinivasan QEMUIOVector *qiov = rwco->iobuf; 143757d6a428SKevin Wolf 1438c060332cSDeepa Srinivasan assert(!qiov || qiov->size == acb->bytes); 1439fbb92b67SKevin Wolf rwco->ret = blk_do_pwritev_part(rwco->blk, rwco->offset, acb->bytes, 1440fbb92b67SKevin Wolf qiov, 0, rwco->flags); 144157d6a428SKevin Wolf blk_aio_complete(acb); 144257d6a428SKevin Wolf } 144357d6a428SKevin Wolf 1444d004bd52SEric Blake BlockAIOCB *blk_aio_pwrite_zeroes(BlockBackend *blk, int64_t offset, 1445983a1600SEric Blake int count, BdrvRequestFlags flags, 14464be74634SMarkus Armbruster BlockCompletionFunc *cb, void *opaque) 14474be74634SMarkus Armbruster { 1448983a1600SEric Blake return blk_aio_prwv(blk, offset, count, NULL, blk_aio_write_entry, 1449983a1600SEric Blake flags | BDRV_REQ_ZERO_WRITE, cb, opaque); 14504be74634SMarkus Armbruster } 14514be74634SMarkus Armbruster 14524be74634SMarkus Armbruster int blk_pread(BlockBackend *blk, int64_t offset, void *buf, int count) 14534be74634SMarkus Armbruster { 1454a55d3fbaSKevin Wolf int ret = blk_prw(blk, offset, buf, count, blk_read_entry, 0); 1455e7f7d676SMax Reitz if (ret < 0) { 1456e7f7d676SMax Reitz return ret; 1457e7f7d676SMax Reitz } 1458a55d3fbaSKevin Wolf return count; 14594be74634SMarkus Armbruster } 14604be74634SMarkus Armbruster 14618341f00dSEric Blake int blk_pwrite(BlockBackend *blk, int64_t offset, const void *buf, int count, 14628341f00dSEric Blake BdrvRequestFlags flags) 14634be74634SMarkus Armbruster { 14648341f00dSEric Blake int ret = blk_prw(blk, offset, (void *) buf, count, blk_write_entry, 14658341f00dSEric Blake flags); 1466e7f7d676SMax Reitz if (ret < 0) { 1467e7f7d676SMax Reitz return ret; 1468e7f7d676SMax Reitz } 1469a55d3fbaSKevin Wolf return count; 14704be74634SMarkus Armbruster } 14714be74634SMarkus Armbruster 14724be74634SMarkus Armbruster int64_t blk_getlength(BlockBackend *blk) 14734be74634SMarkus Armbruster { 1474c09ba36cSMax Reitz if (!blk_is_available(blk)) { 1475c09ba36cSMax Reitz return -ENOMEDIUM; 1476c09ba36cSMax Reitz } 1477c09ba36cSMax Reitz 1478f21d96d0SKevin Wolf return bdrv_getlength(blk_bs(blk)); 14794be74634SMarkus Armbruster } 14804be74634SMarkus Armbruster 14814be74634SMarkus Armbruster void blk_get_geometry(BlockBackend *blk, uint64_t *nb_sectors_ptr) 14824be74634SMarkus Armbruster { 1483f21d96d0SKevin Wolf if (!blk_bs(blk)) { 1484a46fc9c9SMax Reitz *nb_sectors_ptr = 0; 1485a46fc9c9SMax Reitz } else { 1486f21d96d0SKevin Wolf bdrv_get_geometry(blk_bs(blk), nb_sectors_ptr); 14874be74634SMarkus Armbruster } 1488a46fc9c9SMax Reitz } 14894be74634SMarkus Armbruster 14901ef01253SMax Reitz int64_t blk_nb_sectors(BlockBackend *blk) 14911ef01253SMax Reitz { 1492c09ba36cSMax Reitz if (!blk_is_available(blk)) { 1493c09ba36cSMax Reitz return -ENOMEDIUM; 1494c09ba36cSMax Reitz } 1495c09ba36cSMax Reitz 1496f21d96d0SKevin Wolf return bdrv_nb_sectors(blk_bs(blk)); 14971ef01253SMax Reitz } 14981ef01253SMax Reitz 149960cb2fa7SEric Blake BlockAIOCB *blk_aio_preadv(BlockBackend *blk, int64_t offset, 150060cb2fa7SEric Blake QEMUIOVector *qiov, BdrvRequestFlags flags, 150160cb2fa7SEric Blake BlockCompletionFunc *cb, void *opaque) 150260cb2fa7SEric Blake { 150360cb2fa7SEric Blake return blk_aio_prwv(blk, offset, qiov->size, qiov, 150460cb2fa7SEric Blake blk_aio_read_entry, flags, cb, opaque); 150560cb2fa7SEric Blake } 150660cb2fa7SEric Blake 150760cb2fa7SEric Blake BlockAIOCB *blk_aio_pwritev(BlockBackend *blk, int64_t offset, 150860cb2fa7SEric Blake QEMUIOVector *qiov, BdrvRequestFlags flags, 150960cb2fa7SEric Blake BlockCompletionFunc *cb, void *opaque) 151060cb2fa7SEric Blake { 151160cb2fa7SEric Blake return blk_aio_prwv(blk, offset, qiov->size, qiov, 151260cb2fa7SEric Blake blk_aio_write_entry, flags, cb, opaque); 151360cb2fa7SEric Blake } 151460cb2fa7SEric Blake 15154be74634SMarkus Armbruster void blk_aio_cancel(BlockAIOCB *acb) 15164be74634SMarkus Armbruster { 15174be74634SMarkus Armbruster bdrv_aio_cancel(acb); 15184be74634SMarkus Armbruster } 15194be74634SMarkus Armbruster 15204be74634SMarkus Armbruster void blk_aio_cancel_async(BlockAIOCB *acb) 15214be74634SMarkus Armbruster { 15224be74634SMarkus Armbruster bdrv_aio_cancel_async(acb); 15234be74634SMarkus Armbruster } 15244be74634SMarkus Armbruster 1525fbb92b67SKevin Wolf /* To be called between exactly one pair of blk_inc/dec_in_flight() */ 1526fbb92b67SKevin Wolf static int coroutine_fn 1527fbb92b67SKevin Wolf blk_do_ioctl(BlockBackend *blk, unsigned long int req, void *buf) 15284be74634SMarkus Armbruster { 1529cf312932SKevin Wolf blk_wait_while_drained(blk); 1530cf312932SKevin Wolf 1531c09ba36cSMax Reitz if (!blk_is_available(blk)) { 1532c09ba36cSMax Reitz return -ENOMEDIUM; 1533c09ba36cSMax Reitz } 1534c09ba36cSMax Reitz 153548af776aSKevin Wolf return bdrv_co_ioctl(blk_bs(blk), req, buf); 153648af776aSKevin Wolf } 153748af776aSKevin Wolf 153848af776aSKevin Wolf static void blk_ioctl_entry(void *opaque) 153948af776aSKevin Wolf { 154048af776aSKevin Wolf BlkRwCo *rwco = opaque; 1541c060332cSDeepa Srinivasan QEMUIOVector *qiov = rwco->iobuf; 1542c060332cSDeepa Srinivasan 1543fbb92b67SKevin Wolf rwco->ret = blk_do_ioctl(rwco->blk, rwco->offset, qiov->iov[0].iov_base); 15444720cbeeSKevin Wolf aio_wait_kick(); 154548af776aSKevin Wolf } 154648af776aSKevin Wolf 154748af776aSKevin Wolf int blk_ioctl(BlockBackend *blk, unsigned long int req, void *buf) 154848af776aSKevin Wolf { 154948af776aSKevin Wolf return blk_prw(blk, req, buf, 0, blk_ioctl_entry, 0); 155048af776aSKevin Wolf } 155148af776aSKevin Wolf 155248af776aSKevin Wolf static void blk_aio_ioctl_entry(void *opaque) 155348af776aSKevin Wolf { 155448af776aSKevin Wolf BlkAioEmAIOCB *acb = opaque; 155548af776aSKevin Wolf BlkRwCo *rwco = &acb->rwco; 155648af776aSKevin Wolf 1557fbb92b67SKevin Wolf rwco->ret = blk_do_ioctl(rwco->blk, rwco->offset, rwco->iobuf); 1558c060332cSDeepa Srinivasan 155948af776aSKevin Wolf blk_aio_complete(acb); 15604be74634SMarkus Armbruster } 15614be74634SMarkus Armbruster 15624be74634SMarkus Armbruster BlockAIOCB *blk_aio_ioctl(BlockBackend *blk, unsigned long int req, void *buf, 15634be74634SMarkus Armbruster BlockCompletionFunc *cb, void *opaque) 15644be74634SMarkus Armbruster { 1565c060332cSDeepa Srinivasan return blk_aio_prwv(blk, req, 0, buf, blk_aio_ioctl_entry, 0, cb, opaque); 15664be74634SMarkus Armbruster } 15674be74634SMarkus Armbruster 1568fbb92b67SKevin Wolf /* To be called between exactly one pair of blk_inc/dec_in_flight() */ 1569fbb92b67SKevin Wolf static int coroutine_fn 1570fbb92b67SKevin Wolf blk_do_pdiscard(BlockBackend *blk, int64_t offset, int bytes) 15712bb0dce7SMax Reitz { 1572cf312932SKevin Wolf int ret; 1573cf312932SKevin Wolf 1574cf312932SKevin Wolf blk_wait_while_drained(blk); 1575cf312932SKevin Wolf 1576cf312932SKevin Wolf ret = blk_check_byte_request(blk, offset, bytes); 1577e7f7d676SMax Reitz if (ret < 0) { 1578e7f7d676SMax Reitz return ret; 1579e7f7d676SMax Reitz } 1580e7f7d676SMax Reitz 15810b9fd3f4SFam Zheng return bdrv_co_pdiscard(blk->root, offset, bytes); 15822bb0dce7SMax Reitz } 15832bb0dce7SMax Reitz 1584564806c5SKevin Wolf static void blk_aio_pdiscard_entry(void *opaque) 1585564806c5SKevin Wolf { 1586564806c5SKevin Wolf BlkAioEmAIOCB *acb = opaque; 1587564806c5SKevin Wolf BlkRwCo *rwco = &acb->rwco; 1588564806c5SKevin Wolf 1589fbb92b67SKevin Wolf rwco->ret = blk_do_pdiscard(rwco->blk, rwco->offset, acb->bytes); 1590564806c5SKevin Wolf blk_aio_complete(acb); 1591564806c5SKevin Wolf } 1592564806c5SKevin Wolf 1593564806c5SKevin Wolf BlockAIOCB *blk_aio_pdiscard(BlockBackend *blk, 1594564806c5SKevin Wolf int64_t offset, int bytes, 1595564806c5SKevin Wolf BlockCompletionFunc *cb, void *opaque) 1596564806c5SKevin Wolf { 1597564806c5SKevin Wolf return blk_aio_prwv(blk, offset, bytes, NULL, blk_aio_pdiscard_entry, 0, 1598564806c5SKevin Wolf cb, opaque); 1599564806c5SKevin Wolf } 1600564806c5SKevin Wolf 1601fbb92b67SKevin Wolf int coroutine_fn blk_co_pdiscard(BlockBackend *blk, int64_t offset, int bytes) 1602fbb92b67SKevin Wolf { 1603fbb92b67SKevin Wolf int ret; 1604fbb92b67SKevin Wolf 1605fbb92b67SKevin Wolf blk_inc_in_flight(blk); 1606fbb92b67SKevin Wolf ret = blk_do_pdiscard(blk, offset, bytes); 1607fbb92b67SKevin Wolf blk_dec_in_flight(blk); 1608fbb92b67SKevin Wolf 1609fbb92b67SKevin Wolf return ret; 1610fbb92b67SKevin Wolf } 1611fbb92b67SKevin Wolf 1612564806c5SKevin Wolf static void blk_pdiscard_entry(void *opaque) 1613564806c5SKevin Wolf { 1614564806c5SKevin Wolf BlkRwCo *rwco = opaque; 1615564806c5SKevin Wolf QEMUIOVector *qiov = rwco->iobuf; 1616564806c5SKevin Wolf 1617fbb92b67SKevin Wolf rwco->ret = blk_do_pdiscard(rwco->blk, rwco->offset, qiov->size); 1618564806c5SKevin Wolf aio_wait_kick(); 1619564806c5SKevin Wolf } 1620564806c5SKevin Wolf 1621564806c5SKevin Wolf int blk_pdiscard(BlockBackend *blk, int64_t offset, int bytes) 1622564806c5SKevin Wolf { 1623564806c5SKevin Wolf return blk_prw(blk, offset, NULL, bytes, blk_pdiscard_entry, 0); 1624564806c5SKevin Wolf } 1625564806c5SKevin Wolf 1626fbb92b67SKevin Wolf /* To be called between exactly one pair of blk_inc/dec_in_flight() */ 1627fbb92b67SKevin Wolf static int coroutine_fn blk_do_flush(BlockBackend *blk) 16282bb0dce7SMax Reitz { 1629cf312932SKevin Wolf blk_wait_while_drained(blk); 1630cf312932SKevin Wolf 1631c09ba36cSMax Reitz if (!blk_is_available(blk)) { 1632c09ba36cSMax Reitz return -ENOMEDIUM; 1633c09ba36cSMax Reitz } 1634c09ba36cSMax Reitz 1635f21d96d0SKevin Wolf return bdrv_co_flush(blk_bs(blk)); 16362bb0dce7SMax Reitz } 16372bb0dce7SMax Reitz 1638564806c5SKevin Wolf static void blk_aio_flush_entry(void *opaque) 1639564806c5SKevin Wolf { 1640564806c5SKevin Wolf BlkAioEmAIOCB *acb = opaque; 1641564806c5SKevin Wolf BlkRwCo *rwco = &acb->rwco; 1642564806c5SKevin Wolf 1643fbb92b67SKevin Wolf rwco->ret = blk_do_flush(rwco->blk); 1644564806c5SKevin Wolf blk_aio_complete(acb); 1645564806c5SKevin Wolf } 1646564806c5SKevin Wolf 1647564806c5SKevin Wolf BlockAIOCB *blk_aio_flush(BlockBackend *blk, 1648564806c5SKevin Wolf BlockCompletionFunc *cb, void *opaque) 1649564806c5SKevin Wolf { 1650564806c5SKevin Wolf return blk_aio_prwv(blk, 0, 0, NULL, blk_aio_flush_entry, 0, cb, opaque); 1651564806c5SKevin Wolf } 1652564806c5SKevin Wolf 1653fbb92b67SKevin Wolf int coroutine_fn blk_co_flush(BlockBackend *blk) 1654fbb92b67SKevin Wolf { 1655fbb92b67SKevin Wolf int ret; 1656fbb92b67SKevin Wolf 1657fbb92b67SKevin Wolf blk_inc_in_flight(blk); 1658fbb92b67SKevin Wolf ret = blk_do_flush(blk); 1659fbb92b67SKevin Wolf blk_dec_in_flight(blk); 1660fbb92b67SKevin Wolf 1661fbb92b67SKevin Wolf return ret; 1662fbb92b67SKevin Wolf } 1663fbb92b67SKevin Wolf 1664be07a889SKevin Wolf static void blk_flush_entry(void *opaque) 16654be74634SMarkus Armbruster { 1666be07a889SKevin Wolf BlkRwCo *rwco = opaque; 1667fbb92b67SKevin Wolf rwco->ret = blk_do_flush(rwco->blk); 16684720cbeeSKevin Wolf aio_wait_kick(); 1669c09ba36cSMax Reitz } 1670c09ba36cSMax Reitz 1671be07a889SKevin Wolf int blk_flush(BlockBackend *blk) 1672be07a889SKevin Wolf { 1673be07a889SKevin Wolf return blk_prw(blk, 0, NULL, 0, blk_flush_entry, 0); 16744be74634SMarkus Armbruster } 16754be74634SMarkus Armbruster 167697b0385aSAlexander Yarygin void blk_drain(BlockBackend *blk) 167797b0385aSAlexander Yarygin { 167833f2a757SStefan Hajnoczi BlockDriverState *bs = blk_bs(blk); 167933f2a757SStefan Hajnoczi 168033f2a757SStefan Hajnoczi if (bs) { 168133f2a757SStefan Hajnoczi bdrv_drained_begin(bs); 168233f2a757SStefan Hajnoczi } 168333f2a757SStefan Hajnoczi 168433f2a757SStefan Hajnoczi /* We may have -ENOMEDIUM completions in flight */ 1685cfe29d82SKevin Wolf AIO_WAIT_WHILE(blk_get_aio_context(blk), 168633f2a757SStefan Hajnoczi atomic_mb_read(&blk->in_flight) > 0); 168733f2a757SStefan Hajnoczi 168833f2a757SStefan Hajnoczi if (bs) { 168933f2a757SStefan Hajnoczi bdrv_drained_end(bs); 169097b0385aSAlexander Yarygin } 1691a46fc9c9SMax Reitz } 169297b0385aSAlexander Yarygin 16934be74634SMarkus Armbruster void blk_drain_all(void) 16944be74634SMarkus Armbruster { 169533f2a757SStefan Hajnoczi BlockBackend *blk = NULL; 169633f2a757SStefan Hajnoczi 169733f2a757SStefan Hajnoczi bdrv_drain_all_begin(); 169833f2a757SStefan Hajnoczi 169933f2a757SStefan Hajnoczi while ((blk = blk_all_next(blk)) != NULL) { 170033f2a757SStefan Hajnoczi AioContext *ctx = blk_get_aio_context(blk); 170133f2a757SStefan Hajnoczi 170233f2a757SStefan Hajnoczi aio_context_acquire(ctx); 170333f2a757SStefan Hajnoczi 170433f2a757SStefan Hajnoczi /* We may have -ENOMEDIUM completions in flight */ 1705cfe29d82SKevin Wolf AIO_WAIT_WHILE(ctx, atomic_mb_read(&blk->in_flight) > 0); 170633f2a757SStefan Hajnoczi 170733f2a757SStefan Hajnoczi aio_context_release(ctx); 170833f2a757SStefan Hajnoczi } 170933f2a757SStefan Hajnoczi 171033f2a757SStefan Hajnoczi bdrv_drain_all_end(); 17114be74634SMarkus Armbruster } 17124be74634SMarkus Armbruster 1713373340b2SMax Reitz void blk_set_on_error(BlockBackend *blk, BlockdevOnError on_read_error, 1714373340b2SMax Reitz BlockdevOnError on_write_error) 1715373340b2SMax Reitz { 1716373340b2SMax Reitz blk->on_read_error = on_read_error; 1717373340b2SMax Reitz blk->on_write_error = on_write_error; 1718373340b2SMax Reitz } 1719373340b2SMax Reitz 17204be74634SMarkus Armbruster BlockdevOnError blk_get_on_error(BlockBackend *blk, bool is_read) 17214be74634SMarkus Armbruster { 1722373340b2SMax Reitz return is_read ? blk->on_read_error : blk->on_write_error; 17234be74634SMarkus Armbruster } 17244be74634SMarkus Armbruster 17254be74634SMarkus Armbruster BlockErrorAction blk_get_error_action(BlockBackend *blk, bool is_read, 17264be74634SMarkus Armbruster int error) 17274be74634SMarkus Armbruster { 1728373340b2SMax Reitz BlockdevOnError on_err = blk_get_on_error(blk, is_read); 1729373340b2SMax Reitz 1730373340b2SMax Reitz switch (on_err) { 1731373340b2SMax Reitz case BLOCKDEV_ON_ERROR_ENOSPC: 1732373340b2SMax Reitz return (error == ENOSPC) ? 1733373340b2SMax Reitz BLOCK_ERROR_ACTION_STOP : BLOCK_ERROR_ACTION_REPORT; 1734373340b2SMax Reitz case BLOCKDEV_ON_ERROR_STOP: 1735373340b2SMax Reitz return BLOCK_ERROR_ACTION_STOP; 1736373340b2SMax Reitz case BLOCKDEV_ON_ERROR_REPORT: 1737373340b2SMax Reitz return BLOCK_ERROR_ACTION_REPORT; 1738373340b2SMax Reitz case BLOCKDEV_ON_ERROR_IGNORE: 1739373340b2SMax Reitz return BLOCK_ERROR_ACTION_IGNORE; 17408c398252SKevin Wolf case BLOCKDEV_ON_ERROR_AUTO: 1741373340b2SMax Reitz default: 1742373340b2SMax Reitz abort(); 1743373340b2SMax Reitz } 17444be74634SMarkus Armbruster } 17454be74634SMarkus Armbruster 1746373340b2SMax Reitz static void send_qmp_error_event(BlockBackend *blk, 1747373340b2SMax Reitz BlockErrorAction action, 1748373340b2SMax Reitz bool is_read, int error) 1749373340b2SMax Reitz { 1750373340b2SMax Reitz IoOperationType optype; 1751bfe1a14cSKevin Wolf BlockDriverState *bs = blk_bs(blk); 1752373340b2SMax Reitz 1753373340b2SMax Reitz optype = is_read ? IO_OPERATION_TYPE_READ : IO_OPERATION_TYPE_WRITE; 1754bfe1a14cSKevin Wolf qapi_event_send_block_io_error(blk_name(blk), !!bs, 1755bfe1a14cSKevin Wolf bs ? bdrv_get_node_name(bs) : NULL, optype, 17562bf7e10fSKevin Wolf action, blk_iostatus_is_enabled(blk), 17573ab72385SPeter Xu error == ENOSPC, strerror(error)); 1758373340b2SMax Reitz } 1759373340b2SMax Reitz 1760373340b2SMax Reitz /* This is done by device models because, while the block layer knows 1761373340b2SMax Reitz * about the error, it does not know whether an operation comes from 1762373340b2SMax Reitz * the device or the block layer (from a job, for example). 1763373340b2SMax Reitz */ 17644be74634SMarkus Armbruster void blk_error_action(BlockBackend *blk, BlockErrorAction action, 17654be74634SMarkus Armbruster bool is_read, int error) 17664be74634SMarkus Armbruster { 1767373340b2SMax Reitz assert(error >= 0); 1768373340b2SMax Reitz 1769373340b2SMax Reitz if (action == BLOCK_ERROR_ACTION_STOP) { 1770373340b2SMax Reitz /* First set the iostatus, so that "info block" returns an iostatus 1771373340b2SMax Reitz * that matches the events raised so far (an additional error iostatus 1772373340b2SMax Reitz * is fine, but not a lost one). 1773373340b2SMax Reitz */ 1774373340b2SMax Reitz blk_iostatus_set_err(blk, error); 1775373340b2SMax Reitz 1776373340b2SMax Reitz /* Then raise the request to stop the VM and the event. 1777373340b2SMax Reitz * qemu_system_vmstop_request_prepare has two effects. First, 1778373340b2SMax Reitz * it ensures that the STOP event always comes after the 1779373340b2SMax Reitz * BLOCK_IO_ERROR event. Second, it ensures that even if management 1780373340b2SMax Reitz * can observe the STOP event and do a "cont" before the STOP 1781373340b2SMax Reitz * event is issued, the VM will not stop. In this case, vm_start() 1782373340b2SMax Reitz * also ensures that the STOP/RESUME pair of events is emitted. 1783373340b2SMax Reitz */ 1784373340b2SMax Reitz qemu_system_vmstop_request_prepare(); 1785373340b2SMax Reitz send_qmp_error_event(blk, action, is_read, error); 1786373340b2SMax Reitz qemu_system_vmstop_request(RUN_STATE_IO_ERROR); 1787373340b2SMax Reitz } else { 1788373340b2SMax Reitz send_qmp_error_event(blk, action, is_read, error); 1789373340b2SMax Reitz } 17904be74634SMarkus Armbruster } 17914be74634SMarkus Armbruster 179296710565SLi Qiang bool blk_is_read_only(BlockBackend *blk) 17934be74634SMarkus Armbruster { 1794f21d96d0SKevin Wolf BlockDriverState *bs = blk_bs(blk); 1795f21d96d0SKevin Wolf 1796f21d96d0SKevin Wolf if (bs) { 1797f21d96d0SKevin Wolf return bdrv_is_read_only(bs); 1798061959e8SMax Reitz } else { 1799061959e8SMax Reitz return blk->root_state.read_only; 1800061959e8SMax Reitz } 18014be74634SMarkus Armbruster } 18024be74634SMarkus Armbruster 180396710565SLi Qiang bool blk_is_sg(BlockBackend *blk) 18044be74634SMarkus Armbruster { 1805f21d96d0SKevin Wolf BlockDriverState *bs = blk_bs(blk); 1806f21d96d0SKevin Wolf 1807f21d96d0SKevin Wolf if (!bs) { 180896710565SLi Qiang return false; 1809a46fc9c9SMax Reitz } 1810a46fc9c9SMax Reitz 1811f21d96d0SKevin Wolf return bdrv_is_sg(bs); 18124be74634SMarkus Armbruster } 18134be74634SMarkus Armbruster 181496710565SLi Qiang bool blk_enable_write_cache(BlockBackend *blk) 18154be74634SMarkus Armbruster { 1816bfd18d1eSKevin Wolf return blk->enable_write_cache; 18174be74634SMarkus Armbruster } 18184be74634SMarkus Armbruster 18194be74634SMarkus Armbruster void blk_set_enable_write_cache(BlockBackend *blk, bool wce) 18204be74634SMarkus Armbruster { 1821bfd18d1eSKevin Wolf blk->enable_write_cache = wce; 18224be74634SMarkus Armbruster } 18234be74634SMarkus Armbruster 18242bb0dce7SMax Reitz void blk_invalidate_cache(BlockBackend *blk, Error **errp) 18252bb0dce7SMax Reitz { 1826f21d96d0SKevin Wolf BlockDriverState *bs = blk_bs(blk); 1827f21d96d0SKevin Wolf 1828f21d96d0SKevin Wolf if (!bs) { 1829c09ba36cSMax Reitz error_setg(errp, "Device '%s' has no medium", blk->name); 1830c09ba36cSMax Reitz return; 1831c09ba36cSMax Reitz } 1832c09ba36cSMax Reitz 1833f21d96d0SKevin Wolf bdrv_invalidate_cache(bs, errp); 18342bb0dce7SMax Reitz } 18352bb0dce7SMax Reitz 1836e031f750SMax Reitz bool blk_is_inserted(BlockBackend *blk) 18374be74634SMarkus Armbruster { 1838f21d96d0SKevin Wolf BlockDriverState *bs = blk_bs(blk); 1839f21d96d0SKevin Wolf 1840f21d96d0SKevin Wolf return bs && bdrv_is_inserted(bs); 1841db0284f8SMax Reitz } 1842db0284f8SMax Reitz 1843db0284f8SMax Reitz bool blk_is_available(BlockBackend *blk) 1844db0284f8SMax Reitz { 1845db0284f8SMax Reitz return blk_is_inserted(blk) && !blk_dev_is_tray_open(blk); 18464be74634SMarkus Armbruster } 18474be74634SMarkus Armbruster 18484be74634SMarkus Armbruster void blk_lock_medium(BlockBackend *blk, bool locked) 18494be74634SMarkus Armbruster { 1850f21d96d0SKevin Wolf BlockDriverState *bs = blk_bs(blk); 1851f21d96d0SKevin Wolf 1852f21d96d0SKevin Wolf if (bs) { 1853f21d96d0SKevin Wolf bdrv_lock_medium(bs, locked); 18544be74634SMarkus Armbruster } 1855a46fc9c9SMax Reitz } 18564be74634SMarkus Armbruster 18574be74634SMarkus Armbruster void blk_eject(BlockBackend *blk, bool eject_flag) 18584be74634SMarkus Armbruster { 1859f21d96d0SKevin Wolf BlockDriverState *bs = blk_bs(blk); 18602d76e724SKevin Wolf char *id; 18612d76e724SKevin Wolf 1862f21d96d0SKevin Wolf if (bs) { 1863f21d96d0SKevin Wolf bdrv_eject(bs, eject_flag); 1864c47ee043SJohn Snow } 18652d76e724SKevin Wolf 1866c47ee043SJohn Snow /* Whether or not we ejected on the backend, 1867c47ee043SJohn Snow * the frontend experienced a tray event. */ 18682d76e724SKevin Wolf id = blk_get_attached_dev_id(blk); 18692d76e724SKevin Wolf qapi_event_send_device_tray_moved(blk_name(blk), id, 18703ab72385SPeter Xu eject_flag); 18712d76e724SKevin Wolf g_free(id); 1872a46fc9c9SMax Reitz } 18734be74634SMarkus Armbruster 18744be74634SMarkus Armbruster int blk_get_flags(BlockBackend *blk) 18754be74634SMarkus Armbruster { 1876f21d96d0SKevin Wolf BlockDriverState *bs = blk_bs(blk); 1877f21d96d0SKevin Wolf 1878f21d96d0SKevin Wolf if (bs) { 1879f21d96d0SKevin Wolf return bdrv_get_flags(bs); 1880061959e8SMax Reitz } else { 1881061959e8SMax Reitz return blk->root_state.open_flags; 1882061959e8SMax Reitz } 18834be74634SMarkus Armbruster } 18844be74634SMarkus Armbruster 18854841211eSEric Blake /* Returns the minimum request alignment, in bytes; guaranteed nonzero */ 18864841211eSEric Blake uint32_t blk_get_request_alignment(BlockBackend *blk) 18874841211eSEric Blake { 18884841211eSEric Blake BlockDriverState *bs = blk_bs(blk); 18894841211eSEric Blake return bs ? bs->bl.request_alignment : BDRV_SECTOR_SIZE; 18904841211eSEric Blake } 18914841211eSEric Blake 18925def6b80SEric Blake /* Returns the maximum transfer length, in bytes; guaranteed nonzero */ 18935def6b80SEric Blake uint32_t blk_get_max_transfer(BlockBackend *blk) 1894454057b7SPeter Lieven { 1895f21d96d0SKevin Wolf BlockDriverState *bs = blk_bs(blk); 18965def6b80SEric Blake uint32_t max = 0; 1897f21d96d0SKevin Wolf 1898f21d96d0SKevin Wolf if (bs) { 18995def6b80SEric Blake max = bs->bl.max_transfer; 1900a46fc9c9SMax Reitz } 19015def6b80SEric Blake return MIN_NON_ZERO(max, INT_MAX); 1902454057b7SPeter Lieven } 1903454057b7SPeter Lieven 1904648296e0SStefan Hajnoczi int blk_get_max_iov(BlockBackend *blk) 1905648296e0SStefan Hajnoczi { 1906f21d96d0SKevin Wolf return blk->root->bs->bl.max_iov; 1907648296e0SStefan Hajnoczi } 1908648296e0SStefan Hajnoczi 19094be74634SMarkus Armbruster void blk_set_guest_block_size(BlockBackend *blk, int align) 19104be74634SMarkus Armbruster { 191168e9ec01SMax Reitz blk->guest_block_size = align; 19124be74634SMarkus Armbruster } 19134be74634SMarkus Armbruster 1914f1c17521SPaolo Bonzini void *blk_try_blockalign(BlockBackend *blk, size_t size) 1915f1c17521SPaolo Bonzini { 1916f21d96d0SKevin Wolf return qemu_try_blockalign(blk ? blk_bs(blk) : NULL, size); 1917f1c17521SPaolo Bonzini } 1918f1c17521SPaolo Bonzini 19194be74634SMarkus Armbruster void *blk_blockalign(BlockBackend *blk, size_t size) 19204be74634SMarkus Armbruster { 1921f21d96d0SKevin Wolf return qemu_blockalign(blk ? blk_bs(blk) : NULL, size); 19224be74634SMarkus Armbruster } 19234be74634SMarkus Armbruster 19244be74634SMarkus Armbruster bool blk_op_is_blocked(BlockBackend *blk, BlockOpType op, Error **errp) 19254be74634SMarkus Armbruster { 1926f21d96d0SKevin Wolf BlockDriverState *bs = blk_bs(blk); 1927f21d96d0SKevin Wolf 1928f21d96d0SKevin Wolf if (!bs) { 1929a46fc9c9SMax Reitz return false; 1930a46fc9c9SMax Reitz } 1931a46fc9c9SMax Reitz 1932f21d96d0SKevin Wolf return bdrv_op_is_blocked(bs, op, errp); 19334be74634SMarkus Armbruster } 19344be74634SMarkus Armbruster 19354be74634SMarkus Armbruster void blk_op_unblock(BlockBackend *blk, BlockOpType op, Error *reason) 19364be74634SMarkus Armbruster { 1937f21d96d0SKevin Wolf BlockDriverState *bs = blk_bs(blk); 1938f21d96d0SKevin Wolf 1939f21d96d0SKevin Wolf if (bs) { 1940f21d96d0SKevin Wolf bdrv_op_unblock(bs, op, reason); 19414be74634SMarkus Armbruster } 1942a46fc9c9SMax Reitz } 19434be74634SMarkus Armbruster 19444be74634SMarkus Armbruster void blk_op_block_all(BlockBackend *blk, Error *reason) 19454be74634SMarkus Armbruster { 1946f21d96d0SKevin Wolf BlockDriverState *bs = blk_bs(blk); 1947f21d96d0SKevin Wolf 1948f21d96d0SKevin Wolf if (bs) { 1949f21d96d0SKevin Wolf bdrv_op_block_all(bs, reason); 19504be74634SMarkus Armbruster } 1951a46fc9c9SMax Reitz } 19524be74634SMarkus Armbruster 19534be74634SMarkus Armbruster void blk_op_unblock_all(BlockBackend *blk, Error *reason) 19544be74634SMarkus Armbruster { 1955f21d96d0SKevin Wolf BlockDriverState *bs = blk_bs(blk); 1956f21d96d0SKevin Wolf 1957f21d96d0SKevin Wolf if (bs) { 1958f21d96d0SKevin Wolf bdrv_op_unblock_all(bs, reason); 19594be74634SMarkus Armbruster } 1960a46fc9c9SMax Reitz } 19614be74634SMarkus Armbruster 19624be74634SMarkus Armbruster AioContext *blk_get_aio_context(BlockBackend *blk) 19634be74634SMarkus Armbruster { 1964d861ab3aSKevin Wolf BlockDriverState *bs = blk_bs(blk); 1965d861ab3aSKevin Wolf 1966d861ab3aSKevin Wolf if (bs) { 1967132ada80SKevin Wolf AioContext *ctx = bdrv_get_aio_context(blk_bs(blk)); 1968132ada80SKevin Wolf assert(ctx == blk->ctx); 19694981bdecSMax Reitz } 19704981bdecSMax Reitz 1971d861ab3aSKevin Wolf return blk->ctx; 1972d861ab3aSKevin Wolf } 1973d861ab3aSKevin Wolf 19744981bdecSMax Reitz static AioContext *blk_aiocb_get_aio_context(BlockAIOCB *acb) 19754981bdecSMax Reitz { 19764981bdecSMax Reitz BlockBackendAIOCB *blk_acb = DO_UPCAST(BlockBackendAIOCB, common, acb); 19774981bdecSMax Reitz return blk_get_aio_context(blk_acb->blk); 19784be74634SMarkus Armbruster } 19794be74634SMarkus Armbruster 198097896a48SKevin Wolf static int blk_do_set_aio_context(BlockBackend *blk, AioContext *new_context, 198197896a48SKevin Wolf bool update_root_node, Error **errp) 19824be74634SMarkus Armbruster { 1983f21d96d0SKevin Wolf BlockDriverState *bs = blk_bs(blk); 1984c61791fcSManos Pitsidianakis ThrottleGroupMember *tgm = &blk->public.throttle_group_member; 198597896a48SKevin Wolf int ret; 1986f21d96d0SKevin Wolf 1987f21d96d0SKevin Wolf if (bs) { 198897896a48SKevin Wolf if (update_root_node) { 198997896a48SKevin Wolf ret = bdrv_child_try_set_aio_context(bs, new_context, blk->root, 199097896a48SKevin Wolf errp); 199197896a48SKevin Wolf if (ret < 0) { 199297896a48SKevin Wolf return ret; 199397896a48SKevin Wolf } 199497896a48SKevin Wolf } 1995c61791fcSManos Pitsidianakis if (tgm->throttle_state) { 1996dc868fb0SStefan Hajnoczi bdrv_drained_begin(bs); 1997c61791fcSManos Pitsidianakis throttle_group_detach_aio_context(tgm); 1998c61791fcSManos Pitsidianakis throttle_group_attach_aio_context(tgm, new_context); 1999dc868fb0SStefan Hajnoczi bdrv_drained_end(bs); 20007ca7f0f6SKevin Wolf } 200138475269SKevin Wolf } 200238475269SKevin Wolf 2003d861ab3aSKevin Wolf blk->ctx = new_context; 200497896a48SKevin Wolf return 0; 200597896a48SKevin Wolf } 200697896a48SKevin Wolf 200797896a48SKevin Wolf int blk_set_aio_context(BlockBackend *blk, AioContext *new_context, 200897896a48SKevin Wolf Error **errp) 200938475269SKevin Wolf { 201097896a48SKevin Wolf return blk_do_set_aio_context(blk, new_context, true, errp); 201138475269SKevin Wolf } 201238475269SKevin Wolf 201338475269SKevin Wolf static bool blk_root_can_set_aio_ctx(BdrvChild *child, AioContext *ctx, 201438475269SKevin Wolf GSList **ignore, Error **errp) 201538475269SKevin Wolf { 201638475269SKevin Wolf BlockBackend *blk = child->opaque; 201738475269SKevin Wolf 2018980b0f94SKevin Wolf if (blk->allow_aio_context_change) { 2019980b0f94SKevin Wolf return true; 2020980b0f94SKevin Wolf } 2021980b0f94SKevin Wolf 202238475269SKevin Wolf /* Only manually created BlockBackends that are not attached to anything 202338475269SKevin Wolf * can change their AioContext without updating their user. */ 202438475269SKevin Wolf if (!blk->name || blk->dev) { 202538475269SKevin Wolf /* TODO Add BB name/QOM path */ 202638475269SKevin Wolf error_setg(errp, "Cannot change iothread of active block backend"); 202738475269SKevin Wolf return false; 202838475269SKevin Wolf } 202938475269SKevin Wolf 203038475269SKevin Wolf return true; 203138475269SKevin Wolf } 203238475269SKevin Wolf 203338475269SKevin Wolf static void blk_root_set_aio_ctx(BdrvChild *child, AioContext *ctx, 203438475269SKevin Wolf GSList **ignore) 203538475269SKevin Wolf { 203638475269SKevin Wolf BlockBackend *blk = child->opaque; 203797896a48SKevin Wolf blk_do_set_aio_context(blk, ctx, false, &error_abort); 203838475269SKevin Wolf } 20394be74634SMarkus Armbruster 20402019ba0aSMax Reitz void blk_add_aio_context_notifier(BlockBackend *blk, 20412019ba0aSMax Reitz void (*attached_aio_context)(AioContext *new_context, void *opaque), 20422019ba0aSMax Reitz void (*detach_aio_context)(void *opaque), void *opaque) 20432019ba0aSMax Reitz { 2044d03654eaSStefan Hajnoczi BlockBackendAioNotifier *notifier; 2045f21d96d0SKevin Wolf BlockDriverState *bs = blk_bs(blk); 2046f21d96d0SKevin Wolf 2047d03654eaSStefan Hajnoczi notifier = g_new(BlockBackendAioNotifier, 1); 2048d03654eaSStefan Hajnoczi notifier->attached_aio_context = attached_aio_context; 2049d03654eaSStefan Hajnoczi notifier->detach_aio_context = detach_aio_context; 2050d03654eaSStefan Hajnoczi notifier->opaque = opaque; 2051d03654eaSStefan Hajnoczi QLIST_INSERT_HEAD(&blk->aio_notifiers, notifier, list); 2052d03654eaSStefan Hajnoczi 2053f21d96d0SKevin Wolf if (bs) { 2054f21d96d0SKevin Wolf bdrv_add_aio_context_notifier(bs, attached_aio_context, 20552019ba0aSMax Reitz detach_aio_context, opaque); 20562019ba0aSMax Reitz } 2057a46fc9c9SMax Reitz } 20582019ba0aSMax Reitz 20592019ba0aSMax Reitz void blk_remove_aio_context_notifier(BlockBackend *blk, 20602019ba0aSMax Reitz void (*attached_aio_context)(AioContext *, 20612019ba0aSMax Reitz void *), 20622019ba0aSMax Reitz void (*detach_aio_context)(void *), 20632019ba0aSMax Reitz void *opaque) 20642019ba0aSMax Reitz { 2065d03654eaSStefan Hajnoczi BlockBackendAioNotifier *notifier; 2066f21d96d0SKevin Wolf BlockDriverState *bs = blk_bs(blk); 2067f21d96d0SKevin Wolf 2068f21d96d0SKevin Wolf if (bs) { 2069f21d96d0SKevin Wolf bdrv_remove_aio_context_notifier(bs, attached_aio_context, 20702019ba0aSMax Reitz detach_aio_context, opaque); 20712019ba0aSMax Reitz } 2072d03654eaSStefan Hajnoczi 2073d03654eaSStefan Hajnoczi QLIST_FOREACH(notifier, &blk->aio_notifiers, list) { 2074d03654eaSStefan Hajnoczi if (notifier->attached_aio_context == attached_aio_context && 2075d03654eaSStefan Hajnoczi notifier->detach_aio_context == detach_aio_context && 2076d03654eaSStefan Hajnoczi notifier->opaque == opaque) { 2077d03654eaSStefan Hajnoczi QLIST_REMOVE(notifier, list); 2078d03654eaSStefan Hajnoczi g_free(notifier); 2079d03654eaSStefan Hajnoczi return; 2080d03654eaSStefan Hajnoczi } 2081d03654eaSStefan Hajnoczi } 2082d03654eaSStefan Hajnoczi 2083d03654eaSStefan Hajnoczi abort(); 2084a46fc9c9SMax Reitz } 20852019ba0aSMax Reitz 20863301f6c6SMax Reitz void blk_add_remove_bs_notifier(BlockBackend *blk, Notifier *notify) 20873301f6c6SMax Reitz { 20883301f6c6SMax Reitz notifier_list_add(&blk->remove_bs_notifiers, notify); 20893301f6c6SMax Reitz } 20903301f6c6SMax Reitz 20913301f6c6SMax Reitz void blk_add_insert_bs_notifier(BlockBackend *blk, Notifier *notify) 20923301f6c6SMax Reitz { 20933301f6c6SMax Reitz notifier_list_add(&blk->insert_bs_notifiers, notify); 20943301f6c6SMax Reitz } 20953301f6c6SMax Reitz 20964be74634SMarkus Armbruster void blk_io_plug(BlockBackend *blk) 20974be74634SMarkus Armbruster { 2098f21d96d0SKevin Wolf BlockDriverState *bs = blk_bs(blk); 2099f21d96d0SKevin Wolf 2100f21d96d0SKevin Wolf if (bs) { 2101f21d96d0SKevin Wolf bdrv_io_plug(bs); 21024be74634SMarkus Armbruster } 2103a46fc9c9SMax Reitz } 21044be74634SMarkus Armbruster 21054be74634SMarkus Armbruster void blk_io_unplug(BlockBackend *blk) 21064be74634SMarkus Armbruster { 2107f21d96d0SKevin Wolf BlockDriverState *bs = blk_bs(blk); 2108f21d96d0SKevin Wolf 2109f21d96d0SKevin Wolf if (bs) { 2110f21d96d0SKevin Wolf bdrv_io_unplug(bs); 21114be74634SMarkus Armbruster } 2112a46fc9c9SMax Reitz } 21134be74634SMarkus Armbruster 21144be74634SMarkus Armbruster BlockAcctStats *blk_get_stats(BlockBackend *blk) 21154be74634SMarkus Armbruster { 21167f0e9da6SMax Reitz return &blk->stats; 21174be74634SMarkus Armbruster } 21184be74634SMarkus Armbruster 21194be74634SMarkus Armbruster void *blk_aio_get(const AIOCBInfo *aiocb_info, BlockBackend *blk, 21204be74634SMarkus Armbruster BlockCompletionFunc *cb, void *opaque) 21214be74634SMarkus Armbruster { 21224be74634SMarkus Armbruster return qemu_aio_get(aiocb_info, blk_bs(blk), cb, opaque); 21234be74634SMarkus Armbruster } 21241ef01253SMax Reitz 2125d004bd52SEric Blake int coroutine_fn blk_co_pwrite_zeroes(BlockBackend *blk, int64_t offset, 2126f5a5ca79SManos Pitsidianakis int bytes, BdrvRequestFlags flags) 21271ef01253SMax Reitz { 2128f5a5ca79SManos Pitsidianakis return blk_co_pwritev(blk, offset, bytes, NULL, 212916aaf975SKevin Wolf flags | BDRV_REQ_ZERO_WRITE); 21301ef01253SMax Reitz } 21311ef01253SMax Reitz 2132fe5c1355SPavel Butsykin int blk_pwrite_compressed(BlockBackend *blk, int64_t offset, const void *buf, 2133fe5c1355SPavel Butsykin int count) 21341ef01253SMax Reitz { 213535fadca8SPavel Butsykin return blk_prw(blk, offset, (void *) buf, count, blk_write_entry, 213635fadca8SPavel Butsykin BDRV_REQ_WRITE_COMPRESSED); 21371ef01253SMax Reitz } 21381ef01253SMax Reitz 2139c80d8b06SMax Reitz int blk_truncate(BlockBackend *blk, int64_t offset, bool exact, 2140*8c6242b6SKevin Wolf PreallocMode prealloc, BdrvRequestFlags flags, Error **errp) 21411ef01253SMax Reitz { 2142c09ba36cSMax Reitz if (!blk_is_available(blk)) { 2143ed3d2ec9SMax Reitz error_setg(errp, "No medium inserted"); 2144c09ba36cSMax Reitz return -ENOMEDIUM; 2145c09ba36cSMax Reitz } 2146c09ba36cSMax Reitz 2147*8c6242b6SKevin Wolf return bdrv_truncate(blk->root, offset, exact, prealloc, flags, errp); 21481ef01253SMax Reitz } 21491ef01253SMax Reitz 21501ef01253SMax Reitz int blk_save_vmstate(BlockBackend *blk, const uint8_t *buf, 21511ef01253SMax Reitz int64_t pos, int size) 21521ef01253SMax Reitz { 2153bfd18d1eSKevin Wolf int ret; 2154bfd18d1eSKevin Wolf 2155c09ba36cSMax Reitz if (!blk_is_available(blk)) { 2156c09ba36cSMax Reitz return -ENOMEDIUM; 2157c09ba36cSMax Reitz } 2158c09ba36cSMax Reitz 2159bfd18d1eSKevin Wolf ret = bdrv_save_vmstate(blk_bs(blk), buf, pos, size); 2160bfd18d1eSKevin Wolf if (ret < 0) { 2161bfd18d1eSKevin Wolf return ret; 2162bfd18d1eSKevin Wolf } 2163bfd18d1eSKevin Wolf 2164bfd18d1eSKevin Wolf if (ret == size && !blk->enable_write_cache) { 2165bfd18d1eSKevin Wolf ret = bdrv_flush(blk_bs(blk)); 2166bfd18d1eSKevin Wolf } 2167bfd18d1eSKevin Wolf 2168bfd18d1eSKevin Wolf return ret < 0 ? ret : size; 21691ef01253SMax Reitz } 21701ef01253SMax Reitz 21711ef01253SMax Reitz int blk_load_vmstate(BlockBackend *blk, uint8_t *buf, int64_t pos, int size) 21721ef01253SMax Reitz { 2173c09ba36cSMax Reitz if (!blk_is_available(blk)) { 2174c09ba36cSMax Reitz return -ENOMEDIUM; 2175c09ba36cSMax Reitz } 2176c09ba36cSMax Reitz 2177f21d96d0SKevin Wolf return bdrv_load_vmstate(blk_bs(blk), buf, pos, size); 21781ef01253SMax Reitz } 2179f0272c4dSEkaterina Tumanova 2180f0272c4dSEkaterina Tumanova int blk_probe_blocksizes(BlockBackend *blk, BlockSizes *bsz) 2181f0272c4dSEkaterina Tumanova { 2182c09ba36cSMax Reitz if (!blk_is_available(blk)) { 2183c09ba36cSMax Reitz return -ENOMEDIUM; 2184c09ba36cSMax Reitz } 2185c09ba36cSMax Reitz 2186f21d96d0SKevin Wolf return bdrv_probe_blocksizes(blk_bs(blk), bsz); 2187f0272c4dSEkaterina Tumanova } 2188f0272c4dSEkaterina Tumanova 2189f0272c4dSEkaterina Tumanova int blk_probe_geometry(BlockBackend *blk, HDGeometry *geo) 2190f0272c4dSEkaterina Tumanova { 2191c09ba36cSMax Reitz if (!blk_is_available(blk)) { 2192c09ba36cSMax Reitz return -ENOMEDIUM; 2193c09ba36cSMax Reitz } 2194c09ba36cSMax Reitz 2195f21d96d0SKevin Wolf return bdrv_probe_geometry(blk_bs(blk), geo); 2196f0272c4dSEkaterina Tumanova } 2197281d22d8SMax Reitz 2198281d22d8SMax Reitz /* 2199281d22d8SMax Reitz * Updates the BlockBackendRootState object with data from the currently 2200281d22d8SMax Reitz * attached BlockDriverState. 2201281d22d8SMax Reitz */ 2202281d22d8SMax Reitz void blk_update_root_state(BlockBackend *blk) 2203281d22d8SMax Reitz { 2204f21d96d0SKevin Wolf assert(blk->root); 2205281d22d8SMax Reitz 2206f21d96d0SKevin Wolf blk->root_state.open_flags = blk->root->bs->open_flags; 2207f21d96d0SKevin Wolf blk->root_state.read_only = blk->root->bs->read_only; 2208f21d96d0SKevin Wolf blk->root_state.detect_zeroes = blk->root->bs->detect_zeroes; 2209281d22d8SMax Reitz } 2210281d22d8SMax Reitz 221138cb18f5SMax Reitz /* 2212b85114f8SKevin Wolf * Returns the detect-zeroes setting to be used for bdrv_open() of a 2213b85114f8SKevin Wolf * BlockDriverState which is supposed to inherit the root state. 221438cb18f5SMax Reitz */ 2215b85114f8SKevin Wolf bool blk_get_detect_zeroes_from_root_state(BlockBackend *blk) 221638cb18f5SMax Reitz { 2217b85114f8SKevin Wolf return blk->root_state.detect_zeroes; 221838cb18f5SMax Reitz } 221938cb18f5SMax Reitz 222038cb18f5SMax Reitz /* 222138cb18f5SMax Reitz * Returns the flags to be used for bdrv_open() of a BlockDriverState which is 222238cb18f5SMax Reitz * supposed to inherit the root state. 222338cb18f5SMax Reitz */ 222438cb18f5SMax Reitz int blk_get_open_flags_from_root_state(BlockBackend *blk) 222538cb18f5SMax Reitz { 222638cb18f5SMax Reitz int bs_flags; 222738cb18f5SMax Reitz 222838cb18f5SMax Reitz bs_flags = blk->root_state.read_only ? 0 : BDRV_O_RDWR; 222938cb18f5SMax Reitz bs_flags |= blk->root_state.open_flags & ~BDRV_O_RDWR; 223038cb18f5SMax Reitz 223138cb18f5SMax Reitz return bs_flags; 223238cb18f5SMax Reitz } 223338cb18f5SMax Reitz 2234281d22d8SMax Reitz BlockBackendRootState *blk_get_root_state(BlockBackend *blk) 2235281d22d8SMax Reitz { 2236281d22d8SMax Reitz return &blk->root_state; 2237281d22d8SMax Reitz } 22381393f212SMax Reitz 22391393f212SMax Reitz int blk_commit_all(void) 22401393f212SMax Reitz { 2241fe1a9cbcSMax Reitz BlockBackend *blk = NULL; 2242fe1a9cbcSMax Reitz 2243fe1a9cbcSMax Reitz while ((blk = blk_all_next(blk)) != NULL) { 2244fe1a9cbcSMax Reitz AioContext *aio_context = blk_get_aio_context(blk); 2245fe1a9cbcSMax Reitz 2246fe1a9cbcSMax Reitz aio_context_acquire(aio_context); 2247f21d96d0SKevin Wolf if (blk_is_inserted(blk) && blk->root->bs->backing) { 2248f21d96d0SKevin Wolf int ret = bdrv_commit(blk->root->bs); 2249fe1a9cbcSMax Reitz if (ret < 0) { 2250fe1a9cbcSMax Reitz aio_context_release(aio_context); 2251fe1a9cbcSMax Reitz return ret; 2252fe1a9cbcSMax Reitz } 2253fe1a9cbcSMax Reitz } 2254fe1a9cbcSMax Reitz aio_context_release(aio_context); 2255fe1a9cbcSMax Reitz } 2256fe1a9cbcSMax Reitz return 0; 2257fe1a9cbcSMax Reitz } 2258fe1a9cbcSMax Reitz 225997148076SKevin Wolf 226097148076SKevin Wolf /* throttling disk I/O limits */ 226197148076SKevin Wolf void blk_set_io_limits(BlockBackend *blk, ThrottleConfig *cfg) 226297148076SKevin Wolf { 2263022cdc9fSManos Pitsidianakis throttle_group_config(&blk->public.throttle_group_member, cfg); 226497148076SKevin Wolf } 226597148076SKevin Wolf 226697148076SKevin Wolf void blk_io_limits_disable(BlockBackend *blk) 226797148076SKevin Wolf { 226848bf7ea8SAlberto Garcia BlockDriverState *bs = blk_bs(blk); 226948bf7ea8SAlberto Garcia ThrottleGroupMember *tgm = &blk->public.throttle_group_member; 227048bf7ea8SAlberto Garcia assert(tgm->throttle_state); 227148bf7ea8SAlberto Garcia if (bs) { 227248bf7ea8SAlberto Garcia bdrv_drained_begin(bs); 227348bf7ea8SAlberto Garcia } 227448bf7ea8SAlberto Garcia throttle_group_unregister_tgm(tgm); 227548bf7ea8SAlberto Garcia if (bs) { 227648bf7ea8SAlberto Garcia bdrv_drained_end(bs); 227748bf7ea8SAlberto Garcia } 227897148076SKevin Wolf } 227997148076SKevin Wolf 228097148076SKevin Wolf /* should be called before blk_set_io_limits if a limit is set */ 228197148076SKevin Wolf void blk_io_limits_enable(BlockBackend *blk, const char *group) 228297148076SKevin Wolf { 2283022cdc9fSManos Pitsidianakis assert(!blk->public.throttle_group_member.throttle_state); 2284c61791fcSManos Pitsidianakis throttle_group_register_tgm(&blk->public.throttle_group_member, 2285c61791fcSManos Pitsidianakis group, blk_get_aio_context(blk)); 228697148076SKevin Wolf } 228797148076SKevin Wolf 228897148076SKevin Wolf void blk_io_limits_update_group(BlockBackend *blk, const char *group) 228997148076SKevin Wolf { 229097148076SKevin Wolf /* this BB is not part of any group */ 2291022cdc9fSManos Pitsidianakis if (!blk->public.throttle_group_member.throttle_state) { 229297148076SKevin Wolf return; 229397148076SKevin Wolf } 229497148076SKevin Wolf 229597148076SKevin Wolf /* this BB is a part of the same group than the one we want */ 2296022cdc9fSManos Pitsidianakis if (!g_strcmp0(throttle_group_get_name(&blk->public.throttle_group_member), 2297022cdc9fSManos Pitsidianakis group)) { 229897148076SKevin Wolf return; 229997148076SKevin Wolf } 230097148076SKevin Wolf 230197148076SKevin Wolf /* need to change the group this bs belong to */ 230297148076SKevin Wolf blk_io_limits_disable(blk); 230397148076SKevin Wolf blk_io_limits_enable(blk, group); 230497148076SKevin Wolf } 2305c2066af0SKevin Wolf 2306c2066af0SKevin Wolf static void blk_root_drained_begin(BdrvChild *child) 2307c2066af0SKevin Wolf { 2308c2066af0SKevin Wolf BlockBackend *blk = child->opaque; 2309c2066af0SKevin Wolf 2310f4d9cc88SJohn Snow if (++blk->quiesce_counter == 1) { 2311f4d9cc88SJohn Snow if (blk->dev_ops && blk->dev_ops->drained_begin) { 2312f4d9cc88SJohn Snow blk->dev_ops->drained_begin(blk->dev_opaque); 2313f4d9cc88SJohn Snow } 2314f4d9cc88SJohn Snow } 2315f4d9cc88SJohn Snow 231636fe1331SKevin Wolf /* Note that blk->root may not be accessible here yet if we are just 231736fe1331SKevin Wolf * attaching to a BlockDriverState that is drained. Use child instead. */ 231836fe1331SKevin Wolf 2319022cdc9fSManos Pitsidianakis if (atomic_fetch_inc(&blk->public.throttle_group_member.io_limits_disabled) == 0) { 2320022cdc9fSManos Pitsidianakis throttle_group_restart_tgm(&blk->public.throttle_group_member); 2321c2066af0SKevin Wolf } 2322c2066af0SKevin Wolf } 2323c2066af0SKevin Wolf 2324fe5258a5SKevin Wolf static bool blk_root_drained_poll(BdrvChild *child) 2325fe5258a5SKevin Wolf { 2326fe5258a5SKevin Wolf BlockBackend *blk = child->opaque; 2327fe5258a5SKevin Wolf assert(blk->quiesce_counter); 2328fe5258a5SKevin Wolf return !!blk->in_flight; 2329fe5258a5SKevin Wolf } 2330fe5258a5SKevin Wolf 2331e037c09cSMax Reitz static void blk_root_drained_end(BdrvChild *child, int *drained_end_counter) 2332c2066af0SKevin Wolf { 2333c2066af0SKevin Wolf BlockBackend *blk = child->opaque; 2334f4d9cc88SJohn Snow assert(blk->quiesce_counter); 2335c2066af0SKevin Wolf 2336022cdc9fSManos Pitsidianakis assert(blk->public.throttle_group_member.io_limits_disabled); 2337022cdc9fSManos Pitsidianakis atomic_dec(&blk->public.throttle_group_member.io_limits_disabled); 2338f4d9cc88SJohn Snow 2339f4d9cc88SJohn Snow if (--blk->quiesce_counter == 0) { 2340f4d9cc88SJohn Snow if (blk->dev_ops && blk->dev_ops->drained_end) { 2341f4d9cc88SJohn Snow blk->dev_ops->drained_end(blk->dev_opaque); 2342f4d9cc88SJohn Snow } 2343cf312932SKevin Wolf while (qemu_co_enter_next(&blk->queued_requests, NULL)) { 2344cf312932SKevin Wolf /* Resume all queued requests */ 2345cf312932SKevin Wolf } 2346f4d9cc88SJohn Snow } 2347c2066af0SKevin Wolf } 234823d0ba93SFam Zheng 234923d0ba93SFam Zheng void blk_register_buf(BlockBackend *blk, void *host, size_t size) 235023d0ba93SFam Zheng { 235123d0ba93SFam Zheng bdrv_register_buf(blk_bs(blk), host, size); 235223d0ba93SFam Zheng } 235323d0ba93SFam Zheng 235423d0ba93SFam Zheng void blk_unregister_buf(BlockBackend *blk, void *host) 235523d0ba93SFam Zheng { 235623d0ba93SFam Zheng bdrv_unregister_buf(blk_bs(blk), host); 235723d0ba93SFam Zheng } 2358b5679fa4SFam Zheng 2359b5679fa4SFam Zheng int coroutine_fn blk_co_copy_range(BlockBackend *blk_in, int64_t off_in, 2360b5679fa4SFam Zheng BlockBackend *blk_out, int64_t off_out, 236167b51fb9SVladimir Sementsov-Ogievskiy int bytes, BdrvRequestFlags read_flags, 236267b51fb9SVladimir Sementsov-Ogievskiy BdrvRequestFlags write_flags) 2363b5679fa4SFam Zheng { 2364b5679fa4SFam Zheng int r; 2365b5679fa4SFam Zheng r = blk_check_byte_request(blk_in, off_in, bytes); 2366b5679fa4SFam Zheng if (r) { 2367b5679fa4SFam Zheng return r; 2368b5679fa4SFam Zheng } 2369b5679fa4SFam Zheng r = blk_check_byte_request(blk_out, off_out, bytes); 2370b5679fa4SFam Zheng if (r) { 2371b5679fa4SFam Zheng return r; 2372b5679fa4SFam Zheng } 2373b5679fa4SFam Zheng return bdrv_co_copy_range(blk_in->root, off_in, 2374b5679fa4SFam Zheng blk_out->root, off_out, 237567b51fb9SVladimir Sementsov-Ogievskiy bytes, read_flags, write_flags); 2376b5679fa4SFam Zheng } 23775d3b4e99SVladimir Sementsov-Ogievskiy 23785d3b4e99SVladimir Sementsov-Ogievskiy const BdrvChild *blk_root(BlockBackend *blk) 23795d3b4e99SVladimir Sementsov-Ogievskiy { 23805d3b4e99SVladimir Sementsov-Ogievskiy return blk->root; 23815d3b4e99SVladimir Sementsov-Ogievskiy } 2382