xref: /openbmc/qemu/block/block-backend.c (revision 109525ad)
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