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" 1818e46a03SMarkus Armbruster #include "sysemu/blockdev.h" 19373340b2SMax Reitz #include "sysemu/sysemu.h" 20a7f53e26SMarkus Armbruster #include "qapi-event.h" 21f348b6d1SVeronia Bahaa #include "qemu/id.h" 22a7f53e26SMarkus Armbruster 23a7f53e26SMarkus Armbruster /* Number of coroutines to reserve per attached device model */ 24a7f53e26SMarkus Armbruster #define COROUTINE_POOL_RESERVATION 64 2526f54e9aSMarkus Armbruster 261bf1cbc9SKevin Wolf #define NOT_DONE 0x7fffffff /* used while emulated sync operation in progress */ 271bf1cbc9SKevin Wolf 284981bdecSMax Reitz static AioContext *blk_aiocb_get_aio_context(BlockAIOCB *acb); 294981bdecSMax Reitz 3026f54e9aSMarkus Armbruster struct BlockBackend { 3126f54e9aSMarkus Armbruster char *name; 3226f54e9aSMarkus Armbruster int refcnt; 33f21d96d0SKevin Wolf BdrvChild *root; 3426f8b3a8SMarkus Armbruster DriveInfo *legacy_dinfo; /* null unless created by drive_new() */ 352cf22d6aSMax Reitz QTAILQ_ENTRY(BlockBackend) link; /* for block_backends */ 369492b0b9SMax Reitz QTAILQ_ENTRY(BlockBackend) monitor_link; /* for monitor_block_backends */ 37f2cd875dSKevin Wolf BlockBackendPublic public; 38a7f53e26SMarkus Armbruster 39a7f53e26SMarkus Armbruster void *dev; /* attached device model, if any */ 40a7f53e26SMarkus Armbruster /* TODO change to DeviceState when all users are qdevified */ 41a7f53e26SMarkus Armbruster const BlockDevOps *dev_ops; 42a7f53e26SMarkus Armbruster void *dev_opaque; 4368e9ec01SMax Reitz 4468e9ec01SMax Reitz /* the block size for which the guest device expects atomicity */ 4568e9ec01SMax Reitz int guest_block_size; 467f0e9da6SMax Reitz 47281d22d8SMax Reitz /* If the BDS tree is removed, some of its options are stored here (which 48281d22d8SMax Reitz * can be used to restore those options in the new BDS on insert) */ 49281d22d8SMax Reitz BlockBackendRootState root_state; 50281d22d8SMax Reitz 51bfd18d1eSKevin Wolf bool enable_write_cache; 52bfd18d1eSKevin Wolf 537f0e9da6SMax Reitz /* I/O stats (display with "info blockstats"). */ 547f0e9da6SMax Reitz BlockAcctStats stats; 55373340b2SMax Reitz 56373340b2SMax Reitz BlockdevOnError on_read_error, on_write_error; 57373340b2SMax Reitz bool iostatus_enabled; 58373340b2SMax Reitz BlockDeviceIoStatus iostatus; 593301f6c6SMax Reitz 60c10c9d96SKevin Wolf bool allow_write_beyond_eof; 61c10c9d96SKevin Wolf 623301f6c6SMax Reitz NotifierList remove_bs_notifiers, insert_bs_notifiers; 6326f54e9aSMarkus Armbruster }; 6426f54e9aSMarkus Armbruster 65e7f7d676SMax Reitz typedef struct BlockBackendAIOCB { 66e7f7d676SMax Reitz BlockAIOCB common; 67e7f7d676SMax Reitz QEMUBH *bh; 684981bdecSMax Reitz BlockBackend *blk; 69e7f7d676SMax Reitz int ret; 70e7f7d676SMax Reitz } BlockBackendAIOCB; 71e7f7d676SMax Reitz 72e7f7d676SMax Reitz static const AIOCBInfo block_backend_aiocb_info = { 734981bdecSMax Reitz .get_aio_context = blk_aiocb_get_aio_context, 74e7f7d676SMax Reitz .aiocb_size = sizeof(BlockBackendAIOCB), 75e7f7d676SMax Reitz }; 76e7f7d676SMax Reitz 778fb3c76cSMarkus Armbruster static void drive_info_del(DriveInfo *dinfo); 788fb3c76cSMarkus Armbruster 792cf22d6aSMax Reitz /* All BlockBackends */ 802cf22d6aSMax Reitz static QTAILQ_HEAD(, BlockBackend) block_backends = 812cf22d6aSMax Reitz QTAILQ_HEAD_INITIALIZER(block_backends); 822cf22d6aSMax Reitz 839492b0b9SMax Reitz /* All BlockBackends referenced by the monitor and which are iterated through by 849492b0b9SMax Reitz * blk_next() */ 859492b0b9SMax Reitz static QTAILQ_HEAD(, BlockBackend) monitor_block_backends = 869492b0b9SMax Reitz QTAILQ_HEAD_INITIALIZER(monitor_block_backends); 8726f54e9aSMarkus Armbruster 88f21d96d0SKevin Wolf static void blk_root_inherit_options(int *child_flags, QDict *child_options, 89f21d96d0SKevin Wolf int parent_flags, QDict *parent_options) 90f21d96d0SKevin Wolf { 91f21d96d0SKevin Wolf /* We're not supposed to call this function for root nodes */ 92f21d96d0SKevin Wolf abort(); 93f21d96d0SKevin Wolf } 94f21d96d0SKevin Wolf 95f21d96d0SKevin Wolf static const BdrvChildRole child_root = { 96f21d96d0SKevin Wolf .inherit_options = blk_root_inherit_options, 97f21d96d0SKevin Wolf }; 98f21d96d0SKevin Wolf 9926f54e9aSMarkus Armbruster /* 100efaa7c4eSMax Reitz * Create a new BlockBackend with a reference count of one. 10126f54e9aSMarkus Armbruster * Store an error through @errp on failure, unless it's null. 10226f54e9aSMarkus Armbruster * Return the new BlockBackend on success, null on failure. 10326f54e9aSMarkus Armbruster */ 104efaa7c4eSMax Reitz BlockBackend *blk_new(Error **errp) 10526f54e9aSMarkus Armbruster { 10626f54e9aSMarkus Armbruster BlockBackend *blk; 10726f54e9aSMarkus Armbruster 10826f54e9aSMarkus Armbruster blk = g_new0(BlockBackend, 1); 10926f54e9aSMarkus Armbruster blk->refcnt = 1; 110*27ccdd52SKevin Wolf qemu_co_queue_init(&blk->public.throttled_reqs[0]); 111*27ccdd52SKevin Wolf qemu_co_queue_init(&blk->public.throttled_reqs[1]); 112*27ccdd52SKevin Wolf 1133301f6c6SMax Reitz notifier_list_init(&blk->remove_bs_notifiers); 1143301f6c6SMax Reitz notifier_list_init(&blk->insert_bs_notifiers); 115*27ccdd52SKevin Wolf 1162cf22d6aSMax Reitz QTAILQ_INSERT_TAIL(&block_backends, blk, link); 11726f54e9aSMarkus Armbruster return blk; 11826f54e9aSMarkus Armbruster } 11926f54e9aSMarkus Armbruster 1207e7d56d9SMarkus Armbruster /* 1217e7d56d9SMarkus Armbruster * Create a new BlockBackend with a new BlockDriverState attached. 1227e7d56d9SMarkus Armbruster * Otherwise just like blk_new(), which see. 1237e7d56d9SMarkus Armbruster */ 124efaa7c4eSMax Reitz BlockBackend *blk_new_with_bs(Error **errp) 1257e7d56d9SMarkus Armbruster { 1267e7d56d9SMarkus Armbruster BlockBackend *blk; 1277e7d56d9SMarkus Armbruster BlockDriverState *bs; 1287e7d56d9SMarkus Armbruster 129efaa7c4eSMax Reitz blk = blk_new(errp); 1307e7d56d9SMarkus Armbruster if (!blk) { 1317e7d56d9SMarkus Armbruster return NULL; 1327e7d56d9SMarkus Armbruster } 1337e7d56d9SMarkus Armbruster 1347f06d47eSMarkus Armbruster bs = bdrv_new_root(); 135f21d96d0SKevin Wolf blk->root = bdrv_root_attach_child(bs, "root", &child_root); 1367e7d56d9SMarkus Armbruster bs->blk = blk; 1377e7d56d9SMarkus Armbruster return blk; 1387e7d56d9SMarkus Armbruster } 1397e7d56d9SMarkus Armbruster 140ca49a4fdSMax Reitz /* 141ca49a4fdSMax Reitz * Calls blk_new_with_bs() and then calls bdrv_open() on the BlockDriverState. 142ca49a4fdSMax Reitz * 143ca49a4fdSMax Reitz * Just as with bdrv_open(), after having called this function the reference to 144ca49a4fdSMax Reitz * @options belongs to the block layer (even on failure). 145ca49a4fdSMax Reitz * 146ca49a4fdSMax Reitz * TODO: Remove @filename and @flags; it should be possible to specify a whole 147ca49a4fdSMax Reitz * BDS tree just by specifying the @options QDict (or @reference, 148ca49a4fdSMax Reitz * alternatively). At the time of adding this function, this is not possible, 149ca49a4fdSMax Reitz * though, so callers of this function have to be able to specify @filename and 150ca49a4fdSMax Reitz * @flags. 151ca49a4fdSMax Reitz */ 152efaa7c4eSMax Reitz BlockBackend *blk_new_open(const char *filename, const char *reference, 153efaa7c4eSMax Reitz QDict *options, int flags, Error **errp) 154ca49a4fdSMax Reitz { 155ca49a4fdSMax Reitz BlockBackend *blk; 156ca49a4fdSMax Reitz int ret; 157ca49a4fdSMax Reitz 158efaa7c4eSMax Reitz blk = blk_new_with_bs(errp); 159ca49a4fdSMax Reitz if (!blk) { 160ca49a4fdSMax Reitz QDECREF(options); 161ca49a4fdSMax Reitz return NULL; 162ca49a4fdSMax Reitz } 163ca49a4fdSMax Reitz 164f21d96d0SKevin Wolf ret = bdrv_open(&blk->root->bs, filename, reference, options, flags, errp); 165ca49a4fdSMax Reitz if (ret < 0) { 166ca49a4fdSMax Reitz blk_unref(blk); 167ca49a4fdSMax Reitz return NULL; 168ca49a4fdSMax Reitz } 169ca49a4fdSMax Reitz 17072e775c7SKevin Wolf blk_set_enable_write_cache(blk, true); 17172e775c7SKevin Wolf 172ca49a4fdSMax Reitz return blk; 173ca49a4fdSMax Reitz } 174ca49a4fdSMax Reitz 17526f54e9aSMarkus Armbruster static void blk_delete(BlockBackend *blk) 17626f54e9aSMarkus Armbruster { 17726f54e9aSMarkus Armbruster assert(!blk->refcnt); 178e5e78550SMax Reitz assert(!blk->name); 179a7f53e26SMarkus Armbruster assert(!blk->dev); 180f21d96d0SKevin Wolf if (blk->root) { 18113855c6bSMax Reitz blk_remove_bs(blk); 1827e7d56d9SMarkus Armbruster } 1833301f6c6SMax Reitz assert(QLIST_EMPTY(&blk->remove_bs_notifiers.notifiers)); 1843301f6c6SMax Reitz assert(QLIST_EMPTY(&blk->insert_bs_notifiers.notifiers)); 185281d22d8SMax Reitz if (blk->root_state.throttle_state) { 186281d22d8SMax Reitz g_free(blk->root_state.throttle_group); 187281d22d8SMax Reitz throttle_group_unref(blk->root_state.throttle_state); 188281d22d8SMax Reitz } 1892cf22d6aSMax Reitz QTAILQ_REMOVE(&block_backends, blk, link); 19018e46a03SMarkus Armbruster drive_info_del(blk->legacy_dinfo); 191979e9b03SAlberto Garcia block_acct_cleanup(&blk->stats); 19226f54e9aSMarkus Armbruster g_free(blk); 19326f54e9aSMarkus Armbruster } 19426f54e9aSMarkus Armbruster 1958fb3c76cSMarkus Armbruster static void drive_info_del(DriveInfo *dinfo) 1968fb3c76cSMarkus Armbruster { 1978fb3c76cSMarkus Armbruster if (!dinfo) { 1988fb3c76cSMarkus Armbruster return; 1998fb3c76cSMarkus Armbruster } 2008fb3c76cSMarkus Armbruster qemu_opts_del(dinfo->opts); 2018fb3c76cSMarkus Armbruster g_free(dinfo->serial); 2028fb3c76cSMarkus Armbruster g_free(dinfo); 2038fb3c76cSMarkus Armbruster } 2048fb3c76cSMarkus Armbruster 205f636ae85SAlberto Garcia int blk_get_refcnt(BlockBackend *blk) 206f636ae85SAlberto Garcia { 207f636ae85SAlberto Garcia return blk ? blk->refcnt : 0; 208f636ae85SAlberto Garcia } 209f636ae85SAlberto Garcia 21026f54e9aSMarkus Armbruster /* 21126f54e9aSMarkus Armbruster * Increment @blk's reference count. 21226f54e9aSMarkus Armbruster * @blk must not be null. 21326f54e9aSMarkus Armbruster */ 21426f54e9aSMarkus Armbruster void blk_ref(BlockBackend *blk) 21526f54e9aSMarkus Armbruster { 21626f54e9aSMarkus Armbruster blk->refcnt++; 21726f54e9aSMarkus Armbruster } 21826f54e9aSMarkus Armbruster 21926f54e9aSMarkus Armbruster /* 22026f54e9aSMarkus Armbruster * Decrement @blk's reference count. 22126f54e9aSMarkus Armbruster * If this drops it to zero, destroy @blk. 22226f54e9aSMarkus Armbruster * For convenience, do nothing if @blk is null. 22326f54e9aSMarkus Armbruster */ 22426f54e9aSMarkus Armbruster void blk_unref(BlockBackend *blk) 22526f54e9aSMarkus Armbruster { 22626f54e9aSMarkus Armbruster if (blk) { 22726f54e9aSMarkus Armbruster assert(blk->refcnt > 0); 22826f54e9aSMarkus Armbruster if (!--blk->refcnt) { 22926f54e9aSMarkus Armbruster blk_delete(blk); 23026f54e9aSMarkus Armbruster } 23126f54e9aSMarkus Armbruster } 23226f54e9aSMarkus Armbruster } 23326f54e9aSMarkus Armbruster 2342cf22d6aSMax Reitz /* 2352cf22d6aSMax Reitz * Behaves similarly to blk_next() but iterates over all BlockBackends, even the 2362cf22d6aSMax Reitz * ones which are hidden (i.e. are not referenced by the monitor). 2372cf22d6aSMax Reitz */ 2382cf22d6aSMax Reitz static BlockBackend *blk_all_next(BlockBackend *blk) 2392cf22d6aSMax Reitz { 2402cf22d6aSMax Reitz return blk ? QTAILQ_NEXT(blk, link) 2412cf22d6aSMax Reitz : QTAILQ_FIRST(&block_backends); 2422cf22d6aSMax Reitz } 2432cf22d6aSMax Reitz 244d8da3cefSMax Reitz void blk_remove_all_bs(void) 245d8da3cefSMax Reitz { 24674d1b8fcSMax Reitz BlockBackend *blk = NULL; 247d8da3cefSMax Reitz 2482cf22d6aSMax Reitz while ((blk = blk_all_next(blk)) != NULL) { 249d8da3cefSMax Reitz AioContext *ctx = blk_get_aio_context(blk); 250d8da3cefSMax Reitz 251d8da3cefSMax Reitz aio_context_acquire(ctx); 252f21d96d0SKevin Wolf if (blk->root) { 253d8da3cefSMax Reitz blk_remove_bs(blk); 254d8da3cefSMax Reitz } 255d8da3cefSMax Reitz aio_context_release(ctx); 256d8da3cefSMax Reitz } 257d8da3cefSMax Reitz } 258d8da3cefSMax Reitz 25926f54e9aSMarkus Armbruster /* 2609492b0b9SMax Reitz * Return the monitor-owned BlockBackend after @blk. 26126f54e9aSMarkus Armbruster * If @blk is null, return the first one. 26226f54e9aSMarkus Armbruster * Else, return @blk's next sibling, which may be null. 26326f54e9aSMarkus Armbruster * 26426f54e9aSMarkus Armbruster * To iterate over all BlockBackends, do 26526f54e9aSMarkus Armbruster * for (blk = blk_next(NULL); blk; blk = blk_next(blk)) { 26626f54e9aSMarkus Armbruster * ... 26726f54e9aSMarkus Armbruster * } 26826f54e9aSMarkus Armbruster */ 26926f54e9aSMarkus Armbruster BlockBackend *blk_next(BlockBackend *blk) 27026f54e9aSMarkus Armbruster { 2719492b0b9SMax Reitz return blk ? QTAILQ_NEXT(blk, monitor_link) 2729492b0b9SMax Reitz : QTAILQ_FIRST(&monitor_block_backends); 27326f54e9aSMarkus Armbruster } 27426f54e9aSMarkus Armbruster 27526f54e9aSMarkus Armbruster /* 276981f4f57SMax Reitz * Iterates over all BlockDriverStates which are attached to a BlockBackend. 277981f4f57SMax Reitz * This function is for use by bdrv_next(). 278981f4f57SMax Reitz * 279981f4f57SMax Reitz * @bs must be NULL or a BDS that is attached to a BB. 280981f4f57SMax Reitz */ 281981f4f57SMax Reitz BlockDriverState *blk_next_root_bs(BlockDriverState *bs) 282981f4f57SMax Reitz { 283981f4f57SMax Reitz BlockBackend *blk; 284981f4f57SMax Reitz 285981f4f57SMax Reitz if (bs) { 286981f4f57SMax Reitz assert(bs->blk); 287981f4f57SMax Reitz blk = bs->blk; 288981f4f57SMax Reitz } else { 289981f4f57SMax Reitz blk = NULL; 290981f4f57SMax Reitz } 291981f4f57SMax Reitz 292981f4f57SMax Reitz do { 293981f4f57SMax Reitz blk = blk_all_next(blk); 294f21d96d0SKevin Wolf } while (blk && !blk->root); 295981f4f57SMax Reitz 296f21d96d0SKevin Wolf return blk ? blk->root->bs : NULL; 297981f4f57SMax Reitz } 298981f4f57SMax Reitz 299981f4f57SMax Reitz /* 300e5e78550SMax Reitz * Add a BlockBackend into the list of backends referenced by the monitor, with 301e5e78550SMax Reitz * the given @name acting as the handle for the monitor. 302e5e78550SMax Reitz * Strictly for use by blockdev.c. 303e5e78550SMax Reitz * 304e5e78550SMax Reitz * @name must not be null or empty. 305e5e78550SMax Reitz * 306e5e78550SMax Reitz * Returns true on success and false on failure. In the latter case, an Error 307e5e78550SMax Reitz * object is returned through @errp. 308e5e78550SMax Reitz */ 309e5e78550SMax Reitz bool monitor_add_blk(BlockBackend *blk, const char *name, Error **errp) 310e5e78550SMax Reitz { 311e5e78550SMax Reitz assert(!blk->name); 312e5e78550SMax Reitz assert(name && name[0]); 313e5e78550SMax Reitz 314e5e78550SMax Reitz if (!id_wellformed(name)) { 315e5e78550SMax Reitz error_setg(errp, "Invalid device name"); 316e5e78550SMax Reitz return false; 317e5e78550SMax Reitz } 318e5e78550SMax Reitz if (blk_by_name(name)) { 319e5e78550SMax Reitz error_setg(errp, "Device with id '%s' already exists", name); 320e5e78550SMax Reitz return false; 321e5e78550SMax Reitz } 322e5e78550SMax Reitz if (bdrv_find_node(name)) { 323e5e78550SMax Reitz error_setg(errp, 324e5e78550SMax Reitz "Device name '%s' conflicts with an existing node name", 325e5e78550SMax Reitz name); 326e5e78550SMax Reitz return false; 327e5e78550SMax Reitz } 328e5e78550SMax Reitz 329e5e78550SMax Reitz blk->name = g_strdup(name); 330e5e78550SMax Reitz QTAILQ_INSERT_TAIL(&monitor_block_backends, blk, monitor_link); 331e5e78550SMax Reitz return true; 332e5e78550SMax Reitz } 333e5e78550SMax Reitz 334e5e78550SMax Reitz /* 335e5e78550SMax Reitz * Remove a BlockBackend from the list of backends referenced by the monitor. 336e5e78550SMax Reitz * Strictly for use by blockdev.c. 337e5e78550SMax Reitz */ 338e5e78550SMax Reitz void monitor_remove_blk(BlockBackend *blk) 339e5e78550SMax Reitz { 340e5e78550SMax Reitz if (!blk->name) { 341e5e78550SMax Reitz return; 342e5e78550SMax Reitz } 343e5e78550SMax Reitz 344e5e78550SMax Reitz QTAILQ_REMOVE(&monitor_block_backends, blk, monitor_link); 345e5e78550SMax Reitz g_free(blk->name); 346e5e78550SMax Reitz blk->name = NULL; 347e5e78550SMax Reitz } 348e5e78550SMax Reitz 349e5e78550SMax Reitz /* 3507e7d56d9SMarkus Armbruster * Return @blk's name, a non-null string. 351e5e78550SMax Reitz * Returns an empty string iff @blk is not referenced by the monitor. 35226f54e9aSMarkus Armbruster */ 35326f54e9aSMarkus Armbruster const char *blk_name(BlockBackend *blk) 35426f54e9aSMarkus Armbruster { 355e5e78550SMax Reitz return blk->name ?: ""; 35626f54e9aSMarkus Armbruster } 35726f54e9aSMarkus Armbruster 35826f54e9aSMarkus Armbruster /* 35926f54e9aSMarkus Armbruster * Return the BlockBackend with name @name if it exists, else null. 36026f54e9aSMarkus Armbruster * @name must not be null. 36126f54e9aSMarkus Armbruster */ 36226f54e9aSMarkus Armbruster BlockBackend *blk_by_name(const char *name) 36326f54e9aSMarkus Armbruster { 36474d1b8fcSMax Reitz BlockBackend *blk = NULL; 36526f54e9aSMarkus Armbruster 36626f54e9aSMarkus Armbruster assert(name); 36774d1b8fcSMax Reitz while ((blk = blk_next(blk)) != NULL) { 36826f54e9aSMarkus Armbruster if (!strcmp(name, blk->name)) { 36926f54e9aSMarkus Armbruster return blk; 37026f54e9aSMarkus Armbruster } 37126f54e9aSMarkus Armbruster } 37226f54e9aSMarkus Armbruster return NULL; 37326f54e9aSMarkus Armbruster } 3747e7d56d9SMarkus Armbruster 3757e7d56d9SMarkus Armbruster /* 3767e7d56d9SMarkus Armbruster * Return the BlockDriverState attached to @blk if any, else null. 3777e7d56d9SMarkus Armbruster */ 3787e7d56d9SMarkus Armbruster BlockDriverState *blk_bs(BlockBackend *blk) 3797e7d56d9SMarkus Armbruster { 380f21d96d0SKevin Wolf return blk->root ? blk->root->bs : NULL; 3817e7d56d9SMarkus Armbruster } 3827e7d56d9SMarkus Armbruster 3837e7d56d9SMarkus Armbruster /* 38418e46a03SMarkus Armbruster * Return @blk's DriveInfo if any, else null. 38518e46a03SMarkus Armbruster */ 38618e46a03SMarkus Armbruster DriveInfo *blk_legacy_dinfo(BlockBackend *blk) 38718e46a03SMarkus Armbruster { 38818e46a03SMarkus Armbruster return blk->legacy_dinfo; 38918e46a03SMarkus Armbruster } 39018e46a03SMarkus Armbruster 39118e46a03SMarkus Armbruster /* 39218e46a03SMarkus Armbruster * Set @blk's DriveInfo to @dinfo, and return it. 39318e46a03SMarkus Armbruster * @blk must not have a DriveInfo set already. 39418e46a03SMarkus Armbruster * No other BlockBackend may have the same DriveInfo set. 39518e46a03SMarkus Armbruster */ 39618e46a03SMarkus Armbruster DriveInfo *blk_set_legacy_dinfo(BlockBackend *blk, DriveInfo *dinfo) 39718e46a03SMarkus Armbruster { 39818e46a03SMarkus Armbruster assert(!blk->legacy_dinfo); 39918e46a03SMarkus Armbruster return blk->legacy_dinfo = dinfo; 40018e46a03SMarkus Armbruster } 40118e46a03SMarkus Armbruster 40218e46a03SMarkus Armbruster /* 40318e46a03SMarkus Armbruster * Return the BlockBackend with DriveInfo @dinfo. 40418e46a03SMarkus Armbruster * It must exist. 40518e46a03SMarkus Armbruster */ 40618e46a03SMarkus Armbruster BlockBackend *blk_by_legacy_dinfo(DriveInfo *dinfo) 40718e46a03SMarkus Armbruster { 40874d1b8fcSMax Reitz BlockBackend *blk = NULL; 40918e46a03SMarkus Armbruster 41074d1b8fcSMax Reitz while ((blk = blk_next(blk)) != NULL) { 41118e46a03SMarkus Armbruster if (blk->legacy_dinfo == dinfo) { 41218e46a03SMarkus Armbruster return blk; 41318e46a03SMarkus Armbruster } 41418e46a03SMarkus Armbruster } 41518e46a03SMarkus Armbruster abort(); 41618e46a03SMarkus Armbruster } 41718e46a03SMarkus Armbruster 41818e46a03SMarkus Armbruster /* 419f2cd875dSKevin Wolf * Returns a pointer to the publicly accessible fields of @blk. 420f2cd875dSKevin Wolf */ 421f2cd875dSKevin Wolf BlockBackendPublic *blk_get_public(BlockBackend *blk) 422f2cd875dSKevin Wolf { 423f2cd875dSKevin Wolf return &blk->public; 424f2cd875dSKevin Wolf } 425f2cd875dSKevin Wolf 426f2cd875dSKevin Wolf /* 427f2cd875dSKevin Wolf * Returns a BlockBackend given the associated @public fields. 428f2cd875dSKevin Wolf */ 429f2cd875dSKevin Wolf BlockBackend *blk_by_public(BlockBackendPublic *public) 430f2cd875dSKevin Wolf { 431f2cd875dSKevin Wolf return container_of(public, BlockBackend, public); 432f2cd875dSKevin Wolf } 433f2cd875dSKevin Wolf 434f2cd875dSKevin Wolf /* 4351c95f7e1SMax Reitz * Disassociates the currently associated BlockDriverState from @blk. 4361c95f7e1SMax Reitz */ 4371c95f7e1SMax Reitz void blk_remove_bs(BlockBackend *blk) 4381c95f7e1SMax Reitz { 439f21d96d0SKevin Wolf assert(blk->root->bs->blk == blk); 44013855c6bSMax Reitz 4413301f6c6SMax Reitz notifier_list_notify(&blk->remove_bs_notifiers, blk); 4423301f6c6SMax Reitz 4431c95f7e1SMax Reitz blk_update_root_state(blk); 444*27ccdd52SKevin Wolf if (blk->public.throttle_state) { 445a5614993SKevin Wolf bdrv_io_limits_disable(blk->root->bs); 446a5614993SKevin Wolf } 4471c95f7e1SMax Reitz 448f21d96d0SKevin Wolf blk->root->bs->blk = NULL; 449f21d96d0SKevin Wolf bdrv_root_unref_child(blk->root); 450f21d96d0SKevin Wolf blk->root = NULL; 4511c95f7e1SMax Reitz } 4521c95f7e1SMax Reitz 4531c95f7e1SMax Reitz /* 4540c3c36d6SMax Reitz * Associates a new BlockDriverState with @blk. 4550c3c36d6SMax Reitz */ 4560c3c36d6SMax Reitz void blk_insert_bs(BlockBackend *blk, BlockDriverState *bs) 4570c3c36d6SMax Reitz { 458f21d96d0SKevin Wolf assert(!blk->root && !bs->blk); 4590c3c36d6SMax Reitz bdrv_ref(bs); 460f21d96d0SKevin Wolf blk->root = bdrv_root_attach_child(bs, "root", &child_root); 4610c3c36d6SMax Reitz bs->blk = blk; 4623301f6c6SMax Reitz 4633301f6c6SMax Reitz notifier_list_notify(&blk->insert_bs_notifiers, blk); 4640c3c36d6SMax Reitz } 4650c3c36d6SMax Reitz 4660c3c36d6SMax Reitz /* 467a7f53e26SMarkus Armbruster * Attach device model @dev to @blk. 468a7f53e26SMarkus Armbruster * Return 0 on success, -EBUSY when a device model is attached already. 469a7f53e26SMarkus Armbruster */ 470a7f53e26SMarkus Armbruster int blk_attach_dev(BlockBackend *blk, void *dev) 471a7f53e26SMarkus Armbruster /* TODO change to DeviceState *dev when all users are qdevified */ 472a7f53e26SMarkus Armbruster { 473a7f53e26SMarkus Armbruster if (blk->dev) { 474a7f53e26SMarkus Armbruster return -EBUSY; 475a7f53e26SMarkus Armbruster } 47684ebe375SMarkus Armbruster blk_ref(blk); 477a7f53e26SMarkus Armbruster blk->dev = dev; 478373340b2SMax Reitz blk_iostatus_reset(blk); 479a7f53e26SMarkus Armbruster return 0; 480a7f53e26SMarkus Armbruster } 481a7f53e26SMarkus Armbruster 482a7f53e26SMarkus Armbruster /* 483a7f53e26SMarkus Armbruster * Attach device model @dev to @blk. 484a7f53e26SMarkus Armbruster * @blk must not have a device model attached already. 485a7f53e26SMarkus Armbruster * TODO qdevified devices don't use this, remove when devices are qdevified 486a7f53e26SMarkus Armbruster */ 487a7f53e26SMarkus Armbruster void blk_attach_dev_nofail(BlockBackend *blk, void *dev) 488a7f53e26SMarkus Armbruster { 489a7f53e26SMarkus Armbruster if (blk_attach_dev(blk, dev) < 0) { 490a7f53e26SMarkus Armbruster abort(); 491a7f53e26SMarkus Armbruster } 492a7f53e26SMarkus Armbruster } 493a7f53e26SMarkus Armbruster 494a7f53e26SMarkus Armbruster /* 495a7f53e26SMarkus Armbruster * Detach device model @dev from @blk. 496a7f53e26SMarkus Armbruster * @dev must be currently attached to @blk. 497a7f53e26SMarkus Armbruster */ 498a7f53e26SMarkus Armbruster void blk_detach_dev(BlockBackend *blk, void *dev) 499a7f53e26SMarkus Armbruster /* TODO change to DeviceState *dev when all users are qdevified */ 500a7f53e26SMarkus Armbruster { 501a7f53e26SMarkus Armbruster assert(blk->dev == dev); 502a7f53e26SMarkus Armbruster blk->dev = NULL; 503a7f53e26SMarkus Armbruster blk->dev_ops = NULL; 504a7f53e26SMarkus Armbruster blk->dev_opaque = NULL; 50568e9ec01SMax Reitz blk->guest_block_size = 512; 50684ebe375SMarkus Armbruster blk_unref(blk); 507a7f53e26SMarkus Armbruster } 508a7f53e26SMarkus Armbruster 509a7f53e26SMarkus Armbruster /* 510a7f53e26SMarkus Armbruster * Return the device model attached to @blk if any, else null. 511a7f53e26SMarkus Armbruster */ 512a7f53e26SMarkus Armbruster void *blk_get_attached_dev(BlockBackend *blk) 513a7f53e26SMarkus Armbruster /* TODO change to return DeviceState * when all users are qdevified */ 514a7f53e26SMarkus Armbruster { 515a7f53e26SMarkus Armbruster return blk->dev; 516a7f53e26SMarkus Armbruster } 517a7f53e26SMarkus Armbruster 518a7f53e26SMarkus Armbruster /* 519a7f53e26SMarkus Armbruster * Set @blk's device model callbacks to @ops. 520a7f53e26SMarkus Armbruster * @opaque is the opaque argument to pass to the callbacks. 521a7f53e26SMarkus Armbruster * This is for use by device models. 522a7f53e26SMarkus Armbruster */ 523a7f53e26SMarkus Armbruster void blk_set_dev_ops(BlockBackend *blk, const BlockDevOps *ops, 524a7f53e26SMarkus Armbruster void *opaque) 525a7f53e26SMarkus Armbruster { 526a7f53e26SMarkus Armbruster blk->dev_ops = ops; 527a7f53e26SMarkus Armbruster blk->dev_opaque = opaque; 528a7f53e26SMarkus Armbruster } 529a7f53e26SMarkus Armbruster 530a7f53e26SMarkus Armbruster /* 531a7f53e26SMarkus Armbruster * Notify @blk's attached device model of media change. 532a7f53e26SMarkus Armbruster * If @load is true, notify of media load. 533a7f53e26SMarkus Armbruster * Else, notify of media eject. 534a7f53e26SMarkus Armbruster * Also send DEVICE_TRAY_MOVED events as appropriate. 535a7f53e26SMarkus Armbruster */ 536a7f53e26SMarkus Armbruster void blk_dev_change_media_cb(BlockBackend *blk, bool load) 537a7f53e26SMarkus Armbruster { 538a7f53e26SMarkus Armbruster if (blk->dev_ops && blk->dev_ops->change_media_cb) { 539f1f57066SMax Reitz bool tray_was_open, tray_is_open; 540a7f53e26SMarkus Armbruster 541f1f57066SMax Reitz tray_was_open = blk_dev_is_tray_open(blk); 542a7f53e26SMarkus Armbruster blk->dev_ops->change_media_cb(blk->dev_opaque, load); 543f1f57066SMax Reitz tray_is_open = blk_dev_is_tray_open(blk); 544f1f57066SMax Reitz 545f1f57066SMax Reitz if (tray_was_open != tray_is_open) { 546f1f57066SMax Reitz qapi_event_send_device_tray_moved(blk_name(blk), tray_is_open, 547f1f57066SMax Reitz &error_abort); 548a7f53e26SMarkus Armbruster } 549a7f53e26SMarkus Armbruster } 550a7f53e26SMarkus Armbruster } 551a7f53e26SMarkus Armbruster 552a7f53e26SMarkus Armbruster /* 553a7f53e26SMarkus Armbruster * Does @blk's attached device model have removable media? 554a7f53e26SMarkus Armbruster * %true if no device model is attached. 555a7f53e26SMarkus Armbruster */ 556a7f53e26SMarkus Armbruster bool blk_dev_has_removable_media(BlockBackend *blk) 557a7f53e26SMarkus Armbruster { 558a7f53e26SMarkus Armbruster return !blk->dev || (blk->dev_ops && blk->dev_ops->change_media_cb); 559a7f53e26SMarkus Armbruster } 560a7f53e26SMarkus Armbruster 561a7f53e26SMarkus Armbruster /* 5628f3a73bcSMax Reitz * Does @blk's attached device model have a tray? 5638f3a73bcSMax Reitz */ 5648f3a73bcSMax Reitz bool blk_dev_has_tray(BlockBackend *blk) 5658f3a73bcSMax Reitz { 5668f3a73bcSMax Reitz return blk->dev_ops && blk->dev_ops->is_tray_open; 5678f3a73bcSMax Reitz } 5688f3a73bcSMax Reitz 5698f3a73bcSMax Reitz /* 570a7f53e26SMarkus Armbruster * Notify @blk's attached device model of a media eject request. 571a7f53e26SMarkus Armbruster * If @force is true, the medium is about to be yanked out forcefully. 572a7f53e26SMarkus Armbruster */ 573a7f53e26SMarkus Armbruster void blk_dev_eject_request(BlockBackend *blk, bool force) 574a7f53e26SMarkus Armbruster { 575a7f53e26SMarkus Armbruster if (blk->dev_ops && blk->dev_ops->eject_request_cb) { 576a7f53e26SMarkus Armbruster blk->dev_ops->eject_request_cb(blk->dev_opaque, force); 577a7f53e26SMarkus Armbruster } 578a7f53e26SMarkus Armbruster } 579a7f53e26SMarkus Armbruster 580a7f53e26SMarkus Armbruster /* 581a7f53e26SMarkus Armbruster * Does @blk's attached device model have a tray, and is it open? 582a7f53e26SMarkus Armbruster */ 583a7f53e26SMarkus Armbruster bool blk_dev_is_tray_open(BlockBackend *blk) 584a7f53e26SMarkus Armbruster { 5858f3a73bcSMax Reitz if (blk_dev_has_tray(blk)) { 586a7f53e26SMarkus Armbruster return blk->dev_ops->is_tray_open(blk->dev_opaque); 587a7f53e26SMarkus Armbruster } 588a7f53e26SMarkus Armbruster return false; 589a7f53e26SMarkus Armbruster } 590a7f53e26SMarkus Armbruster 591a7f53e26SMarkus Armbruster /* 592a7f53e26SMarkus Armbruster * Does @blk's attached device model have the medium locked? 593a7f53e26SMarkus Armbruster * %false if the device model has no such lock. 594a7f53e26SMarkus Armbruster */ 595a7f53e26SMarkus Armbruster bool blk_dev_is_medium_locked(BlockBackend *blk) 596a7f53e26SMarkus Armbruster { 597a7f53e26SMarkus Armbruster if (blk->dev_ops && blk->dev_ops->is_medium_locked) { 598a7f53e26SMarkus Armbruster return blk->dev_ops->is_medium_locked(blk->dev_opaque); 599a7f53e26SMarkus Armbruster } 600a7f53e26SMarkus Armbruster return false; 601a7f53e26SMarkus Armbruster } 602a7f53e26SMarkus Armbruster 603a7f53e26SMarkus Armbruster /* 604a7f53e26SMarkus Armbruster * Notify @blk's attached device model of a backend size change. 605a7f53e26SMarkus Armbruster */ 606a7f53e26SMarkus Armbruster void blk_dev_resize_cb(BlockBackend *blk) 607a7f53e26SMarkus Armbruster { 608a7f53e26SMarkus Armbruster if (blk->dev_ops && blk->dev_ops->resize_cb) { 609a7f53e26SMarkus Armbruster blk->dev_ops->resize_cb(blk->dev_opaque); 610a7f53e26SMarkus Armbruster } 611a7f53e26SMarkus Armbruster } 612a7f53e26SMarkus Armbruster 6134be74634SMarkus Armbruster void blk_iostatus_enable(BlockBackend *blk) 6144be74634SMarkus Armbruster { 615373340b2SMax Reitz blk->iostatus_enabled = true; 616373340b2SMax Reitz blk->iostatus = BLOCK_DEVICE_IO_STATUS_OK; 617373340b2SMax Reitz } 618373340b2SMax Reitz 619373340b2SMax Reitz /* The I/O status is only enabled if the drive explicitly 620373340b2SMax Reitz * enables it _and_ the VM is configured to stop on errors */ 621373340b2SMax Reitz bool blk_iostatus_is_enabled(const BlockBackend *blk) 622373340b2SMax Reitz { 623373340b2SMax Reitz return (blk->iostatus_enabled && 624373340b2SMax Reitz (blk->on_write_error == BLOCKDEV_ON_ERROR_ENOSPC || 625373340b2SMax Reitz blk->on_write_error == BLOCKDEV_ON_ERROR_STOP || 626373340b2SMax Reitz blk->on_read_error == BLOCKDEV_ON_ERROR_STOP)); 627373340b2SMax Reitz } 628373340b2SMax Reitz 629373340b2SMax Reitz BlockDeviceIoStatus blk_iostatus(const BlockBackend *blk) 630373340b2SMax Reitz { 631373340b2SMax Reitz return blk->iostatus; 632373340b2SMax Reitz } 633373340b2SMax Reitz 634373340b2SMax Reitz void blk_iostatus_disable(BlockBackend *blk) 635373340b2SMax Reitz { 636373340b2SMax Reitz blk->iostatus_enabled = false; 637373340b2SMax Reitz } 638373340b2SMax Reitz 639373340b2SMax Reitz void blk_iostatus_reset(BlockBackend *blk) 640373340b2SMax Reitz { 641373340b2SMax Reitz if (blk_iostatus_is_enabled(blk)) { 642f21d96d0SKevin Wolf BlockDriverState *bs = blk_bs(blk); 643373340b2SMax Reitz blk->iostatus = BLOCK_DEVICE_IO_STATUS_OK; 644f21d96d0SKevin Wolf if (bs && bs->job) { 645f21d96d0SKevin Wolf block_job_iostatus_reset(bs->job); 646373340b2SMax Reitz } 647373340b2SMax Reitz } 648373340b2SMax Reitz } 649373340b2SMax Reitz 650373340b2SMax Reitz void blk_iostatus_set_err(BlockBackend *blk, int error) 651373340b2SMax Reitz { 652373340b2SMax Reitz assert(blk_iostatus_is_enabled(blk)); 653373340b2SMax Reitz if (blk->iostatus == BLOCK_DEVICE_IO_STATUS_OK) { 654373340b2SMax Reitz blk->iostatus = error == ENOSPC ? BLOCK_DEVICE_IO_STATUS_NOSPACE : 655373340b2SMax Reitz BLOCK_DEVICE_IO_STATUS_FAILED; 656373340b2SMax Reitz } 6574be74634SMarkus Armbruster } 6584be74634SMarkus Armbruster 659c10c9d96SKevin Wolf void blk_set_allow_write_beyond_eof(BlockBackend *blk, bool allow) 660c10c9d96SKevin Wolf { 661c10c9d96SKevin Wolf blk->allow_write_beyond_eof = allow; 662c10c9d96SKevin Wolf } 663c10c9d96SKevin Wolf 664e7f7d676SMax Reitz static int blk_check_byte_request(BlockBackend *blk, int64_t offset, 665e7f7d676SMax Reitz size_t size) 666e7f7d676SMax Reitz { 667e7f7d676SMax Reitz int64_t len; 668e7f7d676SMax Reitz 669e7f7d676SMax Reitz if (size > INT_MAX) { 670e7f7d676SMax Reitz return -EIO; 671e7f7d676SMax Reitz } 672e7f7d676SMax Reitz 673c09ba36cSMax Reitz if (!blk_is_available(blk)) { 674e7f7d676SMax Reitz return -ENOMEDIUM; 675e7f7d676SMax Reitz } 676e7f7d676SMax Reitz 677c10c9d96SKevin Wolf if (offset < 0) { 678c10c9d96SKevin Wolf return -EIO; 679c10c9d96SKevin Wolf } 680c10c9d96SKevin Wolf 681c10c9d96SKevin Wolf if (!blk->allow_write_beyond_eof) { 682e7f7d676SMax Reitz len = blk_getlength(blk); 683e7f7d676SMax Reitz if (len < 0) { 684e7f7d676SMax Reitz return len; 685e7f7d676SMax Reitz } 686e7f7d676SMax Reitz 687e7f7d676SMax Reitz if (offset > len || len - offset < size) { 688e7f7d676SMax Reitz return -EIO; 689e7f7d676SMax Reitz } 690c10c9d96SKevin Wolf } 691e7f7d676SMax Reitz 692e7f7d676SMax Reitz return 0; 693e7f7d676SMax Reitz } 694e7f7d676SMax Reitz 695e7f7d676SMax Reitz static int blk_check_request(BlockBackend *blk, int64_t sector_num, 696e7f7d676SMax Reitz int nb_sectors) 697e7f7d676SMax Reitz { 698e7f7d676SMax Reitz if (sector_num < 0 || sector_num > INT64_MAX / BDRV_SECTOR_SIZE) { 699e7f7d676SMax Reitz return -EIO; 700e7f7d676SMax Reitz } 701e7f7d676SMax Reitz 702e7f7d676SMax Reitz if (nb_sectors < 0 || nb_sectors > INT_MAX / BDRV_SECTOR_SIZE) { 703e7f7d676SMax Reitz return -EIO; 704e7f7d676SMax Reitz } 705e7f7d676SMax Reitz 706e7f7d676SMax Reitz return blk_check_byte_request(blk, sector_num * BDRV_SECTOR_SIZE, 707e7f7d676SMax Reitz nb_sectors * BDRV_SECTOR_SIZE); 708e7f7d676SMax Reitz } 709e7f7d676SMax Reitz 7101bf1cbc9SKevin Wolf static int coroutine_fn blk_co_preadv(BlockBackend *blk, int64_t offset, 7111bf1cbc9SKevin Wolf unsigned int bytes, QEMUIOVector *qiov, 7121bf1cbc9SKevin Wolf BdrvRequestFlags flags) 7134be74634SMarkus Armbruster { 7141bf1cbc9SKevin Wolf int ret = blk_check_byte_request(blk, offset, bytes); 715e7f7d676SMax Reitz if (ret < 0) { 716e7f7d676SMax Reitz return ret; 717e7f7d676SMax Reitz } 718e7f7d676SMax Reitz 719cab3a356SKevin Wolf return bdrv_co_preadv(blk_bs(blk), offset, bytes, qiov, flags); 7201bf1cbc9SKevin Wolf } 7211bf1cbc9SKevin Wolf 722a8823a3bSKevin Wolf static int coroutine_fn blk_co_pwritev(BlockBackend *blk, int64_t offset, 723a8823a3bSKevin Wolf unsigned int bytes, QEMUIOVector *qiov, 724a8823a3bSKevin Wolf BdrvRequestFlags flags) 725a8823a3bSKevin Wolf { 726bfd18d1eSKevin Wolf int ret; 727bfd18d1eSKevin Wolf 728bfd18d1eSKevin Wolf ret = blk_check_byte_request(blk, offset, bytes); 729a8823a3bSKevin Wolf if (ret < 0) { 730a8823a3bSKevin Wolf return ret; 731a8823a3bSKevin Wolf } 732a8823a3bSKevin Wolf 733bfd18d1eSKevin Wolf if (!blk->enable_write_cache) { 734bfd18d1eSKevin Wolf flags |= BDRV_REQ_FUA; 735bfd18d1eSKevin Wolf } 736bfd18d1eSKevin Wolf 737cab3a356SKevin Wolf return bdrv_co_pwritev(blk_bs(blk), offset, bytes, qiov, flags); 738a8823a3bSKevin Wolf } 739a8823a3bSKevin Wolf 7401bf1cbc9SKevin Wolf typedef struct BlkRwCo { 7411bf1cbc9SKevin Wolf BlockBackend *blk; 7421bf1cbc9SKevin Wolf int64_t offset; 7431bf1cbc9SKevin Wolf QEMUIOVector *qiov; 7441bf1cbc9SKevin Wolf int ret; 7451bf1cbc9SKevin Wolf BdrvRequestFlags flags; 7461bf1cbc9SKevin Wolf } BlkRwCo; 7471bf1cbc9SKevin Wolf 7481bf1cbc9SKevin Wolf static void blk_read_entry(void *opaque) 7491bf1cbc9SKevin Wolf { 7501bf1cbc9SKevin Wolf BlkRwCo *rwco = opaque; 7511bf1cbc9SKevin Wolf 7521bf1cbc9SKevin Wolf rwco->ret = blk_co_preadv(rwco->blk, rwco->offset, rwco->qiov->size, 7531bf1cbc9SKevin Wolf rwco->qiov, rwco->flags); 7541bf1cbc9SKevin Wolf } 7551bf1cbc9SKevin Wolf 756a8823a3bSKevin Wolf static void blk_write_entry(void *opaque) 757a8823a3bSKevin Wolf { 758a8823a3bSKevin Wolf BlkRwCo *rwco = opaque; 759a8823a3bSKevin Wolf 760a8823a3bSKevin Wolf rwco->ret = blk_co_pwritev(rwco->blk, rwco->offset, rwco->qiov->size, 761a8823a3bSKevin Wolf rwco->qiov, rwco->flags); 762a8823a3bSKevin Wolf } 763a8823a3bSKevin Wolf 764a55d3fbaSKevin Wolf static int blk_prw(BlockBackend *blk, int64_t offset, uint8_t *buf, 765a55d3fbaSKevin Wolf int64_t bytes, CoroutineEntry co_entry, 766fc1453cdSKevin Wolf BdrvRequestFlags flags) 7671bf1cbc9SKevin Wolf { 7681bf1cbc9SKevin Wolf AioContext *aio_context; 7691bf1cbc9SKevin Wolf QEMUIOVector qiov; 7701bf1cbc9SKevin Wolf struct iovec iov; 7711bf1cbc9SKevin Wolf Coroutine *co; 7721bf1cbc9SKevin Wolf BlkRwCo rwco; 7731bf1cbc9SKevin Wolf 7741bf1cbc9SKevin Wolf iov = (struct iovec) { 7751bf1cbc9SKevin Wolf .iov_base = buf, 776a55d3fbaSKevin Wolf .iov_len = bytes, 7771bf1cbc9SKevin Wolf }; 7781bf1cbc9SKevin Wolf qemu_iovec_init_external(&qiov, &iov, 1); 7791bf1cbc9SKevin Wolf 7801bf1cbc9SKevin Wolf rwco = (BlkRwCo) { 7811bf1cbc9SKevin Wolf .blk = blk, 782a55d3fbaSKevin Wolf .offset = offset, 7831bf1cbc9SKevin Wolf .qiov = &qiov, 784fc1453cdSKevin Wolf .flags = flags, 7851bf1cbc9SKevin Wolf .ret = NOT_DONE, 7861bf1cbc9SKevin Wolf }; 7871bf1cbc9SKevin Wolf 788a8823a3bSKevin Wolf co = qemu_coroutine_create(co_entry); 7891bf1cbc9SKevin Wolf qemu_coroutine_enter(co, &rwco); 7901bf1cbc9SKevin Wolf 7911bf1cbc9SKevin Wolf aio_context = blk_get_aio_context(blk); 7921bf1cbc9SKevin Wolf while (rwco.ret == NOT_DONE) { 7931bf1cbc9SKevin Wolf aio_poll(aio_context, true); 7941bf1cbc9SKevin Wolf } 7951bf1cbc9SKevin Wolf 7961bf1cbc9SKevin Wolf return rwco.ret; 7974be74634SMarkus Armbruster } 7984be74634SMarkus Armbruster 799b7d17f9fSEric Blake int blk_pread_unthrottled(BlockBackend *blk, int64_t offset, uint8_t *buf, 800b7d17f9fSEric Blake int count) 8014be74634SMarkus Armbruster { 8025bd51196SKevin Wolf int ret; 8035bd51196SKevin Wolf 804b7d17f9fSEric Blake ret = blk_check_byte_request(blk, offset, count); 805e7f7d676SMax Reitz if (ret < 0) { 806e7f7d676SMax Reitz return ret; 807e7f7d676SMax Reitz } 808e7f7d676SMax Reitz 809*27ccdd52SKevin Wolf bdrv_no_throttling_begin(blk_bs(blk)); 810b7d17f9fSEric Blake ret = blk_pread(blk, offset, buf, count); 811*27ccdd52SKevin Wolf bdrv_no_throttling_end(blk_bs(blk)); 8125bd51196SKevin Wolf return ret; 8134be74634SMarkus Armbruster } 8144be74634SMarkus Armbruster 815983a1600SEric Blake int blk_write_zeroes(BlockBackend *blk, int64_t offset, 816983a1600SEric Blake int count, BdrvRequestFlags flags) 8170df89e8eSKevin Wolf { 818983a1600SEric Blake return blk_prw(blk, offset, NULL, count, blk_write_entry, 81916aaf975SKevin Wolf flags | BDRV_REQ_ZERO_WRITE); 8200df89e8eSKevin Wolf } 8210df89e8eSKevin Wolf 822e7f7d676SMax Reitz static void error_callback_bh(void *opaque) 823e7f7d676SMax Reitz { 824e7f7d676SMax Reitz struct BlockBackendAIOCB *acb = opaque; 825e7f7d676SMax Reitz qemu_bh_delete(acb->bh); 826e7f7d676SMax Reitz acb->common.cb(acb->common.opaque, acb->ret); 827e7f7d676SMax Reitz qemu_aio_unref(acb); 828e7f7d676SMax Reitz } 829e7f7d676SMax Reitz 830ca78ecfaSPeter Lieven BlockAIOCB *blk_abort_aio_request(BlockBackend *blk, 831ca78ecfaSPeter Lieven BlockCompletionFunc *cb, 832e7f7d676SMax Reitz void *opaque, int ret) 833e7f7d676SMax Reitz { 834e7f7d676SMax Reitz struct BlockBackendAIOCB *acb; 835e7f7d676SMax Reitz QEMUBH *bh; 836e7f7d676SMax Reitz 837e7f7d676SMax Reitz acb = blk_aio_get(&block_backend_aiocb_info, blk, cb, opaque); 8384981bdecSMax Reitz acb->blk = blk; 839e7f7d676SMax Reitz acb->ret = ret; 840e7f7d676SMax Reitz 841e7f7d676SMax Reitz bh = aio_bh_new(blk_get_aio_context(blk), error_callback_bh, acb); 842e7f7d676SMax Reitz acb->bh = bh; 843e7f7d676SMax Reitz qemu_bh_schedule(bh); 844e7f7d676SMax Reitz 845e7f7d676SMax Reitz return &acb->common; 846e7f7d676SMax Reitz } 847e7f7d676SMax Reitz 84857d6a428SKevin Wolf typedef struct BlkAioEmAIOCB { 84957d6a428SKevin Wolf BlockAIOCB common; 85057d6a428SKevin Wolf BlkRwCo rwco; 8517fa84cd8SKevin Wolf int bytes; 85257d6a428SKevin Wolf bool has_returned; 85357d6a428SKevin Wolf QEMUBH* bh; 85457d6a428SKevin Wolf } BlkAioEmAIOCB; 85557d6a428SKevin Wolf 85657d6a428SKevin Wolf static const AIOCBInfo blk_aio_em_aiocb_info = { 85757d6a428SKevin Wolf .aiocb_size = sizeof(BlkAioEmAIOCB), 85857d6a428SKevin Wolf }; 85957d6a428SKevin Wolf 86057d6a428SKevin Wolf static void blk_aio_complete(BlkAioEmAIOCB *acb) 86157d6a428SKevin Wolf { 86257d6a428SKevin Wolf if (acb->bh) { 86357d6a428SKevin Wolf assert(acb->has_returned); 86457d6a428SKevin Wolf qemu_bh_delete(acb->bh); 86557d6a428SKevin Wolf } 86657d6a428SKevin Wolf if (acb->has_returned) { 86757d6a428SKevin Wolf acb->common.cb(acb->common.opaque, acb->rwco.ret); 86857d6a428SKevin Wolf qemu_aio_unref(acb); 86957d6a428SKevin Wolf } 87057d6a428SKevin Wolf } 87157d6a428SKevin Wolf 87257d6a428SKevin Wolf static void blk_aio_complete_bh(void *opaque) 87357d6a428SKevin Wolf { 87457d6a428SKevin Wolf blk_aio_complete(opaque); 87557d6a428SKevin Wolf } 87657d6a428SKevin Wolf 8777fa84cd8SKevin Wolf static BlockAIOCB *blk_aio_prwv(BlockBackend *blk, int64_t offset, int bytes, 87857d6a428SKevin Wolf QEMUIOVector *qiov, CoroutineEntry co_entry, 87957d6a428SKevin Wolf BdrvRequestFlags flags, 88057d6a428SKevin Wolf BlockCompletionFunc *cb, void *opaque) 88157d6a428SKevin Wolf { 88257d6a428SKevin Wolf BlkAioEmAIOCB *acb; 88357d6a428SKevin Wolf Coroutine *co; 88457d6a428SKevin Wolf 88557d6a428SKevin Wolf acb = blk_aio_get(&blk_aio_em_aiocb_info, blk, cb, opaque); 88657d6a428SKevin Wolf acb->rwco = (BlkRwCo) { 88757d6a428SKevin Wolf .blk = blk, 88857d6a428SKevin Wolf .offset = offset, 88957d6a428SKevin Wolf .qiov = qiov, 89057d6a428SKevin Wolf .flags = flags, 89157d6a428SKevin Wolf .ret = NOT_DONE, 89257d6a428SKevin Wolf }; 8937fa84cd8SKevin Wolf acb->bytes = bytes; 89457d6a428SKevin Wolf acb->bh = NULL; 89557d6a428SKevin Wolf acb->has_returned = false; 89657d6a428SKevin Wolf 89757d6a428SKevin Wolf co = qemu_coroutine_create(co_entry); 89857d6a428SKevin Wolf qemu_coroutine_enter(co, acb); 89957d6a428SKevin Wolf 90057d6a428SKevin Wolf acb->has_returned = true; 90157d6a428SKevin Wolf if (acb->rwco.ret != NOT_DONE) { 90257d6a428SKevin Wolf acb->bh = aio_bh_new(blk_get_aio_context(blk), blk_aio_complete_bh, acb); 90357d6a428SKevin Wolf qemu_bh_schedule(acb->bh); 90457d6a428SKevin Wolf } 90557d6a428SKevin Wolf 90657d6a428SKevin Wolf return &acb->common; 90757d6a428SKevin Wolf } 90857d6a428SKevin Wolf 90957d6a428SKevin Wolf static void blk_aio_read_entry(void *opaque) 91057d6a428SKevin Wolf { 91157d6a428SKevin Wolf BlkAioEmAIOCB *acb = opaque; 91257d6a428SKevin Wolf BlkRwCo *rwco = &acb->rwco; 91357d6a428SKevin Wolf 9147fa84cd8SKevin Wolf assert(rwco->qiov->size == acb->bytes); 9157fa84cd8SKevin Wolf rwco->ret = blk_co_preadv(rwco->blk, rwco->offset, acb->bytes, 91657d6a428SKevin Wolf rwco->qiov, rwco->flags); 91757d6a428SKevin Wolf blk_aio_complete(acb); 91857d6a428SKevin Wolf } 91957d6a428SKevin Wolf 92057d6a428SKevin Wolf static void blk_aio_write_entry(void *opaque) 92157d6a428SKevin Wolf { 92257d6a428SKevin Wolf BlkAioEmAIOCB *acb = opaque; 92357d6a428SKevin Wolf BlkRwCo *rwco = &acb->rwco; 92457d6a428SKevin Wolf 9257fa84cd8SKevin Wolf assert(!rwco->qiov || rwco->qiov->size == acb->bytes); 9267fa84cd8SKevin Wolf rwco->ret = blk_co_pwritev(rwco->blk, rwco->offset, acb->bytes, 92757d6a428SKevin Wolf rwco->qiov, rwco->flags); 92857d6a428SKevin Wolf blk_aio_complete(acb); 92957d6a428SKevin Wolf } 93057d6a428SKevin Wolf 931983a1600SEric Blake BlockAIOCB *blk_aio_write_zeroes(BlockBackend *blk, int64_t offset, 932983a1600SEric Blake int count, BdrvRequestFlags flags, 9334be74634SMarkus Armbruster BlockCompletionFunc *cb, void *opaque) 9344be74634SMarkus Armbruster { 935983a1600SEric Blake return blk_aio_prwv(blk, offset, count, NULL, blk_aio_write_entry, 936983a1600SEric Blake flags | BDRV_REQ_ZERO_WRITE, cb, opaque); 9374be74634SMarkus Armbruster } 9384be74634SMarkus Armbruster 9394be74634SMarkus Armbruster int blk_pread(BlockBackend *blk, int64_t offset, void *buf, int count) 9404be74634SMarkus Armbruster { 941a55d3fbaSKevin Wolf int ret = blk_prw(blk, offset, buf, count, blk_read_entry, 0); 942e7f7d676SMax Reitz if (ret < 0) { 943e7f7d676SMax Reitz return ret; 944e7f7d676SMax Reitz } 945a55d3fbaSKevin Wolf return count; 9464be74634SMarkus Armbruster } 9474be74634SMarkus Armbruster 9488341f00dSEric Blake int blk_pwrite(BlockBackend *blk, int64_t offset, const void *buf, int count, 9498341f00dSEric Blake BdrvRequestFlags flags) 9504be74634SMarkus Armbruster { 9518341f00dSEric Blake int ret = blk_prw(blk, offset, (void *) buf, count, blk_write_entry, 9528341f00dSEric Blake flags); 953e7f7d676SMax Reitz if (ret < 0) { 954e7f7d676SMax Reitz return ret; 955e7f7d676SMax Reitz } 956a55d3fbaSKevin Wolf return count; 9574be74634SMarkus Armbruster } 9584be74634SMarkus Armbruster 9594be74634SMarkus Armbruster int64_t blk_getlength(BlockBackend *blk) 9604be74634SMarkus Armbruster { 961c09ba36cSMax Reitz if (!blk_is_available(blk)) { 962c09ba36cSMax Reitz return -ENOMEDIUM; 963c09ba36cSMax Reitz } 964c09ba36cSMax Reitz 965f21d96d0SKevin Wolf return bdrv_getlength(blk_bs(blk)); 9664be74634SMarkus Armbruster } 9674be74634SMarkus Armbruster 9684be74634SMarkus Armbruster void blk_get_geometry(BlockBackend *blk, uint64_t *nb_sectors_ptr) 9694be74634SMarkus Armbruster { 970f21d96d0SKevin Wolf if (!blk_bs(blk)) { 971a46fc9c9SMax Reitz *nb_sectors_ptr = 0; 972a46fc9c9SMax Reitz } else { 973f21d96d0SKevin Wolf bdrv_get_geometry(blk_bs(blk), nb_sectors_ptr); 9744be74634SMarkus Armbruster } 975a46fc9c9SMax Reitz } 9764be74634SMarkus Armbruster 9771ef01253SMax Reitz int64_t blk_nb_sectors(BlockBackend *blk) 9781ef01253SMax Reitz { 979c09ba36cSMax Reitz if (!blk_is_available(blk)) { 980c09ba36cSMax Reitz return -ENOMEDIUM; 981c09ba36cSMax Reitz } 982c09ba36cSMax Reitz 983f21d96d0SKevin Wolf return bdrv_nb_sectors(blk_bs(blk)); 9841ef01253SMax Reitz } 9851ef01253SMax Reitz 98660cb2fa7SEric Blake BlockAIOCB *blk_aio_preadv(BlockBackend *blk, int64_t offset, 98760cb2fa7SEric Blake QEMUIOVector *qiov, BdrvRequestFlags flags, 98860cb2fa7SEric Blake BlockCompletionFunc *cb, void *opaque) 98960cb2fa7SEric Blake { 99060cb2fa7SEric Blake return blk_aio_prwv(blk, offset, qiov->size, qiov, 99160cb2fa7SEric Blake blk_aio_read_entry, flags, cb, opaque); 99260cb2fa7SEric Blake } 99360cb2fa7SEric Blake 99460cb2fa7SEric Blake BlockAIOCB *blk_aio_pwritev(BlockBackend *blk, int64_t offset, 99560cb2fa7SEric Blake QEMUIOVector *qiov, BdrvRequestFlags flags, 99660cb2fa7SEric Blake BlockCompletionFunc *cb, void *opaque) 99760cb2fa7SEric Blake { 99860cb2fa7SEric Blake return blk_aio_prwv(blk, offset, qiov->size, qiov, 99960cb2fa7SEric Blake blk_aio_write_entry, flags, cb, opaque); 100060cb2fa7SEric Blake } 100160cb2fa7SEric Blake 10024be74634SMarkus Armbruster BlockAIOCB *blk_aio_flush(BlockBackend *blk, 10034be74634SMarkus Armbruster BlockCompletionFunc *cb, void *opaque) 10044be74634SMarkus Armbruster { 1005c09ba36cSMax Reitz if (!blk_is_available(blk)) { 1006ca78ecfaSPeter Lieven return blk_abort_aio_request(blk, cb, opaque, -ENOMEDIUM); 1007c09ba36cSMax Reitz } 1008c09ba36cSMax Reitz 1009f21d96d0SKevin Wolf return bdrv_aio_flush(blk_bs(blk), cb, opaque); 10104be74634SMarkus Armbruster } 10114be74634SMarkus Armbruster 10124be74634SMarkus Armbruster BlockAIOCB *blk_aio_discard(BlockBackend *blk, 10134be74634SMarkus Armbruster int64_t sector_num, int nb_sectors, 10144be74634SMarkus Armbruster BlockCompletionFunc *cb, void *opaque) 10154be74634SMarkus Armbruster { 1016e7f7d676SMax Reitz int ret = blk_check_request(blk, sector_num, nb_sectors); 1017e7f7d676SMax Reitz if (ret < 0) { 1018ca78ecfaSPeter Lieven return blk_abort_aio_request(blk, cb, opaque, ret); 1019e7f7d676SMax Reitz } 1020e7f7d676SMax Reitz 1021f21d96d0SKevin Wolf return bdrv_aio_discard(blk_bs(blk), sector_num, nb_sectors, cb, opaque); 10224be74634SMarkus Armbruster } 10234be74634SMarkus Armbruster 10244be74634SMarkus Armbruster void blk_aio_cancel(BlockAIOCB *acb) 10254be74634SMarkus Armbruster { 10264be74634SMarkus Armbruster bdrv_aio_cancel(acb); 10274be74634SMarkus Armbruster } 10284be74634SMarkus Armbruster 10294be74634SMarkus Armbruster void blk_aio_cancel_async(BlockAIOCB *acb) 10304be74634SMarkus Armbruster { 10314be74634SMarkus Armbruster bdrv_aio_cancel_async(acb); 10324be74634SMarkus Armbruster } 10334be74634SMarkus Armbruster 10344be74634SMarkus Armbruster int blk_aio_multiwrite(BlockBackend *blk, BlockRequest *reqs, int num_reqs) 10354be74634SMarkus Armbruster { 1036e7f7d676SMax Reitz int i, ret; 1037e7f7d676SMax Reitz 1038e7f7d676SMax Reitz for (i = 0; i < num_reqs; i++) { 1039e7f7d676SMax Reitz ret = blk_check_request(blk, reqs[i].sector, reqs[i].nb_sectors); 1040e7f7d676SMax Reitz if (ret < 0) { 1041e7f7d676SMax Reitz return ret; 1042e7f7d676SMax Reitz } 1043e7f7d676SMax Reitz } 1044e7f7d676SMax Reitz 1045f21d96d0SKevin Wolf return bdrv_aio_multiwrite(blk_bs(blk), reqs, num_reqs); 10464be74634SMarkus Armbruster } 10474be74634SMarkus Armbruster 10484be74634SMarkus Armbruster int blk_ioctl(BlockBackend *blk, unsigned long int req, void *buf) 10494be74634SMarkus Armbruster { 1050c09ba36cSMax Reitz if (!blk_is_available(blk)) { 1051c09ba36cSMax Reitz return -ENOMEDIUM; 1052c09ba36cSMax Reitz } 1053c09ba36cSMax Reitz 1054f21d96d0SKevin Wolf return bdrv_ioctl(blk_bs(blk), req, buf); 10554be74634SMarkus Armbruster } 10564be74634SMarkus Armbruster 10574be74634SMarkus Armbruster BlockAIOCB *blk_aio_ioctl(BlockBackend *blk, unsigned long int req, void *buf, 10584be74634SMarkus Armbruster BlockCompletionFunc *cb, void *opaque) 10594be74634SMarkus Armbruster { 1060c09ba36cSMax Reitz if (!blk_is_available(blk)) { 1061ca78ecfaSPeter Lieven return blk_abort_aio_request(blk, cb, opaque, -ENOMEDIUM); 1062c09ba36cSMax Reitz } 1063c09ba36cSMax Reitz 1064f21d96d0SKevin Wolf return bdrv_aio_ioctl(blk_bs(blk), req, buf, cb, opaque); 10654be74634SMarkus Armbruster } 10664be74634SMarkus Armbruster 10672bb0dce7SMax Reitz int blk_co_discard(BlockBackend *blk, int64_t sector_num, int nb_sectors) 10682bb0dce7SMax Reitz { 1069e7f7d676SMax Reitz int ret = blk_check_request(blk, sector_num, nb_sectors); 1070e7f7d676SMax Reitz if (ret < 0) { 1071e7f7d676SMax Reitz return ret; 1072e7f7d676SMax Reitz } 1073e7f7d676SMax Reitz 1074f21d96d0SKevin Wolf return bdrv_co_discard(blk_bs(blk), sector_num, nb_sectors); 10752bb0dce7SMax Reitz } 10762bb0dce7SMax Reitz 10772bb0dce7SMax Reitz int blk_co_flush(BlockBackend *blk) 10782bb0dce7SMax Reitz { 1079c09ba36cSMax Reitz if (!blk_is_available(blk)) { 1080c09ba36cSMax Reitz return -ENOMEDIUM; 1081c09ba36cSMax Reitz } 1082c09ba36cSMax Reitz 1083f21d96d0SKevin Wolf return bdrv_co_flush(blk_bs(blk)); 10842bb0dce7SMax Reitz } 10852bb0dce7SMax Reitz 10864be74634SMarkus Armbruster int blk_flush(BlockBackend *blk) 10874be74634SMarkus Armbruster { 1088c09ba36cSMax Reitz if (!blk_is_available(blk)) { 1089c09ba36cSMax Reitz return -ENOMEDIUM; 1090c09ba36cSMax Reitz } 1091c09ba36cSMax Reitz 1092f21d96d0SKevin Wolf return bdrv_flush(blk_bs(blk)); 10934be74634SMarkus Armbruster } 10944be74634SMarkus Armbruster 109597b0385aSAlexander Yarygin void blk_drain(BlockBackend *blk) 109697b0385aSAlexander Yarygin { 1097f21d96d0SKevin Wolf if (blk_bs(blk)) { 1098f21d96d0SKevin Wolf bdrv_drain(blk_bs(blk)); 109997b0385aSAlexander Yarygin } 1100a46fc9c9SMax Reitz } 110197b0385aSAlexander Yarygin 11024be74634SMarkus Armbruster void blk_drain_all(void) 11034be74634SMarkus Armbruster { 11044be74634SMarkus Armbruster bdrv_drain_all(); 11054be74634SMarkus Armbruster } 11064be74634SMarkus Armbruster 1107373340b2SMax Reitz void blk_set_on_error(BlockBackend *blk, BlockdevOnError on_read_error, 1108373340b2SMax Reitz BlockdevOnError on_write_error) 1109373340b2SMax Reitz { 1110373340b2SMax Reitz blk->on_read_error = on_read_error; 1111373340b2SMax Reitz blk->on_write_error = on_write_error; 1112373340b2SMax Reitz } 1113373340b2SMax Reitz 11144be74634SMarkus Armbruster BlockdevOnError blk_get_on_error(BlockBackend *blk, bool is_read) 11154be74634SMarkus Armbruster { 1116373340b2SMax Reitz return is_read ? blk->on_read_error : blk->on_write_error; 11174be74634SMarkus Armbruster } 11184be74634SMarkus Armbruster 11194be74634SMarkus Armbruster BlockErrorAction blk_get_error_action(BlockBackend *blk, bool is_read, 11204be74634SMarkus Armbruster int error) 11214be74634SMarkus Armbruster { 1122373340b2SMax Reitz BlockdevOnError on_err = blk_get_on_error(blk, is_read); 1123373340b2SMax Reitz 1124373340b2SMax Reitz switch (on_err) { 1125373340b2SMax Reitz case BLOCKDEV_ON_ERROR_ENOSPC: 1126373340b2SMax Reitz return (error == ENOSPC) ? 1127373340b2SMax Reitz BLOCK_ERROR_ACTION_STOP : BLOCK_ERROR_ACTION_REPORT; 1128373340b2SMax Reitz case BLOCKDEV_ON_ERROR_STOP: 1129373340b2SMax Reitz return BLOCK_ERROR_ACTION_STOP; 1130373340b2SMax Reitz case BLOCKDEV_ON_ERROR_REPORT: 1131373340b2SMax Reitz return BLOCK_ERROR_ACTION_REPORT; 1132373340b2SMax Reitz case BLOCKDEV_ON_ERROR_IGNORE: 1133373340b2SMax Reitz return BLOCK_ERROR_ACTION_IGNORE; 1134373340b2SMax Reitz default: 1135373340b2SMax Reitz abort(); 1136373340b2SMax Reitz } 11374be74634SMarkus Armbruster } 11384be74634SMarkus Armbruster 1139373340b2SMax Reitz static void send_qmp_error_event(BlockBackend *blk, 1140373340b2SMax Reitz BlockErrorAction action, 1141373340b2SMax Reitz bool is_read, int error) 1142373340b2SMax Reitz { 1143373340b2SMax Reitz IoOperationType optype; 1144373340b2SMax Reitz 1145373340b2SMax Reitz optype = is_read ? IO_OPERATION_TYPE_READ : IO_OPERATION_TYPE_WRITE; 1146373340b2SMax Reitz qapi_event_send_block_io_error(blk_name(blk), optype, action, 1147373340b2SMax Reitz blk_iostatus_is_enabled(blk), 1148373340b2SMax Reitz error == ENOSPC, strerror(error), 1149373340b2SMax Reitz &error_abort); 1150373340b2SMax Reitz } 1151373340b2SMax Reitz 1152373340b2SMax Reitz /* This is done by device models because, while the block layer knows 1153373340b2SMax Reitz * about the error, it does not know whether an operation comes from 1154373340b2SMax Reitz * the device or the block layer (from a job, for example). 1155373340b2SMax Reitz */ 11564be74634SMarkus Armbruster void blk_error_action(BlockBackend *blk, BlockErrorAction action, 11574be74634SMarkus Armbruster bool is_read, int error) 11584be74634SMarkus Armbruster { 1159373340b2SMax Reitz assert(error >= 0); 1160373340b2SMax Reitz 1161373340b2SMax Reitz if (action == BLOCK_ERROR_ACTION_STOP) { 1162373340b2SMax Reitz /* First set the iostatus, so that "info block" returns an iostatus 1163373340b2SMax Reitz * that matches the events raised so far (an additional error iostatus 1164373340b2SMax Reitz * is fine, but not a lost one). 1165373340b2SMax Reitz */ 1166373340b2SMax Reitz blk_iostatus_set_err(blk, error); 1167373340b2SMax Reitz 1168373340b2SMax Reitz /* Then raise the request to stop the VM and the event. 1169373340b2SMax Reitz * qemu_system_vmstop_request_prepare has two effects. First, 1170373340b2SMax Reitz * it ensures that the STOP event always comes after the 1171373340b2SMax Reitz * BLOCK_IO_ERROR event. Second, it ensures that even if management 1172373340b2SMax Reitz * can observe the STOP event and do a "cont" before the STOP 1173373340b2SMax Reitz * event is issued, the VM will not stop. In this case, vm_start() 1174373340b2SMax Reitz * also ensures that the STOP/RESUME pair of events is emitted. 1175373340b2SMax Reitz */ 1176373340b2SMax Reitz qemu_system_vmstop_request_prepare(); 1177373340b2SMax Reitz send_qmp_error_event(blk, action, is_read, error); 1178373340b2SMax Reitz qemu_system_vmstop_request(RUN_STATE_IO_ERROR); 1179373340b2SMax Reitz } else { 1180373340b2SMax Reitz send_qmp_error_event(blk, action, is_read, error); 1181373340b2SMax Reitz } 11824be74634SMarkus Armbruster } 11834be74634SMarkus Armbruster 11844be74634SMarkus Armbruster int blk_is_read_only(BlockBackend *blk) 11854be74634SMarkus Armbruster { 1186f21d96d0SKevin Wolf BlockDriverState *bs = blk_bs(blk); 1187f21d96d0SKevin Wolf 1188f21d96d0SKevin Wolf if (bs) { 1189f21d96d0SKevin Wolf return bdrv_is_read_only(bs); 1190061959e8SMax Reitz } else { 1191061959e8SMax Reitz return blk->root_state.read_only; 1192061959e8SMax Reitz } 11934be74634SMarkus Armbruster } 11944be74634SMarkus Armbruster 11954be74634SMarkus Armbruster int blk_is_sg(BlockBackend *blk) 11964be74634SMarkus Armbruster { 1197f21d96d0SKevin Wolf BlockDriverState *bs = blk_bs(blk); 1198f21d96d0SKevin Wolf 1199f21d96d0SKevin Wolf if (!bs) { 1200a46fc9c9SMax Reitz return 0; 1201a46fc9c9SMax Reitz } 1202a46fc9c9SMax Reitz 1203f21d96d0SKevin Wolf return bdrv_is_sg(bs); 12044be74634SMarkus Armbruster } 12054be74634SMarkus Armbruster 12064be74634SMarkus Armbruster int blk_enable_write_cache(BlockBackend *blk) 12074be74634SMarkus Armbruster { 1208bfd18d1eSKevin Wolf return blk->enable_write_cache; 12094be74634SMarkus Armbruster } 12104be74634SMarkus Armbruster 12114be74634SMarkus Armbruster void blk_set_enable_write_cache(BlockBackend *blk, bool wce) 12124be74634SMarkus Armbruster { 1213bfd18d1eSKevin Wolf blk->enable_write_cache = wce; 12144be74634SMarkus Armbruster } 12154be74634SMarkus Armbruster 12162bb0dce7SMax Reitz void blk_invalidate_cache(BlockBackend *blk, Error **errp) 12172bb0dce7SMax Reitz { 1218f21d96d0SKevin Wolf BlockDriverState *bs = blk_bs(blk); 1219f21d96d0SKevin Wolf 1220f21d96d0SKevin Wolf if (!bs) { 1221c09ba36cSMax Reitz error_setg(errp, "Device '%s' has no medium", blk->name); 1222c09ba36cSMax Reitz return; 1223c09ba36cSMax Reitz } 1224c09ba36cSMax Reitz 1225f21d96d0SKevin Wolf bdrv_invalidate_cache(bs, errp); 12262bb0dce7SMax Reitz } 12272bb0dce7SMax Reitz 1228e031f750SMax Reitz bool blk_is_inserted(BlockBackend *blk) 12294be74634SMarkus Armbruster { 1230f21d96d0SKevin Wolf BlockDriverState *bs = blk_bs(blk); 1231f21d96d0SKevin Wolf 1232f21d96d0SKevin Wolf return bs && bdrv_is_inserted(bs); 1233db0284f8SMax Reitz } 1234db0284f8SMax Reitz 1235db0284f8SMax Reitz bool blk_is_available(BlockBackend *blk) 1236db0284f8SMax Reitz { 1237db0284f8SMax Reitz return blk_is_inserted(blk) && !blk_dev_is_tray_open(blk); 12384be74634SMarkus Armbruster } 12394be74634SMarkus Armbruster 12404be74634SMarkus Armbruster void blk_lock_medium(BlockBackend *blk, bool locked) 12414be74634SMarkus Armbruster { 1242f21d96d0SKevin Wolf BlockDriverState *bs = blk_bs(blk); 1243f21d96d0SKevin Wolf 1244f21d96d0SKevin Wolf if (bs) { 1245f21d96d0SKevin Wolf bdrv_lock_medium(bs, locked); 12464be74634SMarkus Armbruster } 1247a46fc9c9SMax Reitz } 12484be74634SMarkus Armbruster 12494be74634SMarkus Armbruster void blk_eject(BlockBackend *blk, bool eject_flag) 12504be74634SMarkus Armbruster { 1251f21d96d0SKevin Wolf BlockDriverState *bs = blk_bs(blk); 1252f21d96d0SKevin Wolf 1253f21d96d0SKevin Wolf if (bs) { 1254f21d96d0SKevin Wolf bdrv_eject(bs, eject_flag); 12554be74634SMarkus Armbruster } 1256a46fc9c9SMax Reitz } 12574be74634SMarkus Armbruster 12584be74634SMarkus Armbruster int blk_get_flags(BlockBackend *blk) 12594be74634SMarkus Armbruster { 1260f21d96d0SKevin Wolf BlockDriverState *bs = blk_bs(blk); 1261f21d96d0SKevin Wolf 1262f21d96d0SKevin Wolf if (bs) { 1263f21d96d0SKevin Wolf return bdrv_get_flags(bs); 1264061959e8SMax Reitz } else { 1265061959e8SMax Reitz return blk->root_state.open_flags; 1266061959e8SMax Reitz } 12674be74634SMarkus Armbruster } 12684be74634SMarkus Armbruster 1269454057b7SPeter Lieven int blk_get_max_transfer_length(BlockBackend *blk) 1270454057b7SPeter Lieven { 1271f21d96d0SKevin Wolf BlockDriverState *bs = blk_bs(blk); 1272f21d96d0SKevin Wolf 1273f21d96d0SKevin Wolf if (bs) { 1274f21d96d0SKevin Wolf return bs->bl.max_transfer_length; 1275a46fc9c9SMax Reitz } else { 1276a46fc9c9SMax Reitz return 0; 1277a46fc9c9SMax Reitz } 1278454057b7SPeter Lieven } 1279454057b7SPeter Lieven 1280648296e0SStefan Hajnoczi int blk_get_max_iov(BlockBackend *blk) 1281648296e0SStefan Hajnoczi { 1282f21d96d0SKevin Wolf return blk->root->bs->bl.max_iov; 1283648296e0SStefan Hajnoczi } 1284648296e0SStefan Hajnoczi 12854be74634SMarkus Armbruster void blk_set_guest_block_size(BlockBackend *blk, int align) 12864be74634SMarkus Armbruster { 128768e9ec01SMax Reitz blk->guest_block_size = align; 12884be74634SMarkus Armbruster } 12894be74634SMarkus Armbruster 1290f1c17521SPaolo Bonzini void *blk_try_blockalign(BlockBackend *blk, size_t size) 1291f1c17521SPaolo Bonzini { 1292f21d96d0SKevin Wolf return qemu_try_blockalign(blk ? blk_bs(blk) : NULL, size); 1293f1c17521SPaolo Bonzini } 1294f1c17521SPaolo Bonzini 12954be74634SMarkus Armbruster void *blk_blockalign(BlockBackend *blk, size_t size) 12964be74634SMarkus Armbruster { 1297f21d96d0SKevin Wolf return qemu_blockalign(blk ? blk_bs(blk) : NULL, size); 12984be74634SMarkus Armbruster } 12994be74634SMarkus Armbruster 13004be74634SMarkus Armbruster bool blk_op_is_blocked(BlockBackend *blk, BlockOpType op, Error **errp) 13014be74634SMarkus Armbruster { 1302f21d96d0SKevin Wolf BlockDriverState *bs = blk_bs(blk); 1303f21d96d0SKevin Wolf 1304f21d96d0SKevin Wolf if (!bs) { 1305a46fc9c9SMax Reitz return false; 1306a46fc9c9SMax Reitz } 1307a46fc9c9SMax Reitz 1308f21d96d0SKevin Wolf return bdrv_op_is_blocked(bs, op, errp); 13094be74634SMarkus Armbruster } 13104be74634SMarkus Armbruster 13114be74634SMarkus Armbruster void blk_op_unblock(BlockBackend *blk, BlockOpType op, Error *reason) 13124be74634SMarkus Armbruster { 1313f21d96d0SKevin Wolf BlockDriverState *bs = blk_bs(blk); 1314f21d96d0SKevin Wolf 1315f21d96d0SKevin Wolf if (bs) { 1316f21d96d0SKevin Wolf bdrv_op_unblock(bs, op, reason); 13174be74634SMarkus Armbruster } 1318a46fc9c9SMax Reitz } 13194be74634SMarkus Armbruster 13204be74634SMarkus Armbruster void blk_op_block_all(BlockBackend *blk, Error *reason) 13214be74634SMarkus Armbruster { 1322f21d96d0SKevin Wolf BlockDriverState *bs = blk_bs(blk); 1323f21d96d0SKevin Wolf 1324f21d96d0SKevin Wolf if (bs) { 1325f21d96d0SKevin Wolf bdrv_op_block_all(bs, reason); 13264be74634SMarkus Armbruster } 1327a46fc9c9SMax Reitz } 13284be74634SMarkus Armbruster 13294be74634SMarkus Armbruster void blk_op_unblock_all(BlockBackend *blk, Error *reason) 13304be74634SMarkus Armbruster { 1331f21d96d0SKevin Wolf BlockDriverState *bs = blk_bs(blk); 1332f21d96d0SKevin Wolf 1333f21d96d0SKevin Wolf if (bs) { 1334f21d96d0SKevin Wolf bdrv_op_unblock_all(bs, reason); 13354be74634SMarkus Armbruster } 1336a46fc9c9SMax Reitz } 13374be74634SMarkus Armbruster 13384be74634SMarkus Armbruster AioContext *blk_get_aio_context(BlockBackend *blk) 13394be74634SMarkus Armbruster { 1340f21d96d0SKevin Wolf BlockDriverState *bs = blk_bs(blk); 1341f21d96d0SKevin Wolf 1342f21d96d0SKevin Wolf if (bs) { 1343f21d96d0SKevin Wolf return bdrv_get_aio_context(bs); 13444981bdecSMax Reitz } else { 13454981bdecSMax Reitz return qemu_get_aio_context(); 13464981bdecSMax Reitz } 13474981bdecSMax Reitz } 13484981bdecSMax Reitz 13494981bdecSMax Reitz static AioContext *blk_aiocb_get_aio_context(BlockAIOCB *acb) 13504981bdecSMax Reitz { 13514981bdecSMax Reitz BlockBackendAIOCB *blk_acb = DO_UPCAST(BlockBackendAIOCB, common, acb); 13524981bdecSMax Reitz return blk_get_aio_context(blk_acb->blk); 13534be74634SMarkus Armbruster } 13544be74634SMarkus Armbruster 13554be74634SMarkus Armbruster void blk_set_aio_context(BlockBackend *blk, AioContext *new_context) 13564be74634SMarkus Armbruster { 1357f21d96d0SKevin Wolf BlockDriverState *bs = blk_bs(blk); 1358f21d96d0SKevin Wolf 1359f21d96d0SKevin Wolf if (bs) { 1360f21d96d0SKevin Wolf bdrv_set_aio_context(bs, new_context); 13614be74634SMarkus Armbruster } 1362a46fc9c9SMax Reitz } 13634be74634SMarkus Armbruster 13642019ba0aSMax Reitz void blk_add_aio_context_notifier(BlockBackend *blk, 13652019ba0aSMax Reitz void (*attached_aio_context)(AioContext *new_context, void *opaque), 13662019ba0aSMax Reitz void (*detach_aio_context)(void *opaque), void *opaque) 13672019ba0aSMax Reitz { 1368f21d96d0SKevin Wolf BlockDriverState *bs = blk_bs(blk); 1369f21d96d0SKevin Wolf 1370f21d96d0SKevin Wolf if (bs) { 1371f21d96d0SKevin Wolf bdrv_add_aio_context_notifier(bs, attached_aio_context, 13722019ba0aSMax Reitz detach_aio_context, opaque); 13732019ba0aSMax Reitz } 1374a46fc9c9SMax Reitz } 13752019ba0aSMax Reitz 13762019ba0aSMax Reitz void blk_remove_aio_context_notifier(BlockBackend *blk, 13772019ba0aSMax Reitz void (*attached_aio_context)(AioContext *, 13782019ba0aSMax Reitz void *), 13792019ba0aSMax Reitz void (*detach_aio_context)(void *), 13802019ba0aSMax Reitz void *opaque) 13812019ba0aSMax Reitz { 1382f21d96d0SKevin Wolf BlockDriverState *bs = blk_bs(blk); 1383f21d96d0SKevin Wolf 1384f21d96d0SKevin Wolf if (bs) { 1385f21d96d0SKevin Wolf bdrv_remove_aio_context_notifier(bs, attached_aio_context, 13862019ba0aSMax Reitz detach_aio_context, opaque); 13872019ba0aSMax Reitz } 1388a46fc9c9SMax Reitz } 13892019ba0aSMax Reitz 13903301f6c6SMax Reitz void blk_add_remove_bs_notifier(BlockBackend *blk, Notifier *notify) 13913301f6c6SMax Reitz { 13923301f6c6SMax Reitz notifier_list_add(&blk->remove_bs_notifiers, notify); 13933301f6c6SMax Reitz } 13943301f6c6SMax Reitz 13953301f6c6SMax Reitz void blk_add_insert_bs_notifier(BlockBackend *blk, Notifier *notify) 13963301f6c6SMax Reitz { 13973301f6c6SMax Reitz notifier_list_add(&blk->insert_bs_notifiers, notify); 13983301f6c6SMax Reitz } 13993301f6c6SMax Reitz 14004be74634SMarkus Armbruster void blk_io_plug(BlockBackend *blk) 14014be74634SMarkus Armbruster { 1402f21d96d0SKevin Wolf BlockDriverState *bs = blk_bs(blk); 1403f21d96d0SKevin Wolf 1404f21d96d0SKevin Wolf if (bs) { 1405f21d96d0SKevin Wolf bdrv_io_plug(bs); 14064be74634SMarkus Armbruster } 1407a46fc9c9SMax Reitz } 14084be74634SMarkus Armbruster 14094be74634SMarkus Armbruster void blk_io_unplug(BlockBackend *blk) 14104be74634SMarkus Armbruster { 1411f21d96d0SKevin Wolf BlockDriverState *bs = blk_bs(blk); 1412f21d96d0SKevin Wolf 1413f21d96d0SKevin Wolf if (bs) { 1414f21d96d0SKevin Wolf bdrv_io_unplug(bs); 14154be74634SMarkus Armbruster } 1416a46fc9c9SMax Reitz } 14174be74634SMarkus Armbruster 14184be74634SMarkus Armbruster BlockAcctStats *blk_get_stats(BlockBackend *blk) 14194be74634SMarkus Armbruster { 14207f0e9da6SMax Reitz return &blk->stats; 14214be74634SMarkus Armbruster } 14224be74634SMarkus Armbruster 14234be74634SMarkus Armbruster void *blk_aio_get(const AIOCBInfo *aiocb_info, BlockBackend *blk, 14244be74634SMarkus Armbruster BlockCompletionFunc *cb, void *opaque) 14254be74634SMarkus Armbruster { 14264be74634SMarkus Armbruster return qemu_aio_get(aiocb_info, blk_bs(blk), cb, opaque); 14274be74634SMarkus Armbruster } 14281ef01253SMax Reitz 1429983a1600SEric Blake int coroutine_fn blk_co_write_zeroes(BlockBackend *blk, int64_t offset, 1430983a1600SEric Blake int count, BdrvRequestFlags flags) 14311ef01253SMax Reitz { 1432983a1600SEric Blake return blk_co_pwritev(blk, offset, count, NULL, 143316aaf975SKevin Wolf flags | BDRV_REQ_ZERO_WRITE); 14341ef01253SMax Reitz } 14351ef01253SMax Reitz 14361ef01253SMax Reitz int blk_write_compressed(BlockBackend *blk, int64_t sector_num, 14371ef01253SMax Reitz const uint8_t *buf, int nb_sectors) 14381ef01253SMax Reitz { 1439e7f7d676SMax Reitz int ret = blk_check_request(blk, sector_num, nb_sectors); 1440e7f7d676SMax Reitz if (ret < 0) { 1441e7f7d676SMax Reitz return ret; 1442e7f7d676SMax Reitz } 1443e7f7d676SMax Reitz 1444f21d96d0SKevin Wolf return bdrv_write_compressed(blk_bs(blk), sector_num, buf, nb_sectors); 14451ef01253SMax Reitz } 14461ef01253SMax Reitz 14471ef01253SMax Reitz int blk_truncate(BlockBackend *blk, int64_t offset) 14481ef01253SMax Reitz { 1449c09ba36cSMax Reitz if (!blk_is_available(blk)) { 1450c09ba36cSMax Reitz return -ENOMEDIUM; 1451c09ba36cSMax Reitz } 1452c09ba36cSMax Reitz 1453f21d96d0SKevin Wolf return bdrv_truncate(blk_bs(blk), offset); 14541ef01253SMax Reitz } 14551ef01253SMax Reitz 14561ef01253SMax Reitz int blk_discard(BlockBackend *blk, int64_t sector_num, int nb_sectors) 14571ef01253SMax Reitz { 1458e7f7d676SMax Reitz int ret = blk_check_request(blk, sector_num, nb_sectors); 1459e7f7d676SMax Reitz if (ret < 0) { 1460e7f7d676SMax Reitz return ret; 1461e7f7d676SMax Reitz } 1462e7f7d676SMax Reitz 1463f21d96d0SKevin Wolf return bdrv_discard(blk_bs(blk), sector_num, nb_sectors); 14641ef01253SMax Reitz } 14651ef01253SMax Reitz 14661ef01253SMax Reitz int blk_save_vmstate(BlockBackend *blk, const uint8_t *buf, 14671ef01253SMax Reitz int64_t pos, int size) 14681ef01253SMax Reitz { 1469bfd18d1eSKevin Wolf int ret; 1470bfd18d1eSKevin Wolf 1471c09ba36cSMax Reitz if (!blk_is_available(blk)) { 1472c09ba36cSMax Reitz return -ENOMEDIUM; 1473c09ba36cSMax Reitz } 1474c09ba36cSMax Reitz 1475bfd18d1eSKevin Wolf ret = bdrv_save_vmstate(blk_bs(blk), buf, pos, size); 1476bfd18d1eSKevin Wolf if (ret < 0) { 1477bfd18d1eSKevin Wolf return ret; 1478bfd18d1eSKevin Wolf } 1479bfd18d1eSKevin Wolf 1480bfd18d1eSKevin Wolf if (ret == size && !blk->enable_write_cache) { 1481bfd18d1eSKevin Wolf ret = bdrv_flush(blk_bs(blk)); 1482bfd18d1eSKevin Wolf } 1483bfd18d1eSKevin Wolf 1484bfd18d1eSKevin Wolf return ret < 0 ? ret : size; 14851ef01253SMax Reitz } 14861ef01253SMax Reitz 14871ef01253SMax Reitz int blk_load_vmstate(BlockBackend *blk, uint8_t *buf, int64_t pos, int size) 14881ef01253SMax Reitz { 1489c09ba36cSMax Reitz if (!blk_is_available(blk)) { 1490c09ba36cSMax Reitz return -ENOMEDIUM; 1491c09ba36cSMax Reitz } 1492c09ba36cSMax Reitz 1493f21d96d0SKevin Wolf return bdrv_load_vmstate(blk_bs(blk), buf, pos, size); 14941ef01253SMax Reitz } 1495f0272c4dSEkaterina Tumanova 1496f0272c4dSEkaterina Tumanova int blk_probe_blocksizes(BlockBackend *blk, BlockSizes *bsz) 1497f0272c4dSEkaterina Tumanova { 1498c09ba36cSMax Reitz if (!blk_is_available(blk)) { 1499c09ba36cSMax Reitz return -ENOMEDIUM; 1500c09ba36cSMax Reitz } 1501c09ba36cSMax Reitz 1502f21d96d0SKevin Wolf return bdrv_probe_blocksizes(blk_bs(blk), bsz); 1503f0272c4dSEkaterina Tumanova } 1504f0272c4dSEkaterina Tumanova 1505f0272c4dSEkaterina Tumanova int blk_probe_geometry(BlockBackend *blk, HDGeometry *geo) 1506f0272c4dSEkaterina Tumanova { 1507c09ba36cSMax Reitz if (!blk_is_available(blk)) { 1508c09ba36cSMax Reitz return -ENOMEDIUM; 1509c09ba36cSMax Reitz } 1510c09ba36cSMax Reitz 1511f21d96d0SKevin Wolf return bdrv_probe_geometry(blk_bs(blk), geo); 1512f0272c4dSEkaterina Tumanova } 1513281d22d8SMax Reitz 1514281d22d8SMax Reitz /* 1515281d22d8SMax Reitz * Updates the BlockBackendRootState object with data from the currently 1516281d22d8SMax Reitz * attached BlockDriverState. 1517281d22d8SMax Reitz */ 1518281d22d8SMax Reitz void blk_update_root_state(BlockBackend *blk) 1519281d22d8SMax Reitz { 1520f21d96d0SKevin Wolf assert(blk->root); 1521281d22d8SMax Reitz 1522f21d96d0SKevin Wolf blk->root_state.open_flags = blk->root->bs->open_flags; 1523f21d96d0SKevin Wolf blk->root_state.read_only = blk->root->bs->read_only; 1524f21d96d0SKevin Wolf blk->root_state.detect_zeroes = blk->root->bs->detect_zeroes; 1525281d22d8SMax Reitz 1526281d22d8SMax Reitz if (blk->root_state.throttle_group) { 1527281d22d8SMax Reitz g_free(blk->root_state.throttle_group); 1528281d22d8SMax Reitz throttle_group_unref(blk->root_state.throttle_state); 1529281d22d8SMax Reitz } 1530*27ccdd52SKevin Wolf if (blk->public.throttle_state) { 153149d2165dSKevin Wolf const char *name = throttle_group_get_name(blk); 1532281d22d8SMax Reitz blk->root_state.throttle_group = g_strdup(name); 1533281d22d8SMax Reitz blk->root_state.throttle_state = throttle_group_incref(name); 1534281d22d8SMax Reitz } else { 1535281d22d8SMax Reitz blk->root_state.throttle_group = NULL; 1536281d22d8SMax Reitz blk->root_state.throttle_state = NULL; 1537281d22d8SMax Reitz } 1538281d22d8SMax Reitz } 1539281d22d8SMax Reitz 154038cb18f5SMax Reitz /* 154138cb18f5SMax Reitz * Applies the information in the root state to the given BlockDriverState. This 154238cb18f5SMax Reitz * does not include the flags which have to be specified for bdrv_open(), use 154338cb18f5SMax Reitz * blk_get_open_flags_from_root_state() to inquire them. 154438cb18f5SMax Reitz */ 154538cb18f5SMax Reitz void blk_apply_root_state(BlockBackend *blk, BlockDriverState *bs) 154638cb18f5SMax Reitz { 154738cb18f5SMax Reitz bs->detect_zeroes = blk->root_state.detect_zeroes; 154838cb18f5SMax Reitz if (blk->root_state.throttle_group) { 154938cb18f5SMax Reitz bdrv_io_limits_enable(bs, blk->root_state.throttle_group); 155038cb18f5SMax Reitz } 155138cb18f5SMax Reitz } 155238cb18f5SMax Reitz 155338cb18f5SMax Reitz /* 155438cb18f5SMax Reitz * Returns the flags to be used for bdrv_open() of a BlockDriverState which is 155538cb18f5SMax Reitz * supposed to inherit the root state. 155638cb18f5SMax Reitz */ 155738cb18f5SMax Reitz int blk_get_open_flags_from_root_state(BlockBackend *blk) 155838cb18f5SMax Reitz { 155938cb18f5SMax Reitz int bs_flags; 156038cb18f5SMax Reitz 156138cb18f5SMax Reitz bs_flags = blk->root_state.read_only ? 0 : BDRV_O_RDWR; 156238cb18f5SMax Reitz bs_flags |= blk->root_state.open_flags & ~BDRV_O_RDWR; 156338cb18f5SMax Reitz 156438cb18f5SMax Reitz return bs_flags; 156538cb18f5SMax Reitz } 156638cb18f5SMax Reitz 1567281d22d8SMax Reitz BlockBackendRootState *blk_get_root_state(BlockBackend *blk) 1568281d22d8SMax Reitz { 1569281d22d8SMax Reitz return &blk->root_state; 1570281d22d8SMax Reitz } 15711393f212SMax Reitz 15721393f212SMax Reitz int blk_commit_all(void) 15731393f212SMax Reitz { 1574fe1a9cbcSMax Reitz BlockBackend *blk = NULL; 1575fe1a9cbcSMax Reitz 1576fe1a9cbcSMax Reitz while ((blk = blk_all_next(blk)) != NULL) { 1577fe1a9cbcSMax Reitz AioContext *aio_context = blk_get_aio_context(blk); 1578fe1a9cbcSMax Reitz 1579fe1a9cbcSMax Reitz aio_context_acquire(aio_context); 1580f21d96d0SKevin Wolf if (blk_is_inserted(blk) && blk->root->bs->backing) { 1581f21d96d0SKevin Wolf int ret = bdrv_commit(blk->root->bs); 1582fe1a9cbcSMax Reitz if (ret < 0) { 1583fe1a9cbcSMax Reitz aio_context_release(aio_context); 1584fe1a9cbcSMax Reitz return ret; 1585fe1a9cbcSMax Reitz } 1586fe1a9cbcSMax Reitz } 1587fe1a9cbcSMax Reitz aio_context_release(aio_context); 1588fe1a9cbcSMax Reitz } 1589fe1a9cbcSMax Reitz return 0; 1590fe1a9cbcSMax Reitz } 1591fe1a9cbcSMax Reitz 1592fe1a9cbcSMax Reitz int blk_flush_all(void) 1593fe1a9cbcSMax Reitz { 1594fe1a9cbcSMax Reitz BlockBackend *blk = NULL; 1595fe1a9cbcSMax Reitz int result = 0; 1596fe1a9cbcSMax Reitz 1597fe1a9cbcSMax Reitz while ((blk = blk_all_next(blk)) != NULL) { 1598fe1a9cbcSMax Reitz AioContext *aio_context = blk_get_aio_context(blk); 1599fe1a9cbcSMax Reitz int ret; 1600fe1a9cbcSMax Reitz 1601fe1a9cbcSMax Reitz aio_context_acquire(aio_context); 1602fe1a9cbcSMax Reitz if (blk_is_inserted(blk)) { 1603fe1a9cbcSMax Reitz ret = blk_flush(blk); 1604fe1a9cbcSMax Reitz if (ret < 0 && !result) { 1605fe1a9cbcSMax Reitz result = ret; 1606fe1a9cbcSMax Reitz } 1607fe1a9cbcSMax Reitz } 1608fe1a9cbcSMax Reitz aio_context_release(aio_context); 1609fe1a9cbcSMax Reitz } 1610fe1a9cbcSMax Reitz 1611fe1a9cbcSMax Reitz return result; 16121393f212SMax Reitz } 1613