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" 221e98fefdSKevin Wolf #include "trace.h" 23a7f53e26SMarkus Armbruster 24a7f53e26SMarkus Armbruster /* Number of coroutines to reserve per attached device model */ 25a7f53e26SMarkus Armbruster #define COROUTINE_POOL_RESERVATION 64 2626f54e9aSMarkus Armbruster 271bf1cbc9SKevin Wolf #define NOT_DONE 0x7fffffff /* used while emulated sync operation in progress */ 281bf1cbc9SKevin Wolf 294981bdecSMax Reitz static AioContext *blk_aiocb_get_aio_context(BlockAIOCB *acb); 304981bdecSMax Reitz 3126f54e9aSMarkus Armbruster struct BlockBackend { 3226f54e9aSMarkus Armbruster char *name; 3326f54e9aSMarkus Armbruster int refcnt; 34f21d96d0SKevin Wolf BdrvChild *root; 3526f8b3a8SMarkus Armbruster DriveInfo *legacy_dinfo; /* null unless created by drive_new() */ 362cf22d6aSMax Reitz QTAILQ_ENTRY(BlockBackend) link; /* for block_backends */ 379492b0b9SMax Reitz QTAILQ_ENTRY(BlockBackend) monitor_link; /* for monitor_block_backends */ 38f2cd875dSKevin Wolf BlockBackendPublic public; 39a7f53e26SMarkus Armbruster 40a7f53e26SMarkus Armbruster void *dev; /* attached device model, if any */ 41a7f53e26SMarkus Armbruster /* TODO change to DeviceState when all users are qdevified */ 42a7f53e26SMarkus Armbruster const BlockDevOps *dev_ops; 43a7f53e26SMarkus Armbruster void *dev_opaque; 4468e9ec01SMax Reitz 4568e9ec01SMax Reitz /* the block size for which the guest device expects atomicity */ 4668e9ec01SMax Reitz int guest_block_size; 477f0e9da6SMax Reitz 48281d22d8SMax Reitz /* If the BDS tree is removed, some of its options are stored here (which 49281d22d8SMax Reitz * can be used to restore those options in the new BDS on insert) */ 50281d22d8SMax Reitz BlockBackendRootState root_state; 51281d22d8SMax Reitz 52bfd18d1eSKevin Wolf bool enable_write_cache; 53bfd18d1eSKevin Wolf 547f0e9da6SMax Reitz /* I/O stats (display with "info blockstats"). */ 557f0e9da6SMax Reitz BlockAcctStats stats; 56373340b2SMax Reitz 57373340b2SMax Reitz BlockdevOnError on_read_error, on_write_error; 58373340b2SMax Reitz bool iostatus_enabled; 59373340b2SMax Reitz BlockDeviceIoStatus iostatus; 603301f6c6SMax Reitz 61c10c9d96SKevin Wolf bool allow_write_beyond_eof; 62c10c9d96SKevin Wolf 633301f6c6SMax Reitz NotifierList remove_bs_notifiers, insert_bs_notifiers; 6426f54e9aSMarkus Armbruster }; 6526f54e9aSMarkus Armbruster 66e7f7d676SMax Reitz typedef struct BlockBackendAIOCB { 67e7f7d676SMax Reitz BlockAIOCB common; 68e7f7d676SMax Reitz QEMUBH *bh; 694981bdecSMax Reitz BlockBackend *blk; 70e7f7d676SMax Reitz int ret; 71e7f7d676SMax Reitz } BlockBackendAIOCB; 72e7f7d676SMax Reitz 73e7f7d676SMax Reitz static const AIOCBInfo block_backend_aiocb_info = { 744981bdecSMax Reitz .get_aio_context = blk_aiocb_get_aio_context, 75e7f7d676SMax Reitz .aiocb_size = sizeof(BlockBackendAIOCB), 76e7f7d676SMax Reitz }; 77e7f7d676SMax Reitz 788fb3c76cSMarkus Armbruster static void drive_info_del(DriveInfo *dinfo); 797c8eece4SKevin Wolf static BlockBackend *bdrv_first_blk(BlockDriverState *bs); 808fb3c76cSMarkus Armbruster 812cf22d6aSMax Reitz /* All BlockBackends */ 822cf22d6aSMax Reitz static QTAILQ_HEAD(, BlockBackend) block_backends = 832cf22d6aSMax Reitz QTAILQ_HEAD_INITIALIZER(block_backends); 842cf22d6aSMax Reitz 859492b0b9SMax Reitz /* All BlockBackends referenced by the monitor and which are iterated through by 869492b0b9SMax Reitz * blk_next() */ 879492b0b9SMax Reitz static QTAILQ_HEAD(, BlockBackend) monitor_block_backends = 889492b0b9SMax Reitz QTAILQ_HEAD_INITIALIZER(monitor_block_backends); 8926f54e9aSMarkus Armbruster 90f21d96d0SKevin Wolf static void blk_root_inherit_options(int *child_flags, QDict *child_options, 91f21d96d0SKevin Wolf int parent_flags, QDict *parent_options) 92f21d96d0SKevin Wolf { 93f21d96d0SKevin Wolf /* We're not supposed to call this function for root nodes */ 94f21d96d0SKevin Wolf abort(); 95f21d96d0SKevin Wolf } 96c2066af0SKevin Wolf static void blk_root_drained_begin(BdrvChild *child); 97c2066af0SKevin Wolf static void blk_root_drained_end(BdrvChild *child); 98f21d96d0SKevin Wolf 995c8cab48SKevin Wolf static void blk_root_change_media(BdrvChild *child, bool load); 1005c8cab48SKevin Wolf static void blk_root_resize(BdrvChild *child); 1015c8cab48SKevin Wolf 1024c265bf9SKevin Wolf static const char *blk_root_get_name(BdrvChild *child) 1034c265bf9SKevin Wolf { 1044c265bf9SKevin Wolf return blk_name(child->opaque); 1054c265bf9SKevin Wolf } 1064c265bf9SKevin Wolf 107f21d96d0SKevin Wolf static const BdrvChildRole child_root = { 108f21d96d0SKevin Wolf .inherit_options = blk_root_inherit_options, 109c2066af0SKevin Wolf 1105c8cab48SKevin Wolf .change_media = blk_root_change_media, 1115c8cab48SKevin Wolf .resize = blk_root_resize, 1124c265bf9SKevin Wolf .get_name = blk_root_get_name, 1135c8cab48SKevin Wolf 114c2066af0SKevin Wolf .drained_begin = blk_root_drained_begin, 115c2066af0SKevin Wolf .drained_end = blk_root_drained_end, 116f21d96d0SKevin Wolf }; 117f21d96d0SKevin Wolf 11826f54e9aSMarkus Armbruster /* 119efaa7c4eSMax Reitz * Create a new BlockBackend with a reference count of one. 12026f54e9aSMarkus Armbruster * Store an error through @errp on failure, unless it's null. 12126f54e9aSMarkus Armbruster * Return the new BlockBackend on success, null on failure. 12226f54e9aSMarkus Armbruster */ 123109525adSMax Reitz BlockBackend *blk_new(void) 12426f54e9aSMarkus Armbruster { 12526f54e9aSMarkus Armbruster BlockBackend *blk; 12626f54e9aSMarkus Armbruster 12726f54e9aSMarkus Armbruster blk = g_new0(BlockBackend, 1); 12826f54e9aSMarkus Armbruster blk->refcnt = 1; 1290c3169dfSKevin Wolf blk_set_enable_write_cache(blk, true); 1300c3169dfSKevin Wolf 13127ccdd52SKevin Wolf qemu_co_queue_init(&blk->public.throttled_reqs[0]); 13227ccdd52SKevin Wolf qemu_co_queue_init(&blk->public.throttled_reqs[1]); 13327ccdd52SKevin Wolf 1343301f6c6SMax Reitz notifier_list_init(&blk->remove_bs_notifiers); 1353301f6c6SMax Reitz notifier_list_init(&blk->insert_bs_notifiers); 13627ccdd52SKevin Wolf 1372cf22d6aSMax Reitz QTAILQ_INSERT_TAIL(&block_backends, blk, link); 13826f54e9aSMarkus Armbruster return blk; 13926f54e9aSMarkus Armbruster } 14026f54e9aSMarkus Armbruster 1417e7d56d9SMarkus Armbruster /* 14228eb9b12SMax Reitz * Creates a new BlockBackend, opens a new BlockDriverState, and connects both. 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; 15728eb9b12SMax Reitz BlockDriverState *bs; 158ca49a4fdSMax Reitz 159109525adSMax Reitz blk = blk_new(); 1605b363937SMax Reitz bs = bdrv_open(filename, reference, options, flags, errp); 1615b363937SMax Reitz if (!bs) { 162ca49a4fdSMax Reitz blk_unref(blk); 163ca49a4fdSMax Reitz return NULL; 164ca49a4fdSMax Reitz } 165ca49a4fdSMax Reitz 16636fe1331SKevin Wolf blk->root = bdrv_root_attach_child(bs, "root", &child_root, blk); 16772e775c7SKevin Wolf 168ca49a4fdSMax Reitz return blk; 169ca49a4fdSMax Reitz } 170ca49a4fdSMax Reitz 17126f54e9aSMarkus Armbruster static void blk_delete(BlockBackend *blk) 17226f54e9aSMarkus Armbruster { 17326f54e9aSMarkus Armbruster assert(!blk->refcnt); 174e5e78550SMax Reitz assert(!blk->name); 175a7f53e26SMarkus Armbruster assert(!blk->dev); 176f21d96d0SKevin Wolf if (blk->root) { 17713855c6bSMax Reitz blk_remove_bs(blk); 1787e7d56d9SMarkus Armbruster } 1793301f6c6SMax Reitz assert(QLIST_EMPTY(&blk->remove_bs_notifiers.notifiers)); 1803301f6c6SMax Reitz assert(QLIST_EMPTY(&blk->insert_bs_notifiers.notifiers)); 1812cf22d6aSMax Reitz QTAILQ_REMOVE(&block_backends, blk, link); 18218e46a03SMarkus Armbruster drive_info_del(blk->legacy_dinfo); 183979e9b03SAlberto Garcia block_acct_cleanup(&blk->stats); 18426f54e9aSMarkus Armbruster g_free(blk); 18526f54e9aSMarkus Armbruster } 18626f54e9aSMarkus Armbruster 1878fb3c76cSMarkus Armbruster static void drive_info_del(DriveInfo *dinfo) 1888fb3c76cSMarkus Armbruster { 1898fb3c76cSMarkus Armbruster if (!dinfo) { 1908fb3c76cSMarkus Armbruster return; 1918fb3c76cSMarkus Armbruster } 1928fb3c76cSMarkus Armbruster qemu_opts_del(dinfo->opts); 1938fb3c76cSMarkus Armbruster g_free(dinfo->serial); 1948fb3c76cSMarkus Armbruster g_free(dinfo); 1958fb3c76cSMarkus Armbruster } 1968fb3c76cSMarkus Armbruster 197f636ae85SAlberto Garcia int blk_get_refcnt(BlockBackend *blk) 198f636ae85SAlberto Garcia { 199f636ae85SAlberto Garcia return blk ? blk->refcnt : 0; 200f636ae85SAlberto Garcia } 201f636ae85SAlberto Garcia 20226f54e9aSMarkus Armbruster /* 20326f54e9aSMarkus Armbruster * Increment @blk's reference count. 20426f54e9aSMarkus Armbruster * @blk must not be null. 20526f54e9aSMarkus Armbruster */ 20626f54e9aSMarkus Armbruster void blk_ref(BlockBackend *blk) 20726f54e9aSMarkus Armbruster { 20826f54e9aSMarkus Armbruster blk->refcnt++; 20926f54e9aSMarkus Armbruster } 21026f54e9aSMarkus Armbruster 21126f54e9aSMarkus Armbruster /* 21226f54e9aSMarkus Armbruster * Decrement @blk's reference count. 21326f54e9aSMarkus Armbruster * If this drops it to zero, destroy @blk. 21426f54e9aSMarkus Armbruster * For convenience, do nothing if @blk is null. 21526f54e9aSMarkus Armbruster */ 21626f54e9aSMarkus Armbruster void blk_unref(BlockBackend *blk) 21726f54e9aSMarkus Armbruster { 21826f54e9aSMarkus Armbruster if (blk) { 21926f54e9aSMarkus Armbruster assert(blk->refcnt > 0); 22026f54e9aSMarkus Armbruster if (!--blk->refcnt) { 22126f54e9aSMarkus Armbruster blk_delete(blk); 22226f54e9aSMarkus Armbruster } 22326f54e9aSMarkus Armbruster } 22426f54e9aSMarkus Armbruster } 22526f54e9aSMarkus Armbruster 2262cf22d6aSMax Reitz /* 2272cf22d6aSMax Reitz * Behaves similarly to blk_next() but iterates over all BlockBackends, even the 2282cf22d6aSMax Reitz * ones which are hidden (i.e. are not referenced by the monitor). 2292cf22d6aSMax Reitz */ 2302cf22d6aSMax Reitz static BlockBackend *blk_all_next(BlockBackend *blk) 2312cf22d6aSMax Reitz { 2322cf22d6aSMax Reitz return blk ? QTAILQ_NEXT(blk, link) 2332cf22d6aSMax Reitz : QTAILQ_FIRST(&block_backends); 2342cf22d6aSMax Reitz } 2352cf22d6aSMax Reitz 236d8da3cefSMax Reitz void blk_remove_all_bs(void) 237d8da3cefSMax Reitz { 23874d1b8fcSMax Reitz BlockBackend *blk = NULL; 239d8da3cefSMax Reitz 2402cf22d6aSMax Reitz while ((blk = blk_all_next(blk)) != NULL) { 241d8da3cefSMax Reitz AioContext *ctx = blk_get_aio_context(blk); 242d8da3cefSMax Reitz 243d8da3cefSMax Reitz aio_context_acquire(ctx); 244f21d96d0SKevin Wolf if (blk->root) { 245d8da3cefSMax Reitz blk_remove_bs(blk); 246d8da3cefSMax Reitz } 247d8da3cefSMax Reitz aio_context_release(ctx); 248d8da3cefSMax Reitz } 249d8da3cefSMax Reitz } 250d8da3cefSMax Reitz 25126f54e9aSMarkus Armbruster /* 2529492b0b9SMax Reitz * Return the monitor-owned BlockBackend after @blk. 25326f54e9aSMarkus Armbruster * If @blk is null, return the first one. 25426f54e9aSMarkus Armbruster * Else, return @blk's next sibling, which may be null. 25526f54e9aSMarkus Armbruster * 25626f54e9aSMarkus Armbruster * To iterate over all BlockBackends, do 25726f54e9aSMarkus Armbruster * for (blk = blk_next(NULL); blk; blk = blk_next(blk)) { 25826f54e9aSMarkus Armbruster * ... 25926f54e9aSMarkus Armbruster * } 26026f54e9aSMarkus Armbruster */ 26126f54e9aSMarkus Armbruster BlockBackend *blk_next(BlockBackend *blk) 26226f54e9aSMarkus Armbruster { 2639492b0b9SMax Reitz return blk ? QTAILQ_NEXT(blk, monitor_link) 2649492b0b9SMax Reitz : QTAILQ_FIRST(&monitor_block_backends); 26526f54e9aSMarkus Armbruster } 26626f54e9aSMarkus Armbruster 2677c8eece4SKevin Wolf /* Iterates over all top-level BlockDriverStates, i.e. BDSs that are owned by 2687c8eece4SKevin Wolf * the monitor or attached to a BlockBackend */ 26988be7b4bSKevin Wolf BlockDriverState *bdrv_next(BdrvNextIterator *it) 2707c8eece4SKevin Wolf { 27188be7b4bSKevin Wolf BlockDriverState *bs; 272981f4f57SMax Reitz 2737c8eece4SKevin Wolf /* First, return all root nodes of BlockBackends. In order to avoid 2747c8eece4SKevin Wolf * returning a BDS twice when multiple BBs refer to it, we only return it 2757c8eece4SKevin Wolf * if the BB is the first one in the parent list of the BDS. */ 2767c8eece4SKevin Wolf if (it->phase == BDRV_NEXT_BACKEND_ROOTS) { 277981f4f57SMax Reitz do { 2787c8eece4SKevin Wolf it->blk = blk_all_next(it->blk); 27988be7b4bSKevin Wolf bs = it->blk ? blk_bs(it->blk) : NULL; 28088be7b4bSKevin Wolf } while (it->blk && (bs == NULL || bdrv_first_blk(bs) != it->blk)); 281981f4f57SMax Reitz 28288be7b4bSKevin Wolf if (bs) { 28388be7b4bSKevin Wolf return bs; 2847c8eece4SKevin Wolf } 2857c8eece4SKevin Wolf it->phase = BDRV_NEXT_MONITOR_OWNED; 2867c8eece4SKevin Wolf } 2877c8eece4SKevin Wolf 2887c8eece4SKevin Wolf /* Then return the monitor-owned BDSes without a BB attached. Ignore all 2897c8eece4SKevin Wolf * BDSes that are attached to a BlockBackend here; they have been handled 2907c8eece4SKevin Wolf * by the above block already */ 2917c8eece4SKevin Wolf do { 2927c8eece4SKevin Wolf it->bs = bdrv_next_monitor_owned(it->bs); 29388be7b4bSKevin Wolf bs = it->bs; 29488be7b4bSKevin Wolf } while (bs && bdrv_has_blk(bs)); 2957c8eece4SKevin Wolf 29688be7b4bSKevin Wolf return bs; 29788be7b4bSKevin Wolf } 29888be7b4bSKevin Wolf 29988be7b4bSKevin Wolf BlockDriverState *bdrv_first(BdrvNextIterator *it) 30088be7b4bSKevin Wolf { 30188be7b4bSKevin Wolf *it = (BdrvNextIterator) { 30288be7b4bSKevin Wolf .phase = BDRV_NEXT_BACKEND_ROOTS, 30388be7b4bSKevin Wolf }; 30488be7b4bSKevin Wolf 30588be7b4bSKevin Wolf return bdrv_next(it); 306981f4f57SMax Reitz } 307981f4f57SMax Reitz 308981f4f57SMax Reitz /* 309e5e78550SMax Reitz * Add a BlockBackend into the list of backends referenced by the monitor, with 310e5e78550SMax Reitz * the given @name acting as the handle for the monitor. 311e5e78550SMax Reitz * Strictly for use by blockdev.c. 312e5e78550SMax Reitz * 313e5e78550SMax Reitz * @name must not be null or empty. 314e5e78550SMax Reitz * 315e5e78550SMax Reitz * Returns true on success and false on failure. In the latter case, an Error 316e5e78550SMax Reitz * object is returned through @errp. 317e5e78550SMax Reitz */ 318e5e78550SMax Reitz bool monitor_add_blk(BlockBackend *blk, const char *name, Error **errp) 319e5e78550SMax Reitz { 320e5e78550SMax Reitz assert(!blk->name); 321e5e78550SMax Reitz assert(name && name[0]); 322e5e78550SMax Reitz 323e5e78550SMax Reitz if (!id_wellformed(name)) { 324e5e78550SMax Reitz error_setg(errp, "Invalid device name"); 325e5e78550SMax Reitz return false; 326e5e78550SMax Reitz } 327e5e78550SMax Reitz if (blk_by_name(name)) { 328e5e78550SMax Reitz error_setg(errp, "Device with id '%s' already exists", name); 329e5e78550SMax Reitz return false; 330e5e78550SMax Reitz } 331e5e78550SMax Reitz if (bdrv_find_node(name)) { 332e5e78550SMax Reitz error_setg(errp, 333e5e78550SMax Reitz "Device name '%s' conflicts with an existing node name", 334e5e78550SMax Reitz name); 335e5e78550SMax Reitz return false; 336e5e78550SMax Reitz } 337e5e78550SMax Reitz 338e5e78550SMax Reitz blk->name = g_strdup(name); 339e5e78550SMax Reitz QTAILQ_INSERT_TAIL(&monitor_block_backends, blk, monitor_link); 340e5e78550SMax Reitz return true; 341e5e78550SMax Reitz } 342e5e78550SMax Reitz 343e5e78550SMax Reitz /* 344e5e78550SMax Reitz * Remove a BlockBackend from the list of backends referenced by the monitor. 345e5e78550SMax Reitz * Strictly for use by blockdev.c. 346e5e78550SMax Reitz */ 347e5e78550SMax Reitz void monitor_remove_blk(BlockBackend *blk) 348e5e78550SMax Reitz { 349e5e78550SMax Reitz if (!blk->name) { 350e5e78550SMax Reitz return; 351e5e78550SMax Reitz } 352e5e78550SMax Reitz 353e5e78550SMax Reitz QTAILQ_REMOVE(&monitor_block_backends, blk, monitor_link); 354e5e78550SMax Reitz g_free(blk->name); 355e5e78550SMax Reitz blk->name = NULL; 356e5e78550SMax Reitz } 357e5e78550SMax Reitz 358e5e78550SMax Reitz /* 3597e7d56d9SMarkus Armbruster * Return @blk's name, a non-null string. 360e5e78550SMax Reitz * Returns an empty string iff @blk is not referenced by the monitor. 36126f54e9aSMarkus Armbruster */ 36226f54e9aSMarkus Armbruster const char *blk_name(BlockBackend *blk) 36326f54e9aSMarkus Armbruster { 364e5e78550SMax Reitz return blk->name ?: ""; 36526f54e9aSMarkus Armbruster } 36626f54e9aSMarkus Armbruster 36726f54e9aSMarkus Armbruster /* 36826f54e9aSMarkus Armbruster * Return the BlockBackend with name @name if it exists, else null. 36926f54e9aSMarkus Armbruster * @name must not be null. 37026f54e9aSMarkus Armbruster */ 37126f54e9aSMarkus Armbruster BlockBackend *blk_by_name(const char *name) 37226f54e9aSMarkus Armbruster { 37374d1b8fcSMax Reitz BlockBackend *blk = NULL; 37426f54e9aSMarkus Armbruster 37526f54e9aSMarkus Armbruster assert(name); 37674d1b8fcSMax Reitz while ((blk = blk_next(blk)) != NULL) { 37726f54e9aSMarkus Armbruster if (!strcmp(name, blk->name)) { 37826f54e9aSMarkus Armbruster return blk; 37926f54e9aSMarkus Armbruster } 38026f54e9aSMarkus Armbruster } 38126f54e9aSMarkus Armbruster return NULL; 38226f54e9aSMarkus Armbruster } 3837e7d56d9SMarkus Armbruster 3847e7d56d9SMarkus Armbruster /* 3857e7d56d9SMarkus Armbruster * Return the BlockDriverState attached to @blk if any, else null. 3867e7d56d9SMarkus Armbruster */ 3877e7d56d9SMarkus Armbruster BlockDriverState *blk_bs(BlockBackend *blk) 3887e7d56d9SMarkus Armbruster { 389f21d96d0SKevin Wolf return blk->root ? blk->root->bs : NULL; 3907e7d56d9SMarkus Armbruster } 3917e7d56d9SMarkus Armbruster 3927c8eece4SKevin Wolf static BlockBackend *bdrv_first_blk(BlockDriverState *bs) 393dde33812SKevin Wolf { 394dde33812SKevin Wolf BdrvChild *child; 395dde33812SKevin Wolf QLIST_FOREACH(child, &bs->parents, next_parent) { 396dde33812SKevin Wolf if (child->role == &child_root) { 3977c8eece4SKevin Wolf return child->opaque; 398dde33812SKevin Wolf } 399dde33812SKevin Wolf } 400dde33812SKevin Wolf 4017c8eece4SKevin Wolf return NULL; 4027c8eece4SKevin Wolf } 4037c8eece4SKevin Wolf 4047c8eece4SKevin Wolf /* 4057c8eece4SKevin Wolf * Returns true if @bs has an associated BlockBackend. 4067c8eece4SKevin Wolf */ 4077c8eece4SKevin Wolf bool bdrv_has_blk(BlockDriverState *bs) 4087c8eece4SKevin Wolf { 4097c8eece4SKevin Wolf return bdrv_first_blk(bs) != NULL; 410dde33812SKevin Wolf } 411dde33812SKevin Wolf 412dde33812SKevin Wolf /* 41318e46a03SMarkus Armbruster * Return @blk's DriveInfo if any, else null. 41418e46a03SMarkus Armbruster */ 41518e46a03SMarkus Armbruster DriveInfo *blk_legacy_dinfo(BlockBackend *blk) 41618e46a03SMarkus Armbruster { 41718e46a03SMarkus Armbruster return blk->legacy_dinfo; 41818e46a03SMarkus Armbruster } 41918e46a03SMarkus Armbruster 42018e46a03SMarkus Armbruster /* 42118e46a03SMarkus Armbruster * Set @blk's DriveInfo to @dinfo, and return it. 42218e46a03SMarkus Armbruster * @blk must not have a DriveInfo set already. 42318e46a03SMarkus Armbruster * No other BlockBackend may have the same DriveInfo set. 42418e46a03SMarkus Armbruster */ 42518e46a03SMarkus Armbruster DriveInfo *blk_set_legacy_dinfo(BlockBackend *blk, DriveInfo *dinfo) 42618e46a03SMarkus Armbruster { 42718e46a03SMarkus Armbruster assert(!blk->legacy_dinfo); 42818e46a03SMarkus Armbruster return blk->legacy_dinfo = dinfo; 42918e46a03SMarkus Armbruster } 43018e46a03SMarkus Armbruster 43118e46a03SMarkus Armbruster /* 43218e46a03SMarkus Armbruster * Return the BlockBackend with DriveInfo @dinfo. 43318e46a03SMarkus Armbruster * It must exist. 43418e46a03SMarkus Armbruster */ 43518e46a03SMarkus Armbruster BlockBackend *blk_by_legacy_dinfo(DriveInfo *dinfo) 43618e46a03SMarkus Armbruster { 43774d1b8fcSMax Reitz BlockBackend *blk = NULL; 43818e46a03SMarkus Armbruster 43974d1b8fcSMax Reitz while ((blk = blk_next(blk)) != NULL) { 44018e46a03SMarkus Armbruster if (blk->legacy_dinfo == dinfo) { 44118e46a03SMarkus Armbruster return blk; 44218e46a03SMarkus Armbruster } 44318e46a03SMarkus Armbruster } 44418e46a03SMarkus Armbruster abort(); 44518e46a03SMarkus Armbruster } 44618e46a03SMarkus Armbruster 44718e46a03SMarkus Armbruster /* 448f2cd875dSKevin Wolf * Returns a pointer to the publicly accessible fields of @blk. 449f2cd875dSKevin Wolf */ 450f2cd875dSKevin Wolf BlockBackendPublic *blk_get_public(BlockBackend *blk) 451f2cd875dSKevin Wolf { 452f2cd875dSKevin Wolf return &blk->public; 453f2cd875dSKevin Wolf } 454f2cd875dSKevin Wolf 455f2cd875dSKevin Wolf /* 456f2cd875dSKevin Wolf * Returns a BlockBackend given the associated @public fields. 457f2cd875dSKevin Wolf */ 458f2cd875dSKevin Wolf BlockBackend *blk_by_public(BlockBackendPublic *public) 459f2cd875dSKevin Wolf { 460f2cd875dSKevin Wolf return container_of(public, BlockBackend, public); 461f2cd875dSKevin Wolf } 462f2cd875dSKevin Wolf 463f2cd875dSKevin Wolf /* 4641c95f7e1SMax Reitz * Disassociates the currently associated BlockDriverState from @blk. 4651c95f7e1SMax Reitz */ 4661c95f7e1SMax Reitz void blk_remove_bs(BlockBackend *blk) 4671c95f7e1SMax Reitz { 4683301f6c6SMax Reitz notifier_list_notify(&blk->remove_bs_notifiers, blk); 4697ca7f0f6SKevin Wolf if (blk->public.throttle_state) { 4707ca7f0f6SKevin Wolf throttle_timers_detach_aio_context(&blk->public.throttle_timers); 4717ca7f0f6SKevin Wolf } 4723301f6c6SMax Reitz 4731c95f7e1SMax Reitz blk_update_root_state(blk); 4741c95f7e1SMax Reitz 475f21d96d0SKevin Wolf bdrv_root_unref_child(blk->root); 476f21d96d0SKevin Wolf blk->root = NULL; 4771c95f7e1SMax Reitz } 4781c95f7e1SMax Reitz 4791c95f7e1SMax Reitz /* 4800c3c36d6SMax Reitz * Associates a new BlockDriverState with @blk. 4810c3c36d6SMax Reitz */ 4820c3c36d6SMax Reitz void blk_insert_bs(BlockBackend *blk, BlockDriverState *bs) 4830c3c36d6SMax Reitz { 4840c3c36d6SMax Reitz bdrv_ref(bs); 48536fe1331SKevin Wolf blk->root = bdrv_root_attach_child(bs, "root", &child_root, 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 7451e98fefdSKevin Wolf int coroutine_fn blk_co_preadv(BlockBackend *blk, int64_t offset, 7461bf1cbc9SKevin Wolf unsigned int bytes, QEMUIOVector *qiov, 7471bf1cbc9SKevin Wolf BdrvRequestFlags flags) 7484be74634SMarkus Armbruster { 7491e98fefdSKevin Wolf int ret; 7501e98fefdSKevin Wolf 7511e98fefdSKevin Wolf trace_blk_co_preadv(blk, blk_bs(blk), offset, bytes, flags); 7521e98fefdSKevin Wolf 7531e98fefdSKevin Wolf ret = blk_check_byte_request(blk, offset, bytes); 754e7f7d676SMax Reitz if (ret < 0) { 755e7f7d676SMax Reitz return ret; 756e7f7d676SMax Reitz } 757e7f7d676SMax Reitz 758441565b2SKevin Wolf /* throttling disk I/O */ 759441565b2SKevin Wolf if (blk->public.throttle_state) { 760441565b2SKevin Wolf throttle_group_co_io_limits_intercept(blk, bytes, false); 761441565b2SKevin Wolf } 762441565b2SKevin Wolf 763a03ef88fSKevin Wolf return bdrv_co_preadv(blk->root, offset, bytes, qiov, flags); 7641bf1cbc9SKevin Wolf } 7651bf1cbc9SKevin Wolf 7661e98fefdSKevin Wolf int coroutine_fn blk_co_pwritev(BlockBackend *blk, int64_t offset, 767a8823a3bSKevin Wolf unsigned int bytes, QEMUIOVector *qiov, 768a8823a3bSKevin Wolf BdrvRequestFlags flags) 769a8823a3bSKevin Wolf { 770bfd18d1eSKevin Wolf int ret; 771bfd18d1eSKevin Wolf 7721e98fefdSKevin Wolf trace_blk_co_pwritev(blk, blk_bs(blk), offset, bytes, flags); 7731e98fefdSKevin Wolf 774bfd18d1eSKevin Wolf ret = blk_check_byte_request(blk, offset, bytes); 775a8823a3bSKevin Wolf if (ret < 0) { 776a8823a3bSKevin Wolf return ret; 777a8823a3bSKevin Wolf } 778a8823a3bSKevin Wolf 779441565b2SKevin Wolf /* throttling disk I/O */ 780441565b2SKevin Wolf if (blk->public.throttle_state) { 781441565b2SKevin Wolf throttle_group_co_io_limits_intercept(blk, bytes, true); 782441565b2SKevin Wolf } 783441565b2SKevin Wolf 784bfd18d1eSKevin Wolf if (!blk->enable_write_cache) { 785bfd18d1eSKevin Wolf flags |= BDRV_REQ_FUA; 786bfd18d1eSKevin Wolf } 787bfd18d1eSKevin Wolf 788a03ef88fSKevin Wolf return bdrv_co_pwritev(blk->root, offset, bytes, qiov, flags); 789a8823a3bSKevin Wolf } 790a8823a3bSKevin Wolf 7911bf1cbc9SKevin Wolf typedef struct BlkRwCo { 7921bf1cbc9SKevin Wolf BlockBackend *blk; 7931bf1cbc9SKevin Wolf int64_t offset; 7941bf1cbc9SKevin Wolf QEMUIOVector *qiov; 7951bf1cbc9SKevin Wolf int ret; 7961bf1cbc9SKevin Wolf BdrvRequestFlags flags; 7971bf1cbc9SKevin Wolf } BlkRwCo; 7981bf1cbc9SKevin Wolf 7991bf1cbc9SKevin Wolf static void blk_read_entry(void *opaque) 8001bf1cbc9SKevin Wolf { 8011bf1cbc9SKevin Wolf BlkRwCo *rwco = opaque; 8021bf1cbc9SKevin Wolf 8031bf1cbc9SKevin Wolf rwco->ret = blk_co_preadv(rwco->blk, rwco->offset, rwco->qiov->size, 8041bf1cbc9SKevin Wolf rwco->qiov, rwco->flags); 8051bf1cbc9SKevin Wolf } 8061bf1cbc9SKevin Wolf 807a8823a3bSKevin Wolf static void blk_write_entry(void *opaque) 808a8823a3bSKevin Wolf { 809a8823a3bSKevin Wolf BlkRwCo *rwco = opaque; 810a8823a3bSKevin Wolf 811a8823a3bSKevin Wolf rwco->ret = blk_co_pwritev(rwco->blk, rwco->offset, rwco->qiov->size, 812a8823a3bSKevin Wolf rwco->qiov, rwco->flags); 813a8823a3bSKevin Wolf } 814a8823a3bSKevin Wolf 815a55d3fbaSKevin Wolf static int blk_prw(BlockBackend *blk, int64_t offset, uint8_t *buf, 816a55d3fbaSKevin Wolf int64_t bytes, CoroutineEntry co_entry, 817fc1453cdSKevin Wolf BdrvRequestFlags flags) 8181bf1cbc9SKevin Wolf { 8191bf1cbc9SKevin Wolf AioContext *aio_context; 8201bf1cbc9SKevin Wolf QEMUIOVector qiov; 8211bf1cbc9SKevin Wolf struct iovec iov; 8221bf1cbc9SKevin Wolf Coroutine *co; 8231bf1cbc9SKevin Wolf BlkRwCo rwco; 8241bf1cbc9SKevin Wolf 8251bf1cbc9SKevin Wolf iov = (struct iovec) { 8261bf1cbc9SKevin Wolf .iov_base = buf, 827a55d3fbaSKevin Wolf .iov_len = bytes, 8281bf1cbc9SKevin Wolf }; 8291bf1cbc9SKevin Wolf qemu_iovec_init_external(&qiov, &iov, 1); 8301bf1cbc9SKevin Wolf 8311bf1cbc9SKevin Wolf rwco = (BlkRwCo) { 8321bf1cbc9SKevin Wolf .blk = blk, 833a55d3fbaSKevin Wolf .offset = offset, 8341bf1cbc9SKevin Wolf .qiov = &qiov, 835fc1453cdSKevin Wolf .flags = flags, 8361bf1cbc9SKevin Wolf .ret = NOT_DONE, 8371bf1cbc9SKevin Wolf }; 8381bf1cbc9SKevin Wolf 8390b8b8753SPaolo Bonzini co = qemu_coroutine_create(co_entry, &rwco); 8400b8b8753SPaolo Bonzini qemu_coroutine_enter(co); 8411bf1cbc9SKevin Wolf 8421bf1cbc9SKevin Wolf aio_context = blk_get_aio_context(blk); 8431bf1cbc9SKevin Wolf while (rwco.ret == NOT_DONE) { 8441bf1cbc9SKevin Wolf aio_poll(aio_context, true); 8451bf1cbc9SKevin Wolf } 8461bf1cbc9SKevin Wolf 8471bf1cbc9SKevin Wolf return rwco.ret; 8484be74634SMarkus Armbruster } 8494be74634SMarkus Armbruster 850b7d17f9fSEric Blake int blk_pread_unthrottled(BlockBackend *blk, int64_t offset, uint8_t *buf, 851b7d17f9fSEric Blake int count) 8524be74634SMarkus Armbruster { 8535bd51196SKevin Wolf int ret; 8545bd51196SKevin Wolf 855b7d17f9fSEric Blake ret = blk_check_byte_request(blk, offset, count); 856e7f7d676SMax Reitz if (ret < 0) { 857e7f7d676SMax Reitz return ret; 858e7f7d676SMax Reitz } 859e7f7d676SMax Reitz 860c2066af0SKevin Wolf blk_root_drained_begin(blk->root); 861b7d17f9fSEric Blake ret = blk_pread(blk, offset, buf, count); 862c2066af0SKevin Wolf blk_root_drained_end(blk->root); 8635bd51196SKevin Wolf return ret; 8644be74634SMarkus Armbruster } 8654be74634SMarkus Armbruster 866d004bd52SEric Blake int blk_pwrite_zeroes(BlockBackend *blk, int64_t offset, 867983a1600SEric Blake int count, BdrvRequestFlags flags) 8680df89e8eSKevin Wolf { 869983a1600SEric Blake return blk_prw(blk, offset, NULL, count, blk_write_entry, 87016aaf975SKevin Wolf flags | BDRV_REQ_ZERO_WRITE); 8710df89e8eSKevin Wolf } 8720df89e8eSKevin Wolf 873720ff280SKevin Wolf int blk_make_zero(BlockBackend *blk, BdrvRequestFlags flags) 874720ff280SKevin Wolf { 875720ff280SKevin Wolf return bdrv_make_zero(blk->root, flags); 876720ff280SKevin Wolf } 877720ff280SKevin Wolf 878e7f7d676SMax Reitz static void error_callback_bh(void *opaque) 879e7f7d676SMax Reitz { 880e7f7d676SMax Reitz struct BlockBackendAIOCB *acb = opaque; 881e7f7d676SMax Reitz qemu_bh_delete(acb->bh); 882e7f7d676SMax Reitz acb->common.cb(acb->common.opaque, acb->ret); 883e7f7d676SMax Reitz qemu_aio_unref(acb); 884e7f7d676SMax Reitz } 885e7f7d676SMax Reitz 886ca78ecfaSPeter Lieven BlockAIOCB *blk_abort_aio_request(BlockBackend *blk, 887ca78ecfaSPeter Lieven BlockCompletionFunc *cb, 888e7f7d676SMax Reitz void *opaque, int ret) 889e7f7d676SMax Reitz { 890e7f7d676SMax Reitz struct BlockBackendAIOCB *acb; 891e7f7d676SMax Reitz QEMUBH *bh; 892e7f7d676SMax Reitz 893e7f7d676SMax Reitz acb = blk_aio_get(&block_backend_aiocb_info, blk, cb, opaque); 8944981bdecSMax Reitz acb->blk = blk; 895e7f7d676SMax Reitz acb->ret = ret; 896e7f7d676SMax Reitz 897e7f7d676SMax Reitz bh = aio_bh_new(blk_get_aio_context(blk), error_callback_bh, acb); 898e7f7d676SMax Reitz acb->bh = bh; 899e7f7d676SMax Reitz qemu_bh_schedule(bh); 900e7f7d676SMax Reitz 901e7f7d676SMax Reitz return &acb->common; 902e7f7d676SMax Reitz } 903e7f7d676SMax Reitz 90457d6a428SKevin Wolf typedef struct BlkAioEmAIOCB { 90557d6a428SKevin Wolf BlockAIOCB common; 90657d6a428SKevin Wolf BlkRwCo rwco; 9077fa84cd8SKevin Wolf int bytes; 90857d6a428SKevin Wolf bool has_returned; 90957d6a428SKevin Wolf QEMUBH* bh; 91057d6a428SKevin Wolf } BlkAioEmAIOCB; 91157d6a428SKevin Wolf 91257d6a428SKevin Wolf static const AIOCBInfo blk_aio_em_aiocb_info = { 91357d6a428SKevin Wolf .aiocb_size = sizeof(BlkAioEmAIOCB), 91457d6a428SKevin Wolf }; 91557d6a428SKevin Wolf 91657d6a428SKevin Wolf static void blk_aio_complete(BlkAioEmAIOCB *acb) 91757d6a428SKevin Wolf { 91857d6a428SKevin Wolf if (acb->bh) { 91957d6a428SKevin Wolf assert(acb->has_returned); 92057d6a428SKevin Wolf qemu_bh_delete(acb->bh); 92157d6a428SKevin Wolf } 92257d6a428SKevin Wolf if (acb->has_returned) { 92357d6a428SKevin Wolf acb->common.cb(acb->common.opaque, acb->rwco.ret); 92457d6a428SKevin Wolf qemu_aio_unref(acb); 92557d6a428SKevin Wolf } 92657d6a428SKevin Wolf } 92757d6a428SKevin Wolf 92857d6a428SKevin Wolf static void blk_aio_complete_bh(void *opaque) 92957d6a428SKevin Wolf { 93057d6a428SKevin Wolf blk_aio_complete(opaque); 93157d6a428SKevin Wolf } 93257d6a428SKevin Wolf 9337fa84cd8SKevin Wolf static BlockAIOCB *blk_aio_prwv(BlockBackend *blk, int64_t offset, int bytes, 93457d6a428SKevin Wolf QEMUIOVector *qiov, CoroutineEntry co_entry, 93557d6a428SKevin Wolf BdrvRequestFlags flags, 93657d6a428SKevin Wolf BlockCompletionFunc *cb, void *opaque) 93757d6a428SKevin Wolf { 93857d6a428SKevin Wolf BlkAioEmAIOCB *acb; 93957d6a428SKevin Wolf Coroutine *co; 94057d6a428SKevin Wolf 94157d6a428SKevin Wolf acb = blk_aio_get(&blk_aio_em_aiocb_info, blk, cb, opaque); 94257d6a428SKevin Wolf acb->rwco = (BlkRwCo) { 94357d6a428SKevin Wolf .blk = blk, 94457d6a428SKevin Wolf .offset = offset, 94557d6a428SKevin Wolf .qiov = qiov, 94657d6a428SKevin Wolf .flags = flags, 94757d6a428SKevin Wolf .ret = NOT_DONE, 94857d6a428SKevin Wolf }; 9497fa84cd8SKevin Wolf acb->bytes = bytes; 95057d6a428SKevin Wolf acb->bh = NULL; 95157d6a428SKevin Wolf acb->has_returned = false; 95257d6a428SKevin Wolf 9530b8b8753SPaolo Bonzini co = qemu_coroutine_create(co_entry, acb); 9540b8b8753SPaolo Bonzini qemu_coroutine_enter(co); 95557d6a428SKevin Wolf 95657d6a428SKevin Wolf acb->has_returned = true; 95757d6a428SKevin Wolf if (acb->rwco.ret != NOT_DONE) { 95857d6a428SKevin Wolf acb->bh = aio_bh_new(blk_get_aio_context(blk), blk_aio_complete_bh, acb); 95957d6a428SKevin Wolf qemu_bh_schedule(acb->bh); 96057d6a428SKevin Wolf } 96157d6a428SKevin Wolf 96257d6a428SKevin Wolf return &acb->common; 96357d6a428SKevin Wolf } 96457d6a428SKevin Wolf 96557d6a428SKevin Wolf static void blk_aio_read_entry(void *opaque) 96657d6a428SKevin Wolf { 96757d6a428SKevin Wolf BlkAioEmAIOCB *acb = opaque; 96857d6a428SKevin Wolf BlkRwCo *rwco = &acb->rwco; 96957d6a428SKevin Wolf 9707fa84cd8SKevin Wolf assert(rwco->qiov->size == acb->bytes); 9717fa84cd8SKevin Wolf rwco->ret = blk_co_preadv(rwco->blk, rwco->offset, acb->bytes, 97257d6a428SKevin Wolf rwco->qiov, rwco->flags); 97357d6a428SKevin Wolf blk_aio_complete(acb); 97457d6a428SKevin Wolf } 97557d6a428SKevin Wolf 97657d6a428SKevin Wolf static void blk_aio_write_entry(void *opaque) 97757d6a428SKevin Wolf { 97857d6a428SKevin Wolf BlkAioEmAIOCB *acb = opaque; 97957d6a428SKevin Wolf BlkRwCo *rwco = &acb->rwco; 98057d6a428SKevin Wolf 9817fa84cd8SKevin Wolf assert(!rwco->qiov || rwco->qiov->size == acb->bytes); 9827fa84cd8SKevin Wolf rwco->ret = blk_co_pwritev(rwco->blk, rwco->offset, acb->bytes, 98357d6a428SKevin Wolf rwco->qiov, rwco->flags); 98457d6a428SKevin Wolf blk_aio_complete(acb); 98557d6a428SKevin Wolf } 98657d6a428SKevin Wolf 987d004bd52SEric Blake BlockAIOCB *blk_aio_pwrite_zeroes(BlockBackend *blk, int64_t offset, 988983a1600SEric Blake int count, BdrvRequestFlags flags, 9894be74634SMarkus Armbruster BlockCompletionFunc *cb, void *opaque) 9904be74634SMarkus Armbruster { 991983a1600SEric Blake return blk_aio_prwv(blk, offset, count, NULL, blk_aio_write_entry, 992983a1600SEric Blake flags | BDRV_REQ_ZERO_WRITE, cb, opaque); 9934be74634SMarkus Armbruster } 9944be74634SMarkus Armbruster 9954be74634SMarkus Armbruster int blk_pread(BlockBackend *blk, int64_t offset, void *buf, int count) 9964be74634SMarkus Armbruster { 997a55d3fbaSKevin Wolf int ret = blk_prw(blk, offset, buf, count, blk_read_entry, 0); 998e7f7d676SMax Reitz if (ret < 0) { 999e7f7d676SMax Reitz return ret; 1000e7f7d676SMax Reitz } 1001a55d3fbaSKevin Wolf return count; 10024be74634SMarkus Armbruster } 10034be74634SMarkus Armbruster 10048341f00dSEric Blake int blk_pwrite(BlockBackend *blk, int64_t offset, const void *buf, int count, 10058341f00dSEric Blake BdrvRequestFlags flags) 10064be74634SMarkus Armbruster { 10078341f00dSEric Blake int ret = blk_prw(blk, offset, (void *) buf, count, blk_write_entry, 10088341f00dSEric Blake flags); 1009e7f7d676SMax Reitz if (ret < 0) { 1010e7f7d676SMax Reitz return ret; 1011e7f7d676SMax Reitz } 1012a55d3fbaSKevin Wolf return count; 10134be74634SMarkus Armbruster } 10144be74634SMarkus Armbruster 10154be74634SMarkus Armbruster int64_t blk_getlength(BlockBackend *blk) 10164be74634SMarkus Armbruster { 1017c09ba36cSMax Reitz if (!blk_is_available(blk)) { 1018c09ba36cSMax Reitz return -ENOMEDIUM; 1019c09ba36cSMax Reitz } 1020c09ba36cSMax Reitz 1021f21d96d0SKevin Wolf return bdrv_getlength(blk_bs(blk)); 10224be74634SMarkus Armbruster } 10234be74634SMarkus Armbruster 10244be74634SMarkus Armbruster void blk_get_geometry(BlockBackend *blk, uint64_t *nb_sectors_ptr) 10254be74634SMarkus Armbruster { 1026f21d96d0SKevin Wolf if (!blk_bs(blk)) { 1027a46fc9c9SMax Reitz *nb_sectors_ptr = 0; 1028a46fc9c9SMax Reitz } else { 1029f21d96d0SKevin Wolf bdrv_get_geometry(blk_bs(blk), nb_sectors_ptr); 10304be74634SMarkus Armbruster } 1031a46fc9c9SMax Reitz } 10324be74634SMarkus Armbruster 10331ef01253SMax Reitz int64_t blk_nb_sectors(BlockBackend *blk) 10341ef01253SMax Reitz { 1035c09ba36cSMax Reitz if (!blk_is_available(blk)) { 1036c09ba36cSMax Reitz return -ENOMEDIUM; 1037c09ba36cSMax Reitz } 1038c09ba36cSMax Reitz 1039f21d96d0SKevin Wolf return bdrv_nb_sectors(blk_bs(blk)); 10401ef01253SMax Reitz } 10411ef01253SMax Reitz 104260cb2fa7SEric Blake BlockAIOCB *blk_aio_preadv(BlockBackend *blk, int64_t offset, 104360cb2fa7SEric Blake QEMUIOVector *qiov, BdrvRequestFlags flags, 104460cb2fa7SEric Blake BlockCompletionFunc *cb, void *opaque) 104560cb2fa7SEric Blake { 104660cb2fa7SEric Blake return blk_aio_prwv(blk, offset, qiov->size, qiov, 104760cb2fa7SEric Blake blk_aio_read_entry, flags, cb, opaque); 104860cb2fa7SEric Blake } 104960cb2fa7SEric Blake 105060cb2fa7SEric Blake BlockAIOCB *blk_aio_pwritev(BlockBackend *blk, int64_t offset, 105160cb2fa7SEric Blake QEMUIOVector *qiov, BdrvRequestFlags flags, 105260cb2fa7SEric Blake BlockCompletionFunc *cb, void *opaque) 105360cb2fa7SEric Blake { 105460cb2fa7SEric Blake return blk_aio_prwv(blk, offset, qiov->size, qiov, 105560cb2fa7SEric Blake blk_aio_write_entry, flags, cb, opaque); 105660cb2fa7SEric Blake } 105760cb2fa7SEric Blake 10584be74634SMarkus Armbruster BlockAIOCB *blk_aio_flush(BlockBackend *blk, 10594be74634SMarkus Armbruster BlockCompletionFunc *cb, void *opaque) 10604be74634SMarkus Armbruster { 1061c09ba36cSMax Reitz if (!blk_is_available(blk)) { 1062ca78ecfaSPeter Lieven return blk_abort_aio_request(blk, cb, opaque, -ENOMEDIUM); 1063c09ba36cSMax Reitz } 1064c09ba36cSMax Reitz 1065f21d96d0SKevin Wolf return bdrv_aio_flush(blk_bs(blk), cb, opaque); 10664be74634SMarkus Armbruster } 10674be74634SMarkus Armbruster 1068*1c6c4bb7SEric Blake BlockAIOCB *blk_aio_pdiscard(BlockBackend *blk, 1069*1c6c4bb7SEric Blake int64_t offset, int count, 10704be74634SMarkus Armbruster BlockCompletionFunc *cb, void *opaque) 10714be74634SMarkus Armbruster { 1072*1c6c4bb7SEric Blake int ret = blk_check_byte_request(blk, offset, count); 1073e7f7d676SMax Reitz if (ret < 0) { 1074ca78ecfaSPeter Lieven return blk_abort_aio_request(blk, cb, opaque, ret); 1075e7f7d676SMax Reitz } 1076e7f7d676SMax Reitz 1077*1c6c4bb7SEric Blake return bdrv_aio_pdiscard(blk_bs(blk), offset, count, cb, opaque); 10784be74634SMarkus Armbruster } 10794be74634SMarkus Armbruster 10804be74634SMarkus Armbruster void blk_aio_cancel(BlockAIOCB *acb) 10814be74634SMarkus Armbruster { 10824be74634SMarkus Armbruster bdrv_aio_cancel(acb); 10834be74634SMarkus Armbruster } 10844be74634SMarkus Armbruster 10854be74634SMarkus Armbruster void blk_aio_cancel_async(BlockAIOCB *acb) 10864be74634SMarkus Armbruster { 10874be74634SMarkus Armbruster bdrv_aio_cancel_async(acb); 10884be74634SMarkus Armbruster } 10894be74634SMarkus Armbruster 10904be74634SMarkus Armbruster int blk_ioctl(BlockBackend *blk, unsigned long int req, void *buf) 10914be74634SMarkus Armbruster { 1092c09ba36cSMax Reitz if (!blk_is_available(blk)) { 1093c09ba36cSMax Reitz return -ENOMEDIUM; 1094c09ba36cSMax Reitz } 1095c09ba36cSMax Reitz 1096f21d96d0SKevin Wolf return bdrv_ioctl(blk_bs(blk), req, buf); 10974be74634SMarkus Armbruster } 10984be74634SMarkus Armbruster 10994be74634SMarkus Armbruster BlockAIOCB *blk_aio_ioctl(BlockBackend *blk, unsigned long int req, void *buf, 11004be74634SMarkus Armbruster BlockCompletionFunc *cb, void *opaque) 11014be74634SMarkus Armbruster { 1102c09ba36cSMax Reitz if (!blk_is_available(blk)) { 1103ca78ecfaSPeter Lieven return blk_abort_aio_request(blk, cb, opaque, -ENOMEDIUM); 1104c09ba36cSMax Reitz } 1105c09ba36cSMax Reitz 1106f21d96d0SKevin Wolf return bdrv_aio_ioctl(blk_bs(blk), req, buf, cb, opaque); 11074be74634SMarkus Armbruster } 11084be74634SMarkus Armbruster 1109*1c6c4bb7SEric Blake int blk_co_pdiscard(BlockBackend *blk, int64_t offset, int count) 11102bb0dce7SMax Reitz { 1111*1c6c4bb7SEric Blake int ret = blk_check_byte_request(blk, offset, count); 1112e7f7d676SMax Reitz if (ret < 0) { 1113e7f7d676SMax Reitz return ret; 1114e7f7d676SMax Reitz } 1115e7f7d676SMax Reitz 1116*1c6c4bb7SEric Blake return bdrv_co_pdiscard(blk_bs(blk), offset, count); 11172bb0dce7SMax Reitz } 11182bb0dce7SMax Reitz 11192bb0dce7SMax Reitz int blk_co_flush(BlockBackend *blk) 11202bb0dce7SMax Reitz { 1121c09ba36cSMax Reitz if (!blk_is_available(blk)) { 1122c09ba36cSMax Reitz return -ENOMEDIUM; 1123c09ba36cSMax Reitz } 1124c09ba36cSMax Reitz 1125f21d96d0SKevin Wolf return bdrv_co_flush(blk_bs(blk)); 11262bb0dce7SMax Reitz } 11272bb0dce7SMax Reitz 11284be74634SMarkus Armbruster int blk_flush(BlockBackend *blk) 11294be74634SMarkus Armbruster { 1130c09ba36cSMax Reitz if (!blk_is_available(blk)) { 1131c09ba36cSMax Reitz return -ENOMEDIUM; 1132c09ba36cSMax Reitz } 1133c09ba36cSMax Reitz 1134f21d96d0SKevin Wolf return bdrv_flush(blk_bs(blk)); 11354be74634SMarkus Armbruster } 11364be74634SMarkus Armbruster 113797b0385aSAlexander Yarygin void blk_drain(BlockBackend *blk) 113897b0385aSAlexander Yarygin { 1139f21d96d0SKevin Wolf if (blk_bs(blk)) { 1140f21d96d0SKevin Wolf bdrv_drain(blk_bs(blk)); 114197b0385aSAlexander Yarygin } 1142a46fc9c9SMax Reitz } 114397b0385aSAlexander Yarygin 11444be74634SMarkus Armbruster void blk_drain_all(void) 11454be74634SMarkus Armbruster { 11464be74634SMarkus Armbruster bdrv_drain_all(); 11474be74634SMarkus Armbruster } 11484be74634SMarkus Armbruster 1149373340b2SMax Reitz void blk_set_on_error(BlockBackend *blk, BlockdevOnError on_read_error, 1150373340b2SMax Reitz BlockdevOnError on_write_error) 1151373340b2SMax Reitz { 1152373340b2SMax Reitz blk->on_read_error = on_read_error; 1153373340b2SMax Reitz blk->on_write_error = on_write_error; 1154373340b2SMax Reitz } 1155373340b2SMax Reitz 11564be74634SMarkus Armbruster BlockdevOnError blk_get_on_error(BlockBackend *blk, bool is_read) 11574be74634SMarkus Armbruster { 1158373340b2SMax Reitz return is_read ? blk->on_read_error : blk->on_write_error; 11594be74634SMarkus Armbruster } 11604be74634SMarkus Armbruster 11614be74634SMarkus Armbruster BlockErrorAction blk_get_error_action(BlockBackend *blk, bool is_read, 11624be74634SMarkus Armbruster int error) 11634be74634SMarkus Armbruster { 1164373340b2SMax Reitz BlockdevOnError on_err = blk_get_on_error(blk, is_read); 1165373340b2SMax Reitz 1166373340b2SMax Reitz switch (on_err) { 1167373340b2SMax Reitz case BLOCKDEV_ON_ERROR_ENOSPC: 1168373340b2SMax Reitz return (error == ENOSPC) ? 1169373340b2SMax Reitz BLOCK_ERROR_ACTION_STOP : BLOCK_ERROR_ACTION_REPORT; 1170373340b2SMax Reitz case BLOCKDEV_ON_ERROR_STOP: 1171373340b2SMax Reitz return BLOCK_ERROR_ACTION_STOP; 1172373340b2SMax Reitz case BLOCKDEV_ON_ERROR_REPORT: 1173373340b2SMax Reitz return BLOCK_ERROR_ACTION_REPORT; 1174373340b2SMax Reitz case BLOCKDEV_ON_ERROR_IGNORE: 1175373340b2SMax Reitz return BLOCK_ERROR_ACTION_IGNORE; 11768c398252SKevin Wolf case BLOCKDEV_ON_ERROR_AUTO: 1177373340b2SMax Reitz default: 1178373340b2SMax Reitz abort(); 1179373340b2SMax Reitz } 11804be74634SMarkus Armbruster } 11814be74634SMarkus Armbruster 1182373340b2SMax Reitz static void send_qmp_error_event(BlockBackend *blk, 1183373340b2SMax Reitz BlockErrorAction action, 1184373340b2SMax Reitz bool is_read, int error) 1185373340b2SMax Reitz { 1186373340b2SMax Reitz IoOperationType optype; 1187373340b2SMax Reitz 1188373340b2SMax Reitz optype = is_read ? IO_OPERATION_TYPE_READ : IO_OPERATION_TYPE_WRITE; 1189373340b2SMax Reitz qapi_event_send_block_io_error(blk_name(blk), optype, action, 1190373340b2SMax Reitz blk_iostatus_is_enabled(blk), 1191373340b2SMax Reitz error == ENOSPC, strerror(error), 1192373340b2SMax Reitz &error_abort); 1193373340b2SMax Reitz } 1194373340b2SMax Reitz 1195373340b2SMax Reitz /* This is done by device models because, while the block layer knows 1196373340b2SMax Reitz * about the error, it does not know whether an operation comes from 1197373340b2SMax Reitz * the device or the block layer (from a job, for example). 1198373340b2SMax Reitz */ 11994be74634SMarkus Armbruster void blk_error_action(BlockBackend *blk, BlockErrorAction action, 12004be74634SMarkus Armbruster bool is_read, int error) 12014be74634SMarkus Armbruster { 1202373340b2SMax Reitz assert(error >= 0); 1203373340b2SMax Reitz 1204373340b2SMax Reitz if (action == BLOCK_ERROR_ACTION_STOP) { 1205373340b2SMax Reitz /* First set the iostatus, so that "info block" returns an iostatus 1206373340b2SMax Reitz * that matches the events raised so far (an additional error iostatus 1207373340b2SMax Reitz * is fine, but not a lost one). 1208373340b2SMax Reitz */ 1209373340b2SMax Reitz blk_iostatus_set_err(blk, error); 1210373340b2SMax Reitz 1211373340b2SMax Reitz /* Then raise the request to stop the VM and the event. 1212373340b2SMax Reitz * qemu_system_vmstop_request_prepare has two effects. First, 1213373340b2SMax Reitz * it ensures that the STOP event always comes after the 1214373340b2SMax Reitz * BLOCK_IO_ERROR event. Second, it ensures that even if management 1215373340b2SMax Reitz * can observe the STOP event and do a "cont" before the STOP 1216373340b2SMax Reitz * event is issued, the VM will not stop. In this case, vm_start() 1217373340b2SMax Reitz * also ensures that the STOP/RESUME pair of events is emitted. 1218373340b2SMax Reitz */ 1219373340b2SMax Reitz qemu_system_vmstop_request_prepare(); 1220373340b2SMax Reitz send_qmp_error_event(blk, action, is_read, error); 1221373340b2SMax Reitz qemu_system_vmstop_request(RUN_STATE_IO_ERROR); 1222373340b2SMax Reitz } else { 1223373340b2SMax Reitz send_qmp_error_event(blk, action, is_read, error); 1224373340b2SMax Reitz } 12254be74634SMarkus Armbruster } 12264be74634SMarkus Armbruster 12274be74634SMarkus Armbruster int blk_is_read_only(BlockBackend *blk) 12284be74634SMarkus Armbruster { 1229f21d96d0SKevin Wolf BlockDriverState *bs = blk_bs(blk); 1230f21d96d0SKevin Wolf 1231f21d96d0SKevin Wolf if (bs) { 1232f21d96d0SKevin Wolf return bdrv_is_read_only(bs); 1233061959e8SMax Reitz } else { 1234061959e8SMax Reitz return blk->root_state.read_only; 1235061959e8SMax Reitz } 12364be74634SMarkus Armbruster } 12374be74634SMarkus Armbruster 12384be74634SMarkus Armbruster int blk_is_sg(BlockBackend *blk) 12394be74634SMarkus Armbruster { 1240f21d96d0SKevin Wolf BlockDriverState *bs = blk_bs(blk); 1241f21d96d0SKevin Wolf 1242f21d96d0SKevin Wolf if (!bs) { 1243a46fc9c9SMax Reitz return 0; 1244a46fc9c9SMax Reitz } 1245a46fc9c9SMax Reitz 1246f21d96d0SKevin Wolf return bdrv_is_sg(bs); 12474be74634SMarkus Armbruster } 12484be74634SMarkus Armbruster 12494be74634SMarkus Armbruster int blk_enable_write_cache(BlockBackend *blk) 12504be74634SMarkus Armbruster { 1251bfd18d1eSKevin Wolf return blk->enable_write_cache; 12524be74634SMarkus Armbruster } 12534be74634SMarkus Armbruster 12544be74634SMarkus Armbruster void blk_set_enable_write_cache(BlockBackend *blk, bool wce) 12554be74634SMarkus Armbruster { 1256bfd18d1eSKevin Wolf blk->enable_write_cache = wce; 12574be74634SMarkus Armbruster } 12584be74634SMarkus Armbruster 12592bb0dce7SMax Reitz void blk_invalidate_cache(BlockBackend *blk, Error **errp) 12602bb0dce7SMax Reitz { 1261f21d96d0SKevin Wolf BlockDriverState *bs = blk_bs(blk); 1262f21d96d0SKevin Wolf 1263f21d96d0SKevin Wolf if (!bs) { 1264c09ba36cSMax Reitz error_setg(errp, "Device '%s' has no medium", blk->name); 1265c09ba36cSMax Reitz return; 1266c09ba36cSMax Reitz } 1267c09ba36cSMax Reitz 1268f21d96d0SKevin Wolf bdrv_invalidate_cache(bs, errp); 12692bb0dce7SMax Reitz } 12702bb0dce7SMax Reitz 1271e031f750SMax Reitz bool blk_is_inserted(BlockBackend *blk) 12724be74634SMarkus Armbruster { 1273f21d96d0SKevin Wolf BlockDriverState *bs = blk_bs(blk); 1274f21d96d0SKevin Wolf 1275f21d96d0SKevin Wolf return bs && bdrv_is_inserted(bs); 1276db0284f8SMax Reitz } 1277db0284f8SMax Reitz 1278db0284f8SMax Reitz bool blk_is_available(BlockBackend *blk) 1279db0284f8SMax Reitz { 1280db0284f8SMax Reitz return blk_is_inserted(blk) && !blk_dev_is_tray_open(blk); 12814be74634SMarkus Armbruster } 12824be74634SMarkus Armbruster 12834be74634SMarkus Armbruster void blk_lock_medium(BlockBackend *blk, bool locked) 12844be74634SMarkus Armbruster { 1285f21d96d0SKevin Wolf BlockDriverState *bs = blk_bs(blk); 1286f21d96d0SKevin Wolf 1287f21d96d0SKevin Wolf if (bs) { 1288f21d96d0SKevin Wolf bdrv_lock_medium(bs, locked); 12894be74634SMarkus Armbruster } 1290a46fc9c9SMax Reitz } 12914be74634SMarkus Armbruster 12924be74634SMarkus Armbruster void blk_eject(BlockBackend *blk, bool eject_flag) 12934be74634SMarkus Armbruster { 1294f21d96d0SKevin Wolf BlockDriverState *bs = blk_bs(blk); 1295f21d96d0SKevin Wolf 1296f21d96d0SKevin Wolf if (bs) { 1297f21d96d0SKevin Wolf bdrv_eject(bs, eject_flag); 12984be74634SMarkus Armbruster } 1299a46fc9c9SMax Reitz } 13004be74634SMarkus Armbruster 13014be74634SMarkus Armbruster int blk_get_flags(BlockBackend *blk) 13024be74634SMarkus Armbruster { 1303f21d96d0SKevin Wolf BlockDriverState *bs = blk_bs(blk); 1304f21d96d0SKevin Wolf 1305f21d96d0SKevin Wolf if (bs) { 1306f21d96d0SKevin Wolf return bdrv_get_flags(bs); 1307061959e8SMax Reitz } else { 1308061959e8SMax Reitz return blk->root_state.open_flags; 1309061959e8SMax Reitz } 13104be74634SMarkus Armbruster } 13114be74634SMarkus Armbruster 13125def6b80SEric Blake /* Returns the maximum transfer length, in bytes; guaranteed nonzero */ 13135def6b80SEric Blake uint32_t blk_get_max_transfer(BlockBackend *blk) 1314454057b7SPeter Lieven { 1315f21d96d0SKevin Wolf BlockDriverState *bs = blk_bs(blk); 13165def6b80SEric Blake uint32_t max = 0; 1317f21d96d0SKevin Wolf 1318f21d96d0SKevin Wolf if (bs) { 13195def6b80SEric Blake max = bs->bl.max_transfer; 1320a46fc9c9SMax Reitz } 13215def6b80SEric Blake return MIN_NON_ZERO(max, INT_MAX); 1322454057b7SPeter Lieven } 1323454057b7SPeter Lieven 1324648296e0SStefan Hajnoczi int blk_get_max_iov(BlockBackend *blk) 1325648296e0SStefan Hajnoczi { 1326f21d96d0SKevin Wolf return blk->root->bs->bl.max_iov; 1327648296e0SStefan Hajnoczi } 1328648296e0SStefan Hajnoczi 13294be74634SMarkus Armbruster void blk_set_guest_block_size(BlockBackend *blk, int align) 13304be74634SMarkus Armbruster { 133168e9ec01SMax Reitz blk->guest_block_size = align; 13324be74634SMarkus Armbruster } 13334be74634SMarkus Armbruster 1334f1c17521SPaolo Bonzini void *blk_try_blockalign(BlockBackend *blk, size_t size) 1335f1c17521SPaolo Bonzini { 1336f21d96d0SKevin Wolf return qemu_try_blockalign(blk ? blk_bs(blk) : NULL, size); 1337f1c17521SPaolo Bonzini } 1338f1c17521SPaolo Bonzini 13394be74634SMarkus Armbruster void *blk_blockalign(BlockBackend *blk, size_t size) 13404be74634SMarkus Armbruster { 1341f21d96d0SKevin Wolf return qemu_blockalign(blk ? blk_bs(blk) : NULL, size); 13424be74634SMarkus Armbruster } 13434be74634SMarkus Armbruster 13444be74634SMarkus Armbruster bool blk_op_is_blocked(BlockBackend *blk, BlockOpType op, Error **errp) 13454be74634SMarkus Armbruster { 1346f21d96d0SKevin Wolf BlockDriverState *bs = blk_bs(blk); 1347f21d96d0SKevin Wolf 1348f21d96d0SKevin Wolf if (!bs) { 1349a46fc9c9SMax Reitz return false; 1350a46fc9c9SMax Reitz } 1351a46fc9c9SMax Reitz 1352f21d96d0SKevin Wolf return bdrv_op_is_blocked(bs, op, errp); 13534be74634SMarkus Armbruster } 13544be74634SMarkus Armbruster 13554be74634SMarkus Armbruster void blk_op_unblock(BlockBackend *blk, BlockOpType op, Error *reason) 13564be74634SMarkus Armbruster { 1357f21d96d0SKevin Wolf BlockDriverState *bs = blk_bs(blk); 1358f21d96d0SKevin Wolf 1359f21d96d0SKevin Wolf if (bs) { 1360f21d96d0SKevin Wolf bdrv_op_unblock(bs, op, reason); 13614be74634SMarkus Armbruster } 1362a46fc9c9SMax Reitz } 13634be74634SMarkus Armbruster 13644be74634SMarkus Armbruster void blk_op_block_all(BlockBackend *blk, Error *reason) 13654be74634SMarkus Armbruster { 1366f21d96d0SKevin Wolf BlockDriverState *bs = blk_bs(blk); 1367f21d96d0SKevin Wolf 1368f21d96d0SKevin Wolf if (bs) { 1369f21d96d0SKevin Wolf bdrv_op_block_all(bs, reason); 13704be74634SMarkus Armbruster } 1371a46fc9c9SMax Reitz } 13724be74634SMarkus Armbruster 13734be74634SMarkus Armbruster void blk_op_unblock_all(BlockBackend *blk, Error *reason) 13744be74634SMarkus Armbruster { 1375f21d96d0SKevin Wolf BlockDriverState *bs = blk_bs(blk); 1376f21d96d0SKevin Wolf 1377f21d96d0SKevin Wolf if (bs) { 1378f21d96d0SKevin Wolf bdrv_op_unblock_all(bs, reason); 13794be74634SMarkus Armbruster } 1380a46fc9c9SMax Reitz } 13814be74634SMarkus Armbruster 13824be74634SMarkus Armbruster AioContext *blk_get_aio_context(BlockBackend *blk) 13834be74634SMarkus Armbruster { 1384f21d96d0SKevin Wolf BlockDriverState *bs = blk_bs(blk); 1385f21d96d0SKevin Wolf 1386f21d96d0SKevin Wolf if (bs) { 1387f21d96d0SKevin Wolf return bdrv_get_aio_context(bs); 13884981bdecSMax Reitz } else { 13894981bdecSMax Reitz return qemu_get_aio_context(); 13904981bdecSMax Reitz } 13914981bdecSMax Reitz } 13924981bdecSMax Reitz 13934981bdecSMax Reitz static AioContext *blk_aiocb_get_aio_context(BlockAIOCB *acb) 13944981bdecSMax Reitz { 13954981bdecSMax Reitz BlockBackendAIOCB *blk_acb = DO_UPCAST(BlockBackendAIOCB, common, acb); 13964981bdecSMax Reitz return blk_get_aio_context(blk_acb->blk); 13974be74634SMarkus Armbruster } 13984be74634SMarkus Armbruster 13994be74634SMarkus Armbruster void blk_set_aio_context(BlockBackend *blk, AioContext *new_context) 14004be74634SMarkus Armbruster { 1401f21d96d0SKevin Wolf BlockDriverState *bs = blk_bs(blk); 1402f21d96d0SKevin Wolf 1403f21d96d0SKevin Wolf if (bs) { 14047ca7f0f6SKevin Wolf if (blk->public.throttle_state) { 14057ca7f0f6SKevin Wolf throttle_timers_detach_aio_context(&blk->public.throttle_timers); 14067ca7f0f6SKevin Wolf } 1407f21d96d0SKevin Wolf bdrv_set_aio_context(bs, new_context); 14087ca7f0f6SKevin Wolf if (blk->public.throttle_state) { 14097ca7f0f6SKevin Wolf throttle_timers_attach_aio_context(&blk->public.throttle_timers, 14107ca7f0f6SKevin Wolf new_context); 14117ca7f0f6SKevin Wolf } 14124be74634SMarkus Armbruster } 1413a46fc9c9SMax Reitz } 14144be74634SMarkus Armbruster 14152019ba0aSMax Reitz void blk_add_aio_context_notifier(BlockBackend *blk, 14162019ba0aSMax Reitz void (*attached_aio_context)(AioContext *new_context, void *opaque), 14172019ba0aSMax Reitz void (*detach_aio_context)(void *opaque), void *opaque) 14182019ba0aSMax Reitz { 1419f21d96d0SKevin Wolf BlockDriverState *bs = blk_bs(blk); 1420f21d96d0SKevin Wolf 1421f21d96d0SKevin Wolf if (bs) { 1422f21d96d0SKevin Wolf bdrv_add_aio_context_notifier(bs, attached_aio_context, 14232019ba0aSMax Reitz detach_aio_context, opaque); 14242019ba0aSMax Reitz } 1425a46fc9c9SMax Reitz } 14262019ba0aSMax Reitz 14272019ba0aSMax Reitz void blk_remove_aio_context_notifier(BlockBackend *blk, 14282019ba0aSMax Reitz void (*attached_aio_context)(AioContext *, 14292019ba0aSMax Reitz void *), 14302019ba0aSMax Reitz void (*detach_aio_context)(void *), 14312019ba0aSMax Reitz void *opaque) 14322019ba0aSMax Reitz { 1433f21d96d0SKevin Wolf BlockDriverState *bs = blk_bs(blk); 1434f21d96d0SKevin Wolf 1435f21d96d0SKevin Wolf if (bs) { 1436f21d96d0SKevin Wolf bdrv_remove_aio_context_notifier(bs, attached_aio_context, 14372019ba0aSMax Reitz detach_aio_context, opaque); 14382019ba0aSMax Reitz } 1439a46fc9c9SMax Reitz } 14402019ba0aSMax Reitz 14413301f6c6SMax Reitz void blk_add_remove_bs_notifier(BlockBackend *blk, Notifier *notify) 14423301f6c6SMax Reitz { 14433301f6c6SMax Reitz notifier_list_add(&blk->remove_bs_notifiers, notify); 14443301f6c6SMax Reitz } 14453301f6c6SMax Reitz 14463301f6c6SMax Reitz void blk_add_insert_bs_notifier(BlockBackend *blk, Notifier *notify) 14473301f6c6SMax Reitz { 14483301f6c6SMax Reitz notifier_list_add(&blk->insert_bs_notifiers, notify); 14493301f6c6SMax Reitz } 14503301f6c6SMax Reitz 14514be74634SMarkus Armbruster void blk_io_plug(BlockBackend *blk) 14524be74634SMarkus Armbruster { 1453f21d96d0SKevin Wolf BlockDriverState *bs = blk_bs(blk); 1454f21d96d0SKevin Wolf 1455f21d96d0SKevin Wolf if (bs) { 1456f21d96d0SKevin Wolf bdrv_io_plug(bs); 14574be74634SMarkus Armbruster } 1458a46fc9c9SMax Reitz } 14594be74634SMarkus Armbruster 14604be74634SMarkus Armbruster void blk_io_unplug(BlockBackend *blk) 14614be74634SMarkus Armbruster { 1462f21d96d0SKevin Wolf BlockDriverState *bs = blk_bs(blk); 1463f21d96d0SKevin Wolf 1464f21d96d0SKevin Wolf if (bs) { 1465f21d96d0SKevin Wolf bdrv_io_unplug(bs); 14664be74634SMarkus Armbruster } 1467a46fc9c9SMax Reitz } 14684be74634SMarkus Armbruster 14694be74634SMarkus Armbruster BlockAcctStats *blk_get_stats(BlockBackend *blk) 14704be74634SMarkus Armbruster { 14717f0e9da6SMax Reitz return &blk->stats; 14724be74634SMarkus Armbruster } 14734be74634SMarkus Armbruster 14744be74634SMarkus Armbruster void *blk_aio_get(const AIOCBInfo *aiocb_info, BlockBackend *blk, 14754be74634SMarkus Armbruster BlockCompletionFunc *cb, void *opaque) 14764be74634SMarkus Armbruster { 14774be74634SMarkus Armbruster return qemu_aio_get(aiocb_info, blk_bs(blk), cb, opaque); 14784be74634SMarkus Armbruster } 14791ef01253SMax Reitz 1480d004bd52SEric Blake int coroutine_fn blk_co_pwrite_zeroes(BlockBackend *blk, int64_t offset, 1481983a1600SEric Blake int count, BdrvRequestFlags flags) 14821ef01253SMax Reitz { 1483983a1600SEric Blake return blk_co_pwritev(blk, offset, count, NULL, 148416aaf975SKevin Wolf flags | BDRV_REQ_ZERO_WRITE); 14851ef01253SMax Reitz } 14861ef01253SMax Reitz 14871ef01253SMax Reitz int blk_write_compressed(BlockBackend *blk, int64_t sector_num, 14881ef01253SMax Reitz const uint8_t *buf, int nb_sectors) 14891ef01253SMax Reitz { 1490e7f7d676SMax Reitz int ret = blk_check_request(blk, sector_num, nb_sectors); 1491e7f7d676SMax Reitz if (ret < 0) { 1492e7f7d676SMax Reitz return ret; 1493e7f7d676SMax Reitz } 1494e7f7d676SMax Reitz 1495f21d96d0SKevin Wolf return bdrv_write_compressed(blk_bs(blk), sector_num, buf, nb_sectors); 14961ef01253SMax Reitz } 14971ef01253SMax Reitz 14981ef01253SMax Reitz int blk_truncate(BlockBackend *blk, int64_t offset) 14991ef01253SMax Reitz { 1500c09ba36cSMax Reitz if (!blk_is_available(blk)) { 1501c09ba36cSMax Reitz return -ENOMEDIUM; 1502c09ba36cSMax Reitz } 1503c09ba36cSMax Reitz 1504f21d96d0SKevin Wolf return bdrv_truncate(blk_bs(blk), offset); 15051ef01253SMax Reitz } 15061ef01253SMax Reitz 1507*1c6c4bb7SEric Blake int blk_pdiscard(BlockBackend *blk, int64_t offset, int count) 15081ef01253SMax Reitz { 1509*1c6c4bb7SEric Blake int ret = blk_check_byte_request(blk, offset, count); 1510e7f7d676SMax Reitz if (ret < 0) { 1511e7f7d676SMax Reitz return ret; 1512e7f7d676SMax Reitz } 1513e7f7d676SMax Reitz 1514*1c6c4bb7SEric Blake return bdrv_pdiscard(blk_bs(blk), offset, count); 15151ef01253SMax Reitz } 15161ef01253SMax Reitz 15171ef01253SMax Reitz int blk_save_vmstate(BlockBackend *blk, const uint8_t *buf, 15181ef01253SMax Reitz int64_t pos, int size) 15191ef01253SMax Reitz { 1520bfd18d1eSKevin Wolf int ret; 1521bfd18d1eSKevin Wolf 1522c09ba36cSMax Reitz if (!blk_is_available(blk)) { 1523c09ba36cSMax Reitz return -ENOMEDIUM; 1524c09ba36cSMax Reitz } 1525c09ba36cSMax Reitz 1526bfd18d1eSKevin Wolf ret = bdrv_save_vmstate(blk_bs(blk), buf, pos, size); 1527bfd18d1eSKevin Wolf if (ret < 0) { 1528bfd18d1eSKevin Wolf return ret; 1529bfd18d1eSKevin Wolf } 1530bfd18d1eSKevin Wolf 1531bfd18d1eSKevin Wolf if (ret == size && !blk->enable_write_cache) { 1532bfd18d1eSKevin Wolf ret = bdrv_flush(blk_bs(blk)); 1533bfd18d1eSKevin Wolf } 1534bfd18d1eSKevin Wolf 1535bfd18d1eSKevin Wolf return ret < 0 ? ret : size; 15361ef01253SMax Reitz } 15371ef01253SMax Reitz 15381ef01253SMax Reitz int blk_load_vmstate(BlockBackend *blk, uint8_t *buf, int64_t pos, int size) 15391ef01253SMax Reitz { 1540c09ba36cSMax Reitz if (!blk_is_available(blk)) { 1541c09ba36cSMax Reitz return -ENOMEDIUM; 1542c09ba36cSMax Reitz } 1543c09ba36cSMax Reitz 1544f21d96d0SKevin Wolf return bdrv_load_vmstate(blk_bs(blk), buf, pos, size); 15451ef01253SMax Reitz } 1546f0272c4dSEkaterina Tumanova 1547f0272c4dSEkaterina Tumanova int blk_probe_blocksizes(BlockBackend *blk, BlockSizes *bsz) 1548f0272c4dSEkaterina Tumanova { 1549c09ba36cSMax Reitz if (!blk_is_available(blk)) { 1550c09ba36cSMax Reitz return -ENOMEDIUM; 1551c09ba36cSMax Reitz } 1552c09ba36cSMax Reitz 1553f21d96d0SKevin Wolf return bdrv_probe_blocksizes(blk_bs(blk), bsz); 1554f0272c4dSEkaterina Tumanova } 1555f0272c4dSEkaterina Tumanova 1556f0272c4dSEkaterina Tumanova int blk_probe_geometry(BlockBackend *blk, HDGeometry *geo) 1557f0272c4dSEkaterina Tumanova { 1558c09ba36cSMax Reitz if (!blk_is_available(blk)) { 1559c09ba36cSMax Reitz return -ENOMEDIUM; 1560c09ba36cSMax Reitz } 1561c09ba36cSMax Reitz 1562f21d96d0SKevin Wolf return bdrv_probe_geometry(blk_bs(blk), geo); 1563f0272c4dSEkaterina Tumanova } 1564281d22d8SMax Reitz 1565281d22d8SMax Reitz /* 1566281d22d8SMax Reitz * Updates the BlockBackendRootState object with data from the currently 1567281d22d8SMax Reitz * attached BlockDriverState. 1568281d22d8SMax Reitz */ 1569281d22d8SMax Reitz void blk_update_root_state(BlockBackend *blk) 1570281d22d8SMax Reitz { 1571f21d96d0SKevin Wolf assert(blk->root); 1572281d22d8SMax Reitz 1573f21d96d0SKevin Wolf blk->root_state.open_flags = blk->root->bs->open_flags; 1574f21d96d0SKevin Wolf blk->root_state.read_only = blk->root->bs->read_only; 1575f21d96d0SKevin Wolf blk->root_state.detect_zeroes = blk->root->bs->detect_zeroes; 1576281d22d8SMax Reitz } 1577281d22d8SMax Reitz 157838cb18f5SMax Reitz /* 157938cb18f5SMax Reitz * Applies the information in the root state to the given BlockDriverState. This 158038cb18f5SMax Reitz * does not include the flags which have to be specified for bdrv_open(), use 158138cb18f5SMax Reitz * blk_get_open_flags_from_root_state() to inquire them. 158238cb18f5SMax Reitz */ 158338cb18f5SMax Reitz void blk_apply_root_state(BlockBackend *blk, BlockDriverState *bs) 158438cb18f5SMax Reitz { 158538cb18f5SMax Reitz bs->detect_zeroes = blk->root_state.detect_zeroes; 158638cb18f5SMax Reitz } 158738cb18f5SMax Reitz 158838cb18f5SMax Reitz /* 158938cb18f5SMax Reitz * Returns the flags to be used for bdrv_open() of a BlockDriverState which is 159038cb18f5SMax Reitz * supposed to inherit the root state. 159138cb18f5SMax Reitz */ 159238cb18f5SMax Reitz int blk_get_open_flags_from_root_state(BlockBackend *blk) 159338cb18f5SMax Reitz { 159438cb18f5SMax Reitz int bs_flags; 159538cb18f5SMax Reitz 159638cb18f5SMax Reitz bs_flags = blk->root_state.read_only ? 0 : BDRV_O_RDWR; 159738cb18f5SMax Reitz bs_flags |= blk->root_state.open_flags & ~BDRV_O_RDWR; 159838cb18f5SMax Reitz 159938cb18f5SMax Reitz return bs_flags; 160038cb18f5SMax Reitz } 160138cb18f5SMax Reitz 1602281d22d8SMax Reitz BlockBackendRootState *blk_get_root_state(BlockBackend *blk) 1603281d22d8SMax Reitz { 1604281d22d8SMax Reitz return &blk->root_state; 1605281d22d8SMax Reitz } 16061393f212SMax Reitz 16071393f212SMax Reitz int blk_commit_all(void) 16081393f212SMax Reitz { 1609fe1a9cbcSMax Reitz BlockBackend *blk = NULL; 1610fe1a9cbcSMax Reitz 1611fe1a9cbcSMax Reitz while ((blk = blk_all_next(blk)) != NULL) { 1612fe1a9cbcSMax Reitz AioContext *aio_context = blk_get_aio_context(blk); 1613fe1a9cbcSMax Reitz 1614fe1a9cbcSMax Reitz aio_context_acquire(aio_context); 1615f21d96d0SKevin Wolf if (blk_is_inserted(blk) && blk->root->bs->backing) { 1616f21d96d0SKevin Wolf int ret = bdrv_commit(blk->root->bs); 1617fe1a9cbcSMax Reitz if (ret < 0) { 1618fe1a9cbcSMax Reitz aio_context_release(aio_context); 1619fe1a9cbcSMax Reitz return ret; 1620fe1a9cbcSMax Reitz } 1621fe1a9cbcSMax Reitz } 1622fe1a9cbcSMax Reitz aio_context_release(aio_context); 1623fe1a9cbcSMax Reitz } 1624fe1a9cbcSMax Reitz return 0; 1625fe1a9cbcSMax Reitz } 1626fe1a9cbcSMax Reitz 1627fe1a9cbcSMax Reitz int blk_flush_all(void) 1628fe1a9cbcSMax Reitz { 1629fe1a9cbcSMax Reitz BlockBackend *blk = NULL; 1630fe1a9cbcSMax Reitz int result = 0; 1631fe1a9cbcSMax Reitz 1632fe1a9cbcSMax Reitz while ((blk = blk_all_next(blk)) != NULL) { 1633fe1a9cbcSMax Reitz AioContext *aio_context = blk_get_aio_context(blk); 1634fe1a9cbcSMax Reitz int ret; 1635fe1a9cbcSMax Reitz 1636fe1a9cbcSMax Reitz aio_context_acquire(aio_context); 1637fe1a9cbcSMax Reitz if (blk_is_inserted(blk)) { 1638fe1a9cbcSMax Reitz ret = blk_flush(blk); 1639fe1a9cbcSMax Reitz if (ret < 0 && !result) { 1640fe1a9cbcSMax Reitz result = ret; 1641fe1a9cbcSMax Reitz } 1642fe1a9cbcSMax Reitz } 1643fe1a9cbcSMax Reitz aio_context_release(aio_context); 1644fe1a9cbcSMax Reitz } 1645fe1a9cbcSMax Reitz 1646fe1a9cbcSMax Reitz return result; 16471393f212SMax Reitz } 164897148076SKevin Wolf 164997148076SKevin Wolf 165097148076SKevin Wolf /* throttling disk I/O limits */ 165197148076SKevin Wolf void blk_set_io_limits(BlockBackend *blk, ThrottleConfig *cfg) 165297148076SKevin Wolf { 165397148076SKevin Wolf throttle_group_config(blk, cfg); 165497148076SKevin Wolf } 165597148076SKevin Wolf 165697148076SKevin Wolf void blk_io_limits_disable(BlockBackend *blk) 165797148076SKevin Wolf { 165897148076SKevin Wolf assert(blk->public.throttle_state); 1659c2066af0SKevin Wolf bdrv_drained_begin(blk_bs(blk)); 166097148076SKevin Wolf throttle_group_unregister_blk(blk); 1661c2066af0SKevin Wolf bdrv_drained_end(blk_bs(blk)); 166297148076SKevin Wolf } 166397148076SKevin Wolf 166497148076SKevin Wolf /* should be called before blk_set_io_limits if a limit is set */ 166597148076SKevin Wolf void blk_io_limits_enable(BlockBackend *blk, const char *group) 166697148076SKevin Wolf { 166797148076SKevin Wolf assert(!blk->public.throttle_state); 166897148076SKevin Wolf throttle_group_register_blk(blk, group); 166997148076SKevin Wolf } 167097148076SKevin Wolf 167197148076SKevin Wolf void blk_io_limits_update_group(BlockBackend *blk, const char *group) 167297148076SKevin Wolf { 167397148076SKevin Wolf /* this BB is not part of any group */ 167497148076SKevin Wolf if (!blk->public.throttle_state) { 167597148076SKevin Wolf return; 167697148076SKevin Wolf } 167797148076SKevin Wolf 167897148076SKevin Wolf /* this BB is a part of the same group than the one we want */ 167997148076SKevin Wolf if (!g_strcmp0(throttle_group_get_name(blk), group)) { 168097148076SKevin Wolf return; 168197148076SKevin Wolf } 168297148076SKevin Wolf 168397148076SKevin Wolf /* need to change the group this bs belong to */ 168497148076SKevin Wolf blk_io_limits_disable(blk); 168597148076SKevin Wolf blk_io_limits_enable(blk, group); 168697148076SKevin Wolf } 1687c2066af0SKevin Wolf 1688c2066af0SKevin Wolf static void blk_root_drained_begin(BdrvChild *child) 1689c2066af0SKevin Wolf { 1690c2066af0SKevin Wolf BlockBackend *blk = child->opaque; 1691c2066af0SKevin Wolf 169236fe1331SKevin Wolf /* Note that blk->root may not be accessible here yet if we are just 169336fe1331SKevin Wolf * attaching to a BlockDriverState that is drained. Use child instead. */ 169436fe1331SKevin Wolf 1695c2066af0SKevin Wolf if (blk->public.io_limits_disabled++ == 0) { 1696c2066af0SKevin Wolf throttle_group_restart_blk(blk); 1697c2066af0SKevin Wolf } 1698c2066af0SKevin Wolf } 1699c2066af0SKevin Wolf 1700c2066af0SKevin Wolf static void blk_root_drained_end(BdrvChild *child) 1701c2066af0SKevin Wolf { 1702c2066af0SKevin Wolf BlockBackend *blk = child->opaque; 1703c2066af0SKevin Wolf 1704c2066af0SKevin Wolf assert(blk->public.io_limits_disabled); 1705c2066af0SKevin Wolf --blk->public.io_limits_disabled; 1706c2066af0SKevin Wolf } 1707