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); 787c8eece4SKevin Wolf static BlockBackend *bdrv_first_blk(BlockDriverState *bs); 798fb3c76cSMarkus Armbruster 802cf22d6aSMax Reitz /* All BlockBackends */ 812cf22d6aSMax Reitz static QTAILQ_HEAD(, BlockBackend) block_backends = 822cf22d6aSMax Reitz QTAILQ_HEAD_INITIALIZER(block_backends); 832cf22d6aSMax Reitz 849492b0b9SMax Reitz /* All BlockBackends referenced by the monitor and which are iterated through by 859492b0b9SMax Reitz * blk_next() */ 869492b0b9SMax Reitz static QTAILQ_HEAD(, BlockBackend) monitor_block_backends = 879492b0b9SMax Reitz QTAILQ_HEAD_INITIALIZER(monitor_block_backends); 8826f54e9aSMarkus Armbruster 89f21d96d0SKevin Wolf static void blk_root_inherit_options(int *child_flags, QDict *child_options, 90f21d96d0SKevin Wolf int parent_flags, QDict *parent_options) 91f21d96d0SKevin Wolf { 92f21d96d0SKevin Wolf /* We're not supposed to call this function for root nodes */ 93f21d96d0SKevin Wolf abort(); 94f21d96d0SKevin Wolf } 95c2066af0SKevin Wolf static void blk_root_drained_begin(BdrvChild *child); 96c2066af0SKevin Wolf static void blk_root_drained_end(BdrvChild *child); 97f21d96d0SKevin Wolf 985c8cab48SKevin Wolf static void blk_root_change_media(BdrvChild *child, bool load); 995c8cab48SKevin Wolf static void blk_root_resize(BdrvChild *child); 1005c8cab48SKevin Wolf 1014c265bf9SKevin Wolf static const char *blk_root_get_name(BdrvChild *child) 1024c265bf9SKevin Wolf { 1034c265bf9SKevin Wolf return blk_name(child->opaque); 1044c265bf9SKevin Wolf } 1054c265bf9SKevin Wolf 106f21d96d0SKevin Wolf static const BdrvChildRole child_root = { 107f21d96d0SKevin Wolf .inherit_options = blk_root_inherit_options, 108c2066af0SKevin Wolf 1095c8cab48SKevin Wolf .change_media = blk_root_change_media, 1105c8cab48SKevin Wolf .resize = blk_root_resize, 1114c265bf9SKevin Wolf .get_name = blk_root_get_name, 1125c8cab48SKevin Wolf 113c2066af0SKevin Wolf .drained_begin = blk_root_drained_begin, 114c2066af0SKevin Wolf .drained_end = blk_root_drained_end, 115f21d96d0SKevin Wolf }; 116f21d96d0SKevin Wolf 11726f54e9aSMarkus Armbruster /* 118efaa7c4eSMax Reitz * Create a new BlockBackend with a reference count of one. 11926f54e9aSMarkus Armbruster * Store an error through @errp on failure, unless it's null. 12026f54e9aSMarkus Armbruster * Return the new BlockBackend on success, null on failure. 12126f54e9aSMarkus Armbruster */ 122*109525adSMax Reitz BlockBackend *blk_new(void) 12326f54e9aSMarkus Armbruster { 12426f54e9aSMarkus Armbruster BlockBackend *blk; 12526f54e9aSMarkus Armbruster 12626f54e9aSMarkus Armbruster blk = g_new0(BlockBackend, 1); 12726f54e9aSMarkus Armbruster blk->refcnt = 1; 12827ccdd52SKevin Wolf qemu_co_queue_init(&blk->public.throttled_reqs[0]); 12927ccdd52SKevin Wolf qemu_co_queue_init(&blk->public.throttled_reqs[1]); 13027ccdd52SKevin Wolf 1313301f6c6SMax Reitz notifier_list_init(&blk->remove_bs_notifiers); 1323301f6c6SMax Reitz notifier_list_init(&blk->insert_bs_notifiers); 13327ccdd52SKevin Wolf 1342cf22d6aSMax Reitz QTAILQ_INSERT_TAIL(&block_backends, blk, link); 13526f54e9aSMarkus Armbruster return blk; 13626f54e9aSMarkus Armbruster } 13726f54e9aSMarkus Armbruster 1387e7d56d9SMarkus Armbruster /* 13928eb9b12SMax Reitz * Creates a new BlockBackend, opens a new BlockDriverState, and connects both. 140ca49a4fdSMax Reitz * 141ca49a4fdSMax Reitz * Just as with bdrv_open(), after having called this function the reference to 142ca49a4fdSMax Reitz * @options belongs to the block layer (even on failure). 143ca49a4fdSMax Reitz * 144ca49a4fdSMax Reitz * TODO: Remove @filename and @flags; it should be possible to specify a whole 145ca49a4fdSMax Reitz * BDS tree just by specifying the @options QDict (or @reference, 146ca49a4fdSMax Reitz * alternatively). At the time of adding this function, this is not possible, 147ca49a4fdSMax Reitz * though, so callers of this function have to be able to specify @filename and 148ca49a4fdSMax Reitz * @flags. 149ca49a4fdSMax Reitz */ 150efaa7c4eSMax Reitz BlockBackend *blk_new_open(const char *filename, const char *reference, 151efaa7c4eSMax Reitz QDict *options, int flags, Error **errp) 152ca49a4fdSMax Reitz { 153ca49a4fdSMax Reitz BlockBackend *blk; 15428eb9b12SMax Reitz BlockDriverState *bs; 155ca49a4fdSMax Reitz 156*109525adSMax Reitz blk = blk_new(); 1575b363937SMax Reitz bs = bdrv_open(filename, reference, options, flags, errp); 1585b363937SMax Reitz if (!bs) { 159ca49a4fdSMax Reitz blk_unref(blk); 160ca49a4fdSMax Reitz return NULL; 161ca49a4fdSMax Reitz } 162ca49a4fdSMax Reitz 16372e775c7SKevin Wolf blk_set_enable_write_cache(blk, true); 16428eb9b12SMax Reitz blk->root = bdrv_root_attach_child(bs, "root", &child_root); 16528eb9b12SMax Reitz blk->root->opaque = blk; 16672e775c7SKevin Wolf 167ca49a4fdSMax Reitz return blk; 168ca49a4fdSMax Reitz } 169ca49a4fdSMax Reitz 17026f54e9aSMarkus Armbruster static void blk_delete(BlockBackend *blk) 17126f54e9aSMarkus Armbruster { 17226f54e9aSMarkus Armbruster assert(!blk->refcnt); 173e5e78550SMax Reitz assert(!blk->name); 174a7f53e26SMarkus Armbruster assert(!blk->dev); 175f21d96d0SKevin Wolf if (blk->root) { 17613855c6bSMax Reitz blk_remove_bs(blk); 1777e7d56d9SMarkus Armbruster } 1783301f6c6SMax Reitz assert(QLIST_EMPTY(&blk->remove_bs_notifiers.notifiers)); 1793301f6c6SMax Reitz assert(QLIST_EMPTY(&blk->insert_bs_notifiers.notifiers)); 1802cf22d6aSMax Reitz QTAILQ_REMOVE(&block_backends, blk, link); 18118e46a03SMarkus Armbruster drive_info_del(blk->legacy_dinfo); 182979e9b03SAlberto Garcia block_acct_cleanup(&blk->stats); 18326f54e9aSMarkus Armbruster g_free(blk); 18426f54e9aSMarkus Armbruster } 18526f54e9aSMarkus Armbruster 1868fb3c76cSMarkus Armbruster static void drive_info_del(DriveInfo *dinfo) 1878fb3c76cSMarkus Armbruster { 1888fb3c76cSMarkus Armbruster if (!dinfo) { 1898fb3c76cSMarkus Armbruster return; 1908fb3c76cSMarkus Armbruster } 1918fb3c76cSMarkus Armbruster qemu_opts_del(dinfo->opts); 1928fb3c76cSMarkus Armbruster g_free(dinfo->serial); 1938fb3c76cSMarkus Armbruster g_free(dinfo); 1948fb3c76cSMarkus Armbruster } 1958fb3c76cSMarkus Armbruster 196f636ae85SAlberto Garcia int blk_get_refcnt(BlockBackend *blk) 197f636ae85SAlberto Garcia { 198f636ae85SAlberto Garcia return blk ? blk->refcnt : 0; 199f636ae85SAlberto Garcia } 200f636ae85SAlberto Garcia 20126f54e9aSMarkus Armbruster /* 20226f54e9aSMarkus Armbruster * Increment @blk's reference count. 20326f54e9aSMarkus Armbruster * @blk must not be null. 20426f54e9aSMarkus Armbruster */ 20526f54e9aSMarkus Armbruster void blk_ref(BlockBackend *blk) 20626f54e9aSMarkus Armbruster { 20726f54e9aSMarkus Armbruster blk->refcnt++; 20826f54e9aSMarkus Armbruster } 20926f54e9aSMarkus Armbruster 21026f54e9aSMarkus Armbruster /* 21126f54e9aSMarkus Armbruster * Decrement @blk's reference count. 21226f54e9aSMarkus Armbruster * If this drops it to zero, destroy @blk. 21326f54e9aSMarkus Armbruster * For convenience, do nothing if @blk is null. 21426f54e9aSMarkus Armbruster */ 21526f54e9aSMarkus Armbruster void blk_unref(BlockBackend *blk) 21626f54e9aSMarkus Armbruster { 21726f54e9aSMarkus Armbruster if (blk) { 21826f54e9aSMarkus Armbruster assert(blk->refcnt > 0); 21926f54e9aSMarkus Armbruster if (!--blk->refcnt) { 22026f54e9aSMarkus Armbruster blk_delete(blk); 22126f54e9aSMarkus Armbruster } 22226f54e9aSMarkus Armbruster } 22326f54e9aSMarkus Armbruster } 22426f54e9aSMarkus Armbruster 2252cf22d6aSMax Reitz /* 2262cf22d6aSMax Reitz * Behaves similarly to blk_next() but iterates over all BlockBackends, even the 2272cf22d6aSMax Reitz * ones which are hidden (i.e. are not referenced by the monitor). 2282cf22d6aSMax Reitz */ 2292cf22d6aSMax Reitz static BlockBackend *blk_all_next(BlockBackend *blk) 2302cf22d6aSMax Reitz { 2312cf22d6aSMax Reitz return blk ? QTAILQ_NEXT(blk, link) 2322cf22d6aSMax Reitz : QTAILQ_FIRST(&block_backends); 2332cf22d6aSMax Reitz } 2342cf22d6aSMax Reitz 235d8da3cefSMax Reitz void blk_remove_all_bs(void) 236d8da3cefSMax Reitz { 23774d1b8fcSMax Reitz BlockBackend *blk = NULL; 238d8da3cefSMax Reitz 2392cf22d6aSMax Reitz while ((blk = blk_all_next(blk)) != NULL) { 240d8da3cefSMax Reitz AioContext *ctx = blk_get_aio_context(blk); 241d8da3cefSMax Reitz 242d8da3cefSMax Reitz aio_context_acquire(ctx); 243f21d96d0SKevin Wolf if (blk->root) { 244d8da3cefSMax Reitz blk_remove_bs(blk); 245d8da3cefSMax Reitz } 246d8da3cefSMax Reitz aio_context_release(ctx); 247d8da3cefSMax Reitz } 248d8da3cefSMax Reitz } 249d8da3cefSMax Reitz 25026f54e9aSMarkus Armbruster /* 2519492b0b9SMax Reitz * Return the monitor-owned BlockBackend after @blk. 25226f54e9aSMarkus Armbruster * If @blk is null, return the first one. 25326f54e9aSMarkus Armbruster * Else, return @blk's next sibling, which may be null. 25426f54e9aSMarkus Armbruster * 25526f54e9aSMarkus Armbruster * To iterate over all BlockBackends, do 25626f54e9aSMarkus Armbruster * for (blk = blk_next(NULL); blk; blk = blk_next(blk)) { 25726f54e9aSMarkus Armbruster * ... 25826f54e9aSMarkus Armbruster * } 25926f54e9aSMarkus Armbruster */ 26026f54e9aSMarkus Armbruster BlockBackend *blk_next(BlockBackend *blk) 26126f54e9aSMarkus Armbruster { 2629492b0b9SMax Reitz return blk ? QTAILQ_NEXT(blk, monitor_link) 2639492b0b9SMax Reitz : QTAILQ_FIRST(&monitor_block_backends); 26426f54e9aSMarkus Armbruster } 26526f54e9aSMarkus Armbruster 2667c8eece4SKevin Wolf /* Iterates over all top-level BlockDriverStates, i.e. BDSs that are owned by 2677c8eece4SKevin Wolf * the monitor or attached to a BlockBackend */ 26888be7b4bSKevin Wolf BlockDriverState *bdrv_next(BdrvNextIterator *it) 2697c8eece4SKevin Wolf { 27088be7b4bSKevin Wolf BlockDriverState *bs; 271981f4f57SMax Reitz 2727c8eece4SKevin Wolf /* First, return all root nodes of BlockBackends. In order to avoid 2737c8eece4SKevin Wolf * returning a BDS twice when multiple BBs refer to it, we only return it 2747c8eece4SKevin Wolf * if the BB is the first one in the parent list of the BDS. */ 2757c8eece4SKevin Wolf if (it->phase == BDRV_NEXT_BACKEND_ROOTS) { 276981f4f57SMax Reitz do { 2777c8eece4SKevin Wolf it->blk = blk_all_next(it->blk); 27888be7b4bSKevin Wolf bs = it->blk ? blk_bs(it->blk) : NULL; 27988be7b4bSKevin Wolf } while (it->blk && (bs == NULL || bdrv_first_blk(bs) != it->blk)); 280981f4f57SMax Reitz 28188be7b4bSKevin Wolf if (bs) { 28288be7b4bSKevin Wolf return bs; 2837c8eece4SKevin Wolf } 2847c8eece4SKevin Wolf it->phase = BDRV_NEXT_MONITOR_OWNED; 2857c8eece4SKevin Wolf } 2867c8eece4SKevin Wolf 2877c8eece4SKevin Wolf /* Then return the monitor-owned BDSes without a BB attached. Ignore all 2887c8eece4SKevin Wolf * BDSes that are attached to a BlockBackend here; they have been handled 2897c8eece4SKevin Wolf * by the above block already */ 2907c8eece4SKevin Wolf do { 2917c8eece4SKevin Wolf it->bs = bdrv_next_monitor_owned(it->bs); 29288be7b4bSKevin Wolf bs = it->bs; 29388be7b4bSKevin Wolf } while (bs && bdrv_has_blk(bs)); 2947c8eece4SKevin Wolf 29588be7b4bSKevin Wolf return bs; 29688be7b4bSKevin Wolf } 29788be7b4bSKevin Wolf 29888be7b4bSKevin Wolf BlockDriverState *bdrv_first(BdrvNextIterator *it) 29988be7b4bSKevin Wolf { 30088be7b4bSKevin Wolf *it = (BdrvNextIterator) { 30188be7b4bSKevin Wolf .phase = BDRV_NEXT_BACKEND_ROOTS, 30288be7b4bSKevin Wolf }; 30388be7b4bSKevin Wolf 30488be7b4bSKevin Wolf return bdrv_next(it); 305981f4f57SMax Reitz } 306981f4f57SMax Reitz 307981f4f57SMax Reitz /* 308e5e78550SMax Reitz * Add a BlockBackend into the list of backends referenced by the monitor, with 309e5e78550SMax Reitz * the given @name acting as the handle for the monitor. 310e5e78550SMax Reitz * Strictly for use by blockdev.c. 311e5e78550SMax Reitz * 312e5e78550SMax Reitz * @name must not be null or empty. 313e5e78550SMax Reitz * 314e5e78550SMax Reitz * Returns true on success and false on failure. In the latter case, an Error 315e5e78550SMax Reitz * object is returned through @errp. 316e5e78550SMax Reitz */ 317e5e78550SMax Reitz bool monitor_add_blk(BlockBackend *blk, const char *name, Error **errp) 318e5e78550SMax Reitz { 319e5e78550SMax Reitz assert(!blk->name); 320e5e78550SMax Reitz assert(name && name[0]); 321e5e78550SMax Reitz 322e5e78550SMax Reitz if (!id_wellformed(name)) { 323e5e78550SMax Reitz error_setg(errp, "Invalid device name"); 324e5e78550SMax Reitz return false; 325e5e78550SMax Reitz } 326e5e78550SMax Reitz if (blk_by_name(name)) { 327e5e78550SMax Reitz error_setg(errp, "Device with id '%s' already exists", name); 328e5e78550SMax Reitz return false; 329e5e78550SMax Reitz } 330e5e78550SMax Reitz if (bdrv_find_node(name)) { 331e5e78550SMax Reitz error_setg(errp, 332e5e78550SMax Reitz "Device name '%s' conflicts with an existing node name", 333e5e78550SMax Reitz name); 334e5e78550SMax Reitz return false; 335e5e78550SMax Reitz } 336e5e78550SMax Reitz 337e5e78550SMax Reitz blk->name = g_strdup(name); 338e5e78550SMax Reitz QTAILQ_INSERT_TAIL(&monitor_block_backends, blk, monitor_link); 339e5e78550SMax Reitz return true; 340e5e78550SMax Reitz } 341e5e78550SMax Reitz 342e5e78550SMax Reitz /* 343e5e78550SMax Reitz * Remove a BlockBackend from the list of backends referenced by the monitor. 344e5e78550SMax Reitz * Strictly for use by blockdev.c. 345e5e78550SMax Reitz */ 346e5e78550SMax Reitz void monitor_remove_blk(BlockBackend *blk) 347e5e78550SMax Reitz { 348e5e78550SMax Reitz if (!blk->name) { 349e5e78550SMax Reitz return; 350e5e78550SMax Reitz } 351e5e78550SMax Reitz 352e5e78550SMax Reitz QTAILQ_REMOVE(&monitor_block_backends, blk, monitor_link); 353e5e78550SMax Reitz g_free(blk->name); 354e5e78550SMax Reitz blk->name = NULL; 355e5e78550SMax Reitz } 356e5e78550SMax Reitz 357e5e78550SMax Reitz /* 3587e7d56d9SMarkus Armbruster * Return @blk's name, a non-null string. 359e5e78550SMax Reitz * Returns an empty string iff @blk is not referenced by the monitor. 36026f54e9aSMarkus Armbruster */ 36126f54e9aSMarkus Armbruster const char *blk_name(BlockBackend *blk) 36226f54e9aSMarkus Armbruster { 363e5e78550SMax Reitz return blk->name ?: ""; 36426f54e9aSMarkus Armbruster } 36526f54e9aSMarkus Armbruster 36626f54e9aSMarkus Armbruster /* 36726f54e9aSMarkus Armbruster * Return the BlockBackend with name @name if it exists, else null. 36826f54e9aSMarkus Armbruster * @name must not be null. 36926f54e9aSMarkus Armbruster */ 37026f54e9aSMarkus Armbruster BlockBackend *blk_by_name(const char *name) 37126f54e9aSMarkus Armbruster { 37274d1b8fcSMax Reitz BlockBackend *blk = NULL; 37326f54e9aSMarkus Armbruster 37426f54e9aSMarkus Armbruster assert(name); 37574d1b8fcSMax Reitz while ((blk = blk_next(blk)) != NULL) { 37626f54e9aSMarkus Armbruster if (!strcmp(name, blk->name)) { 37726f54e9aSMarkus Armbruster return blk; 37826f54e9aSMarkus Armbruster } 37926f54e9aSMarkus Armbruster } 38026f54e9aSMarkus Armbruster return NULL; 38126f54e9aSMarkus Armbruster } 3827e7d56d9SMarkus Armbruster 3837e7d56d9SMarkus Armbruster /* 3847e7d56d9SMarkus Armbruster * Return the BlockDriverState attached to @blk if any, else null. 3857e7d56d9SMarkus Armbruster */ 3867e7d56d9SMarkus Armbruster BlockDriverState *blk_bs(BlockBackend *blk) 3877e7d56d9SMarkus Armbruster { 388f21d96d0SKevin Wolf return blk->root ? blk->root->bs : NULL; 3897e7d56d9SMarkus Armbruster } 3907e7d56d9SMarkus Armbruster 3917c8eece4SKevin Wolf static BlockBackend *bdrv_first_blk(BlockDriverState *bs) 392dde33812SKevin Wolf { 393dde33812SKevin Wolf BdrvChild *child; 394dde33812SKevin Wolf QLIST_FOREACH(child, &bs->parents, next_parent) { 395dde33812SKevin Wolf if (child->role == &child_root) { 3967c8eece4SKevin Wolf return child->opaque; 397dde33812SKevin Wolf } 398dde33812SKevin Wolf } 399dde33812SKevin Wolf 4007c8eece4SKevin Wolf return NULL; 4017c8eece4SKevin Wolf } 4027c8eece4SKevin Wolf 4037c8eece4SKevin Wolf /* 4047c8eece4SKevin Wolf * Returns true if @bs has an associated BlockBackend. 4057c8eece4SKevin Wolf */ 4067c8eece4SKevin Wolf bool bdrv_has_blk(BlockDriverState *bs) 4077c8eece4SKevin Wolf { 4087c8eece4SKevin Wolf return bdrv_first_blk(bs) != NULL; 409dde33812SKevin Wolf } 410dde33812SKevin Wolf 411dde33812SKevin Wolf /* 41218e46a03SMarkus Armbruster * Return @blk's DriveInfo if any, else null. 41318e46a03SMarkus Armbruster */ 41418e46a03SMarkus Armbruster DriveInfo *blk_legacy_dinfo(BlockBackend *blk) 41518e46a03SMarkus Armbruster { 41618e46a03SMarkus Armbruster return blk->legacy_dinfo; 41718e46a03SMarkus Armbruster } 41818e46a03SMarkus Armbruster 41918e46a03SMarkus Armbruster /* 42018e46a03SMarkus Armbruster * Set @blk's DriveInfo to @dinfo, and return it. 42118e46a03SMarkus Armbruster * @blk must not have a DriveInfo set already. 42218e46a03SMarkus Armbruster * No other BlockBackend may have the same DriveInfo set. 42318e46a03SMarkus Armbruster */ 42418e46a03SMarkus Armbruster DriveInfo *blk_set_legacy_dinfo(BlockBackend *blk, DriveInfo *dinfo) 42518e46a03SMarkus Armbruster { 42618e46a03SMarkus Armbruster assert(!blk->legacy_dinfo); 42718e46a03SMarkus Armbruster return blk->legacy_dinfo = dinfo; 42818e46a03SMarkus Armbruster } 42918e46a03SMarkus Armbruster 43018e46a03SMarkus Armbruster /* 43118e46a03SMarkus Armbruster * Return the BlockBackend with DriveInfo @dinfo. 43218e46a03SMarkus Armbruster * It must exist. 43318e46a03SMarkus Armbruster */ 43418e46a03SMarkus Armbruster BlockBackend *blk_by_legacy_dinfo(DriveInfo *dinfo) 43518e46a03SMarkus Armbruster { 43674d1b8fcSMax Reitz BlockBackend *blk = NULL; 43718e46a03SMarkus Armbruster 43874d1b8fcSMax Reitz while ((blk = blk_next(blk)) != NULL) { 43918e46a03SMarkus Armbruster if (blk->legacy_dinfo == dinfo) { 44018e46a03SMarkus Armbruster return blk; 44118e46a03SMarkus Armbruster } 44218e46a03SMarkus Armbruster } 44318e46a03SMarkus Armbruster abort(); 44418e46a03SMarkus Armbruster } 44518e46a03SMarkus Armbruster 44618e46a03SMarkus Armbruster /* 447f2cd875dSKevin Wolf * Returns a pointer to the publicly accessible fields of @blk. 448f2cd875dSKevin Wolf */ 449f2cd875dSKevin Wolf BlockBackendPublic *blk_get_public(BlockBackend *blk) 450f2cd875dSKevin Wolf { 451f2cd875dSKevin Wolf return &blk->public; 452f2cd875dSKevin Wolf } 453f2cd875dSKevin Wolf 454f2cd875dSKevin Wolf /* 455f2cd875dSKevin Wolf * Returns a BlockBackend given the associated @public fields. 456f2cd875dSKevin Wolf */ 457f2cd875dSKevin Wolf BlockBackend *blk_by_public(BlockBackendPublic *public) 458f2cd875dSKevin Wolf { 459f2cd875dSKevin Wolf return container_of(public, BlockBackend, public); 460f2cd875dSKevin Wolf } 461f2cd875dSKevin Wolf 462f2cd875dSKevin Wolf /* 4631c95f7e1SMax Reitz * Disassociates the currently associated BlockDriverState from @blk. 4641c95f7e1SMax Reitz */ 4651c95f7e1SMax Reitz void blk_remove_bs(BlockBackend *blk) 4661c95f7e1SMax Reitz { 4673301f6c6SMax Reitz notifier_list_notify(&blk->remove_bs_notifiers, blk); 4687ca7f0f6SKevin Wolf if (blk->public.throttle_state) { 4697ca7f0f6SKevin Wolf throttle_timers_detach_aio_context(&blk->public.throttle_timers); 4707ca7f0f6SKevin Wolf } 4713301f6c6SMax Reitz 4721c95f7e1SMax Reitz blk_update_root_state(blk); 4731c95f7e1SMax Reitz 474f21d96d0SKevin Wolf bdrv_root_unref_child(blk->root); 475f21d96d0SKevin Wolf blk->root = NULL; 4761c95f7e1SMax Reitz } 4771c95f7e1SMax Reitz 4781c95f7e1SMax Reitz /* 4790c3c36d6SMax Reitz * Associates a new BlockDriverState with @blk. 4800c3c36d6SMax Reitz */ 4810c3c36d6SMax Reitz void blk_insert_bs(BlockBackend *blk, BlockDriverState *bs) 4820c3c36d6SMax Reitz { 4830c3c36d6SMax Reitz bdrv_ref(bs); 484f21d96d0SKevin Wolf blk->root = bdrv_root_attach_child(bs, "root", &child_root); 48522aa8b24SKevin Wolf blk->root->opaque = blk; 4863301f6c6SMax Reitz 4873301f6c6SMax Reitz notifier_list_notify(&blk->insert_bs_notifiers, blk); 4887ca7f0f6SKevin Wolf if (blk->public.throttle_state) { 4897ca7f0f6SKevin Wolf throttle_timers_attach_aio_context( 4907ca7f0f6SKevin Wolf &blk->public.throttle_timers, bdrv_get_aio_context(bs)); 4917ca7f0f6SKevin Wolf } 4920c3c36d6SMax Reitz } 4930c3c36d6SMax Reitz 4940c3c36d6SMax Reitz /* 495a7f53e26SMarkus Armbruster * Attach device model @dev to @blk. 496a7f53e26SMarkus Armbruster * Return 0 on success, -EBUSY when a device model is attached already. 497a7f53e26SMarkus Armbruster */ 498a7f53e26SMarkus Armbruster int blk_attach_dev(BlockBackend *blk, void *dev) 499a7f53e26SMarkus Armbruster /* TODO change to DeviceState *dev when all users are qdevified */ 500a7f53e26SMarkus Armbruster { 501a7f53e26SMarkus Armbruster if (blk->dev) { 502a7f53e26SMarkus Armbruster return -EBUSY; 503a7f53e26SMarkus Armbruster } 50484ebe375SMarkus Armbruster blk_ref(blk); 505a7f53e26SMarkus Armbruster blk->dev = dev; 506373340b2SMax Reitz blk_iostatus_reset(blk); 507a7f53e26SMarkus Armbruster return 0; 508a7f53e26SMarkus Armbruster } 509a7f53e26SMarkus Armbruster 510a7f53e26SMarkus Armbruster /* 511a7f53e26SMarkus Armbruster * Attach device model @dev to @blk. 512a7f53e26SMarkus Armbruster * @blk must not have a device model attached already. 513a7f53e26SMarkus Armbruster * TODO qdevified devices don't use this, remove when devices are qdevified 514a7f53e26SMarkus Armbruster */ 515a7f53e26SMarkus Armbruster void blk_attach_dev_nofail(BlockBackend *blk, void *dev) 516a7f53e26SMarkus Armbruster { 517a7f53e26SMarkus Armbruster if (blk_attach_dev(blk, dev) < 0) { 518a7f53e26SMarkus Armbruster abort(); 519a7f53e26SMarkus Armbruster } 520a7f53e26SMarkus Armbruster } 521a7f53e26SMarkus Armbruster 522a7f53e26SMarkus Armbruster /* 523a7f53e26SMarkus Armbruster * Detach device model @dev from @blk. 524a7f53e26SMarkus Armbruster * @dev must be currently attached to @blk. 525a7f53e26SMarkus Armbruster */ 526a7f53e26SMarkus Armbruster void blk_detach_dev(BlockBackend *blk, void *dev) 527a7f53e26SMarkus Armbruster /* TODO change to DeviceState *dev when all users are qdevified */ 528a7f53e26SMarkus Armbruster { 529a7f53e26SMarkus Armbruster assert(blk->dev == dev); 530a7f53e26SMarkus Armbruster blk->dev = NULL; 531a7f53e26SMarkus Armbruster blk->dev_ops = NULL; 532a7f53e26SMarkus Armbruster blk->dev_opaque = NULL; 53368e9ec01SMax Reitz blk->guest_block_size = 512; 53484ebe375SMarkus Armbruster blk_unref(blk); 535a7f53e26SMarkus Armbruster } 536a7f53e26SMarkus Armbruster 537a7f53e26SMarkus Armbruster /* 538a7f53e26SMarkus Armbruster * Return the device model attached to @blk if any, else null. 539a7f53e26SMarkus Armbruster */ 540a7f53e26SMarkus Armbruster void *blk_get_attached_dev(BlockBackend *blk) 541a7f53e26SMarkus Armbruster /* TODO change to return DeviceState * when all users are qdevified */ 542a7f53e26SMarkus Armbruster { 543a7f53e26SMarkus Armbruster return blk->dev; 544a7f53e26SMarkus Armbruster } 545a7f53e26SMarkus Armbruster 546a7f53e26SMarkus Armbruster /* 547a7f53e26SMarkus Armbruster * Set @blk's device model callbacks to @ops. 548a7f53e26SMarkus Armbruster * @opaque is the opaque argument to pass to the callbacks. 549a7f53e26SMarkus Armbruster * This is for use by device models. 550a7f53e26SMarkus Armbruster */ 551a7f53e26SMarkus Armbruster void blk_set_dev_ops(BlockBackend *blk, const BlockDevOps *ops, 552a7f53e26SMarkus Armbruster void *opaque) 553a7f53e26SMarkus Armbruster { 554a7f53e26SMarkus Armbruster blk->dev_ops = ops; 555a7f53e26SMarkus Armbruster blk->dev_opaque = opaque; 556a7f53e26SMarkus Armbruster } 557a7f53e26SMarkus Armbruster 558a7f53e26SMarkus Armbruster /* 559a7f53e26SMarkus Armbruster * Notify @blk's attached device model of media change. 560a7f53e26SMarkus Armbruster * If @load is true, notify of media load. 561a7f53e26SMarkus Armbruster * Else, notify of media eject. 562a7f53e26SMarkus Armbruster * Also send DEVICE_TRAY_MOVED events as appropriate. 563a7f53e26SMarkus Armbruster */ 564a7f53e26SMarkus Armbruster void blk_dev_change_media_cb(BlockBackend *blk, bool load) 565a7f53e26SMarkus Armbruster { 566a7f53e26SMarkus Armbruster if (blk->dev_ops && blk->dev_ops->change_media_cb) { 567f1f57066SMax Reitz bool tray_was_open, tray_is_open; 568a7f53e26SMarkus Armbruster 569f1f57066SMax Reitz tray_was_open = blk_dev_is_tray_open(blk); 570a7f53e26SMarkus Armbruster blk->dev_ops->change_media_cb(blk->dev_opaque, load); 571f1f57066SMax Reitz tray_is_open = blk_dev_is_tray_open(blk); 572f1f57066SMax Reitz 573f1f57066SMax Reitz if (tray_was_open != tray_is_open) { 574f1f57066SMax Reitz qapi_event_send_device_tray_moved(blk_name(blk), tray_is_open, 575f1f57066SMax Reitz &error_abort); 576a7f53e26SMarkus Armbruster } 577a7f53e26SMarkus Armbruster } 578a7f53e26SMarkus Armbruster } 579a7f53e26SMarkus Armbruster 5805c8cab48SKevin Wolf static void blk_root_change_media(BdrvChild *child, bool load) 5815c8cab48SKevin Wolf { 5825c8cab48SKevin Wolf blk_dev_change_media_cb(child->opaque, load); 5835c8cab48SKevin Wolf } 5845c8cab48SKevin Wolf 585a7f53e26SMarkus Armbruster /* 586a7f53e26SMarkus Armbruster * Does @blk's attached device model have removable media? 587a7f53e26SMarkus Armbruster * %true if no device model is attached. 588a7f53e26SMarkus Armbruster */ 589a7f53e26SMarkus Armbruster bool blk_dev_has_removable_media(BlockBackend *blk) 590a7f53e26SMarkus Armbruster { 591a7f53e26SMarkus Armbruster return !blk->dev || (blk->dev_ops && blk->dev_ops->change_media_cb); 592a7f53e26SMarkus Armbruster } 593a7f53e26SMarkus Armbruster 594a7f53e26SMarkus Armbruster /* 5958f3a73bcSMax Reitz * Does @blk's attached device model have a tray? 5968f3a73bcSMax Reitz */ 5978f3a73bcSMax Reitz bool blk_dev_has_tray(BlockBackend *blk) 5988f3a73bcSMax Reitz { 5998f3a73bcSMax Reitz return blk->dev_ops && blk->dev_ops->is_tray_open; 6008f3a73bcSMax Reitz } 6018f3a73bcSMax Reitz 6028f3a73bcSMax Reitz /* 603a7f53e26SMarkus Armbruster * Notify @blk's attached device model of a media eject request. 604a7f53e26SMarkus Armbruster * If @force is true, the medium is about to be yanked out forcefully. 605a7f53e26SMarkus Armbruster */ 606a7f53e26SMarkus Armbruster void blk_dev_eject_request(BlockBackend *blk, bool force) 607a7f53e26SMarkus Armbruster { 608a7f53e26SMarkus Armbruster if (blk->dev_ops && blk->dev_ops->eject_request_cb) { 609a7f53e26SMarkus Armbruster blk->dev_ops->eject_request_cb(blk->dev_opaque, force); 610a7f53e26SMarkus Armbruster } 611a7f53e26SMarkus Armbruster } 612a7f53e26SMarkus Armbruster 613a7f53e26SMarkus Armbruster /* 614a7f53e26SMarkus Armbruster * Does @blk's attached device model have a tray, and is it open? 615a7f53e26SMarkus Armbruster */ 616a7f53e26SMarkus Armbruster bool blk_dev_is_tray_open(BlockBackend *blk) 617a7f53e26SMarkus Armbruster { 6188f3a73bcSMax Reitz if (blk_dev_has_tray(blk)) { 619a7f53e26SMarkus Armbruster return blk->dev_ops->is_tray_open(blk->dev_opaque); 620a7f53e26SMarkus Armbruster } 621a7f53e26SMarkus Armbruster return false; 622a7f53e26SMarkus Armbruster } 623a7f53e26SMarkus Armbruster 624a7f53e26SMarkus Armbruster /* 625a7f53e26SMarkus Armbruster * Does @blk's attached device model have the medium locked? 626a7f53e26SMarkus Armbruster * %false if the device model has no such lock. 627a7f53e26SMarkus Armbruster */ 628a7f53e26SMarkus Armbruster bool blk_dev_is_medium_locked(BlockBackend *blk) 629a7f53e26SMarkus Armbruster { 630a7f53e26SMarkus Armbruster if (blk->dev_ops && blk->dev_ops->is_medium_locked) { 631a7f53e26SMarkus Armbruster return blk->dev_ops->is_medium_locked(blk->dev_opaque); 632a7f53e26SMarkus Armbruster } 633a7f53e26SMarkus Armbruster return false; 634a7f53e26SMarkus Armbruster } 635a7f53e26SMarkus Armbruster 636a7f53e26SMarkus Armbruster /* 637a7f53e26SMarkus Armbruster * Notify @blk's attached device model of a backend size change. 638a7f53e26SMarkus Armbruster */ 6395c8cab48SKevin Wolf static void blk_root_resize(BdrvChild *child) 640a7f53e26SMarkus Armbruster { 6415c8cab48SKevin Wolf BlockBackend *blk = child->opaque; 6425c8cab48SKevin Wolf 643a7f53e26SMarkus Armbruster if (blk->dev_ops && blk->dev_ops->resize_cb) { 644a7f53e26SMarkus Armbruster blk->dev_ops->resize_cb(blk->dev_opaque); 645a7f53e26SMarkus Armbruster } 646a7f53e26SMarkus Armbruster } 647a7f53e26SMarkus Armbruster 6484be74634SMarkus Armbruster void blk_iostatus_enable(BlockBackend *blk) 6494be74634SMarkus Armbruster { 650373340b2SMax Reitz blk->iostatus_enabled = true; 651373340b2SMax Reitz blk->iostatus = BLOCK_DEVICE_IO_STATUS_OK; 652373340b2SMax Reitz } 653373340b2SMax Reitz 654373340b2SMax Reitz /* The I/O status is only enabled if the drive explicitly 655373340b2SMax Reitz * enables it _and_ the VM is configured to stop on errors */ 656373340b2SMax Reitz bool blk_iostatus_is_enabled(const BlockBackend *blk) 657373340b2SMax Reitz { 658373340b2SMax Reitz return (blk->iostatus_enabled && 659373340b2SMax Reitz (blk->on_write_error == BLOCKDEV_ON_ERROR_ENOSPC || 660373340b2SMax Reitz blk->on_write_error == BLOCKDEV_ON_ERROR_STOP || 661373340b2SMax Reitz blk->on_read_error == BLOCKDEV_ON_ERROR_STOP)); 662373340b2SMax Reitz } 663373340b2SMax Reitz 664373340b2SMax Reitz BlockDeviceIoStatus blk_iostatus(const BlockBackend *blk) 665373340b2SMax Reitz { 666373340b2SMax Reitz return blk->iostatus; 667373340b2SMax Reitz } 668373340b2SMax Reitz 669373340b2SMax Reitz void blk_iostatus_disable(BlockBackend *blk) 670373340b2SMax Reitz { 671373340b2SMax Reitz blk->iostatus_enabled = false; 672373340b2SMax Reitz } 673373340b2SMax Reitz 674373340b2SMax Reitz void blk_iostatus_reset(BlockBackend *blk) 675373340b2SMax Reitz { 676373340b2SMax Reitz if (blk_iostatus_is_enabled(blk)) { 677f21d96d0SKevin Wolf BlockDriverState *bs = blk_bs(blk); 678373340b2SMax Reitz blk->iostatus = BLOCK_DEVICE_IO_STATUS_OK; 679f21d96d0SKevin Wolf if (bs && bs->job) { 680f21d96d0SKevin Wolf block_job_iostatus_reset(bs->job); 681373340b2SMax Reitz } 682373340b2SMax Reitz } 683373340b2SMax Reitz } 684373340b2SMax Reitz 685373340b2SMax Reitz void blk_iostatus_set_err(BlockBackend *blk, int error) 686373340b2SMax Reitz { 687373340b2SMax Reitz assert(blk_iostatus_is_enabled(blk)); 688373340b2SMax Reitz if (blk->iostatus == BLOCK_DEVICE_IO_STATUS_OK) { 689373340b2SMax Reitz blk->iostatus = error == ENOSPC ? BLOCK_DEVICE_IO_STATUS_NOSPACE : 690373340b2SMax Reitz BLOCK_DEVICE_IO_STATUS_FAILED; 691373340b2SMax Reitz } 6924be74634SMarkus Armbruster } 6934be74634SMarkus Armbruster 694c10c9d96SKevin Wolf void blk_set_allow_write_beyond_eof(BlockBackend *blk, bool allow) 695c10c9d96SKevin Wolf { 696c10c9d96SKevin Wolf blk->allow_write_beyond_eof = allow; 697c10c9d96SKevin Wolf } 698c10c9d96SKevin Wolf 699e7f7d676SMax Reitz static int blk_check_byte_request(BlockBackend *blk, int64_t offset, 700e7f7d676SMax Reitz size_t size) 701e7f7d676SMax Reitz { 702e7f7d676SMax Reitz int64_t len; 703e7f7d676SMax Reitz 704e7f7d676SMax Reitz if (size > INT_MAX) { 705e7f7d676SMax Reitz return -EIO; 706e7f7d676SMax Reitz } 707e7f7d676SMax Reitz 708c09ba36cSMax Reitz if (!blk_is_available(blk)) { 709e7f7d676SMax Reitz return -ENOMEDIUM; 710e7f7d676SMax Reitz } 711e7f7d676SMax Reitz 712c10c9d96SKevin Wolf if (offset < 0) { 713c10c9d96SKevin Wolf return -EIO; 714c10c9d96SKevin Wolf } 715c10c9d96SKevin Wolf 716c10c9d96SKevin Wolf if (!blk->allow_write_beyond_eof) { 717e7f7d676SMax Reitz len = blk_getlength(blk); 718e7f7d676SMax Reitz if (len < 0) { 719e7f7d676SMax Reitz return len; 720e7f7d676SMax Reitz } 721e7f7d676SMax Reitz 722e7f7d676SMax Reitz if (offset > len || len - offset < size) { 723e7f7d676SMax Reitz return -EIO; 724e7f7d676SMax Reitz } 725c10c9d96SKevin Wolf } 726e7f7d676SMax Reitz 727e7f7d676SMax Reitz return 0; 728e7f7d676SMax Reitz } 729e7f7d676SMax Reitz 730e7f7d676SMax Reitz static int blk_check_request(BlockBackend *blk, int64_t sector_num, 731e7f7d676SMax Reitz int nb_sectors) 732e7f7d676SMax Reitz { 733e7f7d676SMax Reitz if (sector_num < 0 || sector_num > INT64_MAX / BDRV_SECTOR_SIZE) { 734e7f7d676SMax Reitz return -EIO; 735e7f7d676SMax Reitz } 736e7f7d676SMax Reitz 737e7f7d676SMax Reitz if (nb_sectors < 0 || nb_sectors > INT_MAX / BDRV_SECTOR_SIZE) { 738e7f7d676SMax Reitz return -EIO; 739e7f7d676SMax Reitz } 740e7f7d676SMax Reitz 741e7f7d676SMax Reitz return blk_check_byte_request(blk, sector_num * BDRV_SECTOR_SIZE, 742e7f7d676SMax Reitz nb_sectors * BDRV_SECTOR_SIZE); 743e7f7d676SMax Reitz } 744e7f7d676SMax Reitz 7451bf1cbc9SKevin Wolf static int coroutine_fn blk_co_preadv(BlockBackend *blk, int64_t offset, 7461bf1cbc9SKevin Wolf unsigned int bytes, QEMUIOVector *qiov, 7471bf1cbc9SKevin Wolf BdrvRequestFlags flags) 7484be74634SMarkus Armbruster { 7491bf1cbc9SKevin Wolf int ret = blk_check_byte_request(blk, offset, bytes); 750e7f7d676SMax Reitz if (ret < 0) { 751e7f7d676SMax Reitz return ret; 752e7f7d676SMax Reitz } 753e7f7d676SMax Reitz 754441565b2SKevin Wolf /* throttling disk I/O */ 755441565b2SKevin Wolf if (blk->public.throttle_state) { 756441565b2SKevin Wolf throttle_group_co_io_limits_intercept(blk, bytes, false); 757441565b2SKevin Wolf } 758441565b2SKevin Wolf 759cab3a356SKevin Wolf return bdrv_co_preadv(blk_bs(blk), offset, bytes, qiov, flags); 7601bf1cbc9SKevin Wolf } 7611bf1cbc9SKevin Wolf 762a8823a3bSKevin Wolf static int coroutine_fn blk_co_pwritev(BlockBackend *blk, int64_t offset, 763a8823a3bSKevin Wolf unsigned int bytes, QEMUIOVector *qiov, 764a8823a3bSKevin Wolf BdrvRequestFlags flags) 765a8823a3bSKevin Wolf { 766bfd18d1eSKevin Wolf int ret; 767bfd18d1eSKevin Wolf 768bfd18d1eSKevin Wolf ret = blk_check_byte_request(blk, offset, bytes); 769a8823a3bSKevin Wolf if (ret < 0) { 770a8823a3bSKevin Wolf return ret; 771a8823a3bSKevin Wolf } 772a8823a3bSKevin Wolf 773441565b2SKevin Wolf /* throttling disk I/O */ 774441565b2SKevin Wolf if (blk->public.throttle_state) { 775441565b2SKevin Wolf throttle_group_co_io_limits_intercept(blk, bytes, true); 776441565b2SKevin Wolf } 777441565b2SKevin Wolf 778bfd18d1eSKevin Wolf if (!blk->enable_write_cache) { 779bfd18d1eSKevin Wolf flags |= BDRV_REQ_FUA; 780bfd18d1eSKevin Wolf } 781bfd18d1eSKevin Wolf 782cab3a356SKevin Wolf return bdrv_co_pwritev(blk_bs(blk), offset, bytes, qiov, flags); 783a8823a3bSKevin Wolf } 784a8823a3bSKevin Wolf 7851bf1cbc9SKevin Wolf typedef struct BlkRwCo { 7861bf1cbc9SKevin Wolf BlockBackend *blk; 7871bf1cbc9SKevin Wolf int64_t offset; 7881bf1cbc9SKevin Wolf QEMUIOVector *qiov; 7891bf1cbc9SKevin Wolf int ret; 7901bf1cbc9SKevin Wolf BdrvRequestFlags flags; 7911bf1cbc9SKevin Wolf } BlkRwCo; 7921bf1cbc9SKevin Wolf 7931bf1cbc9SKevin Wolf static void blk_read_entry(void *opaque) 7941bf1cbc9SKevin Wolf { 7951bf1cbc9SKevin Wolf BlkRwCo *rwco = opaque; 7961bf1cbc9SKevin Wolf 7971bf1cbc9SKevin Wolf rwco->ret = blk_co_preadv(rwco->blk, rwco->offset, rwco->qiov->size, 7981bf1cbc9SKevin Wolf rwco->qiov, rwco->flags); 7991bf1cbc9SKevin Wolf } 8001bf1cbc9SKevin Wolf 801a8823a3bSKevin Wolf static void blk_write_entry(void *opaque) 802a8823a3bSKevin Wolf { 803a8823a3bSKevin Wolf BlkRwCo *rwco = opaque; 804a8823a3bSKevin Wolf 805a8823a3bSKevin Wolf rwco->ret = blk_co_pwritev(rwco->blk, rwco->offset, rwco->qiov->size, 806a8823a3bSKevin Wolf rwco->qiov, rwco->flags); 807a8823a3bSKevin Wolf } 808a8823a3bSKevin Wolf 809a55d3fbaSKevin Wolf static int blk_prw(BlockBackend *blk, int64_t offset, uint8_t *buf, 810a55d3fbaSKevin Wolf int64_t bytes, CoroutineEntry co_entry, 811fc1453cdSKevin Wolf BdrvRequestFlags flags) 8121bf1cbc9SKevin Wolf { 8131bf1cbc9SKevin Wolf AioContext *aio_context; 8141bf1cbc9SKevin Wolf QEMUIOVector qiov; 8151bf1cbc9SKevin Wolf struct iovec iov; 8161bf1cbc9SKevin Wolf Coroutine *co; 8171bf1cbc9SKevin Wolf BlkRwCo rwco; 8181bf1cbc9SKevin Wolf 8191bf1cbc9SKevin Wolf iov = (struct iovec) { 8201bf1cbc9SKevin Wolf .iov_base = buf, 821a55d3fbaSKevin Wolf .iov_len = bytes, 8221bf1cbc9SKevin Wolf }; 8231bf1cbc9SKevin Wolf qemu_iovec_init_external(&qiov, &iov, 1); 8241bf1cbc9SKevin Wolf 8251bf1cbc9SKevin Wolf rwco = (BlkRwCo) { 8261bf1cbc9SKevin Wolf .blk = blk, 827a55d3fbaSKevin Wolf .offset = offset, 8281bf1cbc9SKevin Wolf .qiov = &qiov, 829fc1453cdSKevin Wolf .flags = flags, 8301bf1cbc9SKevin Wolf .ret = NOT_DONE, 8311bf1cbc9SKevin Wolf }; 8321bf1cbc9SKevin Wolf 833a8823a3bSKevin Wolf co = qemu_coroutine_create(co_entry); 8341bf1cbc9SKevin Wolf qemu_coroutine_enter(co, &rwco); 8351bf1cbc9SKevin Wolf 8361bf1cbc9SKevin Wolf aio_context = blk_get_aio_context(blk); 8371bf1cbc9SKevin Wolf while (rwco.ret == NOT_DONE) { 8381bf1cbc9SKevin Wolf aio_poll(aio_context, true); 8391bf1cbc9SKevin Wolf } 8401bf1cbc9SKevin Wolf 8411bf1cbc9SKevin Wolf return rwco.ret; 8424be74634SMarkus Armbruster } 8434be74634SMarkus Armbruster 844b7d17f9fSEric Blake int blk_pread_unthrottled(BlockBackend *blk, int64_t offset, uint8_t *buf, 845b7d17f9fSEric Blake int count) 8464be74634SMarkus Armbruster { 8475bd51196SKevin Wolf int ret; 8485bd51196SKevin Wolf 849b7d17f9fSEric Blake ret = blk_check_byte_request(blk, offset, count); 850e7f7d676SMax Reitz if (ret < 0) { 851e7f7d676SMax Reitz return ret; 852e7f7d676SMax Reitz } 853e7f7d676SMax Reitz 854c2066af0SKevin Wolf blk_root_drained_begin(blk->root); 855b7d17f9fSEric Blake ret = blk_pread(blk, offset, buf, count); 856c2066af0SKevin Wolf blk_root_drained_end(blk->root); 8575bd51196SKevin Wolf return ret; 8584be74634SMarkus Armbruster } 8594be74634SMarkus Armbruster 860983a1600SEric Blake int blk_write_zeroes(BlockBackend *blk, int64_t offset, 861983a1600SEric Blake int count, BdrvRequestFlags flags) 8620df89e8eSKevin Wolf { 863983a1600SEric Blake return blk_prw(blk, offset, NULL, count, blk_write_entry, 86416aaf975SKevin Wolf flags | BDRV_REQ_ZERO_WRITE); 8650df89e8eSKevin Wolf } 8660df89e8eSKevin Wolf 867e7f7d676SMax Reitz static void error_callback_bh(void *opaque) 868e7f7d676SMax Reitz { 869e7f7d676SMax Reitz struct BlockBackendAIOCB *acb = opaque; 870e7f7d676SMax Reitz qemu_bh_delete(acb->bh); 871e7f7d676SMax Reitz acb->common.cb(acb->common.opaque, acb->ret); 872e7f7d676SMax Reitz qemu_aio_unref(acb); 873e7f7d676SMax Reitz } 874e7f7d676SMax Reitz 875ca78ecfaSPeter Lieven BlockAIOCB *blk_abort_aio_request(BlockBackend *blk, 876ca78ecfaSPeter Lieven BlockCompletionFunc *cb, 877e7f7d676SMax Reitz void *opaque, int ret) 878e7f7d676SMax Reitz { 879e7f7d676SMax Reitz struct BlockBackendAIOCB *acb; 880e7f7d676SMax Reitz QEMUBH *bh; 881e7f7d676SMax Reitz 882e7f7d676SMax Reitz acb = blk_aio_get(&block_backend_aiocb_info, blk, cb, opaque); 8834981bdecSMax Reitz acb->blk = blk; 884e7f7d676SMax Reitz acb->ret = ret; 885e7f7d676SMax Reitz 886e7f7d676SMax Reitz bh = aio_bh_new(blk_get_aio_context(blk), error_callback_bh, acb); 887e7f7d676SMax Reitz acb->bh = bh; 888e7f7d676SMax Reitz qemu_bh_schedule(bh); 889e7f7d676SMax Reitz 890e7f7d676SMax Reitz return &acb->common; 891e7f7d676SMax Reitz } 892e7f7d676SMax Reitz 89357d6a428SKevin Wolf typedef struct BlkAioEmAIOCB { 89457d6a428SKevin Wolf BlockAIOCB common; 89557d6a428SKevin Wolf BlkRwCo rwco; 8967fa84cd8SKevin Wolf int bytes; 89757d6a428SKevin Wolf bool has_returned; 89857d6a428SKevin Wolf QEMUBH* bh; 89957d6a428SKevin Wolf } BlkAioEmAIOCB; 90057d6a428SKevin Wolf 90157d6a428SKevin Wolf static const AIOCBInfo blk_aio_em_aiocb_info = { 90257d6a428SKevin Wolf .aiocb_size = sizeof(BlkAioEmAIOCB), 90357d6a428SKevin Wolf }; 90457d6a428SKevin Wolf 90557d6a428SKevin Wolf static void blk_aio_complete(BlkAioEmAIOCB *acb) 90657d6a428SKevin Wolf { 90757d6a428SKevin Wolf if (acb->bh) { 90857d6a428SKevin Wolf assert(acb->has_returned); 90957d6a428SKevin Wolf qemu_bh_delete(acb->bh); 91057d6a428SKevin Wolf } 91157d6a428SKevin Wolf if (acb->has_returned) { 91257d6a428SKevin Wolf acb->common.cb(acb->common.opaque, acb->rwco.ret); 91357d6a428SKevin Wolf qemu_aio_unref(acb); 91457d6a428SKevin Wolf } 91557d6a428SKevin Wolf } 91657d6a428SKevin Wolf 91757d6a428SKevin Wolf static void blk_aio_complete_bh(void *opaque) 91857d6a428SKevin Wolf { 91957d6a428SKevin Wolf blk_aio_complete(opaque); 92057d6a428SKevin Wolf } 92157d6a428SKevin Wolf 9227fa84cd8SKevin Wolf static BlockAIOCB *blk_aio_prwv(BlockBackend *blk, int64_t offset, int bytes, 92357d6a428SKevin Wolf QEMUIOVector *qiov, CoroutineEntry co_entry, 92457d6a428SKevin Wolf BdrvRequestFlags flags, 92557d6a428SKevin Wolf BlockCompletionFunc *cb, void *opaque) 92657d6a428SKevin Wolf { 92757d6a428SKevin Wolf BlkAioEmAIOCB *acb; 92857d6a428SKevin Wolf Coroutine *co; 92957d6a428SKevin Wolf 93057d6a428SKevin Wolf acb = blk_aio_get(&blk_aio_em_aiocb_info, blk, cb, opaque); 93157d6a428SKevin Wolf acb->rwco = (BlkRwCo) { 93257d6a428SKevin Wolf .blk = blk, 93357d6a428SKevin Wolf .offset = offset, 93457d6a428SKevin Wolf .qiov = qiov, 93557d6a428SKevin Wolf .flags = flags, 93657d6a428SKevin Wolf .ret = NOT_DONE, 93757d6a428SKevin Wolf }; 9387fa84cd8SKevin Wolf acb->bytes = bytes; 93957d6a428SKevin Wolf acb->bh = NULL; 94057d6a428SKevin Wolf acb->has_returned = false; 94157d6a428SKevin Wolf 94257d6a428SKevin Wolf co = qemu_coroutine_create(co_entry); 94357d6a428SKevin Wolf qemu_coroutine_enter(co, acb); 94457d6a428SKevin Wolf 94557d6a428SKevin Wolf acb->has_returned = true; 94657d6a428SKevin Wolf if (acb->rwco.ret != NOT_DONE) { 94757d6a428SKevin Wolf acb->bh = aio_bh_new(blk_get_aio_context(blk), blk_aio_complete_bh, acb); 94857d6a428SKevin Wolf qemu_bh_schedule(acb->bh); 94957d6a428SKevin Wolf } 95057d6a428SKevin Wolf 95157d6a428SKevin Wolf return &acb->common; 95257d6a428SKevin Wolf } 95357d6a428SKevin Wolf 95457d6a428SKevin Wolf static void blk_aio_read_entry(void *opaque) 95557d6a428SKevin Wolf { 95657d6a428SKevin Wolf BlkAioEmAIOCB *acb = opaque; 95757d6a428SKevin Wolf BlkRwCo *rwco = &acb->rwco; 95857d6a428SKevin Wolf 9597fa84cd8SKevin Wolf assert(rwco->qiov->size == acb->bytes); 9607fa84cd8SKevin Wolf rwco->ret = blk_co_preadv(rwco->blk, rwco->offset, acb->bytes, 96157d6a428SKevin Wolf rwco->qiov, rwco->flags); 96257d6a428SKevin Wolf blk_aio_complete(acb); 96357d6a428SKevin Wolf } 96457d6a428SKevin Wolf 96557d6a428SKevin Wolf static void blk_aio_write_entry(void *opaque) 96657d6a428SKevin Wolf { 96757d6a428SKevin Wolf BlkAioEmAIOCB *acb = opaque; 96857d6a428SKevin Wolf BlkRwCo *rwco = &acb->rwco; 96957d6a428SKevin Wolf 9707fa84cd8SKevin Wolf assert(!rwco->qiov || rwco->qiov->size == acb->bytes); 9717fa84cd8SKevin Wolf rwco->ret = blk_co_pwritev(rwco->blk, rwco->offset, acb->bytes, 97257d6a428SKevin Wolf rwco->qiov, rwco->flags); 97357d6a428SKevin Wolf blk_aio_complete(acb); 97457d6a428SKevin Wolf } 97557d6a428SKevin Wolf 976983a1600SEric Blake BlockAIOCB *blk_aio_write_zeroes(BlockBackend *blk, int64_t offset, 977983a1600SEric Blake int count, BdrvRequestFlags flags, 9784be74634SMarkus Armbruster BlockCompletionFunc *cb, void *opaque) 9794be74634SMarkus Armbruster { 980983a1600SEric Blake return blk_aio_prwv(blk, offset, count, NULL, blk_aio_write_entry, 981983a1600SEric Blake flags | BDRV_REQ_ZERO_WRITE, cb, opaque); 9824be74634SMarkus Armbruster } 9834be74634SMarkus Armbruster 9844be74634SMarkus Armbruster int blk_pread(BlockBackend *blk, int64_t offset, void *buf, int count) 9854be74634SMarkus Armbruster { 986a55d3fbaSKevin Wolf int ret = blk_prw(blk, offset, buf, count, blk_read_entry, 0); 987e7f7d676SMax Reitz if (ret < 0) { 988e7f7d676SMax Reitz return ret; 989e7f7d676SMax Reitz } 990a55d3fbaSKevin Wolf return count; 9914be74634SMarkus Armbruster } 9924be74634SMarkus Armbruster 9938341f00dSEric Blake int blk_pwrite(BlockBackend *blk, int64_t offset, const void *buf, int count, 9948341f00dSEric Blake BdrvRequestFlags flags) 9954be74634SMarkus Armbruster { 9968341f00dSEric Blake int ret = blk_prw(blk, offset, (void *) buf, count, blk_write_entry, 9978341f00dSEric Blake flags); 998e7f7d676SMax Reitz if (ret < 0) { 999e7f7d676SMax Reitz return ret; 1000e7f7d676SMax Reitz } 1001a55d3fbaSKevin Wolf return count; 10024be74634SMarkus Armbruster } 10034be74634SMarkus Armbruster 10044be74634SMarkus Armbruster int64_t blk_getlength(BlockBackend *blk) 10054be74634SMarkus Armbruster { 1006c09ba36cSMax Reitz if (!blk_is_available(blk)) { 1007c09ba36cSMax Reitz return -ENOMEDIUM; 1008c09ba36cSMax Reitz } 1009c09ba36cSMax Reitz 1010f21d96d0SKevin Wolf return bdrv_getlength(blk_bs(blk)); 10114be74634SMarkus Armbruster } 10124be74634SMarkus Armbruster 10134be74634SMarkus Armbruster void blk_get_geometry(BlockBackend *blk, uint64_t *nb_sectors_ptr) 10144be74634SMarkus Armbruster { 1015f21d96d0SKevin Wolf if (!blk_bs(blk)) { 1016a46fc9c9SMax Reitz *nb_sectors_ptr = 0; 1017a46fc9c9SMax Reitz } else { 1018f21d96d0SKevin Wolf bdrv_get_geometry(blk_bs(blk), nb_sectors_ptr); 10194be74634SMarkus Armbruster } 1020a46fc9c9SMax Reitz } 10214be74634SMarkus Armbruster 10221ef01253SMax Reitz int64_t blk_nb_sectors(BlockBackend *blk) 10231ef01253SMax Reitz { 1024c09ba36cSMax Reitz if (!blk_is_available(blk)) { 1025c09ba36cSMax Reitz return -ENOMEDIUM; 1026c09ba36cSMax Reitz } 1027c09ba36cSMax Reitz 1028f21d96d0SKevin Wolf return bdrv_nb_sectors(blk_bs(blk)); 10291ef01253SMax Reitz } 10301ef01253SMax Reitz 103160cb2fa7SEric Blake BlockAIOCB *blk_aio_preadv(BlockBackend *blk, int64_t offset, 103260cb2fa7SEric Blake QEMUIOVector *qiov, BdrvRequestFlags flags, 103360cb2fa7SEric Blake BlockCompletionFunc *cb, void *opaque) 103460cb2fa7SEric Blake { 103560cb2fa7SEric Blake return blk_aio_prwv(blk, offset, qiov->size, qiov, 103660cb2fa7SEric Blake blk_aio_read_entry, flags, cb, opaque); 103760cb2fa7SEric Blake } 103860cb2fa7SEric Blake 103960cb2fa7SEric Blake BlockAIOCB *blk_aio_pwritev(BlockBackend *blk, int64_t offset, 104060cb2fa7SEric Blake QEMUIOVector *qiov, BdrvRequestFlags flags, 104160cb2fa7SEric Blake BlockCompletionFunc *cb, void *opaque) 104260cb2fa7SEric Blake { 104360cb2fa7SEric Blake return blk_aio_prwv(blk, offset, qiov->size, qiov, 104460cb2fa7SEric Blake blk_aio_write_entry, flags, cb, opaque); 104560cb2fa7SEric Blake } 104660cb2fa7SEric Blake 10474be74634SMarkus Armbruster BlockAIOCB *blk_aio_flush(BlockBackend *blk, 10484be74634SMarkus Armbruster BlockCompletionFunc *cb, void *opaque) 10494be74634SMarkus Armbruster { 1050c09ba36cSMax Reitz if (!blk_is_available(blk)) { 1051ca78ecfaSPeter Lieven return blk_abort_aio_request(blk, cb, opaque, -ENOMEDIUM); 1052c09ba36cSMax Reitz } 1053c09ba36cSMax Reitz 1054f21d96d0SKevin Wolf return bdrv_aio_flush(blk_bs(blk), cb, opaque); 10554be74634SMarkus Armbruster } 10564be74634SMarkus Armbruster 10574be74634SMarkus Armbruster BlockAIOCB *blk_aio_discard(BlockBackend *blk, 10584be74634SMarkus Armbruster int64_t sector_num, int nb_sectors, 10594be74634SMarkus Armbruster BlockCompletionFunc *cb, void *opaque) 10604be74634SMarkus Armbruster { 1061e7f7d676SMax Reitz int ret = blk_check_request(blk, sector_num, nb_sectors); 1062e7f7d676SMax Reitz if (ret < 0) { 1063ca78ecfaSPeter Lieven return blk_abort_aio_request(blk, cb, opaque, ret); 1064e7f7d676SMax Reitz } 1065e7f7d676SMax Reitz 1066f21d96d0SKevin Wolf return bdrv_aio_discard(blk_bs(blk), sector_num, nb_sectors, cb, opaque); 10674be74634SMarkus Armbruster } 10684be74634SMarkus Armbruster 10694be74634SMarkus Armbruster void blk_aio_cancel(BlockAIOCB *acb) 10704be74634SMarkus Armbruster { 10714be74634SMarkus Armbruster bdrv_aio_cancel(acb); 10724be74634SMarkus Armbruster } 10734be74634SMarkus Armbruster 10744be74634SMarkus Armbruster void blk_aio_cancel_async(BlockAIOCB *acb) 10754be74634SMarkus Armbruster { 10764be74634SMarkus Armbruster bdrv_aio_cancel_async(acb); 10774be74634SMarkus Armbruster } 10784be74634SMarkus Armbruster 10794be74634SMarkus Armbruster int blk_ioctl(BlockBackend *blk, unsigned long int req, void *buf) 10804be74634SMarkus Armbruster { 1081c09ba36cSMax Reitz if (!blk_is_available(blk)) { 1082c09ba36cSMax Reitz return -ENOMEDIUM; 1083c09ba36cSMax Reitz } 1084c09ba36cSMax Reitz 1085f21d96d0SKevin Wolf return bdrv_ioctl(blk_bs(blk), req, buf); 10864be74634SMarkus Armbruster } 10874be74634SMarkus Armbruster 10884be74634SMarkus Armbruster BlockAIOCB *blk_aio_ioctl(BlockBackend *blk, unsigned long int req, void *buf, 10894be74634SMarkus Armbruster BlockCompletionFunc *cb, void *opaque) 10904be74634SMarkus Armbruster { 1091c09ba36cSMax Reitz if (!blk_is_available(blk)) { 1092ca78ecfaSPeter Lieven return blk_abort_aio_request(blk, cb, opaque, -ENOMEDIUM); 1093c09ba36cSMax Reitz } 1094c09ba36cSMax Reitz 1095f21d96d0SKevin Wolf return bdrv_aio_ioctl(blk_bs(blk), req, buf, cb, opaque); 10964be74634SMarkus Armbruster } 10974be74634SMarkus Armbruster 10982bb0dce7SMax Reitz int blk_co_discard(BlockBackend *blk, int64_t sector_num, int nb_sectors) 10992bb0dce7SMax Reitz { 1100e7f7d676SMax Reitz int ret = blk_check_request(blk, sector_num, nb_sectors); 1101e7f7d676SMax Reitz if (ret < 0) { 1102e7f7d676SMax Reitz return ret; 1103e7f7d676SMax Reitz } 1104e7f7d676SMax Reitz 1105f21d96d0SKevin Wolf return bdrv_co_discard(blk_bs(blk), sector_num, nb_sectors); 11062bb0dce7SMax Reitz } 11072bb0dce7SMax Reitz 11082bb0dce7SMax Reitz int blk_co_flush(BlockBackend *blk) 11092bb0dce7SMax Reitz { 1110c09ba36cSMax Reitz if (!blk_is_available(blk)) { 1111c09ba36cSMax Reitz return -ENOMEDIUM; 1112c09ba36cSMax Reitz } 1113c09ba36cSMax Reitz 1114f21d96d0SKevin Wolf return bdrv_co_flush(blk_bs(blk)); 11152bb0dce7SMax Reitz } 11162bb0dce7SMax Reitz 11174be74634SMarkus Armbruster int blk_flush(BlockBackend *blk) 11184be74634SMarkus Armbruster { 1119c09ba36cSMax Reitz if (!blk_is_available(blk)) { 1120c09ba36cSMax Reitz return -ENOMEDIUM; 1121c09ba36cSMax Reitz } 1122c09ba36cSMax Reitz 1123f21d96d0SKevin Wolf return bdrv_flush(blk_bs(blk)); 11244be74634SMarkus Armbruster } 11254be74634SMarkus Armbruster 112697b0385aSAlexander Yarygin void blk_drain(BlockBackend *blk) 112797b0385aSAlexander Yarygin { 1128f21d96d0SKevin Wolf if (blk_bs(blk)) { 1129f21d96d0SKevin Wolf bdrv_drain(blk_bs(blk)); 113097b0385aSAlexander Yarygin } 1131a46fc9c9SMax Reitz } 113297b0385aSAlexander Yarygin 11334be74634SMarkus Armbruster void blk_drain_all(void) 11344be74634SMarkus Armbruster { 11354be74634SMarkus Armbruster bdrv_drain_all(); 11364be74634SMarkus Armbruster } 11374be74634SMarkus Armbruster 1138373340b2SMax Reitz void blk_set_on_error(BlockBackend *blk, BlockdevOnError on_read_error, 1139373340b2SMax Reitz BlockdevOnError on_write_error) 1140373340b2SMax Reitz { 1141373340b2SMax Reitz blk->on_read_error = on_read_error; 1142373340b2SMax Reitz blk->on_write_error = on_write_error; 1143373340b2SMax Reitz } 1144373340b2SMax Reitz 11454be74634SMarkus Armbruster BlockdevOnError blk_get_on_error(BlockBackend *blk, bool is_read) 11464be74634SMarkus Armbruster { 1147373340b2SMax Reitz return is_read ? blk->on_read_error : blk->on_write_error; 11484be74634SMarkus Armbruster } 11494be74634SMarkus Armbruster 11504be74634SMarkus Armbruster BlockErrorAction blk_get_error_action(BlockBackend *blk, bool is_read, 11514be74634SMarkus Armbruster int error) 11524be74634SMarkus Armbruster { 1153373340b2SMax Reitz BlockdevOnError on_err = blk_get_on_error(blk, is_read); 1154373340b2SMax Reitz 1155373340b2SMax Reitz switch (on_err) { 1156373340b2SMax Reitz case BLOCKDEV_ON_ERROR_ENOSPC: 1157373340b2SMax Reitz return (error == ENOSPC) ? 1158373340b2SMax Reitz BLOCK_ERROR_ACTION_STOP : BLOCK_ERROR_ACTION_REPORT; 1159373340b2SMax Reitz case BLOCKDEV_ON_ERROR_STOP: 1160373340b2SMax Reitz return BLOCK_ERROR_ACTION_STOP; 1161373340b2SMax Reitz case BLOCKDEV_ON_ERROR_REPORT: 1162373340b2SMax Reitz return BLOCK_ERROR_ACTION_REPORT; 1163373340b2SMax Reitz case BLOCKDEV_ON_ERROR_IGNORE: 1164373340b2SMax Reitz return BLOCK_ERROR_ACTION_IGNORE; 1165373340b2SMax Reitz default: 1166373340b2SMax Reitz abort(); 1167373340b2SMax Reitz } 11684be74634SMarkus Armbruster } 11694be74634SMarkus Armbruster 1170373340b2SMax Reitz static void send_qmp_error_event(BlockBackend *blk, 1171373340b2SMax Reitz BlockErrorAction action, 1172373340b2SMax Reitz bool is_read, int error) 1173373340b2SMax Reitz { 1174373340b2SMax Reitz IoOperationType optype; 1175373340b2SMax Reitz 1176373340b2SMax Reitz optype = is_read ? IO_OPERATION_TYPE_READ : IO_OPERATION_TYPE_WRITE; 1177373340b2SMax Reitz qapi_event_send_block_io_error(blk_name(blk), optype, action, 1178373340b2SMax Reitz blk_iostatus_is_enabled(blk), 1179373340b2SMax Reitz error == ENOSPC, strerror(error), 1180373340b2SMax Reitz &error_abort); 1181373340b2SMax Reitz } 1182373340b2SMax Reitz 1183373340b2SMax Reitz /* This is done by device models because, while the block layer knows 1184373340b2SMax Reitz * about the error, it does not know whether an operation comes from 1185373340b2SMax Reitz * the device or the block layer (from a job, for example). 1186373340b2SMax Reitz */ 11874be74634SMarkus Armbruster void blk_error_action(BlockBackend *blk, BlockErrorAction action, 11884be74634SMarkus Armbruster bool is_read, int error) 11894be74634SMarkus Armbruster { 1190373340b2SMax Reitz assert(error >= 0); 1191373340b2SMax Reitz 1192373340b2SMax Reitz if (action == BLOCK_ERROR_ACTION_STOP) { 1193373340b2SMax Reitz /* First set the iostatus, so that "info block" returns an iostatus 1194373340b2SMax Reitz * that matches the events raised so far (an additional error iostatus 1195373340b2SMax Reitz * is fine, but not a lost one). 1196373340b2SMax Reitz */ 1197373340b2SMax Reitz blk_iostatus_set_err(blk, error); 1198373340b2SMax Reitz 1199373340b2SMax Reitz /* Then raise the request to stop the VM and the event. 1200373340b2SMax Reitz * qemu_system_vmstop_request_prepare has two effects. First, 1201373340b2SMax Reitz * it ensures that the STOP event always comes after the 1202373340b2SMax Reitz * BLOCK_IO_ERROR event. Second, it ensures that even if management 1203373340b2SMax Reitz * can observe the STOP event and do a "cont" before the STOP 1204373340b2SMax Reitz * event is issued, the VM will not stop. In this case, vm_start() 1205373340b2SMax Reitz * also ensures that the STOP/RESUME pair of events is emitted. 1206373340b2SMax Reitz */ 1207373340b2SMax Reitz qemu_system_vmstop_request_prepare(); 1208373340b2SMax Reitz send_qmp_error_event(blk, action, is_read, error); 1209373340b2SMax Reitz qemu_system_vmstop_request(RUN_STATE_IO_ERROR); 1210373340b2SMax Reitz } else { 1211373340b2SMax Reitz send_qmp_error_event(blk, action, is_read, error); 1212373340b2SMax Reitz } 12134be74634SMarkus Armbruster } 12144be74634SMarkus Armbruster 12154be74634SMarkus Armbruster int blk_is_read_only(BlockBackend *blk) 12164be74634SMarkus Armbruster { 1217f21d96d0SKevin Wolf BlockDriverState *bs = blk_bs(blk); 1218f21d96d0SKevin Wolf 1219f21d96d0SKevin Wolf if (bs) { 1220f21d96d0SKevin Wolf return bdrv_is_read_only(bs); 1221061959e8SMax Reitz } else { 1222061959e8SMax Reitz return blk->root_state.read_only; 1223061959e8SMax Reitz } 12244be74634SMarkus Armbruster } 12254be74634SMarkus Armbruster 12264be74634SMarkus Armbruster int blk_is_sg(BlockBackend *blk) 12274be74634SMarkus Armbruster { 1228f21d96d0SKevin Wolf BlockDriverState *bs = blk_bs(blk); 1229f21d96d0SKevin Wolf 1230f21d96d0SKevin Wolf if (!bs) { 1231a46fc9c9SMax Reitz return 0; 1232a46fc9c9SMax Reitz } 1233a46fc9c9SMax Reitz 1234f21d96d0SKevin Wolf return bdrv_is_sg(bs); 12354be74634SMarkus Armbruster } 12364be74634SMarkus Armbruster 12374be74634SMarkus Armbruster int blk_enable_write_cache(BlockBackend *blk) 12384be74634SMarkus Armbruster { 1239bfd18d1eSKevin Wolf return blk->enable_write_cache; 12404be74634SMarkus Armbruster } 12414be74634SMarkus Armbruster 12424be74634SMarkus Armbruster void blk_set_enable_write_cache(BlockBackend *blk, bool wce) 12434be74634SMarkus Armbruster { 1244bfd18d1eSKevin Wolf blk->enable_write_cache = wce; 12454be74634SMarkus Armbruster } 12464be74634SMarkus Armbruster 12472bb0dce7SMax Reitz void blk_invalidate_cache(BlockBackend *blk, Error **errp) 12482bb0dce7SMax Reitz { 1249f21d96d0SKevin Wolf BlockDriverState *bs = blk_bs(blk); 1250f21d96d0SKevin Wolf 1251f21d96d0SKevin Wolf if (!bs) { 1252c09ba36cSMax Reitz error_setg(errp, "Device '%s' has no medium", blk->name); 1253c09ba36cSMax Reitz return; 1254c09ba36cSMax Reitz } 1255c09ba36cSMax Reitz 1256f21d96d0SKevin Wolf bdrv_invalidate_cache(bs, errp); 12572bb0dce7SMax Reitz } 12582bb0dce7SMax Reitz 1259e031f750SMax Reitz bool blk_is_inserted(BlockBackend *blk) 12604be74634SMarkus Armbruster { 1261f21d96d0SKevin Wolf BlockDriverState *bs = blk_bs(blk); 1262f21d96d0SKevin Wolf 1263f21d96d0SKevin Wolf return bs && bdrv_is_inserted(bs); 1264db0284f8SMax Reitz } 1265db0284f8SMax Reitz 1266db0284f8SMax Reitz bool blk_is_available(BlockBackend *blk) 1267db0284f8SMax Reitz { 1268db0284f8SMax Reitz return blk_is_inserted(blk) && !blk_dev_is_tray_open(blk); 12694be74634SMarkus Armbruster } 12704be74634SMarkus Armbruster 12714be74634SMarkus Armbruster void blk_lock_medium(BlockBackend *blk, bool locked) 12724be74634SMarkus Armbruster { 1273f21d96d0SKevin Wolf BlockDriverState *bs = blk_bs(blk); 1274f21d96d0SKevin Wolf 1275f21d96d0SKevin Wolf if (bs) { 1276f21d96d0SKevin Wolf bdrv_lock_medium(bs, locked); 12774be74634SMarkus Armbruster } 1278a46fc9c9SMax Reitz } 12794be74634SMarkus Armbruster 12804be74634SMarkus Armbruster void blk_eject(BlockBackend *blk, bool eject_flag) 12814be74634SMarkus Armbruster { 1282f21d96d0SKevin Wolf BlockDriverState *bs = blk_bs(blk); 1283f21d96d0SKevin Wolf 1284f21d96d0SKevin Wolf if (bs) { 1285f21d96d0SKevin Wolf bdrv_eject(bs, eject_flag); 12864be74634SMarkus Armbruster } 1287a46fc9c9SMax Reitz } 12884be74634SMarkus Armbruster 12894be74634SMarkus Armbruster int blk_get_flags(BlockBackend *blk) 12904be74634SMarkus Armbruster { 1291f21d96d0SKevin Wolf BlockDriverState *bs = blk_bs(blk); 1292f21d96d0SKevin Wolf 1293f21d96d0SKevin Wolf if (bs) { 1294f21d96d0SKevin Wolf return bdrv_get_flags(bs); 1295061959e8SMax Reitz } else { 1296061959e8SMax Reitz return blk->root_state.open_flags; 1297061959e8SMax Reitz } 12984be74634SMarkus Armbruster } 12994be74634SMarkus Armbruster 1300454057b7SPeter Lieven int blk_get_max_transfer_length(BlockBackend *blk) 1301454057b7SPeter Lieven { 1302f21d96d0SKevin Wolf BlockDriverState *bs = blk_bs(blk); 1303f21d96d0SKevin Wolf 1304f21d96d0SKevin Wolf if (bs) { 1305f21d96d0SKevin Wolf return bs->bl.max_transfer_length; 1306a46fc9c9SMax Reitz } else { 1307a46fc9c9SMax Reitz return 0; 1308a46fc9c9SMax Reitz } 1309454057b7SPeter Lieven } 1310454057b7SPeter Lieven 1311648296e0SStefan Hajnoczi int blk_get_max_iov(BlockBackend *blk) 1312648296e0SStefan Hajnoczi { 1313f21d96d0SKevin Wolf return blk->root->bs->bl.max_iov; 1314648296e0SStefan Hajnoczi } 1315648296e0SStefan Hajnoczi 13164be74634SMarkus Armbruster void blk_set_guest_block_size(BlockBackend *blk, int align) 13174be74634SMarkus Armbruster { 131868e9ec01SMax Reitz blk->guest_block_size = align; 13194be74634SMarkus Armbruster } 13204be74634SMarkus Armbruster 1321f1c17521SPaolo Bonzini void *blk_try_blockalign(BlockBackend *blk, size_t size) 1322f1c17521SPaolo Bonzini { 1323f21d96d0SKevin Wolf return qemu_try_blockalign(blk ? blk_bs(blk) : NULL, size); 1324f1c17521SPaolo Bonzini } 1325f1c17521SPaolo Bonzini 13264be74634SMarkus Armbruster void *blk_blockalign(BlockBackend *blk, size_t size) 13274be74634SMarkus Armbruster { 1328f21d96d0SKevin Wolf return qemu_blockalign(blk ? blk_bs(blk) : NULL, size); 13294be74634SMarkus Armbruster } 13304be74634SMarkus Armbruster 13314be74634SMarkus Armbruster bool blk_op_is_blocked(BlockBackend *blk, BlockOpType op, Error **errp) 13324be74634SMarkus Armbruster { 1333f21d96d0SKevin Wolf BlockDriverState *bs = blk_bs(blk); 1334f21d96d0SKevin Wolf 1335f21d96d0SKevin Wolf if (!bs) { 1336a46fc9c9SMax Reitz return false; 1337a46fc9c9SMax Reitz } 1338a46fc9c9SMax Reitz 1339f21d96d0SKevin Wolf return bdrv_op_is_blocked(bs, op, errp); 13404be74634SMarkus Armbruster } 13414be74634SMarkus Armbruster 13424be74634SMarkus Armbruster void blk_op_unblock(BlockBackend *blk, BlockOpType op, Error *reason) 13434be74634SMarkus Armbruster { 1344f21d96d0SKevin Wolf BlockDriverState *bs = blk_bs(blk); 1345f21d96d0SKevin Wolf 1346f21d96d0SKevin Wolf if (bs) { 1347f21d96d0SKevin Wolf bdrv_op_unblock(bs, op, reason); 13484be74634SMarkus Armbruster } 1349a46fc9c9SMax Reitz } 13504be74634SMarkus Armbruster 13514be74634SMarkus Armbruster void blk_op_block_all(BlockBackend *blk, Error *reason) 13524be74634SMarkus Armbruster { 1353f21d96d0SKevin Wolf BlockDriverState *bs = blk_bs(blk); 1354f21d96d0SKevin Wolf 1355f21d96d0SKevin Wolf if (bs) { 1356f21d96d0SKevin Wolf bdrv_op_block_all(bs, reason); 13574be74634SMarkus Armbruster } 1358a46fc9c9SMax Reitz } 13594be74634SMarkus Armbruster 13604be74634SMarkus Armbruster void blk_op_unblock_all(BlockBackend *blk, Error *reason) 13614be74634SMarkus Armbruster { 1362f21d96d0SKevin Wolf BlockDriverState *bs = blk_bs(blk); 1363f21d96d0SKevin Wolf 1364f21d96d0SKevin Wolf if (bs) { 1365f21d96d0SKevin Wolf bdrv_op_unblock_all(bs, reason); 13664be74634SMarkus Armbruster } 1367a46fc9c9SMax Reitz } 13684be74634SMarkus Armbruster 13694be74634SMarkus Armbruster AioContext *blk_get_aio_context(BlockBackend *blk) 13704be74634SMarkus Armbruster { 1371f21d96d0SKevin Wolf BlockDriverState *bs = blk_bs(blk); 1372f21d96d0SKevin Wolf 1373f21d96d0SKevin Wolf if (bs) { 1374f21d96d0SKevin Wolf return bdrv_get_aio_context(bs); 13754981bdecSMax Reitz } else { 13764981bdecSMax Reitz return qemu_get_aio_context(); 13774981bdecSMax Reitz } 13784981bdecSMax Reitz } 13794981bdecSMax Reitz 13804981bdecSMax Reitz static AioContext *blk_aiocb_get_aio_context(BlockAIOCB *acb) 13814981bdecSMax Reitz { 13824981bdecSMax Reitz BlockBackendAIOCB *blk_acb = DO_UPCAST(BlockBackendAIOCB, common, acb); 13834981bdecSMax Reitz return blk_get_aio_context(blk_acb->blk); 13844be74634SMarkus Armbruster } 13854be74634SMarkus Armbruster 13864be74634SMarkus Armbruster void blk_set_aio_context(BlockBackend *blk, AioContext *new_context) 13874be74634SMarkus Armbruster { 1388f21d96d0SKevin Wolf BlockDriverState *bs = blk_bs(blk); 1389f21d96d0SKevin Wolf 1390f21d96d0SKevin Wolf if (bs) { 13917ca7f0f6SKevin Wolf if (blk->public.throttle_state) { 13927ca7f0f6SKevin Wolf throttle_timers_detach_aio_context(&blk->public.throttle_timers); 13937ca7f0f6SKevin Wolf } 1394f21d96d0SKevin Wolf bdrv_set_aio_context(bs, new_context); 13957ca7f0f6SKevin Wolf if (blk->public.throttle_state) { 13967ca7f0f6SKevin Wolf throttle_timers_attach_aio_context(&blk->public.throttle_timers, 13977ca7f0f6SKevin Wolf new_context); 13987ca7f0f6SKevin Wolf } 13994be74634SMarkus Armbruster } 1400a46fc9c9SMax Reitz } 14014be74634SMarkus Armbruster 14022019ba0aSMax Reitz void blk_add_aio_context_notifier(BlockBackend *blk, 14032019ba0aSMax Reitz void (*attached_aio_context)(AioContext *new_context, void *opaque), 14042019ba0aSMax Reitz void (*detach_aio_context)(void *opaque), void *opaque) 14052019ba0aSMax Reitz { 1406f21d96d0SKevin Wolf BlockDriverState *bs = blk_bs(blk); 1407f21d96d0SKevin Wolf 1408f21d96d0SKevin Wolf if (bs) { 1409f21d96d0SKevin Wolf bdrv_add_aio_context_notifier(bs, attached_aio_context, 14102019ba0aSMax Reitz detach_aio_context, opaque); 14112019ba0aSMax Reitz } 1412a46fc9c9SMax Reitz } 14132019ba0aSMax Reitz 14142019ba0aSMax Reitz void blk_remove_aio_context_notifier(BlockBackend *blk, 14152019ba0aSMax Reitz void (*attached_aio_context)(AioContext *, 14162019ba0aSMax Reitz void *), 14172019ba0aSMax Reitz void (*detach_aio_context)(void *), 14182019ba0aSMax Reitz void *opaque) 14192019ba0aSMax Reitz { 1420f21d96d0SKevin Wolf BlockDriverState *bs = blk_bs(blk); 1421f21d96d0SKevin Wolf 1422f21d96d0SKevin Wolf if (bs) { 1423f21d96d0SKevin Wolf bdrv_remove_aio_context_notifier(bs, attached_aio_context, 14242019ba0aSMax Reitz detach_aio_context, opaque); 14252019ba0aSMax Reitz } 1426a46fc9c9SMax Reitz } 14272019ba0aSMax Reitz 14283301f6c6SMax Reitz void blk_add_remove_bs_notifier(BlockBackend *blk, Notifier *notify) 14293301f6c6SMax Reitz { 14303301f6c6SMax Reitz notifier_list_add(&blk->remove_bs_notifiers, notify); 14313301f6c6SMax Reitz } 14323301f6c6SMax Reitz 14333301f6c6SMax Reitz void blk_add_insert_bs_notifier(BlockBackend *blk, Notifier *notify) 14343301f6c6SMax Reitz { 14353301f6c6SMax Reitz notifier_list_add(&blk->insert_bs_notifiers, notify); 14363301f6c6SMax Reitz } 14373301f6c6SMax Reitz 14384be74634SMarkus Armbruster void blk_io_plug(BlockBackend *blk) 14394be74634SMarkus Armbruster { 1440f21d96d0SKevin Wolf BlockDriverState *bs = blk_bs(blk); 1441f21d96d0SKevin Wolf 1442f21d96d0SKevin Wolf if (bs) { 1443f21d96d0SKevin Wolf bdrv_io_plug(bs); 14444be74634SMarkus Armbruster } 1445a46fc9c9SMax Reitz } 14464be74634SMarkus Armbruster 14474be74634SMarkus Armbruster void blk_io_unplug(BlockBackend *blk) 14484be74634SMarkus Armbruster { 1449f21d96d0SKevin Wolf BlockDriverState *bs = blk_bs(blk); 1450f21d96d0SKevin Wolf 1451f21d96d0SKevin Wolf if (bs) { 1452f21d96d0SKevin Wolf bdrv_io_unplug(bs); 14534be74634SMarkus Armbruster } 1454a46fc9c9SMax Reitz } 14554be74634SMarkus Armbruster 14564be74634SMarkus Armbruster BlockAcctStats *blk_get_stats(BlockBackend *blk) 14574be74634SMarkus Armbruster { 14587f0e9da6SMax Reitz return &blk->stats; 14594be74634SMarkus Armbruster } 14604be74634SMarkus Armbruster 14614be74634SMarkus Armbruster void *blk_aio_get(const AIOCBInfo *aiocb_info, BlockBackend *blk, 14624be74634SMarkus Armbruster BlockCompletionFunc *cb, void *opaque) 14634be74634SMarkus Armbruster { 14644be74634SMarkus Armbruster return qemu_aio_get(aiocb_info, blk_bs(blk), cb, opaque); 14654be74634SMarkus Armbruster } 14661ef01253SMax Reitz 1467983a1600SEric Blake int coroutine_fn blk_co_write_zeroes(BlockBackend *blk, int64_t offset, 1468983a1600SEric Blake int count, BdrvRequestFlags flags) 14691ef01253SMax Reitz { 1470983a1600SEric Blake return blk_co_pwritev(blk, offset, count, NULL, 147116aaf975SKevin Wolf flags | BDRV_REQ_ZERO_WRITE); 14721ef01253SMax Reitz } 14731ef01253SMax Reitz 14741ef01253SMax Reitz int blk_write_compressed(BlockBackend *blk, int64_t sector_num, 14751ef01253SMax Reitz const uint8_t *buf, int nb_sectors) 14761ef01253SMax Reitz { 1477e7f7d676SMax Reitz int ret = blk_check_request(blk, sector_num, nb_sectors); 1478e7f7d676SMax Reitz if (ret < 0) { 1479e7f7d676SMax Reitz return ret; 1480e7f7d676SMax Reitz } 1481e7f7d676SMax Reitz 1482f21d96d0SKevin Wolf return bdrv_write_compressed(blk_bs(blk), sector_num, buf, nb_sectors); 14831ef01253SMax Reitz } 14841ef01253SMax Reitz 14851ef01253SMax Reitz int blk_truncate(BlockBackend *blk, int64_t offset) 14861ef01253SMax Reitz { 1487c09ba36cSMax Reitz if (!blk_is_available(blk)) { 1488c09ba36cSMax Reitz return -ENOMEDIUM; 1489c09ba36cSMax Reitz } 1490c09ba36cSMax Reitz 1491f21d96d0SKevin Wolf return bdrv_truncate(blk_bs(blk), offset); 14921ef01253SMax Reitz } 14931ef01253SMax Reitz 14941ef01253SMax Reitz int blk_discard(BlockBackend *blk, int64_t sector_num, int nb_sectors) 14951ef01253SMax Reitz { 1496e7f7d676SMax Reitz int ret = blk_check_request(blk, sector_num, nb_sectors); 1497e7f7d676SMax Reitz if (ret < 0) { 1498e7f7d676SMax Reitz return ret; 1499e7f7d676SMax Reitz } 1500e7f7d676SMax Reitz 1501f21d96d0SKevin Wolf return bdrv_discard(blk_bs(blk), sector_num, nb_sectors); 15021ef01253SMax Reitz } 15031ef01253SMax Reitz 15041ef01253SMax Reitz int blk_save_vmstate(BlockBackend *blk, const uint8_t *buf, 15051ef01253SMax Reitz int64_t pos, int size) 15061ef01253SMax Reitz { 1507bfd18d1eSKevin Wolf int ret; 1508bfd18d1eSKevin Wolf 1509c09ba36cSMax Reitz if (!blk_is_available(blk)) { 1510c09ba36cSMax Reitz return -ENOMEDIUM; 1511c09ba36cSMax Reitz } 1512c09ba36cSMax Reitz 1513bfd18d1eSKevin Wolf ret = bdrv_save_vmstate(blk_bs(blk), buf, pos, size); 1514bfd18d1eSKevin Wolf if (ret < 0) { 1515bfd18d1eSKevin Wolf return ret; 1516bfd18d1eSKevin Wolf } 1517bfd18d1eSKevin Wolf 1518bfd18d1eSKevin Wolf if (ret == size && !blk->enable_write_cache) { 1519bfd18d1eSKevin Wolf ret = bdrv_flush(blk_bs(blk)); 1520bfd18d1eSKevin Wolf } 1521bfd18d1eSKevin Wolf 1522bfd18d1eSKevin Wolf return ret < 0 ? ret : size; 15231ef01253SMax Reitz } 15241ef01253SMax Reitz 15251ef01253SMax Reitz int blk_load_vmstate(BlockBackend *blk, uint8_t *buf, int64_t pos, int size) 15261ef01253SMax Reitz { 1527c09ba36cSMax Reitz if (!blk_is_available(blk)) { 1528c09ba36cSMax Reitz return -ENOMEDIUM; 1529c09ba36cSMax Reitz } 1530c09ba36cSMax Reitz 1531f21d96d0SKevin Wolf return bdrv_load_vmstate(blk_bs(blk), buf, pos, size); 15321ef01253SMax Reitz } 1533f0272c4dSEkaterina Tumanova 1534f0272c4dSEkaterina Tumanova int blk_probe_blocksizes(BlockBackend *blk, BlockSizes *bsz) 1535f0272c4dSEkaterina Tumanova { 1536c09ba36cSMax Reitz if (!blk_is_available(blk)) { 1537c09ba36cSMax Reitz return -ENOMEDIUM; 1538c09ba36cSMax Reitz } 1539c09ba36cSMax Reitz 1540f21d96d0SKevin Wolf return bdrv_probe_blocksizes(blk_bs(blk), bsz); 1541f0272c4dSEkaterina Tumanova } 1542f0272c4dSEkaterina Tumanova 1543f0272c4dSEkaterina Tumanova int blk_probe_geometry(BlockBackend *blk, HDGeometry *geo) 1544f0272c4dSEkaterina Tumanova { 1545c09ba36cSMax Reitz if (!blk_is_available(blk)) { 1546c09ba36cSMax Reitz return -ENOMEDIUM; 1547c09ba36cSMax Reitz } 1548c09ba36cSMax Reitz 1549f21d96d0SKevin Wolf return bdrv_probe_geometry(blk_bs(blk), geo); 1550f0272c4dSEkaterina Tumanova } 1551281d22d8SMax Reitz 1552281d22d8SMax Reitz /* 1553281d22d8SMax Reitz * Updates the BlockBackendRootState object with data from the currently 1554281d22d8SMax Reitz * attached BlockDriverState. 1555281d22d8SMax Reitz */ 1556281d22d8SMax Reitz void blk_update_root_state(BlockBackend *blk) 1557281d22d8SMax Reitz { 1558f21d96d0SKevin Wolf assert(blk->root); 1559281d22d8SMax Reitz 1560f21d96d0SKevin Wolf blk->root_state.open_flags = blk->root->bs->open_flags; 1561f21d96d0SKevin Wolf blk->root_state.read_only = blk->root->bs->read_only; 1562f21d96d0SKevin Wolf blk->root_state.detect_zeroes = blk->root->bs->detect_zeroes; 1563281d22d8SMax Reitz } 1564281d22d8SMax Reitz 156538cb18f5SMax Reitz /* 156638cb18f5SMax Reitz * Applies the information in the root state to the given BlockDriverState. This 156738cb18f5SMax Reitz * does not include the flags which have to be specified for bdrv_open(), use 156838cb18f5SMax Reitz * blk_get_open_flags_from_root_state() to inquire them. 156938cb18f5SMax Reitz */ 157038cb18f5SMax Reitz void blk_apply_root_state(BlockBackend *blk, BlockDriverState *bs) 157138cb18f5SMax Reitz { 157238cb18f5SMax Reitz bs->detect_zeroes = blk->root_state.detect_zeroes; 157338cb18f5SMax Reitz } 157438cb18f5SMax Reitz 157538cb18f5SMax Reitz /* 157638cb18f5SMax Reitz * Returns the flags to be used for bdrv_open() of a BlockDriverState which is 157738cb18f5SMax Reitz * supposed to inherit the root state. 157838cb18f5SMax Reitz */ 157938cb18f5SMax Reitz int blk_get_open_flags_from_root_state(BlockBackend *blk) 158038cb18f5SMax Reitz { 158138cb18f5SMax Reitz int bs_flags; 158238cb18f5SMax Reitz 158338cb18f5SMax Reitz bs_flags = blk->root_state.read_only ? 0 : BDRV_O_RDWR; 158438cb18f5SMax Reitz bs_flags |= blk->root_state.open_flags & ~BDRV_O_RDWR; 158538cb18f5SMax Reitz 158638cb18f5SMax Reitz return bs_flags; 158738cb18f5SMax Reitz } 158838cb18f5SMax Reitz 1589281d22d8SMax Reitz BlockBackendRootState *blk_get_root_state(BlockBackend *blk) 1590281d22d8SMax Reitz { 1591281d22d8SMax Reitz return &blk->root_state; 1592281d22d8SMax Reitz } 15931393f212SMax Reitz 15941393f212SMax Reitz int blk_commit_all(void) 15951393f212SMax Reitz { 1596fe1a9cbcSMax Reitz BlockBackend *blk = NULL; 1597fe1a9cbcSMax Reitz 1598fe1a9cbcSMax Reitz while ((blk = blk_all_next(blk)) != NULL) { 1599fe1a9cbcSMax Reitz AioContext *aio_context = blk_get_aio_context(blk); 1600fe1a9cbcSMax Reitz 1601fe1a9cbcSMax Reitz aio_context_acquire(aio_context); 1602f21d96d0SKevin Wolf if (blk_is_inserted(blk) && blk->root->bs->backing) { 1603f21d96d0SKevin Wolf int ret = bdrv_commit(blk->root->bs); 1604fe1a9cbcSMax Reitz if (ret < 0) { 1605fe1a9cbcSMax Reitz aio_context_release(aio_context); 1606fe1a9cbcSMax Reitz return ret; 1607fe1a9cbcSMax Reitz } 1608fe1a9cbcSMax Reitz } 1609fe1a9cbcSMax Reitz aio_context_release(aio_context); 1610fe1a9cbcSMax Reitz } 1611fe1a9cbcSMax Reitz return 0; 1612fe1a9cbcSMax Reitz } 1613fe1a9cbcSMax Reitz 1614fe1a9cbcSMax Reitz int blk_flush_all(void) 1615fe1a9cbcSMax Reitz { 1616fe1a9cbcSMax Reitz BlockBackend *blk = NULL; 1617fe1a9cbcSMax Reitz int result = 0; 1618fe1a9cbcSMax Reitz 1619fe1a9cbcSMax Reitz while ((blk = blk_all_next(blk)) != NULL) { 1620fe1a9cbcSMax Reitz AioContext *aio_context = blk_get_aio_context(blk); 1621fe1a9cbcSMax Reitz int ret; 1622fe1a9cbcSMax Reitz 1623fe1a9cbcSMax Reitz aio_context_acquire(aio_context); 1624fe1a9cbcSMax Reitz if (blk_is_inserted(blk)) { 1625fe1a9cbcSMax Reitz ret = blk_flush(blk); 1626fe1a9cbcSMax Reitz if (ret < 0 && !result) { 1627fe1a9cbcSMax Reitz result = ret; 1628fe1a9cbcSMax Reitz } 1629fe1a9cbcSMax Reitz } 1630fe1a9cbcSMax Reitz aio_context_release(aio_context); 1631fe1a9cbcSMax Reitz } 1632fe1a9cbcSMax Reitz 1633fe1a9cbcSMax Reitz return result; 16341393f212SMax Reitz } 163597148076SKevin Wolf 163697148076SKevin Wolf 163797148076SKevin Wolf /* throttling disk I/O limits */ 163897148076SKevin Wolf void blk_set_io_limits(BlockBackend *blk, ThrottleConfig *cfg) 163997148076SKevin Wolf { 164097148076SKevin Wolf throttle_group_config(blk, cfg); 164197148076SKevin Wolf } 164297148076SKevin Wolf 164397148076SKevin Wolf void blk_io_limits_disable(BlockBackend *blk) 164497148076SKevin Wolf { 164597148076SKevin Wolf assert(blk->public.throttle_state); 1646c2066af0SKevin Wolf bdrv_drained_begin(blk_bs(blk)); 164797148076SKevin Wolf throttle_group_unregister_blk(blk); 1648c2066af0SKevin Wolf bdrv_drained_end(blk_bs(blk)); 164997148076SKevin Wolf } 165097148076SKevin Wolf 165197148076SKevin Wolf /* should be called before blk_set_io_limits if a limit is set */ 165297148076SKevin Wolf void blk_io_limits_enable(BlockBackend *blk, const char *group) 165397148076SKevin Wolf { 165497148076SKevin Wolf assert(!blk->public.throttle_state); 165597148076SKevin Wolf throttle_group_register_blk(blk, group); 165697148076SKevin Wolf } 165797148076SKevin Wolf 165897148076SKevin Wolf void blk_io_limits_update_group(BlockBackend *blk, const char *group) 165997148076SKevin Wolf { 166097148076SKevin Wolf /* this BB is not part of any group */ 166197148076SKevin Wolf if (!blk->public.throttle_state) { 166297148076SKevin Wolf return; 166397148076SKevin Wolf } 166497148076SKevin Wolf 166597148076SKevin Wolf /* this BB is a part of the same group than the one we want */ 166697148076SKevin Wolf if (!g_strcmp0(throttle_group_get_name(blk), group)) { 166797148076SKevin Wolf return; 166897148076SKevin Wolf } 166997148076SKevin Wolf 167097148076SKevin Wolf /* need to change the group this bs belong to */ 167197148076SKevin Wolf blk_io_limits_disable(blk); 167297148076SKevin Wolf blk_io_limits_enable(blk, group); 167397148076SKevin Wolf } 1674c2066af0SKevin Wolf 1675c2066af0SKevin Wolf static void blk_root_drained_begin(BdrvChild *child) 1676c2066af0SKevin Wolf { 1677c2066af0SKevin Wolf BlockBackend *blk = child->opaque; 1678c2066af0SKevin Wolf 1679c2066af0SKevin Wolf if (blk->public.io_limits_disabled++ == 0) { 1680c2066af0SKevin Wolf throttle_group_restart_blk(blk); 1681c2066af0SKevin Wolf } 1682c2066af0SKevin Wolf } 1683c2066af0SKevin Wolf 1684c2066af0SKevin Wolf static void blk_root_drained_end(BdrvChild *child) 1685c2066af0SKevin Wolf { 1686c2066af0SKevin Wolf BlockBackend *blk = child->opaque; 1687c2066af0SKevin Wolf 1688c2066af0SKevin Wolf assert(blk->public.io_limits_disabled); 1689c2066af0SKevin Wolf --blk->public.io_limits_disabled; 1690c2066af0SKevin Wolf } 1691