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; 11027ccdd52SKevin Wolf qemu_co_queue_init(&blk->public.throttled_reqs[0]); 11127ccdd52SKevin Wolf qemu_co_queue_init(&blk->public.throttled_reqs[1]); 11227ccdd52SKevin Wolf 1133301f6c6SMax Reitz notifier_list_init(&blk->remove_bs_notifiers); 1143301f6c6SMax Reitz notifier_list_init(&blk->insert_bs_notifiers); 11527ccdd52SKevin 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); 136*22aa8b24SKevin Wolf blk->root->opaque = blk; 1377e7d56d9SMarkus Armbruster bs->blk = blk; 1387e7d56d9SMarkus Armbruster return blk; 1397e7d56d9SMarkus Armbruster } 1407e7d56d9SMarkus Armbruster 141ca49a4fdSMax Reitz /* 142ca49a4fdSMax Reitz * Calls blk_new_with_bs() and then calls bdrv_open() on the BlockDriverState. 143ca49a4fdSMax Reitz * 144ca49a4fdSMax Reitz * Just as with bdrv_open(), after having called this function the reference to 145ca49a4fdSMax Reitz * @options belongs to the block layer (even on failure). 146ca49a4fdSMax Reitz * 147ca49a4fdSMax Reitz * TODO: Remove @filename and @flags; it should be possible to specify a whole 148ca49a4fdSMax Reitz * BDS tree just by specifying the @options QDict (or @reference, 149ca49a4fdSMax Reitz * alternatively). At the time of adding this function, this is not possible, 150ca49a4fdSMax Reitz * though, so callers of this function have to be able to specify @filename and 151ca49a4fdSMax Reitz * @flags. 152ca49a4fdSMax Reitz */ 153efaa7c4eSMax Reitz BlockBackend *blk_new_open(const char *filename, const char *reference, 154efaa7c4eSMax Reitz QDict *options, int flags, Error **errp) 155ca49a4fdSMax Reitz { 156ca49a4fdSMax Reitz BlockBackend *blk; 157ca49a4fdSMax Reitz int ret; 158ca49a4fdSMax Reitz 159efaa7c4eSMax Reitz blk = blk_new_with_bs(errp); 160ca49a4fdSMax Reitz if (!blk) { 161ca49a4fdSMax Reitz QDECREF(options); 162ca49a4fdSMax Reitz return NULL; 163ca49a4fdSMax Reitz } 164ca49a4fdSMax Reitz 165f21d96d0SKevin Wolf ret = bdrv_open(&blk->root->bs, filename, reference, options, flags, errp); 166ca49a4fdSMax Reitz if (ret < 0) { 167ca49a4fdSMax Reitz blk_unref(blk); 168ca49a4fdSMax Reitz return NULL; 169ca49a4fdSMax Reitz } 170ca49a4fdSMax Reitz 17172e775c7SKevin Wolf blk_set_enable_write_cache(blk, true); 17272e775c7SKevin Wolf 173ca49a4fdSMax Reitz return blk; 174ca49a4fdSMax Reitz } 175ca49a4fdSMax Reitz 17626f54e9aSMarkus Armbruster static void blk_delete(BlockBackend *blk) 17726f54e9aSMarkus Armbruster { 17826f54e9aSMarkus Armbruster assert(!blk->refcnt); 179e5e78550SMax Reitz assert(!blk->name); 180a7f53e26SMarkus Armbruster assert(!blk->dev); 181f21d96d0SKevin Wolf if (blk->root) { 18213855c6bSMax Reitz blk_remove_bs(blk); 1837e7d56d9SMarkus Armbruster } 1843301f6c6SMax Reitz assert(QLIST_EMPTY(&blk->remove_bs_notifiers.notifiers)); 1853301f6c6SMax Reitz assert(QLIST_EMPTY(&blk->insert_bs_notifiers.notifiers)); 186281d22d8SMax Reitz if (blk->root_state.throttle_state) { 187281d22d8SMax Reitz g_free(blk->root_state.throttle_group); 188281d22d8SMax Reitz throttle_group_unref(blk->root_state.throttle_state); 189281d22d8SMax Reitz } 1902cf22d6aSMax Reitz QTAILQ_REMOVE(&block_backends, blk, link); 19118e46a03SMarkus Armbruster drive_info_del(blk->legacy_dinfo); 192979e9b03SAlberto Garcia block_acct_cleanup(&blk->stats); 19326f54e9aSMarkus Armbruster g_free(blk); 19426f54e9aSMarkus Armbruster } 19526f54e9aSMarkus Armbruster 1968fb3c76cSMarkus Armbruster static void drive_info_del(DriveInfo *dinfo) 1978fb3c76cSMarkus Armbruster { 1988fb3c76cSMarkus Armbruster if (!dinfo) { 1998fb3c76cSMarkus Armbruster return; 2008fb3c76cSMarkus Armbruster } 2018fb3c76cSMarkus Armbruster qemu_opts_del(dinfo->opts); 2028fb3c76cSMarkus Armbruster g_free(dinfo->serial); 2038fb3c76cSMarkus Armbruster g_free(dinfo); 2048fb3c76cSMarkus Armbruster } 2058fb3c76cSMarkus Armbruster 206f636ae85SAlberto Garcia int blk_get_refcnt(BlockBackend *blk) 207f636ae85SAlberto Garcia { 208f636ae85SAlberto Garcia return blk ? blk->refcnt : 0; 209f636ae85SAlberto Garcia } 210f636ae85SAlberto Garcia 21126f54e9aSMarkus Armbruster /* 21226f54e9aSMarkus Armbruster * Increment @blk's reference count. 21326f54e9aSMarkus Armbruster * @blk must not be null. 21426f54e9aSMarkus Armbruster */ 21526f54e9aSMarkus Armbruster void blk_ref(BlockBackend *blk) 21626f54e9aSMarkus Armbruster { 21726f54e9aSMarkus Armbruster blk->refcnt++; 21826f54e9aSMarkus Armbruster } 21926f54e9aSMarkus Armbruster 22026f54e9aSMarkus Armbruster /* 22126f54e9aSMarkus Armbruster * Decrement @blk's reference count. 22226f54e9aSMarkus Armbruster * If this drops it to zero, destroy @blk. 22326f54e9aSMarkus Armbruster * For convenience, do nothing if @blk is null. 22426f54e9aSMarkus Armbruster */ 22526f54e9aSMarkus Armbruster void blk_unref(BlockBackend *blk) 22626f54e9aSMarkus Armbruster { 22726f54e9aSMarkus Armbruster if (blk) { 22826f54e9aSMarkus Armbruster assert(blk->refcnt > 0); 22926f54e9aSMarkus Armbruster if (!--blk->refcnt) { 23026f54e9aSMarkus Armbruster blk_delete(blk); 23126f54e9aSMarkus Armbruster } 23226f54e9aSMarkus Armbruster } 23326f54e9aSMarkus Armbruster } 23426f54e9aSMarkus Armbruster 2352cf22d6aSMax Reitz /* 2362cf22d6aSMax Reitz * Behaves similarly to blk_next() but iterates over all BlockBackends, even the 2372cf22d6aSMax Reitz * ones which are hidden (i.e. are not referenced by the monitor). 2382cf22d6aSMax Reitz */ 2392cf22d6aSMax Reitz static BlockBackend *blk_all_next(BlockBackend *blk) 2402cf22d6aSMax Reitz { 2412cf22d6aSMax Reitz return blk ? QTAILQ_NEXT(blk, link) 2422cf22d6aSMax Reitz : QTAILQ_FIRST(&block_backends); 2432cf22d6aSMax Reitz } 2442cf22d6aSMax Reitz 245d8da3cefSMax Reitz void blk_remove_all_bs(void) 246d8da3cefSMax Reitz { 24774d1b8fcSMax Reitz BlockBackend *blk = NULL; 248d8da3cefSMax Reitz 2492cf22d6aSMax Reitz while ((blk = blk_all_next(blk)) != NULL) { 250d8da3cefSMax Reitz AioContext *ctx = blk_get_aio_context(blk); 251d8da3cefSMax Reitz 252d8da3cefSMax Reitz aio_context_acquire(ctx); 253f21d96d0SKevin Wolf if (blk->root) { 254d8da3cefSMax Reitz blk_remove_bs(blk); 255d8da3cefSMax Reitz } 256d8da3cefSMax Reitz aio_context_release(ctx); 257d8da3cefSMax Reitz } 258d8da3cefSMax Reitz } 259d8da3cefSMax Reitz 26026f54e9aSMarkus Armbruster /* 2619492b0b9SMax Reitz * Return the monitor-owned BlockBackend after @blk. 26226f54e9aSMarkus Armbruster * If @blk is null, return the first one. 26326f54e9aSMarkus Armbruster * Else, return @blk's next sibling, which may be null. 26426f54e9aSMarkus Armbruster * 26526f54e9aSMarkus Armbruster * To iterate over all BlockBackends, do 26626f54e9aSMarkus Armbruster * for (blk = blk_next(NULL); blk; blk = blk_next(blk)) { 26726f54e9aSMarkus Armbruster * ... 26826f54e9aSMarkus Armbruster * } 26926f54e9aSMarkus Armbruster */ 27026f54e9aSMarkus Armbruster BlockBackend *blk_next(BlockBackend *blk) 27126f54e9aSMarkus Armbruster { 2729492b0b9SMax Reitz return blk ? QTAILQ_NEXT(blk, monitor_link) 2739492b0b9SMax Reitz : QTAILQ_FIRST(&monitor_block_backends); 27426f54e9aSMarkus Armbruster } 27526f54e9aSMarkus Armbruster 27626f54e9aSMarkus Armbruster /* 277981f4f57SMax Reitz * Iterates over all BlockDriverStates which are attached to a BlockBackend. 278981f4f57SMax Reitz * This function is for use by bdrv_next(). 279981f4f57SMax Reitz * 280981f4f57SMax Reitz * @bs must be NULL or a BDS that is attached to a BB. 281981f4f57SMax Reitz */ 282981f4f57SMax Reitz BlockDriverState *blk_next_root_bs(BlockDriverState *bs) 283981f4f57SMax Reitz { 284981f4f57SMax Reitz BlockBackend *blk; 285981f4f57SMax Reitz 286981f4f57SMax Reitz if (bs) { 287981f4f57SMax Reitz assert(bs->blk); 288981f4f57SMax Reitz blk = bs->blk; 289981f4f57SMax Reitz } else { 290981f4f57SMax Reitz blk = NULL; 291981f4f57SMax Reitz } 292981f4f57SMax Reitz 293981f4f57SMax Reitz do { 294981f4f57SMax Reitz blk = blk_all_next(blk); 295f21d96d0SKevin Wolf } while (blk && !blk->root); 296981f4f57SMax Reitz 297f21d96d0SKevin Wolf return blk ? blk->root->bs : NULL; 298981f4f57SMax Reitz } 299981f4f57SMax Reitz 300981f4f57SMax Reitz /* 301e5e78550SMax Reitz * Add a BlockBackend into the list of backends referenced by the monitor, with 302e5e78550SMax Reitz * the given @name acting as the handle for the monitor. 303e5e78550SMax Reitz * Strictly for use by blockdev.c. 304e5e78550SMax Reitz * 305e5e78550SMax Reitz * @name must not be null or empty. 306e5e78550SMax Reitz * 307e5e78550SMax Reitz * Returns true on success and false on failure. In the latter case, an Error 308e5e78550SMax Reitz * object is returned through @errp. 309e5e78550SMax Reitz */ 310e5e78550SMax Reitz bool monitor_add_blk(BlockBackend *blk, const char *name, Error **errp) 311e5e78550SMax Reitz { 312e5e78550SMax Reitz assert(!blk->name); 313e5e78550SMax Reitz assert(name && name[0]); 314e5e78550SMax Reitz 315e5e78550SMax Reitz if (!id_wellformed(name)) { 316e5e78550SMax Reitz error_setg(errp, "Invalid device name"); 317e5e78550SMax Reitz return false; 318e5e78550SMax Reitz } 319e5e78550SMax Reitz if (blk_by_name(name)) { 320e5e78550SMax Reitz error_setg(errp, "Device with id '%s' already exists", name); 321e5e78550SMax Reitz return false; 322e5e78550SMax Reitz } 323e5e78550SMax Reitz if (bdrv_find_node(name)) { 324e5e78550SMax Reitz error_setg(errp, 325e5e78550SMax Reitz "Device name '%s' conflicts with an existing node name", 326e5e78550SMax Reitz name); 327e5e78550SMax Reitz return false; 328e5e78550SMax Reitz } 329e5e78550SMax Reitz 330e5e78550SMax Reitz blk->name = g_strdup(name); 331e5e78550SMax Reitz QTAILQ_INSERT_TAIL(&monitor_block_backends, blk, monitor_link); 332e5e78550SMax Reitz return true; 333e5e78550SMax Reitz } 334e5e78550SMax Reitz 335e5e78550SMax Reitz /* 336e5e78550SMax Reitz * Remove a BlockBackend from the list of backends referenced by the monitor. 337e5e78550SMax Reitz * Strictly for use by blockdev.c. 338e5e78550SMax Reitz */ 339e5e78550SMax Reitz void monitor_remove_blk(BlockBackend *blk) 340e5e78550SMax Reitz { 341e5e78550SMax Reitz if (!blk->name) { 342e5e78550SMax Reitz return; 343e5e78550SMax Reitz } 344e5e78550SMax Reitz 345e5e78550SMax Reitz QTAILQ_REMOVE(&monitor_block_backends, blk, monitor_link); 346e5e78550SMax Reitz g_free(blk->name); 347e5e78550SMax Reitz blk->name = NULL; 348e5e78550SMax Reitz } 349e5e78550SMax Reitz 350e5e78550SMax Reitz /* 3517e7d56d9SMarkus Armbruster * Return @blk's name, a non-null string. 352e5e78550SMax Reitz * Returns an empty string iff @blk is not referenced by the monitor. 35326f54e9aSMarkus Armbruster */ 35426f54e9aSMarkus Armbruster const char *blk_name(BlockBackend *blk) 35526f54e9aSMarkus Armbruster { 356e5e78550SMax Reitz return blk->name ?: ""; 35726f54e9aSMarkus Armbruster } 35826f54e9aSMarkus Armbruster 35926f54e9aSMarkus Armbruster /* 36026f54e9aSMarkus Armbruster * Return the BlockBackend with name @name if it exists, else null. 36126f54e9aSMarkus Armbruster * @name must not be null. 36226f54e9aSMarkus Armbruster */ 36326f54e9aSMarkus Armbruster BlockBackend *blk_by_name(const char *name) 36426f54e9aSMarkus Armbruster { 36574d1b8fcSMax Reitz BlockBackend *blk = NULL; 36626f54e9aSMarkus Armbruster 36726f54e9aSMarkus Armbruster assert(name); 36874d1b8fcSMax Reitz while ((blk = blk_next(blk)) != NULL) { 36926f54e9aSMarkus Armbruster if (!strcmp(name, blk->name)) { 37026f54e9aSMarkus Armbruster return blk; 37126f54e9aSMarkus Armbruster } 37226f54e9aSMarkus Armbruster } 37326f54e9aSMarkus Armbruster return NULL; 37426f54e9aSMarkus Armbruster } 3757e7d56d9SMarkus Armbruster 3767e7d56d9SMarkus Armbruster /* 3777e7d56d9SMarkus Armbruster * Return the BlockDriverState attached to @blk if any, else null. 3787e7d56d9SMarkus Armbruster */ 3797e7d56d9SMarkus Armbruster BlockDriverState *blk_bs(BlockBackend *blk) 3807e7d56d9SMarkus Armbruster { 381f21d96d0SKevin Wolf return blk->root ? blk->root->bs : NULL; 3827e7d56d9SMarkus Armbruster } 3837e7d56d9SMarkus Armbruster 3847e7d56d9SMarkus Armbruster /* 38518e46a03SMarkus Armbruster * Return @blk's DriveInfo if any, else null. 38618e46a03SMarkus Armbruster */ 38718e46a03SMarkus Armbruster DriveInfo *blk_legacy_dinfo(BlockBackend *blk) 38818e46a03SMarkus Armbruster { 38918e46a03SMarkus Armbruster return blk->legacy_dinfo; 39018e46a03SMarkus Armbruster } 39118e46a03SMarkus Armbruster 39218e46a03SMarkus Armbruster /* 39318e46a03SMarkus Armbruster * Set @blk's DriveInfo to @dinfo, and return it. 39418e46a03SMarkus Armbruster * @blk must not have a DriveInfo set already. 39518e46a03SMarkus Armbruster * No other BlockBackend may have the same DriveInfo set. 39618e46a03SMarkus Armbruster */ 39718e46a03SMarkus Armbruster DriveInfo *blk_set_legacy_dinfo(BlockBackend *blk, DriveInfo *dinfo) 39818e46a03SMarkus Armbruster { 39918e46a03SMarkus Armbruster assert(!blk->legacy_dinfo); 40018e46a03SMarkus Armbruster return blk->legacy_dinfo = dinfo; 40118e46a03SMarkus Armbruster } 40218e46a03SMarkus Armbruster 40318e46a03SMarkus Armbruster /* 40418e46a03SMarkus Armbruster * Return the BlockBackend with DriveInfo @dinfo. 40518e46a03SMarkus Armbruster * It must exist. 40618e46a03SMarkus Armbruster */ 40718e46a03SMarkus Armbruster BlockBackend *blk_by_legacy_dinfo(DriveInfo *dinfo) 40818e46a03SMarkus Armbruster { 40974d1b8fcSMax Reitz BlockBackend *blk = NULL; 41018e46a03SMarkus Armbruster 41174d1b8fcSMax Reitz while ((blk = blk_next(blk)) != NULL) { 41218e46a03SMarkus Armbruster if (blk->legacy_dinfo == dinfo) { 41318e46a03SMarkus Armbruster return blk; 41418e46a03SMarkus Armbruster } 41518e46a03SMarkus Armbruster } 41618e46a03SMarkus Armbruster abort(); 41718e46a03SMarkus Armbruster } 41818e46a03SMarkus Armbruster 41918e46a03SMarkus Armbruster /* 420f2cd875dSKevin Wolf * Returns a pointer to the publicly accessible fields of @blk. 421f2cd875dSKevin Wolf */ 422f2cd875dSKevin Wolf BlockBackendPublic *blk_get_public(BlockBackend *blk) 423f2cd875dSKevin Wolf { 424f2cd875dSKevin Wolf return &blk->public; 425f2cd875dSKevin Wolf } 426f2cd875dSKevin Wolf 427f2cd875dSKevin Wolf /* 428f2cd875dSKevin Wolf * Returns a BlockBackend given the associated @public fields. 429f2cd875dSKevin Wolf */ 430f2cd875dSKevin Wolf BlockBackend *blk_by_public(BlockBackendPublic *public) 431f2cd875dSKevin Wolf { 432f2cd875dSKevin Wolf return container_of(public, BlockBackend, public); 433f2cd875dSKevin Wolf } 434f2cd875dSKevin Wolf 435f2cd875dSKevin Wolf /* 4361c95f7e1SMax Reitz * Disassociates the currently associated BlockDriverState from @blk. 4371c95f7e1SMax Reitz */ 4381c95f7e1SMax Reitz void blk_remove_bs(BlockBackend *blk) 4391c95f7e1SMax Reitz { 440f21d96d0SKevin Wolf assert(blk->root->bs->blk == blk); 44113855c6bSMax Reitz 4423301f6c6SMax Reitz notifier_list_notify(&blk->remove_bs_notifiers, blk); 4433301f6c6SMax Reitz 4441c95f7e1SMax Reitz blk_update_root_state(blk); 44527ccdd52SKevin Wolf if (blk->public.throttle_state) { 44697148076SKevin Wolf blk_io_limits_disable(blk); 447a5614993SKevin Wolf } 4481c95f7e1SMax Reitz 449f21d96d0SKevin Wolf blk->root->bs->blk = NULL; 450f21d96d0SKevin Wolf bdrv_root_unref_child(blk->root); 451f21d96d0SKevin Wolf blk->root = NULL; 4521c95f7e1SMax Reitz } 4531c95f7e1SMax Reitz 4541c95f7e1SMax Reitz /* 4550c3c36d6SMax Reitz * Associates a new BlockDriverState with @blk. 4560c3c36d6SMax Reitz */ 4570c3c36d6SMax Reitz void blk_insert_bs(BlockBackend *blk, BlockDriverState *bs) 4580c3c36d6SMax Reitz { 459f21d96d0SKevin Wolf assert(!blk->root && !bs->blk); 4600c3c36d6SMax Reitz bdrv_ref(bs); 461f21d96d0SKevin Wolf blk->root = bdrv_root_attach_child(bs, "root", &child_root); 462*22aa8b24SKevin Wolf blk->root->opaque = blk; 4630c3c36d6SMax Reitz bs->blk = blk; 4643301f6c6SMax Reitz 4653301f6c6SMax Reitz notifier_list_notify(&blk->insert_bs_notifiers, blk); 4660c3c36d6SMax Reitz } 4670c3c36d6SMax Reitz 4680c3c36d6SMax Reitz /* 469a7f53e26SMarkus Armbruster * Attach device model @dev to @blk. 470a7f53e26SMarkus Armbruster * Return 0 on success, -EBUSY when a device model is attached already. 471a7f53e26SMarkus Armbruster */ 472a7f53e26SMarkus Armbruster int blk_attach_dev(BlockBackend *blk, void *dev) 473a7f53e26SMarkus Armbruster /* TODO change to DeviceState *dev when all users are qdevified */ 474a7f53e26SMarkus Armbruster { 475a7f53e26SMarkus Armbruster if (blk->dev) { 476a7f53e26SMarkus Armbruster return -EBUSY; 477a7f53e26SMarkus Armbruster } 47884ebe375SMarkus Armbruster blk_ref(blk); 479a7f53e26SMarkus Armbruster blk->dev = dev; 480373340b2SMax Reitz blk_iostatus_reset(blk); 481a7f53e26SMarkus Armbruster return 0; 482a7f53e26SMarkus Armbruster } 483a7f53e26SMarkus Armbruster 484a7f53e26SMarkus Armbruster /* 485a7f53e26SMarkus Armbruster * Attach device model @dev to @blk. 486a7f53e26SMarkus Armbruster * @blk must not have a device model attached already. 487a7f53e26SMarkus Armbruster * TODO qdevified devices don't use this, remove when devices are qdevified 488a7f53e26SMarkus Armbruster */ 489a7f53e26SMarkus Armbruster void blk_attach_dev_nofail(BlockBackend *blk, void *dev) 490a7f53e26SMarkus Armbruster { 491a7f53e26SMarkus Armbruster if (blk_attach_dev(blk, dev) < 0) { 492a7f53e26SMarkus Armbruster abort(); 493a7f53e26SMarkus Armbruster } 494a7f53e26SMarkus Armbruster } 495a7f53e26SMarkus Armbruster 496a7f53e26SMarkus Armbruster /* 497a7f53e26SMarkus Armbruster * Detach device model @dev from @blk. 498a7f53e26SMarkus Armbruster * @dev must be currently attached to @blk. 499a7f53e26SMarkus Armbruster */ 500a7f53e26SMarkus Armbruster void blk_detach_dev(BlockBackend *blk, void *dev) 501a7f53e26SMarkus Armbruster /* TODO change to DeviceState *dev when all users are qdevified */ 502a7f53e26SMarkus Armbruster { 503a7f53e26SMarkus Armbruster assert(blk->dev == dev); 504a7f53e26SMarkus Armbruster blk->dev = NULL; 505a7f53e26SMarkus Armbruster blk->dev_ops = NULL; 506a7f53e26SMarkus Armbruster blk->dev_opaque = NULL; 50768e9ec01SMax Reitz blk->guest_block_size = 512; 50884ebe375SMarkus Armbruster blk_unref(blk); 509a7f53e26SMarkus Armbruster } 510a7f53e26SMarkus Armbruster 511a7f53e26SMarkus Armbruster /* 512a7f53e26SMarkus Armbruster * Return the device model attached to @blk if any, else null. 513a7f53e26SMarkus Armbruster */ 514a7f53e26SMarkus Armbruster void *blk_get_attached_dev(BlockBackend *blk) 515a7f53e26SMarkus Armbruster /* TODO change to return DeviceState * when all users are qdevified */ 516a7f53e26SMarkus Armbruster { 517a7f53e26SMarkus Armbruster return blk->dev; 518a7f53e26SMarkus Armbruster } 519a7f53e26SMarkus Armbruster 520a7f53e26SMarkus Armbruster /* 521a7f53e26SMarkus Armbruster * Set @blk's device model callbacks to @ops. 522a7f53e26SMarkus Armbruster * @opaque is the opaque argument to pass to the callbacks. 523a7f53e26SMarkus Armbruster * This is for use by device models. 524a7f53e26SMarkus Armbruster */ 525a7f53e26SMarkus Armbruster void blk_set_dev_ops(BlockBackend *blk, const BlockDevOps *ops, 526a7f53e26SMarkus Armbruster void *opaque) 527a7f53e26SMarkus Armbruster { 528a7f53e26SMarkus Armbruster blk->dev_ops = ops; 529a7f53e26SMarkus Armbruster blk->dev_opaque = opaque; 530a7f53e26SMarkus Armbruster } 531a7f53e26SMarkus Armbruster 532a7f53e26SMarkus Armbruster /* 533a7f53e26SMarkus Armbruster * Notify @blk's attached device model of media change. 534a7f53e26SMarkus Armbruster * If @load is true, notify of media load. 535a7f53e26SMarkus Armbruster * Else, notify of media eject. 536a7f53e26SMarkus Armbruster * Also send DEVICE_TRAY_MOVED events as appropriate. 537a7f53e26SMarkus Armbruster */ 538a7f53e26SMarkus Armbruster void blk_dev_change_media_cb(BlockBackend *blk, bool load) 539a7f53e26SMarkus Armbruster { 540a7f53e26SMarkus Armbruster if (blk->dev_ops && blk->dev_ops->change_media_cb) { 541f1f57066SMax Reitz bool tray_was_open, tray_is_open; 542a7f53e26SMarkus Armbruster 543f1f57066SMax Reitz tray_was_open = blk_dev_is_tray_open(blk); 544a7f53e26SMarkus Armbruster blk->dev_ops->change_media_cb(blk->dev_opaque, load); 545f1f57066SMax Reitz tray_is_open = blk_dev_is_tray_open(blk); 546f1f57066SMax Reitz 547f1f57066SMax Reitz if (tray_was_open != tray_is_open) { 548f1f57066SMax Reitz qapi_event_send_device_tray_moved(blk_name(blk), tray_is_open, 549f1f57066SMax Reitz &error_abort); 550a7f53e26SMarkus Armbruster } 551a7f53e26SMarkus Armbruster } 552a7f53e26SMarkus Armbruster } 553a7f53e26SMarkus Armbruster 554a7f53e26SMarkus Armbruster /* 555a7f53e26SMarkus Armbruster * Does @blk's attached device model have removable media? 556a7f53e26SMarkus Armbruster * %true if no device model is attached. 557a7f53e26SMarkus Armbruster */ 558a7f53e26SMarkus Armbruster bool blk_dev_has_removable_media(BlockBackend *blk) 559a7f53e26SMarkus Armbruster { 560a7f53e26SMarkus Armbruster return !blk->dev || (blk->dev_ops && blk->dev_ops->change_media_cb); 561a7f53e26SMarkus Armbruster } 562a7f53e26SMarkus Armbruster 563a7f53e26SMarkus Armbruster /* 5648f3a73bcSMax Reitz * Does @blk's attached device model have a tray? 5658f3a73bcSMax Reitz */ 5668f3a73bcSMax Reitz bool blk_dev_has_tray(BlockBackend *blk) 5678f3a73bcSMax Reitz { 5688f3a73bcSMax Reitz return blk->dev_ops && blk->dev_ops->is_tray_open; 5698f3a73bcSMax Reitz } 5708f3a73bcSMax Reitz 5718f3a73bcSMax Reitz /* 572a7f53e26SMarkus Armbruster * Notify @blk's attached device model of a media eject request. 573a7f53e26SMarkus Armbruster * If @force is true, the medium is about to be yanked out forcefully. 574a7f53e26SMarkus Armbruster */ 575a7f53e26SMarkus Armbruster void blk_dev_eject_request(BlockBackend *blk, bool force) 576a7f53e26SMarkus Armbruster { 577a7f53e26SMarkus Armbruster if (blk->dev_ops && blk->dev_ops->eject_request_cb) { 578a7f53e26SMarkus Armbruster blk->dev_ops->eject_request_cb(blk->dev_opaque, force); 579a7f53e26SMarkus Armbruster } 580a7f53e26SMarkus Armbruster } 581a7f53e26SMarkus Armbruster 582a7f53e26SMarkus Armbruster /* 583a7f53e26SMarkus Armbruster * Does @blk's attached device model have a tray, and is it open? 584a7f53e26SMarkus Armbruster */ 585a7f53e26SMarkus Armbruster bool blk_dev_is_tray_open(BlockBackend *blk) 586a7f53e26SMarkus Armbruster { 5878f3a73bcSMax Reitz if (blk_dev_has_tray(blk)) { 588a7f53e26SMarkus Armbruster return blk->dev_ops->is_tray_open(blk->dev_opaque); 589a7f53e26SMarkus Armbruster } 590a7f53e26SMarkus Armbruster return false; 591a7f53e26SMarkus Armbruster } 592a7f53e26SMarkus Armbruster 593a7f53e26SMarkus Armbruster /* 594a7f53e26SMarkus Armbruster * Does @blk's attached device model have the medium locked? 595a7f53e26SMarkus Armbruster * %false if the device model has no such lock. 596a7f53e26SMarkus Armbruster */ 597a7f53e26SMarkus Armbruster bool blk_dev_is_medium_locked(BlockBackend *blk) 598a7f53e26SMarkus Armbruster { 599a7f53e26SMarkus Armbruster if (blk->dev_ops && blk->dev_ops->is_medium_locked) { 600a7f53e26SMarkus Armbruster return blk->dev_ops->is_medium_locked(blk->dev_opaque); 601a7f53e26SMarkus Armbruster } 602a7f53e26SMarkus Armbruster return false; 603a7f53e26SMarkus Armbruster } 604a7f53e26SMarkus Armbruster 605a7f53e26SMarkus Armbruster /* 606a7f53e26SMarkus Armbruster * Notify @blk's attached device model of a backend size change. 607a7f53e26SMarkus Armbruster */ 608a7f53e26SMarkus Armbruster void blk_dev_resize_cb(BlockBackend *blk) 609a7f53e26SMarkus Armbruster { 610a7f53e26SMarkus Armbruster if (blk->dev_ops && blk->dev_ops->resize_cb) { 611a7f53e26SMarkus Armbruster blk->dev_ops->resize_cb(blk->dev_opaque); 612a7f53e26SMarkus Armbruster } 613a7f53e26SMarkus Armbruster } 614a7f53e26SMarkus Armbruster 6154be74634SMarkus Armbruster void blk_iostatus_enable(BlockBackend *blk) 6164be74634SMarkus Armbruster { 617373340b2SMax Reitz blk->iostatus_enabled = true; 618373340b2SMax Reitz blk->iostatus = BLOCK_DEVICE_IO_STATUS_OK; 619373340b2SMax Reitz } 620373340b2SMax Reitz 621373340b2SMax Reitz /* The I/O status is only enabled if the drive explicitly 622373340b2SMax Reitz * enables it _and_ the VM is configured to stop on errors */ 623373340b2SMax Reitz bool blk_iostatus_is_enabled(const BlockBackend *blk) 624373340b2SMax Reitz { 625373340b2SMax Reitz return (blk->iostatus_enabled && 626373340b2SMax Reitz (blk->on_write_error == BLOCKDEV_ON_ERROR_ENOSPC || 627373340b2SMax Reitz blk->on_write_error == BLOCKDEV_ON_ERROR_STOP || 628373340b2SMax Reitz blk->on_read_error == BLOCKDEV_ON_ERROR_STOP)); 629373340b2SMax Reitz } 630373340b2SMax Reitz 631373340b2SMax Reitz BlockDeviceIoStatus blk_iostatus(const BlockBackend *blk) 632373340b2SMax Reitz { 633373340b2SMax Reitz return blk->iostatus; 634373340b2SMax Reitz } 635373340b2SMax Reitz 636373340b2SMax Reitz void blk_iostatus_disable(BlockBackend *blk) 637373340b2SMax Reitz { 638373340b2SMax Reitz blk->iostatus_enabled = false; 639373340b2SMax Reitz } 640373340b2SMax Reitz 641373340b2SMax Reitz void blk_iostatus_reset(BlockBackend *blk) 642373340b2SMax Reitz { 643373340b2SMax Reitz if (blk_iostatus_is_enabled(blk)) { 644f21d96d0SKevin Wolf BlockDriverState *bs = blk_bs(blk); 645373340b2SMax Reitz blk->iostatus = BLOCK_DEVICE_IO_STATUS_OK; 646f21d96d0SKevin Wolf if (bs && bs->job) { 647f21d96d0SKevin Wolf block_job_iostatus_reset(bs->job); 648373340b2SMax Reitz } 649373340b2SMax Reitz } 650373340b2SMax Reitz } 651373340b2SMax Reitz 652373340b2SMax Reitz void blk_iostatus_set_err(BlockBackend *blk, int error) 653373340b2SMax Reitz { 654373340b2SMax Reitz assert(blk_iostatus_is_enabled(blk)); 655373340b2SMax Reitz if (blk->iostatus == BLOCK_DEVICE_IO_STATUS_OK) { 656373340b2SMax Reitz blk->iostatus = error == ENOSPC ? BLOCK_DEVICE_IO_STATUS_NOSPACE : 657373340b2SMax Reitz BLOCK_DEVICE_IO_STATUS_FAILED; 658373340b2SMax Reitz } 6594be74634SMarkus Armbruster } 6604be74634SMarkus Armbruster 661c10c9d96SKevin Wolf void blk_set_allow_write_beyond_eof(BlockBackend *blk, bool allow) 662c10c9d96SKevin Wolf { 663c10c9d96SKevin Wolf blk->allow_write_beyond_eof = allow; 664c10c9d96SKevin Wolf } 665c10c9d96SKevin Wolf 666e7f7d676SMax Reitz static int blk_check_byte_request(BlockBackend *blk, int64_t offset, 667e7f7d676SMax Reitz size_t size) 668e7f7d676SMax Reitz { 669e7f7d676SMax Reitz int64_t len; 670e7f7d676SMax Reitz 671e7f7d676SMax Reitz if (size > INT_MAX) { 672e7f7d676SMax Reitz return -EIO; 673e7f7d676SMax Reitz } 674e7f7d676SMax Reitz 675c09ba36cSMax Reitz if (!blk_is_available(blk)) { 676e7f7d676SMax Reitz return -ENOMEDIUM; 677e7f7d676SMax Reitz } 678e7f7d676SMax Reitz 679c10c9d96SKevin Wolf if (offset < 0) { 680c10c9d96SKevin Wolf return -EIO; 681c10c9d96SKevin Wolf } 682c10c9d96SKevin Wolf 683c10c9d96SKevin Wolf if (!blk->allow_write_beyond_eof) { 684e7f7d676SMax Reitz len = blk_getlength(blk); 685e7f7d676SMax Reitz if (len < 0) { 686e7f7d676SMax Reitz return len; 687e7f7d676SMax Reitz } 688e7f7d676SMax Reitz 689e7f7d676SMax Reitz if (offset > len || len - offset < size) { 690e7f7d676SMax Reitz return -EIO; 691e7f7d676SMax Reitz } 692c10c9d96SKevin Wolf } 693e7f7d676SMax Reitz 694e7f7d676SMax Reitz return 0; 695e7f7d676SMax Reitz } 696e7f7d676SMax Reitz 697e7f7d676SMax Reitz static int blk_check_request(BlockBackend *blk, int64_t sector_num, 698e7f7d676SMax Reitz int nb_sectors) 699e7f7d676SMax Reitz { 700e7f7d676SMax Reitz if (sector_num < 0 || sector_num > INT64_MAX / BDRV_SECTOR_SIZE) { 701e7f7d676SMax Reitz return -EIO; 702e7f7d676SMax Reitz } 703e7f7d676SMax Reitz 704e7f7d676SMax Reitz if (nb_sectors < 0 || nb_sectors > INT_MAX / BDRV_SECTOR_SIZE) { 705e7f7d676SMax Reitz return -EIO; 706e7f7d676SMax Reitz } 707e7f7d676SMax Reitz 708e7f7d676SMax Reitz return blk_check_byte_request(blk, sector_num * BDRV_SECTOR_SIZE, 709e7f7d676SMax Reitz nb_sectors * BDRV_SECTOR_SIZE); 710e7f7d676SMax Reitz } 711e7f7d676SMax Reitz 7121bf1cbc9SKevin Wolf static int coroutine_fn blk_co_preadv(BlockBackend *blk, int64_t offset, 7131bf1cbc9SKevin Wolf unsigned int bytes, QEMUIOVector *qiov, 7141bf1cbc9SKevin Wolf BdrvRequestFlags flags) 7154be74634SMarkus Armbruster { 7161bf1cbc9SKevin Wolf int ret = blk_check_byte_request(blk, offset, bytes); 717e7f7d676SMax Reitz if (ret < 0) { 718e7f7d676SMax Reitz return ret; 719e7f7d676SMax Reitz } 720e7f7d676SMax Reitz 721441565b2SKevin Wolf /* throttling disk I/O */ 722441565b2SKevin Wolf if (blk->public.throttle_state) { 723441565b2SKevin Wolf throttle_group_co_io_limits_intercept(blk, bytes, false); 724441565b2SKevin Wolf } 725441565b2SKevin Wolf 726cab3a356SKevin Wolf return bdrv_co_preadv(blk_bs(blk), offset, bytes, qiov, flags); 7271bf1cbc9SKevin Wolf } 7281bf1cbc9SKevin Wolf 729a8823a3bSKevin Wolf static int coroutine_fn blk_co_pwritev(BlockBackend *blk, int64_t offset, 730a8823a3bSKevin Wolf unsigned int bytes, QEMUIOVector *qiov, 731a8823a3bSKevin Wolf BdrvRequestFlags flags) 732a8823a3bSKevin Wolf { 733bfd18d1eSKevin Wolf int ret; 734bfd18d1eSKevin Wolf 735bfd18d1eSKevin Wolf ret = blk_check_byte_request(blk, offset, bytes); 736a8823a3bSKevin Wolf if (ret < 0) { 737a8823a3bSKevin Wolf return ret; 738a8823a3bSKevin Wolf } 739a8823a3bSKevin Wolf 740441565b2SKevin Wolf /* throttling disk I/O */ 741441565b2SKevin Wolf if (blk->public.throttle_state) { 742441565b2SKevin Wolf throttle_group_co_io_limits_intercept(blk, bytes, true); 743441565b2SKevin Wolf } 744441565b2SKevin Wolf 745bfd18d1eSKevin Wolf if (!blk->enable_write_cache) { 746bfd18d1eSKevin Wolf flags |= BDRV_REQ_FUA; 747bfd18d1eSKevin Wolf } 748bfd18d1eSKevin Wolf 749cab3a356SKevin Wolf return bdrv_co_pwritev(blk_bs(blk), offset, bytes, qiov, flags); 750a8823a3bSKevin Wolf } 751a8823a3bSKevin Wolf 7521bf1cbc9SKevin Wolf typedef struct BlkRwCo { 7531bf1cbc9SKevin Wolf BlockBackend *blk; 7541bf1cbc9SKevin Wolf int64_t offset; 7551bf1cbc9SKevin Wolf QEMUIOVector *qiov; 7561bf1cbc9SKevin Wolf int ret; 7571bf1cbc9SKevin Wolf BdrvRequestFlags flags; 7581bf1cbc9SKevin Wolf } BlkRwCo; 7591bf1cbc9SKevin Wolf 7601bf1cbc9SKevin Wolf static void blk_read_entry(void *opaque) 7611bf1cbc9SKevin Wolf { 7621bf1cbc9SKevin Wolf BlkRwCo *rwco = opaque; 7631bf1cbc9SKevin Wolf 7641bf1cbc9SKevin Wolf rwco->ret = blk_co_preadv(rwco->blk, rwco->offset, rwco->qiov->size, 7651bf1cbc9SKevin Wolf rwco->qiov, rwco->flags); 7661bf1cbc9SKevin Wolf } 7671bf1cbc9SKevin Wolf 768a8823a3bSKevin Wolf static void blk_write_entry(void *opaque) 769a8823a3bSKevin Wolf { 770a8823a3bSKevin Wolf BlkRwCo *rwco = opaque; 771a8823a3bSKevin Wolf 772a8823a3bSKevin Wolf rwco->ret = blk_co_pwritev(rwco->blk, rwco->offset, rwco->qiov->size, 773a8823a3bSKevin Wolf rwco->qiov, rwco->flags); 774a8823a3bSKevin Wolf } 775a8823a3bSKevin Wolf 776a55d3fbaSKevin Wolf static int blk_prw(BlockBackend *blk, int64_t offset, uint8_t *buf, 777a55d3fbaSKevin Wolf int64_t bytes, CoroutineEntry co_entry, 778fc1453cdSKevin Wolf BdrvRequestFlags flags) 7791bf1cbc9SKevin Wolf { 7801bf1cbc9SKevin Wolf AioContext *aio_context; 7811bf1cbc9SKevin Wolf QEMUIOVector qiov; 7821bf1cbc9SKevin Wolf struct iovec iov; 7831bf1cbc9SKevin Wolf Coroutine *co; 7841bf1cbc9SKevin Wolf BlkRwCo rwco; 7851bf1cbc9SKevin Wolf 7861bf1cbc9SKevin Wolf iov = (struct iovec) { 7871bf1cbc9SKevin Wolf .iov_base = buf, 788a55d3fbaSKevin Wolf .iov_len = bytes, 7891bf1cbc9SKevin Wolf }; 7901bf1cbc9SKevin Wolf qemu_iovec_init_external(&qiov, &iov, 1); 7911bf1cbc9SKevin Wolf 7921bf1cbc9SKevin Wolf rwco = (BlkRwCo) { 7931bf1cbc9SKevin Wolf .blk = blk, 794a55d3fbaSKevin Wolf .offset = offset, 7951bf1cbc9SKevin Wolf .qiov = &qiov, 796fc1453cdSKevin Wolf .flags = flags, 7971bf1cbc9SKevin Wolf .ret = NOT_DONE, 7981bf1cbc9SKevin Wolf }; 7991bf1cbc9SKevin Wolf 800a8823a3bSKevin Wolf co = qemu_coroutine_create(co_entry); 8011bf1cbc9SKevin Wolf qemu_coroutine_enter(co, &rwco); 8021bf1cbc9SKevin Wolf 8031bf1cbc9SKevin Wolf aio_context = blk_get_aio_context(blk); 8041bf1cbc9SKevin Wolf while (rwco.ret == NOT_DONE) { 8051bf1cbc9SKevin Wolf aio_poll(aio_context, true); 8061bf1cbc9SKevin Wolf } 8071bf1cbc9SKevin Wolf 8081bf1cbc9SKevin Wolf return rwco.ret; 8094be74634SMarkus Armbruster } 8104be74634SMarkus Armbruster 811b7d17f9fSEric Blake int blk_pread_unthrottled(BlockBackend *blk, int64_t offset, uint8_t *buf, 812b7d17f9fSEric Blake int count) 8134be74634SMarkus Armbruster { 8145bd51196SKevin Wolf int ret; 8155bd51196SKevin Wolf 816b7d17f9fSEric Blake ret = blk_check_byte_request(blk, offset, count); 817e7f7d676SMax Reitz if (ret < 0) { 818e7f7d676SMax Reitz return ret; 819e7f7d676SMax Reitz } 820e7f7d676SMax Reitz 82127ccdd52SKevin Wolf bdrv_no_throttling_begin(blk_bs(blk)); 822b7d17f9fSEric Blake ret = blk_pread(blk, offset, buf, count); 82327ccdd52SKevin Wolf bdrv_no_throttling_end(blk_bs(blk)); 8245bd51196SKevin Wolf return ret; 8254be74634SMarkus Armbruster } 8264be74634SMarkus Armbruster 827983a1600SEric Blake int blk_write_zeroes(BlockBackend *blk, int64_t offset, 828983a1600SEric Blake int count, BdrvRequestFlags flags) 8290df89e8eSKevin Wolf { 830983a1600SEric Blake return blk_prw(blk, offset, NULL, count, blk_write_entry, 83116aaf975SKevin Wolf flags | BDRV_REQ_ZERO_WRITE); 8320df89e8eSKevin Wolf } 8330df89e8eSKevin Wolf 834e7f7d676SMax Reitz static void error_callback_bh(void *opaque) 835e7f7d676SMax Reitz { 836e7f7d676SMax Reitz struct BlockBackendAIOCB *acb = opaque; 837e7f7d676SMax Reitz qemu_bh_delete(acb->bh); 838e7f7d676SMax Reitz acb->common.cb(acb->common.opaque, acb->ret); 839e7f7d676SMax Reitz qemu_aio_unref(acb); 840e7f7d676SMax Reitz } 841e7f7d676SMax Reitz 842ca78ecfaSPeter Lieven BlockAIOCB *blk_abort_aio_request(BlockBackend *blk, 843ca78ecfaSPeter Lieven BlockCompletionFunc *cb, 844e7f7d676SMax Reitz void *opaque, int ret) 845e7f7d676SMax Reitz { 846e7f7d676SMax Reitz struct BlockBackendAIOCB *acb; 847e7f7d676SMax Reitz QEMUBH *bh; 848e7f7d676SMax Reitz 849e7f7d676SMax Reitz acb = blk_aio_get(&block_backend_aiocb_info, blk, cb, opaque); 8504981bdecSMax Reitz acb->blk = blk; 851e7f7d676SMax Reitz acb->ret = ret; 852e7f7d676SMax Reitz 853e7f7d676SMax Reitz bh = aio_bh_new(blk_get_aio_context(blk), error_callback_bh, acb); 854e7f7d676SMax Reitz acb->bh = bh; 855e7f7d676SMax Reitz qemu_bh_schedule(bh); 856e7f7d676SMax Reitz 857e7f7d676SMax Reitz return &acb->common; 858e7f7d676SMax Reitz } 859e7f7d676SMax Reitz 86057d6a428SKevin Wolf typedef struct BlkAioEmAIOCB { 86157d6a428SKevin Wolf BlockAIOCB common; 86257d6a428SKevin Wolf BlkRwCo rwco; 8637fa84cd8SKevin Wolf int bytes; 86457d6a428SKevin Wolf bool has_returned; 86557d6a428SKevin Wolf QEMUBH* bh; 86657d6a428SKevin Wolf } BlkAioEmAIOCB; 86757d6a428SKevin Wolf 86857d6a428SKevin Wolf static const AIOCBInfo blk_aio_em_aiocb_info = { 86957d6a428SKevin Wolf .aiocb_size = sizeof(BlkAioEmAIOCB), 87057d6a428SKevin Wolf }; 87157d6a428SKevin Wolf 87257d6a428SKevin Wolf static void blk_aio_complete(BlkAioEmAIOCB *acb) 87357d6a428SKevin Wolf { 87457d6a428SKevin Wolf if (acb->bh) { 87557d6a428SKevin Wolf assert(acb->has_returned); 87657d6a428SKevin Wolf qemu_bh_delete(acb->bh); 87757d6a428SKevin Wolf } 87857d6a428SKevin Wolf if (acb->has_returned) { 87957d6a428SKevin Wolf acb->common.cb(acb->common.opaque, acb->rwco.ret); 88057d6a428SKevin Wolf qemu_aio_unref(acb); 88157d6a428SKevin Wolf } 88257d6a428SKevin Wolf } 88357d6a428SKevin Wolf 88457d6a428SKevin Wolf static void blk_aio_complete_bh(void *opaque) 88557d6a428SKevin Wolf { 88657d6a428SKevin Wolf blk_aio_complete(opaque); 88757d6a428SKevin Wolf } 88857d6a428SKevin Wolf 8897fa84cd8SKevin Wolf static BlockAIOCB *blk_aio_prwv(BlockBackend *blk, int64_t offset, int bytes, 89057d6a428SKevin Wolf QEMUIOVector *qiov, CoroutineEntry co_entry, 89157d6a428SKevin Wolf BdrvRequestFlags flags, 89257d6a428SKevin Wolf BlockCompletionFunc *cb, void *opaque) 89357d6a428SKevin Wolf { 89457d6a428SKevin Wolf BlkAioEmAIOCB *acb; 89557d6a428SKevin Wolf Coroutine *co; 89657d6a428SKevin Wolf 89757d6a428SKevin Wolf acb = blk_aio_get(&blk_aio_em_aiocb_info, blk, cb, opaque); 89857d6a428SKevin Wolf acb->rwco = (BlkRwCo) { 89957d6a428SKevin Wolf .blk = blk, 90057d6a428SKevin Wolf .offset = offset, 90157d6a428SKevin Wolf .qiov = qiov, 90257d6a428SKevin Wolf .flags = flags, 90357d6a428SKevin Wolf .ret = NOT_DONE, 90457d6a428SKevin Wolf }; 9057fa84cd8SKevin Wolf acb->bytes = bytes; 90657d6a428SKevin Wolf acb->bh = NULL; 90757d6a428SKevin Wolf acb->has_returned = false; 90857d6a428SKevin Wolf 90957d6a428SKevin Wolf co = qemu_coroutine_create(co_entry); 91057d6a428SKevin Wolf qemu_coroutine_enter(co, acb); 91157d6a428SKevin Wolf 91257d6a428SKevin Wolf acb->has_returned = true; 91357d6a428SKevin Wolf if (acb->rwco.ret != NOT_DONE) { 91457d6a428SKevin Wolf acb->bh = aio_bh_new(blk_get_aio_context(blk), blk_aio_complete_bh, acb); 91557d6a428SKevin Wolf qemu_bh_schedule(acb->bh); 91657d6a428SKevin Wolf } 91757d6a428SKevin Wolf 91857d6a428SKevin Wolf return &acb->common; 91957d6a428SKevin Wolf } 92057d6a428SKevin Wolf 92157d6a428SKevin Wolf static void blk_aio_read_entry(void *opaque) 92257d6a428SKevin Wolf { 92357d6a428SKevin Wolf BlkAioEmAIOCB *acb = opaque; 92457d6a428SKevin Wolf BlkRwCo *rwco = &acb->rwco; 92557d6a428SKevin Wolf 9267fa84cd8SKevin Wolf assert(rwco->qiov->size == acb->bytes); 9277fa84cd8SKevin Wolf rwco->ret = blk_co_preadv(rwco->blk, rwco->offset, acb->bytes, 92857d6a428SKevin Wolf rwco->qiov, rwco->flags); 92957d6a428SKevin Wolf blk_aio_complete(acb); 93057d6a428SKevin Wolf } 93157d6a428SKevin Wolf 93257d6a428SKevin Wolf static void blk_aio_write_entry(void *opaque) 93357d6a428SKevin Wolf { 93457d6a428SKevin Wolf BlkAioEmAIOCB *acb = opaque; 93557d6a428SKevin Wolf BlkRwCo *rwco = &acb->rwco; 93657d6a428SKevin Wolf 9377fa84cd8SKevin Wolf assert(!rwco->qiov || rwco->qiov->size == acb->bytes); 9387fa84cd8SKevin Wolf rwco->ret = blk_co_pwritev(rwco->blk, rwco->offset, acb->bytes, 93957d6a428SKevin Wolf rwco->qiov, rwco->flags); 94057d6a428SKevin Wolf blk_aio_complete(acb); 94157d6a428SKevin Wolf } 94257d6a428SKevin Wolf 943983a1600SEric Blake BlockAIOCB *blk_aio_write_zeroes(BlockBackend *blk, int64_t offset, 944983a1600SEric Blake int count, BdrvRequestFlags flags, 9454be74634SMarkus Armbruster BlockCompletionFunc *cb, void *opaque) 9464be74634SMarkus Armbruster { 947983a1600SEric Blake return blk_aio_prwv(blk, offset, count, NULL, blk_aio_write_entry, 948983a1600SEric Blake flags | BDRV_REQ_ZERO_WRITE, cb, opaque); 9494be74634SMarkus Armbruster } 9504be74634SMarkus Armbruster 9514be74634SMarkus Armbruster int blk_pread(BlockBackend *blk, int64_t offset, void *buf, int count) 9524be74634SMarkus Armbruster { 953a55d3fbaSKevin Wolf int ret = blk_prw(blk, offset, buf, count, blk_read_entry, 0); 954e7f7d676SMax Reitz if (ret < 0) { 955e7f7d676SMax Reitz return ret; 956e7f7d676SMax Reitz } 957a55d3fbaSKevin Wolf return count; 9584be74634SMarkus Armbruster } 9594be74634SMarkus Armbruster 9608341f00dSEric Blake int blk_pwrite(BlockBackend *blk, int64_t offset, const void *buf, int count, 9618341f00dSEric Blake BdrvRequestFlags flags) 9624be74634SMarkus Armbruster { 9638341f00dSEric Blake int ret = blk_prw(blk, offset, (void *) buf, count, blk_write_entry, 9648341f00dSEric Blake flags); 965e7f7d676SMax Reitz if (ret < 0) { 966e7f7d676SMax Reitz return ret; 967e7f7d676SMax Reitz } 968a55d3fbaSKevin Wolf return count; 9694be74634SMarkus Armbruster } 9704be74634SMarkus Armbruster 9714be74634SMarkus Armbruster int64_t blk_getlength(BlockBackend *blk) 9724be74634SMarkus Armbruster { 973c09ba36cSMax Reitz if (!blk_is_available(blk)) { 974c09ba36cSMax Reitz return -ENOMEDIUM; 975c09ba36cSMax Reitz } 976c09ba36cSMax Reitz 977f21d96d0SKevin Wolf return bdrv_getlength(blk_bs(blk)); 9784be74634SMarkus Armbruster } 9794be74634SMarkus Armbruster 9804be74634SMarkus Armbruster void blk_get_geometry(BlockBackend *blk, uint64_t *nb_sectors_ptr) 9814be74634SMarkus Armbruster { 982f21d96d0SKevin Wolf if (!blk_bs(blk)) { 983a46fc9c9SMax Reitz *nb_sectors_ptr = 0; 984a46fc9c9SMax Reitz } else { 985f21d96d0SKevin Wolf bdrv_get_geometry(blk_bs(blk), nb_sectors_ptr); 9864be74634SMarkus Armbruster } 987a46fc9c9SMax Reitz } 9884be74634SMarkus Armbruster 9891ef01253SMax Reitz int64_t blk_nb_sectors(BlockBackend *blk) 9901ef01253SMax Reitz { 991c09ba36cSMax Reitz if (!blk_is_available(blk)) { 992c09ba36cSMax Reitz return -ENOMEDIUM; 993c09ba36cSMax Reitz } 994c09ba36cSMax Reitz 995f21d96d0SKevin Wolf return bdrv_nb_sectors(blk_bs(blk)); 9961ef01253SMax Reitz } 9971ef01253SMax Reitz 99860cb2fa7SEric Blake BlockAIOCB *blk_aio_preadv(BlockBackend *blk, int64_t offset, 99960cb2fa7SEric Blake QEMUIOVector *qiov, BdrvRequestFlags flags, 100060cb2fa7SEric Blake BlockCompletionFunc *cb, void *opaque) 100160cb2fa7SEric Blake { 100260cb2fa7SEric Blake return blk_aio_prwv(blk, offset, qiov->size, qiov, 100360cb2fa7SEric Blake blk_aio_read_entry, flags, cb, opaque); 100460cb2fa7SEric Blake } 100560cb2fa7SEric Blake 100660cb2fa7SEric Blake BlockAIOCB *blk_aio_pwritev(BlockBackend *blk, int64_t offset, 100760cb2fa7SEric Blake QEMUIOVector *qiov, BdrvRequestFlags flags, 100860cb2fa7SEric Blake BlockCompletionFunc *cb, void *opaque) 100960cb2fa7SEric Blake { 101060cb2fa7SEric Blake return blk_aio_prwv(blk, offset, qiov->size, qiov, 101160cb2fa7SEric Blake blk_aio_write_entry, flags, cb, opaque); 101260cb2fa7SEric Blake } 101360cb2fa7SEric Blake 10144be74634SMarkus Armbruster BlockAIOCB *blk_aio_flush(BlockBackend *blk, 10154be74634SMarkus Armbruster BlockCompletionFunc *cb, void *opaque) 10164be74634SMarkus Armbruster { 1017c09ba36cSMax Reitz if (!blk_is_available(blk)) { 1018ca78ecfaSPeter Lieven return blk_abort_aio_request(blk, cb, opaque, -ENOMEDIUM); 1019c09ba36cSMax Reitz } 1020c09ba36cSMax Reitz 1021f21d96d0SKevin Wolf return bdrv_aio_flush(blk_bs(blk), cb, opaque); 10224be74634SMarkus Armbruster } 10234be74634SMarkus Armbruster 10244be74634SMarkus Armbruster BlockAIOCB *blk_aio_discard(BlockBackend *blk, 10254be74634SMarkus Armbruster int64_t sector_num, int nb_sectors, 10264be74634SMarkus Armbruster BlockCompletionFunc *cb, void *opaque) 10274be74634SMarkus Armbruster { 1028e7f7d676SMax Reitz int ret = blk_check_request(blk, sector_num, nb_sectors); 1029e7f7d676SMax Reitz if (ret < 0) { 1030ca78ecfaSPeter Lieven return blk_abort_aio_request(blk, cb, opaque, ret); 1031e7f7d676SMax Reitz } 1032e7f7d676SMax Reitz 1033f21d96d0SKevin Wolf return bdrv_aio_discard(blk_bs(blk), sector_num, nb_sectors, cb, opaque); 10344be74634SMarkus Armbruster } 10354be74634SMarkus Armbruster 10364be74634SMarkus Armbruster void blk_aio_cancel(BlockAIOCB *acb) 10374be74634SMarkus Armbruster { 10384be74634SMarkus Armbruster bdrv_aio_cancel(acb); 10394be74634SMarkus Armbruster } 10404be74634SMarkus Armbruster 10414be74634SMarkus Armbruster void blk_aio_cancel_async(BlockAIOCB *acb) 10424be74634SMarkus Armbruster { 10434be74634SMarkus Armbruster bdrv_aio_cancel_async(acb); 10444be74634SMarkus Armbruster } 10454be74634SMarkus Armbruster 10464be74634SMarkus Armbruster int blk_aio_multiwrite(BlockBackend *blk, BlockRequest *reqs, int num_reqs) 10474be74634SMarkus Armbruster { 1048e7f7d676SMax Reitz int i, ret; 1049e7f7d676SMax Reitz 1050e7f7d676SMax Reitz for (i = 0; i < num_reqs; i++) { 1051e7f7d676SMax Reitz ret = blk_check_request(blk, reqs[i].sector, reqs[i].nb_sectors); 1052e7f7d676SMax Reitz if (ret < 0) { 1053e7f7d676SMax Reitz return ret; 1054e7f7d676SMax Reitz } 1055e7f7d676SMax Reitz } 1056e7f7d676SMax Reitz 1057f21d96d0SKevin Wolf return bdrv_aio_multiwrite(blk_bs(blk), reqs, num_reqs); 10584be74634SMarkus Armbruster } 10594be74634SMarkus Armbruster 10604be74634SMarkus Armbruster int blk_ioctl(BlockBackend *blk, unsigned long int req, void *buf) 10614be74634SMarkus Armbruster { 1062c09ba36cSMax Reitz if (!blk_is_available(blk)) { 1063c09ba36cSMax Reitz return -ENOMEDIUM; 1064c09ba36cSMax Reitz } 1065c09ba36cSMax Reitz 1066f21d96d0SKevin Wolf return bdrv_ioctl(blk_bs(blk), req, buf); 10674be74634SMarkus Armbruster } 10684be74634SMarkus Armbruster 10694be74634SMarkus Armbruster BlockAIOCB *blk_aio_ioctl(BlockBackend *blk, unsigned long int req, void *buf, 10704be74634SMarkus Armbruster BlockCompletionFunc *cb, void *opaque) 10714be74634SMarkus Armbruster { 1072c09ba36cSMax Reitz if (!blk_is_available(blk)) { 1073ca78ecfaSPeter Lieven return blk_abort_aio_request(blk, cb, opaque, -ENOMEDIUM); 1074c09ba36cSMax Reitz } 1075c09ba36cSMax Reitz 1076f21d96d0SKevin Wolf return bdrv_aio_ioctl(blk_bs(blk), req, buf, cb, opaque); 10774be74634SMarkus Armbruster } 10784be74634SMarkus Armbruster 10792bb0dce7SMax Reitz int blk_co_discard(BlockBackend *blk, int64_t sector_num, int nb_sectors) 10802bb0dce7SMax Reitz { 1081e7f7d676SMax Reitz int ret = blk_check_request(blk, sector_num, nb_sectors); 1082e7f7d676SMax Reitz if (ret < 0) { 1083e7f7d676SMax Reitz return ret; 1084e7f7d676SMax Reitz } 1085e7f7d676SMax Reitz 1086f21d96d0SKevin Wolf return bdrv_co_discard(blk_bs(blk), sector_num, nb_sectors); 10872bb0dce7SMax Reitz } 10882bb0dce7SMax Reitz 10892bb0dce7SMax Reitz int blk_co_flush(BlockBackend *blk) 10902bb0dce7SMax Reitz { 1091c09ba36cSMax Reitz if (!blk_is_available(blk)) { 1092c09ba36cSMax Reitz return -ENOMEDIUM; 1093c09ba36cSMax Reitz } 1094c09ba36cSMax Reitz 1095f21d96d0SKevin Wolf return bdrv_co_flush(blk_bs(blk)); 10962bb0dce7SMax Reitz } 10972bb0dce7SMax Reitz 10984be74634SMarkus Armbruster int blk_flush(BlockBackend *blk) 10994be74634SMarkus Armbruster { 1100c09ba36cSMax Reitz if (!blk_is_available(blk)) { 1101c09ba36cSMax Reitz return -ENOMEDIUM; 1102c09ba36cSMax Reitz } 1103c09ba36cSMax Reitz 1104f21d96d0SKevin Wolf return bdrv_flush(blk_bs(blk)); 11054be74634SMarkus Armbruster } 11064be74634SMarkus Armbruster 110797b0385aSAlexander Yarygin void blk_drain(BlockBackend *blk) 110897b0385aSAlexander Yarygin { 1109f21d96d0SKevin Wolf if (blk_bs(blk)) { 1110f21d96d0SKevin Wolf bdrv_drain(blk_bs(blk)); 111197b0385aSAlexander Yarygin } 1112a46fc9c9SMax Reitz } 111397b0385aSAlexander Yarygin 11144be74634SMarkus Armbruster void blk_drain_all(void) 11154be74634SMarkus Armbruster { 11164be74634SMarkus Armbruster bdrv_drain_all(); 11174be74634SMarkus Armbruster } 11184be74634SMarkus Armbruster 1119373340b2SMax Reitz void blk_set_on_error(BlockBackend *blk, BlockdevOnError on_read_error, 1120373340b2SMax Reitz BlockdevOnError on_write_error) 1121373340b2SMax Reitz { 1122373340b2SMax Reitz blk->on_read_error = on_read_error; 1123373340b2SMax Reitz blk->on_write_error = on_write_error; 1124373340b2SMax Reitz } 1125373340b2SMax Reitz 11264be74634SMarkus Armbruster BlockdevOnError blk_get_on_error(BlockBackend *blk, bool is_read) 11274be74634SMarkus Armbruster { 1128373340b2SMax Reitz return is_read ? blk->on_read_error : blk->on_write_error; 11294be74634SMarkus Armbruster } 11304be74634SMarkus Armbruster 11314be74634SMarkus Armbruster BlockErrorAction blk_get_error_action(BlockBackend *blk, bool is_read, 11324be74634SMarkus Armbruster int error) 11334be74634SMarkus Armbruster { 1134373340b2SMax Reitz BlockdevOnError on_err = blk_get_on_error(blk, is_read); 1135373340b2SMax Reitz 1136373340b2SMax Reitz switch (on_err) { 1137373340b2SMax Reitz case BLOCKDEV_ON_ERROR_ENOSPC: 1138373340b2SMax Reitz return (error == ENOSPC) ? 1139373340b2SMax Reitz BLOCK_ERROR_ACTION_STOP : BLOCK_ERROR_ACTION_REPORT; 1140373340b2SMax Reitz case BLOCKDEV_ON_ERROR_STOP: 1141373340b2SMax Reitz return BLOCK_ERROR_ACTION_STOP; 1142373340b2SMax Reitz case BLOCKDEV_ON_ERROR_REPORT: 1143373340b2SMax Reitz return BLOCK_ERROR_ACTION_REPORT; 1144373340b2SMax Reitz case BLOCKDEV_ON_ERROR_IGNORE: 1145373340b2SMax Reitz return BLOCK_ERROR_ACTION_IGNORE; 1146373340b2SMax Reitz default: 1147373340b2SMax Reitz abort(); 1148373340b2SMax Reitz } 11494be74634SMarkus Armbruster } 11504be74634SMarkus Armbruster 1151373340b2SMax Reitz static void send_qmp_error_event(BlockBackend *blk, 1152373340b2SMax Reitz BlockErrorAction action, 1153373340b2SMax Reitz bool is_read, int error) 1154373340b2SMax Reitz { 1155373340b2SMax Reitz IoOperationType optype; 1156373340b2SMax Reitz 1157373340b2SMax Reitz optype = is_read ? IO_OPERATION_TYPE_READ : IO_OPERATION_TYPE_WRITE; 1158373340b2SMax Reitz qapi_event_send_block_io_error(blk_name(blk), optype, action, 1159373340b2SMax Reitz blk_iostatus_is_enabled(blk), 1160373340b2SMax Reitz error == ENOSPC, strerror(error), 1161373340b2SMax Reitz &error_abort); 1162373340b2SMax Reitz } 1163373340b2SMax Reitz 1164373340b2SMax Reitz /* This is done by device models because, while the block layer knows 1165373340b2SMax Reitz * about the error, it does not know whether an operation comes from 1166373340b2SMax Reitz * the device or the block layer (from a job, for example). 1167373340b2SMax Reitz */ 11684be74634SMarkus Armbruster void blk_error_action(BlockBackend *blk, BlockErrorAction action, 11694be74634SMarkus Armbruster bool is_read, int error) 11704be74634SMarkus Armbruster { 1171373340b2SMax Reitz assert(error >= 0); 1172373340b2SMax Reitz 1173373340b2SMax Reitz if (action == BLOCK_ERROR_ACTION_STOP) { 1174373340b2SMax Reitz /* First set the iostatus, so that "info block" returns an iostatus 1175373340b2SMax Reitz * that matches the events raised so far (an additional error iostatus 1176373340b2SMax Reitz * is fine, but not a lost one). 1177373340b2SMax Reitz */ 1178373340b2SMax Reitz blk_iostatus_set_err(blk, error); 1179373340b2SMax Reitz 1180373340b2SMax Reitz /* Then raise the request to stop the VM and the event. 1181373340b2SMax Reitz * qemu_system_vmstop_request_prepare has two effects. First, 1182373340b2SMax Reitz * it ensures that the STOP event always comes after the 1183373340b2SMax Reitz * BLOCK_IO_ERROR event. Second, it ensures that even if management 1184373340b2SMax Reitz * can observe the STOP event and do a "cont" before the STOP 1185373340b2SMax Reitz * event is issued, the VM will not stop. In this case, vm_start() 1186373340b2SMax Reitz * also ensures that the STOP/RESUME pair of events is emitted. 1187373340b2SMax Reitz */ 1188373340b2SMax Reitz qemu_system_vmstop_request_prepare(); 1189373340b2SMax Reitz send_qmp_error_event(blk, action, is_read, error); 1190373340b2SMax Reitz qemu_system_vmstop_request(RUN_STATE_IO_ERROR); 1191373340b2SMax Reitz } else { 1192373340b2SMax Reitz send_qmp_error_event(blk, action, is_read, error); 1193373340b2SMax Reitz } 11944be74634SMarkus Armbruster } 11954be74634SMarkus Armbruster 11964be74634SMarkus Armbruster int blk_is_read_only(BlockBackend *blk) 11974be74634SMarkus Armbruster { 1198f21d96d0SKevin Wolf BlockDriverState *bs = blk_bs(blk); 1199f21d96d0SKevin Wolf 1200f21d96d0SKevin Wolf if (bs) { 1201f21d96d0SKevin Wolf return bdrv_is_read_only(bs); 1202061959e8SMax Reitz } else { 1203061959e8SMax Reitz return blk->root_state.read_only; 1204061959e8SMax Reitz } 12054be74634SMarkus Armbruster } 12064be74634SMarkus Armbruster 12074be74634SMarkus Armbruster int blk_is_sg(BlockBackend *blk) 12084be74634SMarkus Armbruster { 1209f21d96d0SKevin Wolf BlockDriverState *bs = blk_bs(blk); 1210f21d96d0SKevin Wolf 1211f21d96d0SKevin Wolf if (!bs) { 1212a46fc9c9SMax Reitz return 0; 1213a46fc9c9SMax Reitz } 1214a46fc9c9SMax Reitz 1215f21d96d0SKevin Wolf return bdrv_is_sg(bs); 12164be74634SMarkus Armbruster } 12174be74634SMarkus Armbruster 12184be74634SMarkus Armbruster int blk_enable_write_cache(BlockBackend *blk) 12194be74634SMarkus Armbruster { 1220bfd18d1eSKevin Wolf return blk->enable_write_cache; 12214be74634SMarkus Armbruster } 12224be74634SMarkus Armbruster 12234be74634SMarkus Armbruster void blk_set_enable_write_cache(BlockBackend *blk, bool wce) 12244be74634SMarkus Armbruster { 1225bfd18d1eSKevin Wolf blk->enable_write_cache = wce; 12264be74634SMarkus Armbruster } 12274be74634SMarkus Armbruster 12282bb0dce7SMax Reitz void blk_invalidate_cache(BlockBackend *blk, Error **errp) 12292bb0dce7SMax Reitz { 1230f21d96d0SKevin Wolf BlockDriverState *bs = blk_bs(blk); 1231f21d96d0SKevin Wolf 1232f21d96d0SKevin Wolf if (!bs) { 1233c09ba36cSMax Reitz error_setg(errp, "Device '%s' has no medium", blk->name); 1234c09ba36cSMax Reitz return; 1235c09ba36cSMax Reitz } 1236c09ba36cSMax Reitz 1237f21d96d0SKevin Wolf bdrv_invalidate_cache(bs, errp); 12382bb0dce7SMax Reitz } 12392bb0dce7SMax Reitz 1240e031f750SMax Reitz bool blk_is_inserted(BlockBackend *blk) 12414be74634SMarkus Armbruster { 1242f21d96d0SKevin Wolf BlockDriverState *bs = blk_bs(blk); 1243f21d96d0SKevin Wolf 1244f21d96d0SKevin Wolf return bs && bdrv_is_inserted(bs); 1245db0284f8SMax Reitz } 1246db0284f8SMax Reitz 1247db0284f8SMax Reitz bool blk_is_available(BlockBackend *blk) 1248db0284f8SMax Reitz { 1249db0284f8SMax Reitz return blk_is_inserted(blk) && !blk_dev_is_tray_open(blk); 12504be74634SMarkus Armbruster } 12514be74634SMarkus Armbruster 12524be74634SMarkus Armbruster void blk_lock_medium(BlockBackend *blk, bool locked) 12534be74634SMarkus Armbruster { 1254f21d96d0SKevin Wolf BlockDriverState *bs = blk_bs(blk); 1255f21d96d0SKevin Wolf 1256f21d96d0SKevin Wolf if (bs) { 1257f21d96d0SKevin Wolf bdrv_lock_medium(bs, locked); 12584be74634SMarkus Armbruster } 1259a46fc9c9SMax Reitz } 12604be74634SMarkus Armbruster 12614be74634SMarkus Armbruster void blk_eject(BlockBackend *blk, bool eject_flag) 12624be74634SMarkus Armbruster { 1263f21d96d0SKevin Wolf BlockDriverState *bs = blk_bs(blk); 1264f21d96d0SKevin Wolf 1265f21d96d0SKevin Wolf if (bs) { 1266f21d96d0SKevin Wolf bdrv_eject(bs, eject_flag); 12674be74634SMarkus Armbruster } 1268a46fc9c9SMax Reitz } 12694be74634SMarkus Armbruster 12704be74634SMarkus Armbruster int blk_get_flags(BlockBackend *blk) 12714be74634SMarkus Armbruster { 1272f21d96d0SKevin Wolf BlockDriverState *bs = blk_bs(blk); 1273f21d96d0SKevin Wolf 1274f21d96d0SKevin Wolf if (bs) { 1275f21d96d0SKevin Wolf return bdrv_get_flags(bs); 1276061959e8SMax Reitz } else { 1277061959e8SMax Reitz return blk->root_state.open_flags; 1278061959e8SMax Reitz } 12794be74634SMarkus Armbruster } 12804be74634SMarkus Armbruster 1281454057b7SPeter Lieven int blk_get_max_transfer_length(BlockBackend *blk) 1282454057b7SPeter Lieven { 1283f21d96d0SKevin Wolf BlockDriverState *bs = blk_bs(blk); 1284f21d96d0SKevin Wolf 1285f21d96d0SKevin Wolf if (bs) { 1286f21d96d0SKevin Wolf return bs->bl.max_transfer_length; 1287a46fc9c9SMax Reitz } else { 1288a46fc9c9SMax Reitz return 0; 1289a46fc9c9SMax Reitz } 1290454057b7SPeter Lieven } 1291454057b7SPeter Lieven 1292648296e0SStefan Hajnoczi int blk_get_max_iov(BlockBackend *blk) 1293648296e0SStefan Hajnoczi { 1294f21d96d0SKevin Wolf return blk->root->bs->bl.max_iov; 1295648296e0SStefan Hajnoczi } 1296648296e0SStefan Hajnoczi 12974be74634SMarkus Armbruster void blk_set_guest_block_size(BlockBackend *blk, int align) 12984be74634SMarkus Armbruster { 129968e9ec01SMax Reitz blk->guest_block_size = align; 13004be74634SMarkus Armbruster } 13014be74634SMarkus Armbruster 1302f1c17521SPaolo Bonzini void *blk_try_blockalign(BlockBackend *blk, size_t size) 1303f1c17521SPaolo Bonzini { 1304f21d96d0SKevin Wolf return qemu_try_blockalign(blk ? blk_bs(blk) : NULL, size); 1305f1c17521SPaolo Bonzini } 1306f1c17521SPaolo Bonzini 13074be74634SMarkus Armbruster void *blk_blockalign(BlockBackend *blk, size_t size) 13084be74634SMarkus Armbruster { 1309f21d96d0SKevin Wolf return qemu_blockalign(blk ? blk_bs(blk) : NULL, size); 13104be74634SMarkus Armbruster } 13114be74634SMarkus Armbruster 13124be74634SMarkus Armbruster bool blk_op_is_blocked(BlockBackend *blk, BlockOpType op, Error **errp) 13134be74634SMarkus Armbruster { 1314f21d96d0SKevin Wolf BlockDriverState *bs = blk_bs(blk); 1315f21d96d0SKevin Wolf 1316f21d96d0SKevin Wolf if (!bs) { 1317a46fc9c9SMax Reitz return false; 1318a46fc9c9SMax Reitz } 1319a46fc9c9SMax Reitz 1320f21d96d0SKevin Wolf return bdrv_op_is_blocked(bs, op, errp); 13214be74634SMarkus Armbruster } 13224be74634SMarkus Armbruster 13234be74634SMarkus Armbruster void blk_op_unblock(BlockBackend *blk, BlockOpType op, Error *reason) 13244be74634SMarkus Armbruster { 1325f21d96d0SKevin Wolf BlockDriverState *bs = blk_bs(blk); 1326f21d96d0SKevin Wolf 1327f21d96d0SKevin Wolf if (bs) { 1328f21d96d0SKevin Wolf bdrv_op_unblock(bs, op, reason); 13294be74634SMarkus Armbruster } 1330a46fc9c9SMax Reitz } 13314be74634SMarkus Armbruster 13324be74634SMarkus Armbruster void blk_op_block_all(BlockBackend *blk, Error *reason) 13334be74634SMarkus Armbruster { 1334f21d96d0SKevin Wolf BlockDriverState *bs = blk_bs(blk); 1335f21d96d0SKevin Wolf 1336f21d96d0SKevin Wolf if (bs) { 1337f21d96d0SKevin Wolf bdrv_op_block_all(bs, reason); 13384be74634SMarkus Armbruster } 1339a46fc9c9SMax Reitz } 13404be74634SMarkus Armbruster 13414be74634SMarkus Armbruster void blk_op_unblock_all(BlockBackend *blk, Error *reason) 13424be74634SMarkus Armbruster { 1343f21d96d0SKevin Wolf BlockDriverState *bs = blk_bs(blk); 1344f21d96d0SKevin Wolf 1345f21d96d0SKevin Wolf if (bs) { 1346f21d96d0SKevin Wolf bdrv_op_unblock_all(bs, reason); 13474be74634SMarkus Armbruster } 1348a46fc9c9SMax Reitz } 13494be74634SMarkus Armbruster 13504be74634SMarkus Armbruster AioContext *blk_get_aio_context(BlockBackend *blk) 13514be74634SMarkus Armbruster { 1352f21d96d0SKevin Wolf BlockDriverState *bs = blk_bs(blk); 1353f21d96d0SKevin Wolf 1354f21d96d0SKevin Wolf if (bs) { 1355f21d96d0SKevin Wolf return bdrv_get_aio_context(bs); 13564981bdecSMax Reitz } else { 13574981bdecSMax Reitz return qemu_get_aio_context(); 13584981bdecSMax Reitz } 13594981bdecSMax Reitz } 13604981bdecSMax Reitz 13614981bdecSMax Reitz static AioContext *blk_aiocb_get_aio_context(BlockAIOCB *acb) 13624981bdecSMax Reitz { 13634981bdecSMax Reitz BlockBackendAIOCB *blk_acb = DO_UPCAST(BlockBackendAIOCB, common, acb); 13644981bdecSMax Reitz return blk_get_aio_context(blk_acb->blk); 13654be74634SMarkus Armbruster } 13664be74634SMarkus Armbruster 13674be74634SMarkus Armbruster void blk_set_aio_context(BlockBackend *blk, AioContext *new_context) 13684be74634SMarkus Armbruster { 1369f21d96d0SKevin Wolf BlockDriverState *bs = blk_bs(blk); 1370f21d96d0SKevin Wolf 1371f21d96d0SKevin Wolf if (bs) { 1372f21d96d0SKevin Wolf bdrv_set_aio_context(bs, new_context); 13734be74634SMarkus Armbruster } 1374a46fc9c9SMax Reitz } 13754be74634SMarkus Armbruster 13762019ba0aSMax Reitz void blk_add_aio_context_notifier(BlockBackend *blk, 13772019ba0aSMax Reitz void (*attached_aio_context)(AioContext *new_context, void *opaque), 13782019ba0aSMax Reitz void (*detach_aio_context)(void *opaque), void *opaque) 13792019ba0aSMax Reitz { 1380f21d96d0SKevin Wolf BlockDriverState *bs = blk_bs(blk); 1381f21d96d0SKevin Wolf 1382f21d96d0SKevin Wolf if (bs) { 1383f21d96d0SKevin Wolf bdrv_add_aio_context_notifier(bs, attached_aio_context, 13842019ba0aSMax Reitz detach_aio_context, opaque); 13852019ba0aSMax Reitz } 1386a46fc9c9SMax Reitz } 13872019ba0aSMax Reitz 13882019ba0aSMax Reitz void blk_remove_aio_context_notifier(BlockBackend *blk, 13892019ba0aSMax Reitz void (*attached_aio_context)(AioContext *, 13902019ba0aSMax Reitz void *), 13912019ba0aSMax Reitz void (*detach_aio_context)(void *), 13922019ba0aSMax Reitz void *opaque) 13932019ba0aSMax Reitz { 1394f21d96d0SKevin Wolf BlockDriverState *bs = blk_bs(blk); 1395f21d96d0SKevin Wolf 1396f21d96d0SKevin Wolf if (bs) { 1397f21d96d0SKevin Wolf bdrv_remove_aio_context_notifier(bs, attached_aio_context, 13982019ba0aSMax Reitz detach_aio_context, opaque); 13992019ba0aSMax Reitz } 1400a46fc9c9SMax Reitz } 14012019ba0aSMax Reitz 14023301f6c6SMax Reitz void blk_add_remove_bs_notifier(BlockBackend *blk, Notifier *notify) 14033301f6c6SMax Reitz { 14043301f6c6SMax Reitz notifier_list_add(&blk->remove_bs_notifiers, notify); 14053301f6c6SMax Reitz } 14063301f6c6SMax Reitz 14073301f6c6SMax Reitz void blk_add_insert_bs_notifier(BlockBackend *blk, Notifier *notify) 14083301f6c6SMax Reitz { 14093301f6c6SMax Reitz notifier_list_add(&blk->insert_bs_notifiers, notify); 14103301f6c6SMax Reitz } 14113301f6c6SMax Reitz 14124be74634SMarkus Armbruster void blk_io_plug(BlockBackend *blk) 14134be74634SMarkus Armbruster { 1414f21d96d0SKevin Wolf BlockDriverState *bs = blk_bs(blk); 1415f21d96d0SKevin Wolf 1416f21d96d0SKevin Wolf if (bs) { 1417f21d96d0SKevin Wolf bdrv_io_plug(bs); 14184be74634SMarkus Armbruster } 1419a46fc9c9SMax Reitz } 14204be74634SMarkus Armbruster 14214be74634SMarkus Armbruster void blk_io_unplug(BlockBackend *blk) 14224be74634SMarkus Armbruster { 1423f21d96d0SKevin Wolf BlockDriverState *bs = blk_bs(blk); 1424f21d96d0SKevin Wolf 1425f21d96d0SKevin Wolf if (bs) { 1426f21d96d0SKevin Wolf bdrv_io_unplug(bs); 14274be74634SMarkus Armbruster } 1428a46fc9c9SMax Reitz } 14294be74634SMarkus Armbruster 14304be74634SMarkus Armbruster BlockAcctStats *blk_get_stats(BlockBackend *blk) 14314be74634SMarkus Armbruster { 14327f0e9da6SMax Reitz return &blk->stats; 14334be74634SMarkus Armbruster } 14344be74634SMarkus Armbruster 14354be74634SMarkus Armbruster void *blk_aio_get(const AIOCBInfo *aiocb_info, BlockBackend *blk, 14364be74634SMarkus Armbruster BlockCompletionFunc *cb, void *opaque) 14374be74634SMarkus Armbruster { 14384be74634SMarkus Armbruster return qemu_aio_get(aiocb_info, blk_bs(blk), cb, opaque); 14394be74634SMarkus Armbruster } 14401ef01253SMax Reitz 1441983a1600SEric Blake int coroutine_fn blk_co_write_zeroes(BlockBackend *blk, int64_t offset, 1442983a1600SEric Blake int count, BdrvRequestFlags flags) 14431ef01253SMax Reitz { 1444983a1600SEric Blake return blk_co_pwritev(blk, offset, count, NULL, 144516aaf975SKevin Wolf flags | BDRV_REQ_ZERO_WRITE); 14461ef01253SMax Reitz } 14471ef01253SMax Reitz 14481ef01253SMax Reitz int blk_write_compressed(BlockBackend *blk, int64_t sector_num, 14491ef01253SMax Reitz const uint8_t *buf, int nb_sectors) 14501ef01253SMax Reitz { 1451e7f7d676SMax Reitz int ret = blk_check_request(blk, sector_num, nb_sectors); 1452e7f7d676SMax Reitz if (ret < 0) { 1453e7f7d676SMax Reitz return ret; 1454e7f7d676SMax Reitz } 1455e7f7d676SMax Reitz 1456f21d96d0SKevin Wolf return bdrv_write_compressed(blk_bs(blk), sector_num, buf, nb_sectors); 14571ef01253SMax Reitz } 14581ef01253SMax Reitz 14591ef01253SMax Reitz int blk_truncate(BlockBackend *blk, int64_t offset) 14601ef01253SMax Reitz { 1461c09ba36cSMax Reitz if (!blk_is_available(blk)) { 1462c09ba36cSMax Reitz return -ENOMEDIUM; 1463c09ba36cSMax Reitz } 1464c09ba36cSMax Reitz 1465f21d96d0SKevin Wolf return bdrv_truncate(blk_bs(blk), offset); 14661ef01253SMax Reitz } 14671ef01253SMax Reitz 14681ef01253SMax Reitz int blk_discard(BlockBackend *blk, int64_t sector_num, int nb_sectors) 14691ef01253SMax Reitz { 1470e7f7d676SMax Reitz int ret = blk_check_request(blk, sector_num, nb_sectors); 1471e7f7d676SMax Reitz if (ret < 0) { 1472e7f7d676SMax Reitz return ret; 1473e7f7d676SMax Reitz } 1474e7f7d676SMax Reitz 1475f21d96d0SKevin Wolf return bdrv_discard(blk_bs(blk), sector_num, nb_sectors); 14761ef01253SMax Reitz } 14771ef01253SMax Reitz 14781ef01253SMax Reitz int blk_save_vmstate(BlockBackend *blk, const uint8_t *buf, 14791ef01253SMax Reitz int64_t pos, int size) 14801ef01253SMax Reitz { 1481bfd18d1eSKevin Wolf int ret; 1482bfd18d1eSKevin Wolf 1483c09ba36cSMax Reitz if (!blk_is_available(blk)) { 1484c09ba36cSMax Reitz return -ENOMEDIUM; 1485c09ba36cSMax Reitz } 1486c09ba36cSMax Reitz 1487bfd18d1eSKevin Wolf ret = bdrv_save_vmstate(blk_bs(blk), buf, pos, size); 1488bfd18d1eSKevin Wolf if (ret < 0) { 1489bfd18d1eSKevin Wolf return ret; 1490bfd18d1eSKevin Wolf } 1491bfd18d1eSKevin Wolf 1492bfd18d1eSKevin Wolf if (ret == size && !blk->enable_write_cache) { 1493bfd18d1eSKevin Wolf ret = bdrv_flush(blk_bs(blk)); 1494bfd18d1eSKevin Wolf } 1495bfd18d1eSKevin Wolf 1496bfd18d1eSKevin Wolf return ret < 0 ? ret : size; 14971ef01253SMax Reitz } 14981ef01253SMax Reitz 14991ef01253SMax Reitz int blk_load_vmstate(BlockBackend *blk, uint8_t *buf, int64_t pos, int size) 15001ef01253SMax Reitz { 1501c09ba36cSMax Reitz if (!blk_is_available(blk)) { 1502c09ba36cSMax Reitz return -ENOMEDIUM; 1503c09ba36cSMax Reitz } 1504c09ba36cSMax Reitz 1505f21d96d0SKevin Wolf return bdrv_load_vmstate(blk_bs(blk), buf, pos, size); 15061ef01253SMax Reitz } 1507f0272c4dSEkaterina Tumanova 1508f0272c4dSEkaterina Tumanova int blk_probe_blocksizes(BlockBackend *blk, BlockSizes *bsz) 1509f0272c4dSEkaterina Tumanova { 1510c09ba36cSMax Reitz if (!blk_is_available(blk)) { 1511c09ba36cSMax Reitz return -ENOMEDIUM; 1512c09ba36cSMax Reitz } 1513c09ba36cSMax Reitz 1514f21d96d0SKevin Wolf return bdrv_probe_blocksizes(blk_bs(blk), bsz); 1515f0272c4dSEkaterina Tumanova } 1516f0272c4dSEkaterina Tumanova 1517f0272c4dSEkaterina Tumanova int blk_probe_geometry(BlockBackend *blk, HDGeometry *geo) 1518f0272c4dSEkaterina Tumanova { 1519c09ba36cSMax Reitz if (!blk_is_available(blk)) { 1520c09ba36cSMax Reitz return -ENOMEDIUM; 1521c09ba36cSMax Reitz } 1522c09ba36cSMax Reitz 1523f21d96d0SKevin Wolf return bdrv_probe_geometry(blk_bs(blk), geo); 1524f0272c4dSEkaterina Tumanova } 1525281d22d8SMax Reitz 1526281d22d8SMax Reitz /* 1527281d22d8SMax Reitz * Updates the BlockBackendRootState object with data from the currently 1528281d22d8SMax Reitz * attached BlockDriverState. 1529281d22d8SMax Reitz */ 1530281d22d8SMax Reitz void blk_update_root_state(BlockBackend *blk) 1531281d22d8SMax Reitz { 1532f21d96d0SKevin Wolf assert(blk->root); 1533281d22d8SMax Reitz 1534f21d96d0SKevin Wolf blk->root_state.open_flags = blk->root->bs->open_flags; 1535f21d96d0SKevin Wolf blk->root_state.read_only = blk->root->bs->read_only; 1536f21d96d0SKevin Wolf blk->root_state.detect_zeroes = blk->root->bs->detect_zeroes; 1537281d22d8SMax Reitz 1538281d22d8SMax Reitz if (blk->root_state.throttle_group) { 1539281d22d8SMax Reitz g_free(blk->root_state.throttle_group); 1540281d22d8SMax Reitz throttle_group_unref(blk->root_state.throttle_state); 1541281d22d8SMax Reitz } 154227ccdd52SKevin Wolf if (blk->public.throttle_state) { 154349d2165dSKevin Wolf const char *name = throttle_group_get_name(blk); 1544281d22d8SMax Reitz blk->root_state.throttle_group = g_strdup(name); 1545281d22d8SMax Reitz blk->root_state.throttle_state = throttle_group_incref(name); 1546281d22d8SMax Reitz } else { 1547281d22d8SMax Reitz blk->root_state.throttle_group = NULL; 1548281d22d8SMax Reitz blk->root_state.throttle_state = NULL; 1549281d22d8SMax Reitz } 1550281d22d8SMax Reitz } 1551281d22d8SMax Reitz 155238cb18f5SMax Reitz /* 155338cb18f5SMax Reitz * Applies the information in the root state to the given BlockDriverState. This 155438cb18f5SMax Reitz * does not include the flags which have to be specified for bdrv_open(), use 155538cb18f5SMax Reitz * blk_get_open_flags_from_root_state() to inquire them. 155638cb18f5SMax Reitz */ 155738cb18f5SMax Reitz void blk_apply_root_state(BlockBackend *blk, BlockDriverState *bs) 155838cb18f5SMax Reitz { 155938cb18f5SMax Reitz bs->detect_zeroes = blk->root_state.detect_zeroes; 156038cb18f5SMax Reitz if (blk->root_state.throttle_group) { 156197148076SKevin Wolf blk_io_limits_enable(blk, blk->root_state.throttle_group); 156238cb18f5SMax Reitz } 156338cb18f5SMax Reitz } 156438cb18f5SMax Reitz 156538cb18f5SMax Reitz /* 156638cb18f5SMax Reitz * Returns the flags to be used for bdrv_open() of a BlockDriverState which is 156738cb18f5SMax Reitz * supposed to inherit the root state. 156838cb18f5SMax Reitz */ 156938cb18f5SMax Reitz int blk_get_open_flags_from_root_state(BlockBackend *blk) 157038cb18f5SMax Reitz { 157138cb18f5SMax Reitz int bs_flags; 157238cb18f5SMax Reitz 157338cb18f5SMax Reitz bs_flags = blk->root_state.read_only ? 0 : BDRV_O_RDWR; 157438cb18f5SMax Reitz bs_flags |= blk->root_state.open_flags & ~BDRV_O_RDWR; 157538cb18f5SMax Reitz 157638cb18f5SMax Reitz return bs_flags; 157738cb18f5SMax Reitz } 157838cb18f5SMax Reitz 1579281d22d8SMax Reitz BlockBackendRootState *blk_get_root_state(BlockBackend *blk) 1580281d22d8SMax Reitz { 1581281d22d8SMax Reitz return &blk->root_state; 1582281d22d8SMax Reitz } 15831393f212SMax Reitz 15841393f212SMax Reitz int blk_commit_all(void) 15851393f212SMax Reitz { 1586fe1a9cbcSMax Reitz BlockBackend *blk = NULL; 1587fe1a9cbcSMax Reitz 1588fe1a9cbcSMax Reitz while ((blk = blk_all_next(blk)) != NULL) { 1589fe1a9cbcSMax Reitz AioContext *aio_context = blk_get_aio_context(blk); 1590fe1a9cbcSMax Reitz 1591fe1a9cbcSMax Reitz aio_context_acquire(aio_context); 1592f21d96d0SKevin Wolf if (blk_is_inserted(blk) && blk->root->bs->backing) { 1593f21d96d0SKevin Wolf int ret = bdrv_commit(blk->root->bs); 1594fe1a9cbcSMax Reitz if (ret < 0) { 1595fe1a9cbcSMax Reitz aio_context_release(aio_context); 1596fe1a9cbcSMax Reitz return ret; 1597fe1a9cbcSMax Reitz } 1598fe1a9cbcSMax Reitz } 1599fe1a9cbcSMax Reitz aio_context_release(aio_context); 1600fe1a9cbcSMax Reitz } 1601fe1a9cbcSMax Reitz return 0; 1602fe1a9cbcSMax Reitz } 1603fe1a9cbcSMax Reitz 1604fe1a9cbcSMax Reitz int blk_flush_all(void) 1605fe1a9cbcSMax Reitz { 1606fe1a9cbcSMax Reitz BlockBackend *blk = NULL; 1607fe1a9cbcSMax Reitz int result = 0; 1608fe1a9cbcSMax Reitz 1609fe1a9cbcSMax Reitz while ((blk = blk_all_next(blk)) != NULL) { 1610fe1a9cbcSMax Reitz AioContext *aio_context = blk_get_aio_context(blk); 1611fe1a9cbcSMax Reitz int ret; 1612fe1a9cbcSMax Reitz 1613fe1a9cbcSMax Reitz aio_context_acquire(aio_context); 1614fe1a9cbcSMax Reitz if (blk_is_inserted(blk)) { 1615fe1a9cbcSMax Reitz ret = blk_flush(blk); 1616fe1a9cbcSMax Reitz if (ret < 0 && !result) { 1617fe1a9cbcSMax Reitz result = ret; 1618fe1a9cbcSMax Reitz } 1619fe1a9cbcSMax Reitz } 1620fe1a9cbcSMax Reitz aio_context_release(aio_context); 1621fe1a9cbcSMax Reitz } 1622fe1a9cbcSMax Reitz 1623fe1a9cbcSMax Reitz return result; 16241393f212SMax Reitz } 162597148076SKevin Wolf 162697148076SKevin Wolf 162797148076SKevin Wolf /* throttling disk I/O limits */ 162897148076SKevin Wolf void blk_set_io_limits(BlockBackend *blk, ThrottleConfig *cfg) 162997148076SKevin Wolf { 163097148076SKevin Wolf throttle_group_config(blk, cfg); 163197148076SKevin Wolf } 163297148076SKevin Wolf 163397148076SKevin Wolf void blk_io_limits_disable(BlockBackend *blk) 163497148076SKevin Wolf { 163597148076SKevin Wolf assert(blk->public.throttle_state); 163697148076SKevin Wolf bdrv_no_throttling_begin(blk_bs(blk)); 163797148076SKevin Wolf throttle_group_unregister_blk(blk); 163897148076SKevin Wolf bdrv_no_throttling_end(blk_bs(blk)); 163997148076SKevin Wolf } 164097148076SKevin Wolf 164197148076SKevin Wolf /* should be called before blk_set_io_limits if a limit is set */ 164297148076SKevin Wolf void blk_io_limits_enable(BlockBackend *blk, const char *group) 164397148076SKevin Wolf { 164497148076SKevin Wolf assert(!blk->public.throttle_state); 164597148076SKevin Wolf throttle_group_register_blk(blk, group); 164697148076SKevin Wolf } 164797148076SKevin Wolf 164897148076SKevin Wolf void blk_io_limits_update_group(BlockBackend *blk, const char *group) 164997148076SKevin Wolf { 165097148076SKevin Wolf /* this BB is not part of any group */ 165197148076SKevin Wolf if (!blk->public.throttle_state) { 165297148076SKevin Wolf return; 165397148076SKevin Wolf } 165497148076SKevin Wolf 165597148076SKevin Wolf /* this BB is a part of the same group than the one we want */ 165697148076SKevin Wolf if (!g_strcmp0(throttle_group_get_name(blk), group)) { 165797148076SKevin Wolf return; 165897148076SKevin Wolf } 165997148076SKevin Wolf 166097148076SKevin Wolf /* need to change the group this bs belong to */ 166197148076SKevin Wolf blk_io_limits_disable(blk); 166297148076SKevin Wolf blk_io_limits_enable(blk, group); 166397148076SKevin Wolf } 1664