xref: /openbmc/qemu/block/block-backend.c (revision 8c6242b6)
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"
1813d4ff07SMarkus Armbruster #include "hw/qdev-core.h"
1918e46a03SMarkus Armbruster #include "sysemu/blockdev.h"
2054d31236SMarkus Armbruster #include "sysemu/runstate.h"
21e4ec5ad4SPavel Dovgalyuk #include "sysemu/sysemu.h"
22e4ec5ad4SPavel Dovgalyuk #include "sysemu/replay.h"
23e688df6bSMarkus Armbruster #include "qapi/error.h"
249af23989SMarkus Armbruster #include "qapi/qapi-events-block.h"
25f348b6d1SVeronia Bahaa #include "qemu/id.h"
26db725815SMarkus Armbruster #include "qemu/main-loop.h"
27922a01a0SMarkus Armbruster #include "qemu/option.h"
281e98fefdSKevin Wolf #include "trace.h"
295f7772c4SFam Zheng #include "migration/misc.h"
30a7f53e26SMarkus Armbruster 
31a7f53e26SMarkus Armbruster /* Number of coroutines to reserve per attached device model */
32a7f53e26SMarkus Armbruster #define COROUTINE_POOL_RESERVATION 64
3326f54e9aSMarkus Armbruster 
341bf1cbc9SKevin Wolf #define NOT_DONE 0x7fffffff /* used while emulated sync operation in progress */
351bf1cbc9SKevin Wolf 
364981bdecSMax Reitz static AioContext *blk_aiocb_get_aio_context(BlockAIOCB *acb);
374981bdecSMax Reitz 
38d03654eaSStefan Hajnoczi typedef struct BlockBackendAioNotifier {
39d03654eaSStefan Hajnoczi     void (*attached_aio_context)(AioContext *new_context, void *opaque);
40d03654eaSStefan Hajnoczi     void (*detach_aio_context)(void *opaque);
41d03654eaSStefan Hajnoczi     void *opaque;
42d03654eaSStefan Hajnoczi     QLIST_ENTRY(BlockBackendAioNotifier) list;
43d03654eaSStefan Hajnoczi } BlockBackendAioNotifier;
44d03654eaSStefan Hajnoczi 
4526f54e9aSMarkus Armbruster struct BlockBackend {
4626f54e9aSMarkus Armbruster     char *name;
4726f54e9aSMarkus Armbruster     int refcnt;
48f21d96d0SKevin Wolf     BdrvChild *root;
49d861ab3aSKevin Wolf     AioContext *ctx;
5026f8b3a8SMarkus Armbruster     DriveInfo *legacy_dinfo;    /* null unless created by drive_new() */
512cf22d6aSMax Reitz     QTAILQ_ENTRY(BlockBackend) link;         /* for block_backends */
529492b0b9SMax Reitz     QTAILQ_ENTRY(BlockBackend) monitor_link; /* for monitor_block_backends */
53f2cd875dSKevin Wolf     BlockBackendPublic public;
54a7f53e26SMarkus Armbruster 
55d09ea2d2SThomas Huth     DeviceState *dev;           /* attached device model, if any */
56a7f53e26SMarkus Armbruster     const BlockDevOps *dev_ops;
57a7f53e26SMarkus Armbruster     void *dev_opaque;
5868e9ec01SMax Reitz 
5968e9ec01SMax Reitz     /* the block size for which the guest device expects atomicity */
6068e9ec01SMax Reitz     int guest_block_size;
617f0e9da6SMax Reitz 
62281d22d8SMax Reitz     /* If the BDS tree is removed, some of its options are stored here (which
63281d22d8SMax Reitz      * can be used to restore those options in the new BDS on insert) */
64281d22d8SMax Reitz     BlockBackendRootState root_state;
65281d22d8SMax Reitz 
66bfd18d1eSKevin Wolf     bool enable_write_cache;
67bfd18d1eSKevin Wolf 
687f0e9da6SMax Reitz     /* I/O stats (display with "info blockstats"). */
697f0e9da6SMax Reitz     BlockAcctStats stats;
70373340b2SMax Reitz 
71373340b2SMax Reitz     BlockdevOnError on_read_error, on_write_error;
72373340b2SMax Reitz     bool iostatus_enabled;
73373340b2SMax Reitz     BlockDeviceIoStatus iostatus;
743301f6c6SMax Reitz 
75981776b3SKevin Wolf     uint64_t perm;
76981776b3SKevin Wolf     uint64_t shared_perm;
77d35ff5e6SKevin Wolf     bool disable_perm;
78981776b3SKevin Wolf 
79980b0f94SKevin Wolf     bool allow_aio_context_change;
80c10c9d96SKevin Wolf     bool allow_write_beyond_eof;
81c10c9d96SKevin Wolf 
823301f6c6SMax Reitz     NotifierList remove_bs_notifiers, insert_bs_notifiers;
83d03654eaSStefan Hajnoczi     QLIST_HEAD(, BlockBackendAioNotifier) aio_notifiers;
84f4d9cc88SJohn Snow 
85f4d9cc88SJohn Snow     int quiesce_counter;
86cf312932SKevin Wolf     CoQueue queued_requests;
87cf312932SKevin Wolf     bool disable_request_queuing;
88cf312932SKevin Wolf 
895f7772c4SFam Zheng     VMChangeStateEntry *vmsh;
90ca2e2144SFam Zheng     bool force_allow_inactivate;
9133f2a757SStefan Hajnoczi 
9233f2a757SStefan Hajnoczi     /* Number of in-flight aio requests.  BlockDriverState also counts
9333f2a757SStefan Hajnoczi      * in-flight requests but aio requests can exist even when blk->root is
9433f2a757SStefan Hajnoczi      * NULL, so we cannot rely on its counter for that case.
9533f2a757SStefan Hajnoczi      * Accessed with atomic ops.
9633f2a757SStefan Hajnoczi      */
9733f2a757SStefan Hajnoczi     unsigned int in_flight;
9826f54e9aSMarkus Armbruster };
9926f54e9aSMarkus Armbruster 
100e7f7d676SMax Reitz typedef struct BlockBackendAIOCB {
101e7f7d676SMax Reitz     BlockAIOCB common;
1024981bdecSMax Reitz     BlockBackend *blk;
103e7f7d676SMax Reitz     int ret;
104e7f7d676SMax Reitz } BlockBackendAIOCB;
105e7f7d676SMax Reitz 
106e7f7d676SMax Reitz static const AIOCBInfo block_backend_aiocb_info = {
1074981bdecSMax Reitz     .get_aio_context = blk_aiocb_get_aio_context,
108e7f7d676SMax Reitz     .aiocb_size = sizeof(BlockBackendAIOCB),
109e7f7d676SMax Reitz };
110e7f7d676SMax Reitz 
1118fb3c76cSMarkus Armbruster static void drive_info_del(DriveInfo *dinfo);
1127c8eece4SKevin Wolf static BlockBackend *bdrv_first_blk(BlockDriverState *bs);
1138fb3c76cSMarkus Armbruster 
1142cf22d6aSMax Reitz /* All BlockBackends */
1152cf22d6aSMax Reitz static QTAILQ_HEAD(, BlockBackend) block_backends =
1162cf22d6aSMax Reitz     QTAILQ_HEAD_INITIALIZER(block_backends);
1172cf22d6aSMax Reitz 
1189492b0b9SMax Reitz /* All BlockBackends referenced by the monitor and which are iterated through by
1199492b0b9SMax Reitz  * blk_next() */
1209492b0b9SMax Reitz static QTAILQ_HEAD(, BlockBackend) monitor_block_backends =
1219492b0b9SMax Reitz     QTAILQ_HEAD_INITIALIZER(monitor_block_backends);
12226f54e9aSMarkus Armbruster 
123f21d96d0SKevin Wolf static void blk_root_inherit_options(int *child_flags, QDict *child_options,
124f21d96d0SKevin Wolf                                      int parent_flags, QDict *parent_options)
125f21d96d0SKevin Wolf {
126f21d96d0SKevin Wolf     /* We're not supposed to call this function for root nodes */
127f21d96d0SKevin Wolf     abort();
128f21d96d0SKevin Wolf }
129c2066af0SKevin Wolf static void blk_root_drained_begin(BdrvChild *child);
130fe5258a5SKevin Wolf static bool blk_root_drained_poll(BdrvChild *child);
131e037c09cSMax Reitz static void blk_root_drained_end(BdrvChild *child, int *drained_end_counter);
132f21d96d0SKevin Wolf 
1335c8cab48SKevin Wolf static void blk_root_change_media(BdrvChild *child, bool load);
1345c8cab48SKevin Wolf static void blk_root_resize(BdrvChild *child);
1355c8cab48SKevin Wolf 
13638475269SKevin Wolf static bool blk_root_can_set_aio_ctx(BdrvChild *child, AioContext *ctx,
13738475269SKevin Wolf                                      GSList **ignore, Error **errp);
13838475269SKevin Wolf static void blk_root_set_aio_ctx(BdrvChild *child, AioContext *ctx,
13938475269SKevin Wolf                                  GSList **ignore);
14038475269SKevin Wolf 
141b5411555SKevin Wolf static char *blk_root_get_parent_desc(BdrvChild *child)
142b5411555SKevin Wolf {
143b5411555SKevin Wolf     BlockBackend *blk = child->opaque;
144b5411555SKevin Wolf     char *dev_id;
145b5411555SKevin Wolf 
146b5411555SKevin Wolf     if (blk->name) {
147b5411555SKevin Wolf         return g_strdup(blk->name);
148b5411555SKevin Wolf     }
149b5411555SKevin Wolf 
150b5411555SKevin Wolf     dev_id = blk_get_attached_dev_id(blk);
151b5411555SKevin Wolf     if (*dev_id) {
152b5411555SKevin Wolf         return dev_id;
153b5411555SKevin Wolf     } else {
154b5411555SKevin Wolf         /* TODO Callback into the BB owner for something more detailed */
155b5411555SKevin Wolf         g_free(dev_id);
156b5411555SKevin Wolf         return g_strdup("a block device");
157b5411555SKevin Wolf     }
158b5411555SKevin Wolf }
159b5411555SKevin Wolf 
1604c265bf9SKevin Wolf static const char *blk_root_get_name(BdrvChild *child)
1614c265bf9SKevin Wolf {
1624c265bf9SKevin Wolf     return blk_name(child->opaque);
1634c265bf9SKevin Wolf }
1644c265bf9SKevin Wolf 
1655f7772c4SFam Zheng static void blk_vm_state_changed(void *opaque, int running, RunState state)
1665f7772c4SFam Zheng {
1675f7772c4SFam Zheng     Error *local_err = NULL;
1685f7772c4SFam Zheng     BlockBackend *blk = opaque;
1695f7772c4SFam Zheng 
1705f7772c4SFam Zheng     if (state == RUN_STATE_INMIGRATE) {
1715f7772c4SFam Zheng         return;
1725f7772c4SFam Zheng     }
1735f7772c4SFam Zheng 
1745f7772c4SFam Zheng     qemu_del_vm_change_state_handler(blk->vmsh);
1755f7772c4SFam Zheng     blk->vmsh = NULL;
1765f7772c4SFam Zheng     blk_set_perm(blk, blk->perm, blk->shared_perm, &local_err);
1775f7772c4SFam Zheng     if (local_err) {
1785f7772c4SFam Zheng         error_report_err(local_err);
1795f7772c4SFam Zheng     }
1805f7772c4SFam Zheng }
1815f7772c4SFam Zheng 
1824417ab7aSKevin Wolf /*
1834417ab7aSKevin Wolf  * Notifies the user of the BlockBackend that migration has completed. qdev
1844417ab7aSKevin Wolf  * devices can tighten their permissions in response (specifically revoke
1854417ab7aSKevin Wolf  * shared write permissions that we needed for storage migration).
1864417ab7aSKevin Wolf  *
1874417ab7aSKevin Wolf  * If an error is returned, the VM cannot be allowed to be resumed.
1884417ab7aSKevin Wolf  */
1894417ab7aSKevin Wolf static void blk_root_activate(BdrvChild *child, Error **errp)
1904417ab7aSKevin Wolf {
1914417ab7aSKevin Wolf     BlockBackend *blk = child->opaque;
1924417ab7aSKevin Wolf     Error *local_err = NULL;
1934417ab7aSKevin Wolf 
1944417ab7aSKevin Wolf     if (!blk->disable_perm) {
1954417ab7aSKevin Wolf         return;
1964417ab7aSKevin Wolf     }
1974417ab7aSKevin Wolf 
1984417ab7aSKevin Wolf     blk->disable_perm = false;
1994417ab7aSKevin Wolf 
2005f7772c4SFam Zheng     blk_set_perm(blk, blk->perm, BLK_PERM_ALL, &local_err);
2015f7772c4SFam Zheng     if (local_err) {
2025f7772c4SFam Zheng         error_propagate(errp, local_err);
2035f7772c4SFam Zheng         blk->disable_perm = true;
2045f7772c4SFam Zheng         return;
2055f7772c4SFam Zheng     }
2065f7772c4SFam Zheng 
2075f7772c4SFam Zheng     if (runstate_check(RUN_STATE_INMIGRATE)) {
2085f7772c4SFam Zheng         /* Activation can happen when migration process is still active, for
2095f7772c4SFam Zheng          * example when nbd_server_add is called during non-shared storage
2105f7772c4SFam Zheng          * migration. Defer the shared_perm update to migration completion. */
2115f7772c4SFam Zheng         if (!blk->vmsh) {
2125f7772c4SFam Zheng             blk->vmsh = qemu_add_vm_change_state_handler(blk_vm_state_changed,
2135f7772c4SFam Zheng                                                          blk);
2145f7772c4SFam Zheng         }
2155f7772c4SFam Zheng         return;
2165f7772c4SFam Zheng     }
2175f7772c4SFam Zheng 
2184417ab7aSKevin Wolf     blk_set_perm(blk, blk->perm, blk->shared_perm, &local_err);
2194417ab7aSKevin Wolf     if (local_err) {
2204417ab7aSKevin Wolf         error_propagate(errp, local_err);
2214417ab7aSKevin Wolf         blk->disable_perm = true;
2224417ab7aSKevin Wolf         return;
2234417ab7aSKevin Wolf     }
2244417ab7aSKevin Wolf }
2254417ab7aSKevin Wolf 
226ca2e2144SFam Zheng void blk_set_force_allow_inactivate(BlockBackend *blk)
227ca2e2144SFam Zheng {
228ca2e2144SFam Zheng     blk->force_allow_inactivate = true;
229ca2e2144SFam Zheng }
230ca2e2144SFam Zheng 
231c16de8f5SFam Zheng static bool blk_can_inactivate(BlockBackend *blk)
232c16de8f5SFam Zheng {
233ca2e2144SFam Zheng     /* If it is a guest device, inactivate is ok. */
234c16de8f5SFam Zheng     if (blk->dev || blk_name(blk)[0]) {
235c16de8f5SFam Zheng         return true;
236c16de8f5SFam Zheng     }
237c16de8f5SFam Zheng 
238ca2e2144SFam Zheng     /* Inactivating means no more writes to the image can be done,
239ca2e2144SFam Zheng      * even if those writes would be changes invisible to the
240ca2e2144SFam Zheng      * guest.  For block job BBs that satisfy this, we can just allow
241ca2e2144SFam Zheng      * it.  This is the case for mirror job source, which is required
242ca2e2144SFam Zheng      * by libvirt non-shared block migration. */
243ca2e2144SFam Zheng     if (!(blk->perm & (BLK_PERM_WRITE | BLK_PERM_WRITE_UNCHANGED))) {
244ca2e2144SFam Zheng         return true;
245ca2e2144SFam Zheng     }
246ca2e2144SFam Zheng 
247ca2e2144SFam Zheng     return blk->force_allow_inactivate;
248c16de8f5SFam Zheng }
249c16de8f5SFam Zheng 
250cfa1a572SKevin Wolf static int blk_root_inactivate(BdrvChild *child)
251cfa1a572SKevin Wolf {
252cfa1a572SKevin Wolf     BlockBackend *blk = child->opaque;
253cfa1a572SKevin Wolf 
254cfa1a572SKevin Wolf     if (blk->disable_perm) {
255cfa1a572SKevin Wolf         return 0;
256cfa1a572SKevin Wolf     }
257cfa1a572SKevin Wolf 
258c16de8f5SFam Zheng     if (!blk_can_inactivate(blk)) {
259cfa1a572SKevin Wolf         return -EPERM;
260cfa1a572SKevin Wolf     }
261cfa1a572SKevin Wolf 
262cfa1a572SKevin Wolf     blk->disable_perm = true;
263cfa1a572SKevin Wolf     if (blk->root) {
264cfa1a572SKevin Wolf         bdrv_child_try_set_perm(blk->root, 0, BLK_PERM_ALL, &error_abort);
265cfa1a572SKevin Wolf     }
266cfa1a572SKevin Wolf 
267cfa1a572SKevin Wolf     return 0;
268cfa1a572SKevin Wolf }
269cfa1a572SKevin Wolf 
270d03654eaSStefan Hajnoczi static void blk_root_attach(BdrvChild *child)
271d03654eaSStefan Hajnoczi {
272d03654eaSStefan Hajnoczi     BlockBackend *blk = child->opaque;
273d03654eaSStefan Hajnoczi     BlockBackendAioNotifier *notifier;
274d03654eaSStefan Hajnoczi 
275d03654eaSStefan Hajnoczi     trace_blk_root_attach(child, blk, child->bs);
276d03654eaSStefan Hajnoczi 
277d03654eaSStefan Hajnoczi     QLIST_FOREACH(notifier, &blk->aio_notifiers, list) {
278d03654eaSStefan Hajnoczi         bdrv_add_aio_context_notifier(child->bs,
279d03654eaSStefan Hajnoczi                 notifier->attached_aio_context,
280d03654eaSStefan Hajnoczi                 notifier->detach_aio_context,
281d03654eaSStefan Hajnoczi                 notifier->opaque);
282d03654eaSStefan Hajnoczi     }
283d03654eaSStefan Hajnoczi }
284d03654eaSStefan Hajnoczi 
285d03654eaSStefan Hajnoczi static void blk_root_detach(BdrvChild *child)
286d03654eaSStefan Hajnoczi {
287d03654eaSStefan Hajnoczi     BlockBackend *blk = child->opaque;
288d03654eaSStefan Hajnoczi     BlockBackendAioNotifier *notifier;
289d03654eaSStefan Hajnoczi 
290d03654eaSStefan Hajnoczi     trace_blk_root_detach(child, blk, child->bs);
291d03654eaSStefan Hajnoczi 
292d03654eaSStefan Hajnoczi     QLIST_FOREACH(notifier, &blk->aio_notifiers, list) {
293d03654eaSStefan Hajnoczi         bdrv_remove_aio_context_notifier(child->bs,
294d03654eaSStefan Hajnoczi                 notifier->attached_aio_context,
295d03654eaSStefan Hajnoczi                 notifier->detach_aio_context,
296d03654eaSStefan Hajnoczi                 notifier->opaque);
297d03654eaSStefan Hajnoczi     }
298d03654eaSStefan Hajnoczi }
299d03654eaSStefan Hajnoczi 
300f21d96d0SKevin Wolf static const BdrvChildRole child_root = {
301f21d96d0SKevin Wolf     .inherit_options    = blk_root_inherit_options,
302c2066af0SKevin Wolf 
3035c8cab48SKevin Wolf     .change_media       = blk_root_change_media,
3045c8cab48SKevin Wolf     .resize             = blk_root_resize,
3054c265bf9SKevin Wolf     .get_name           = blk_root_get_name,
306b5411555SKevin Wolf     .get_parent_desc    = blk_root_get_parent_desc,
3075c8cab48SKevin Wolf 
308c2066af0SKevin Wolf     .drained_begin      = blk_root_drained_begin,
309fe5258a5SKevin Wolf     .drained_poll       = blk_root_drained_poll,
310c2066af0SKevin Wolf     .drained_end        = blk_root_drained_end,
3114417ab7aSKevin Wolf 
3124417ab7aSKevin Wolf     .activate           = blk_root_activate,
313cfa1a572SKevin Wolf     .inactivate         = blk_root_inactivate,
314d03654eaSStefan Hajnoczi 
315d03654eaSStefan Hajnoczi     .attach             = blk_root_attach,
316d03654eaSStefan Hajnoczi     .detach             = blk_root_detach,
31738475269SKevin Wolf 
31838475269SKevin Wolf     .can_set_aio_ctx    = blk_root_can_set_aio_ctx,
31938475269SKevin Wolf     .set_aio_ctx        = blk_root_set_aio_ctx,
320f21d96d0SKevin Wolf };
321f21d96d0SKevin Wolf 
32226f54e9aSMarkus Armbruster /*
323efaa7c4eSMax Reitz  * Create a new BlockBackend with a reference count of one.
3246d0eb64dSKevin Wolf  *
3256d0eb64dSKevin Wolf  * @perm is a bitmasks of BLK_PERM_* constants which describes the permissions
3266d0eb64dSKevin Wolf  * to request for a block driver node that is attached to this BlockBackend.
3276d0eb64dSKevin Wolf  * @shared_perm is a bitmask which describes which permissions may be granted
3286d0eb64dSKevin Wolf  * to other users of the attached node.
3296d0eb64dSKevin Wolf  * Both sets of permissions can be changed later using blk_set_perm().
3306d0eb64dSKevin Wolf  *
33126f54e9aSMarkus Armbruster  * Return the new BlockBackend on success, null on failure.
33226f54e9aSMarkus Armbruster  */
333d861ab3aSKevin Wolf BlockBackend *blk_new(AioContext *ctx, uint64_t perm, uint64_t shared_perm)
33426f54e9aSMarkus Armbruster {
33526f54e9aSMarkus Armbruster     BlockBackend *blk;
33626f54e9aSMarkus Armbruster 
33726f54e9aSMarkus Armbruster     blk = g_new0(BlockBackend, 1);
33826f54e9aSMarkus Armbruster     blk->refcnt = 1;
339d861ab3aSKevin Wolf     blk->ctx = ctx;
3406d0eb64dSKevin Wolf     blk->perm = perm;
3416d0eb64dSKevin Wolf     blk->shared_perm = shared_perm;
3420c3169dfSKevin Wolf     blk_set_enable_write_cache(blk, true);
3430c3169dfSKevin Wolf 
344cb53460bSKevin Wolf     blk->on_read_error = BLOCKDEV_ON_ERROR_REPORT;
345cb53460bSKevin Wolf     blk->on_write_error = BLOCKDEV_ON_ERROR_ENOSPC;
346cb53460bSKevin Wolf 
3479caa6f3dSPaolo Bonzini     block_acct_init(&blk->stats);
34827ccdd52SKevin Wolf 
349cf312932SKevin Wolf     qemu_co_queue_init(&blk->queued_requests);
3503301f6c6SMax Reitz     notifier_list_init(&blk->remove_bs_notifiers);
3513301f6c6SMax Reitz     notifier_list_init(&blk->insert_bs_notifiers);
352d03654eaSStefan Hajnoczi     QLIST_INIT(&blk->aio_notifiers);
35327ccdd52SKevin Wolf 
3542cf22d6aSMax Reitz     QTAILQ_INSERT_TAIL(&block_backends, blk, link);
35526f54e9aSMarkus Armbruster     return blk;
35626f54e9aSMarkus Armbruster }
35726f54e9aSMarkus Armbruster 
3587e7d56d9SMarkus Armbruster /*
35928eb9b12SMax Reitz  * Creates a new BlockBackend, opens a new BlockDriverState, and connects both.
360d861ab3aSKevin Wolf  * The new BlockBackend is in the main AioContext.
361ca49a4fdSMax Reitz  *
362ca49a4fdSMax Reitz  * Just as with bdrv_open(), after having called this function the reference to
363ca49a4fdSMax Reitz  * @options belongs to the block layer (even on failure).
364ca49a4fdSMax Reitz  *
365ca49a4fdSMax Reitz  * TODO: Remove @filename and @flags; it should be possible to specify a whole
366ca49a4fdSMax Reitz  * BDS tree just by specifying the @options QDict (or @reference,
367ca49a4fdSMax Reitz  * alternatively). At the time of adding this function, this is not possible,
368ca49a4fdSMax Reitz  * though, so callers of this function have to be able to specify @filename and
369ca49a4fdSMax Reitz  * @flags.
370ca49a4fdSMax Reitz  */
371efaa7c4eSMax Reitz BlockBackend *blk_new_open(const char *filename, const char *reference,
372efaa7c4eSMax Reitz                            QDict *options, int flags, Error **errp)
373ca49a4fdSMax Reitz {
374ca49a4fdSMax Reitz     BlockBackend *blk;
37528eb9b12SMax Reitz     BlockDriverState *bs;
3761f4ad7d3SKevin Wolf     uint64_t perm = 0;
377ca49a4fdSMax Reitz 
378c62d32f5SKevin Wolf     /* blk_new_open() is mainly used in .bdrv_create implementations and the
379c62d32f5SKevin Wolf      * tools where sharing isn't a concern because the BDS stays private, so we
380c62d32f5SKevin Wolf      * just request permission according to the flags.
381c62d32f5SKevin Wolf      *
382c62d32f5SKevin Wolf      * The exceptions are xen_disk and blockdev_init(); in these cases, the
383c62d32f5SKevin Wolf      * caller of blk_new_open() doesn't make use of the permissions, but they
384c62d32f5SKevin Wolf      * shouldn't hurt either. We can still share everything here because the
385c62d32f5SKevin Wolf      * guest devices will add their own blockers if they can't share. */
3861f4ad7d3SKevin Wolf     if ((flags & BDRV_O_NO_IO) == 0) {
3871f4ad7d3SKevin Wolf         perm |= BLK_PERM_CONSISTENT_READ;
388c62d32f5SKevin Wolf         if (flags & BDRV_O_RDWR) {
389c62d32f5SKevin Wolf             perm |= BLK_PERM_WRITE;
390c62d32f5SKevin Wolf         }
3911f4ad7d3SKevin Wolf     }
392c62d32f5SKevin Wolf     if (flags & BDRV_O_RESIZE) {
393c62d32f5SKevin Wolf         perm |= BLK_PERM_RESIZE;
394c62d32f5SKevin Wolf     }
395c62d32f5SKevin Wolf 
396d861ab3aSKevin Wolf     blk = blk_new(qemu_get_aio_context(), perm, BLK_PERM_ALL);
3975b363937SMax Reitz     bs = bdrv_open(filename, reference, options, flags, errp);
3985b363937SMax Reitz     if (!bs) {
399ca49a4fdSMax Reitz         blk_unref(blk);
400ca49a4fdSMax Reitz         return NULL;
401ca49a4fdSMax Reitz     }
402ca49a4fdSMax Reitz 
403132ada80SKevin Wolf     blk->root = bdrv_root_attach_child(bs, "root", &child_root, blk->ctx,
40450bfbe93SFam Zheng                                        perm, BLK_PERM_ALL, blk, errp);
40550bfbe93SFam Zheng     if (!blk->root) {
40650bfbe93SFam Zheng         blk_unref(blk);
40750bfbe93SFam Zheng         return NULL;
40850bfbe93SFam Zheng     }
40972e775c7SKevin Wolf 
410ca49a4fdSMax Reitz     return blk;
411ca49a4fdSMax Reitz }
412ca49a4fdSMax Reitz 
41326f54e9aSMarkus Armbruster static void blk_delete(BlockBackend *blk)
41426f54e9aSMarkus Armbruster {
41526f54e9aSMarkus Armbruster     assert(!blk->refcnt);
416e5e78550SMax Reitz     assert(!blk->name);
417a7f53e26SMarkus Armbruster     assert(!blk->dev);
418022cdc9fSManos Pitsidianakis     if (blk->public.throttle_group_member.throttle_state) {
4191606e4cfSEric Blake         blk_io_limits_disable(blk);
4201606e4cfSEric Blake     }
421f21d96d0SKevin Wolf     if (blk->root) {
42213855c6bSMax Reitz         blk_remove_bs(blk);
4237e7d56d9SMarkus Armbruster     }
4245f7772c4SFam Zheng     if (blk->vmsh) {
4255f7772c4SFam Zheng         qemu_del_vm_change_state_handler(blk->vmsh);
4265f7772c4SFam Zheng         blk->vmsh = NULL;
4275f7772c4SFam Zheng     }
4283301f6c6SMax Reitz     assert(QLIST_EMPTY(&blk->remove_bs_notifiers.notifiers));
4293301f6c6SMax Reitz     assert(QLIST_EMPTY(&blk->insert_bs_notifiers.notifiers));
430d03654eaSStefan Hajnoczi     assert(QLIST_EMPTY(&blk->aio_notifiers));
4312cf22d6aSMax Reitz     QTAILQ_REMOVE(&block_backends, blk, link);
43218e46a03SMarkus Armbruster     drive_info_del(blk->legacy_dinfo);
433979e9b03SAlberto Garcia     block_acct_cleanup(&blk->stats);
43426f54e9aSMarkus Armbruster     g_free(blk);
43526f54e9aSMarkus Armbruster }
43626f54e9aSMarkus Armbruster 
4378fb3c76cSMarkus Armbruster static void drive_info_del(DriveInfo *dinfo)
4388fb3c76cSMarkus Armbruster {
4398fb3c76cSMarkus Armbruster     if (!dinfo) {
4408fb3c76cSMarkus Armbruster         return;
4418fb3c76cSMarkus Armbruster     }
4428fb3c76cSMarkus Armbruster     qemu_opts_del(dinfo->opts);
4438fb3c76cSMarkus Armbruster     g_free(dinfo);
4448fb3c76cSMarkus Armbruster }
4458fb3c76cSMarkus Armbruster 
446f636ae85SAlberto Garcia int blk_get_refcnt(BlockBackend *blk)
447f636ae85SAlberto Garcia {
448f636ae85SAlberto Garcia     return blk ? blk->refcnt : 0;
449f636ae85SAlberto Garcia }
450f636ae85SAlberto Garcia 
45126f54e9aSMarkus Armbruster /*
45226f54e9aSMarkus Armbruster  * Increment @blk's reference count.
45326f54e9aSMarkus Armbruster  * @blk must not be null.
45426f54e9aSMarkus Armbruster  */
45526f54e9aSMarkus Armbruster void blk_ref(BlockBackend *blk)
45626f54e9aSMarkus Armbruster {
4575ca9d21bSKevin Wolf     assert(blk->refcnt > 0);
45826f54e9aSMarkus Armbruster     blk->refcnt++;
45926f54e9aSMarkus Armbruster }
46026f54e9aSMarkus Armbruster 
46126f54e9aSMarkus Armbruster /*
46226f54e9aSMarkus Armbruster  * Decrement @blk's reference count.
46326f54e9aSMarkus Armbruster  * If this drops it to zero, destroy @blk.
46426f54e9aSMarkus Armbruster  * For convenience, do nothing if @blk is null.
46526f54e9aSMarkus Armbruster  */
46626f54e9aSMarkus Armbruster void blk_unref(BlockBackend *blk)
46726f54e9aSMarkus Armbruster {
46826f54e9aSMarkus Armbruster     if (blk) {
46926f54e9aSMarkus Armbruster         assert(blk->refcnt > 0);
4705ca9d21bSKevin Wolf         if (blk->refcnt > 1) {
4715ca9d21bSKevin Wolf             blk->refcnt--;
4725ca9d21bSKevin Wolf         } else {
4735ca9d21bSKevin Wolf             blk_drain(blk);
4745ca9d21bSKevin Wolf             /* blk_drain() cannot resurrect blk, nobody held a reference */
4755ca9d21bSKevin Wolf             assert(blk->refcnt == 1);
4765ca9d21bSKevin Wolf             blk->refcnt = 0;
47726f54e9aSMarkus Armbruster             blk_delete(blk);
47826f54e9aSMarkus Armbruster         }
47926f54e9aSMarkus Armbruster     }
48026f54e9aSMarkus Armbruster }
48126f54e9aSMarkus Armbruster 
4822cf22d6aSMax Reitz /*
4832cf22d6aSMax Reitz  * Behaves similarly to blk_next() but iterates over all BlockBackends, even the
4842cf22d6aSMax Reitz  * ones which are hidden (i.e. are not referenced by the monitor).
4852cf22d6aSMax Reitz  */
486a429b9b5SKevin Wolf BlockBackend *blk_all_next(BlockBackend *blk)
4872cf22d6aSMax Reitz {
4882cf22d6aSMax Reitz     return blk ? QTAILQ_NEXT(blk, link)
4892cf22d6aSMax Reitz                : QTAILQ_FIRST(&block_backends);
4902cf22d6aSMax Reitz }
4912cf22d6aSMax Reitz 
492d8da3cefSMax Reitz void blk_remove_all_bs(void)
493d8da3cefSMax Reitz {
49474d1b8fcSMax Reitz     BlockBackend *blk = NULL;
495d8da3cefSMax Reitz 
4962cf22d6aSMax Reitz     while ((blk = blk_all_next(blk)) != NULL) {
497d8da3cefSMax Reitz         AioContext *ctx = blk_get_aio_context(blk);
498d8da3cefSMax Reitz 
499d8da3cefSMax Reitz         aio_context_acquire(ctx);
500f21d96d0SKevin Wolf         if (blk->root) {
501d8da3cefSMax Reitz             blk_remove_bs(blk);
502d8da3cefSMax Reitz         }
503d8da3cefSMax Reitz         aio_context_release(ctx);
504d8da3cefSMax Reitz     }
505d8da3cefSMax Reitz }
506d8da3cefSMax Reitz 
50726f54e9aSMarkus Armbruster /*
5089492b0b9SMax Reitz  * Return the monitor-owned BlockBackend after @blk.
50926f54e9aSMarkus Armbruster  * If @blk is null, return the first one.
51026f54e9aSMarkus Armbruster  * Else, return @blk's next sibling, which may be null.
51126f54e9aSMarkus Armbruster  *
51226f54e9aSMarkus Armbruster  * To iterate over all BlockBackends, do
51326f54e9aSMarkus Armbruster  * for (blk = blk_next(NULL); blk; blk = blk_next(blk)) {
51426f54e9aSMarkus Armbruster  *     ...
51526f54e9aSMarkus Armbruster  * }
51626f54e9aSMarkus Armbruster  */
51726f54e9aSMarkus Armbruster BlockBackend *blk_next(BlockBackend *blk)
51826f54e9aSMarkus Armbruster {
5199492b0b9SMax Reitz     return blk ? QTAILQ_NEXT(blk, monitor_link)
5209492b0b9SMax Reitz                : QTAILQ_FIRST(&monitor_block_backends);
52126f54e9aSMarkus Armbruster }
52226f54e9aSMarkus Armbruster 
5237c8eece4SKevin Wolf /* Iterates over all top-level BlockDriverStates, i.e. BDSs that are owned by
5247c8eece4SKevin Wolf  * the monitor or attached to a BlockBackend */
52588be7b4bSKevin Wolf BlockDriverState *bdrv_next(BdrvNextIterator *it)
5267c8eece4SKevin Wolf {
5275e003f17SMax Reitz     BlockDriverState *bs, *old_bs;
5285e003f17SMax Reitz 
5295e003f17SMax Reitz     /* Must be called from the main loop */
5305e003f17SMax Reitz     assert(qemu_get_current_aio_context() == qemu_get_aio_context());
531981f4f57SMax Reitz 
5327c8eece4SKevin Wolf     /* First, return all root nodes of BlockBackends. In order to avoid
5337c8eece4SKevin Wolf      * returning a BDS twice when multiple BBs refer to it, we only return it
5347c8eece4SKevin Wolf      * if the BB is the first one in the parent list of the BDS. */
5357c8eece4SKevin Wolf     if (it->phase == BDRV_NEXT_BACKEND_ROOTS) {
5365e003f17SMax Reitz         BlockBackend *old_blk = it->blk;
5375e003f17SMax Reitz 
5385e003f17SMax Reitz         old_bs = old_blk ? blk_bs(old_blk) : NULL;
5395e003f17SMax Reitz 
540981f4f57SMax Reitz         do {
5417c8eece4SKevin Wolf             it->blk = blk_all_next(it->blk);
54288be7b4bSKevin Wolf             bs = it->blk ? blk_bs(it->blk) : NULL;
54388be7b4bSKevin Wolf         } while (it->blk && (bs == NULL || bdrv_first_blk(bs) != it->blk));
544981f4f57SMax Reitz 
5455e003f17SMax Reitz         if (it->blk) {
5465e003f17SMax Reitz             blk_ref(it->blk);
5475e003f17SMax Reitz         }
5485e003f17SMax Reitz         blk_unref(old_blk);
5495e003f17SMax Reitz 
55088be7b4bSKevin Wolf         if (bs) {
5515e003f17SMax Reitz             bdrv_ref(bs);
5525e003f17SMax Reitz             bdrv_unref(old_bs);
55388be7b4bSKevin Wolf             return bs;
5547c8eece4SKevin Wolf         }
5557c8eece4SKevin Wolf         it->phase = BDRV_NEXT_MONITOR_OWNED;
5565e003f17SMax Reitz     } else {
5575e003f17SMax Reitz         old_bs = it->bs;
5587c8eece4SKevin Wolf     }
5597c8eece4SKevin Wolf 
5607c8eece4SKevin Wolf     /* Then return the monitor-owned BDSes without a BB attached. Ignore all
5617c8eece4SKevin Wolf      * BDSes that are attached to a BlockBackend here; they have been handled
5627c8eece4SKevin Wolf      * by the above block already */
5637c8eece4SKevin Wolf     do {
5647c8eece4SKevin Wolf         it->bs = bdrv_next_monitor_owned(it->bs);
56588be7b4bSKevin Wolf         bs = it->bs;
56688be7b4bSKevin Wolf     } while (bs && bdrv_has_blk(bs));
5677c8eece4SKevin Wolf 
5685e003f17SMax Reitz     if (bs) {
5695e003f17SMax Reitz         bdrv_ref(bs);
5705e003f17SMax Reitz     }
5715e003f17SMax Reitz     bdrv_unref(old_bs);
5725e003f17SMax Reitz 
57388be7b4bSKevin Wolf     return bs;
57488be7b4bSKevin Wolf }
57588be7b4bSKevin Wolf 
5765e003f17SMax Reitz static void bdrv_next_reset(BdrvNextIterator *it)
57788be7b4bSKevin Wolf {
57888be7b4bSKevin Wolf     *it = (BdrvNextIterator) {
57988be7b4bSKevin Wolf         .phase = BDRV_NEXT_BACKEND_ROOTS,
58088be7b4bSKevin Wolf     };
5815e003f17SMax Reitz }
58288be7b4bSKevin Wolf 
5835e003f17SMax Reitz BlockDriverState *bdrv_first(BdrvNextIterator *it)
5845e003f17SMax Reitz {
5855e003f17SMax Reitz     bdrv_next_reset(it);
58688be7b4bSKevin Wolf     return bdrv_next(it);
587981f4f57SMax Reitz }
588981f4f57SMax Reitz 
5895e003f17SMax Reitz /* Must be called when aborting a bdrv_next() iteration before
5905e003f17SMax Reitz  * bdrv_next() returns NULL */
5915e003f17SMax Reitz void bdrv_next_cleanup(BdrvNextIterator *it)
5925e003f17SMax Reitz {
5935e003f17SMax Reitz     /* Must be called from the main loop */
5945e003f17SMax Reitz     assert(qemu_get_current_aio_context() == qemu_get_aio_context());
5955e003f17SMax Reitz 
5965e003f17SMax Reitz     if (it->phase == BDRV_NEXT_BACKEND_ROOTS) {
5975e003f17SMax Reitz         if (it->blk) {
5985e003f17SMax Reitz             bdrv_unref(blk_bs(it->blk));
5995e003f17SMax Reitz             blk_unref(it->blk);
6005e003f17SMax Reitz         }
6015e003f17SMax Reitz     } else {
6025e003f17SMax Reitz         bdrv_unref(it->bs);
6035e003f17SMax Reitz     }
6045e003f17SMax Reitz 
6055e003f17SMax Reitz     bdrv_next_reset(it);
6065e003f17SMax Reitz }
6075e003f17SMax Reitz 
608981f4f57SMax Reitz /*
609e5e78550SMax Reitz  * Add a BlockBackend into the list of backends referenced by the monitor, with
610e5e78550SMax Reitz  * the given @name acting as the handle for the monitor.
611e5e78550SMax Reitz  * Strictly for use by blockdev.c.
612e5e78550SMax Reitz  *
613e5e78550SMax Reitz  * @name must not be null or empty.
614e5e78550SMax Reitz  *
615e5e78550SMax Reitz  * Returns true on success and false on failure. In the latter case, an Error
616e5e78550SMax Reitz  * object is returned through @errp.
617e5e78550SMax Reitz  */
618e5e78550SMax Reitz bool monitor_add_blk(BlockBackend *blk, const char *name, Error **errp)
619e5e78550SMax Reitz {
620e5e78550SMax Reitz     assert(!blk->name);
621e5e78550SMax Reitz     assert(name && name[0]);
622e5e78550SMax Reitz 
623e5e78550SMax Reitz     if (!id_wellformed(name)) {
624e5e78550SMax Reitz         error_setg(errp, "Invalid device name");
625e5e78550SMax Reitz         return false;
626e5e78550SMax Reitz     }
627e5e78550SMax Reitz     if (blk_by_name(name)) {
628e5e78550SMax Reitz         error_setg(errp, "Device with id '%s' already exists", name);
629e5e78550SMax Reitz         return false;
630e5e78550SMax Reitz     }
631e5e78550SMax Reitz     if (bdrv_find_node(name)) {
632e5e78550SMax Reitz         error_setg(errp,
633e5e78550SMax Reitz                    "Device name '%s' conflicts with an existing node name",
634e5e78550SMax Reitz                    name);
635e5e78550SMax Reitz         return false;
636e5e78550SMax Reitz     }
637e5e78550SMax Reitz 
638e5e78550SMax Reitz     blk->name = g_strdup(name);
639e5e78550SMax Reitz     QTAILQ_INSERT_TAIL(&monitor_block_backends, blk, monitor_link);
640e5e78550SMax Reitz     return true;
641e5e78550SMax Reitz }
642e5e78550SMax Reitz 
643e5e78550SMax Reitz /*
644e5e78550SMax Reitz  * Remove a BlockBackend from the list of backends referenced by the monitor.
645e5e78550SMax Reitz  * Strictly for use by blockdev.c.
646e5e78550SMax Reitz  */
647e5e78550SMax Reitz void monitor_remove_blk(BlockBackend *blk)
648e5e78550SMax Reitz {
649e5e78550SMax Reitz     if (!blk->name) {
650e5e78550SMax Reitz         return;
651e5e78550SMax Reitz     }
652e5e78550SMax Reitz 
653e5e78550SMax Reitz     QTAILQ_REMOVE(&monitor_block_backends, blk, monitor_link);
654e5e78550SMax Reitz     g_free(blk->name);
655e5e78550SMax Reitz     blk->name = NULL;
656e5e78550SMax Reitz }
657e5e78550SMax Reitz 
658e5e78550SMax Reitz /*
6597e7d56d9SMarkus Armbruster  * Return @blk's name, a non-null string.
660e5e78550SMax Reitz  * Returns an empty string iff @blk is not referenced by the monitor.
66126f54e9aSMarkus Armbruster  */
6620731a50fSKrzysztof Kozlowski const char *blk_name(const BlockBackend *blk)
66326f54e9aSMarkus Armbruster {
664e5e78550SMax Reitz     return blk->name ?: "";
66526f54e9aSMarkus Armbruster }
66626f54e9aSMarkus Armbruster 
66726f54e9aSMarkus Armbruster /*
66826f54e9aSMarkus Armbruster  * Return the BlockBackend with name @name if it exists, else null.
66926f54e9aSMarkus Armbruster  * @name must not be null.
67026f54e9aSMarkus Armbruster  */
67126f54e9aSMarkus Armbruster BlockBackend *blk_by_name(const char *name)
67226f54e9aSMarkus Armbruster {
67374d1b8fcSMax Reitz     BlockBackend *blk = NULL;
67426f54e9aSMarkus Armbruster 
67526f54e9aSMarkus Armbruster     assert(name);
67674d1b8fcSMax Reitz     while ((blk = blk_next(blk)) != NULL) {
67726f54e9aSMarkus Armbruster         if (!strcmp(name, blk->name)) {
67826f54e9aSMarkus Armbruster             return blk;
67926f54e9aSMarkus Armbruster         }
68026f54e9aSMarkus Armbruster     }
68126f54e9aSMarkus Armbruster     return NULL;
68226f54e9aSMarkus Armbruster }
6837e7d56d9SMarkus Armbruster 
6847e7d56d9SMarkus Armbruster /*
6857e7d56d9SMarkus Armbruster  * Return the BlockDriverState attached to @blk if any, else null.
6867e7d56d9SMarkus Armbruster  */
6877e7d56d9SMarkus Armbruster BlockDriverState *blk_bs(BlockBackend *blk)
6887e7d56d9SMarkus Armbruster {
689f21d96d0SKevin Wolf     return blk->root ? blk->root->bs : NULL;
6907e7d56d9SMarkus Armbruster }
6917e7d56d9SMarkus Armbruster 
6927c8eece4SKevin Wolf static BlockBackend *bdrv_first_blk(BlockDriverState *bs)
693dde33812SKevin Wolf {
694dde33812SKevin Wolf     BdrvChild *child;
695dde33812SKevin Wolf     QLIST_FOREACH(child, &bs->parents, next_parent) {
696dde33812SKevin Wolf         if (child->role == &child_root) {
6977c8eece4SKevin Wolf             return child->opaque;
698dde33812SKevin Wolf         }
699dde33812SKevin Wolf     }
700dde33812SKevin Wolf 
7017c8eece4SKevin Wolf     return NULL;
7027c8eece4SKevin Wolf }
7037c8eece4SKevin Wolf 
7047c8eece4SKevin Wolf /*
7057c8eece4SKevin Wolf  * Returns true if @bs has an associated BlockBackend.
7067c8eece4SKevin Wolf  */
7077c8eece4SKevin Wolf bool bdrv_has_blk(BlockDriverState *bs)
7087c8eece4SKevin Wolf {
7097c8eece4SKevin Wolf     return bdrv_first_blk(bs) != NULL;
710dde33812SKevin Wolf }
711dde33812SKevin Wolf 
712dde33812SKevin Wolf /*
713b6c1bae5SKevin Wolf  * Returns true if @bs has only BlockBackends as parents.
714b6c1bae5SKevin Wolf  */
715b6c1bae5SKevin Wolf bool bdrv_is_root_node(BlockDriverState *bs)
716b6c1bae5SKevin Wolf {
717b6c1bae5SKevin Wolf     BdrvChild *c;
718b6c1bae5SKevin Wolf 
719b6c1bae5SKevin Wolf     QLIST_FOREACH(c, &bs->parents, next_parent) {
720b6c1bae5SKevin Wolf         if (c->role != &child_root) {
721b6c1bae5SKevin Wolf             return false;
722b6c1bae5SKevin Wolf         }
723b6c1bae5SKevin Wolf     }
724b6c1bae5SKevin Wolf 
725b6c1bae5SKevin Wolf     return true;
726b6c1bae5SKevin Wolf }
727b6c1bae5SKevin Wolf 
728b6c1bae5SKevin Wolf /*
72918e46a03SMarkus Armbruster  * Return @blk's DriveInfo if any, else null.
73018e46a03SMarkus Armbruster  */
73118e46a03SMarkus Armbruster DriveInfo *blk_legacy_dinfo(BlockBackend *blk)
73218e46a03SMarkus Armbruster {
73318e46a03SMarkus Armbruster     return blk->legacy_dinfo;
73418e46a03SMarkus Armbruster }
73518e46a03SMarkus Armbruster 
73618e46a03SMarkus Armbruster /*
73718e46a03SMarkus Armbruster  * Set @blk's DriveInfo to @dinfo, and return it.
73818e46a03SMarkus Armbruster  * @blk must not have a DriveInfo set already.
73918e46a03SMarkus Armbruster  * No other BlockBackend may have the same DriveInfo set.
74018e46a03SMarkus Armbruster  */
74118e46a03SMarkus Armbruster DriveInfo *blk_set_legacy_dinfo(BlockBackend *blk, DriveInfo *dinfo)
74218e46a03SMarkus Armbruster {
74318e46a03SMarkus Armbruster     assert(!blk->legacy_dinfo);
74418e46a03SMarkus Armbruster     return blk->legacy_dinfo = dinfo;
74518e46a03SMarkus Armbruster }
74618e46a03SMarkus Armbruster 
74718e46a03SMarkus Armbruster /*
74818e46a03SMarkus Armbruster  * Return the BlockBackend with DriveInfo @dinfo.
74918e46a03SMarkus Armbruster  * It must exist.
75018e46a03SMarkus Armbruster  */
75118e46a03SMarkus Armbruster BlockBackend *blk_by_legacy_dinfo(DriveInfo *dinfo)
75218e46a03SMarkus Armbruster {
75374d1b8fcSMax Reitz     BlockBackend *blk = NULL;
75418e46a03SMarkus Armbruster 
75574d1b8fcSMax Reitz     while ((blk = blk_next(blk)) != NULL) {
75618e46a03SMarkus Armbruster         if (blk->legacy_dinfo == dinfo) {
75718e46a03SMarkus Armbruster             return blk;
75818e46a03SMarkus Armbruster         }
75918e46a03SMarkus Armbruster     }
76018e46a03SMarkus Armbruster     abort();
76118e46a03SMarkus Armbruster }
76218e46a03SMarkus Armbruster 
76318e46a03SMarkus Armbruster /*
764f2cd875dSKevin Wolf  * Returns a pointer to the publicly accessible fields of @blk.
765f2cd875dSKevin Wolf  */
766f2cd875dSKevin Wolf BlockBackendPublic *blk_get_public(BlockBackend *blk)
767f2cd875dSKevin Wolf {
768f2cd875dSKevin Wolf     return &blk->public;
769f2cd875dSKevin Wolf }
770f2cd875dSKevin Wolf 
771f2cd875dSKevin Wolf /*
772f2cd875dSKevin Wolf  * Returns a BlockBackend given the associated @public fields.
773f2cd875dSKevin Wolf  */
774f2cd875dSKevin Wolf BlockBackend *blk_by_public(BlockBackendPublic *public)
775f2cd875dSKevin Wolf {
776f2cd875dSKevin Wolf     return container_of(public, BlockBackend, public);
777f2cd875dSKevin Wolf }
778f2cd875dSKevin Wolf 
779f2cd875dSKevin Wolf /*
7801c95f7e1SMax Reitz  * Disassociates the currently associated BlockDriverState from @blk.
7811c95f7e1SMax Reitz  */
7821c95f7e1SMax Reitz void blk_remove_bs(BlockBackend *blk)
7831c95f7e1SMax Reitz {
784c89bcf3aSAlberto Garcia     ThrottleGroupMember *tgm = &blk->public.throttle_group_member;
785632a7735SZhengui     BlockDriverState *bs;
786022cdc9fSManos Pitsidianakis 
7873301f6c6SMax Reitz     notifier_list_notify(&blk->remove_bs_notifiers, blk);
788c89bcf3aSAlberto Garcia     if (tgm->throttle_state) {
789632a7735SZhengui         bs = blk_bs(blk);
790632a7735SZhengui         bdrv_drained_begin(bs);
791c89bcf3aSAlberto Garcia         throttle_group_detach_aio_context(tgm);
792c89bcf3aSAlberto Garcia         throttle_group_attach_aio_context(tgm, qemu_get_aio_context());
793632a7735SZhengui         bdrv_drained_end(bs);
7947ca7f0f6SKevin Wolf     }
7953301f6c6SMax Reitz 
7961c95f7e1SMax Reitz     blk_update_root_state(blk);
7971c95f7e1SMax Reitz 
798f45280cbSGreg Kurz     /* bdrv_root_unref_child() will cause blk->root to become stale and may
799f45280cbSGreg Kurz      * switch to a completion coroutine later on. Let's drain all I/O here
800f45280cbSGreg Kurz      * to avoid that and a potential QEMU crash.
801f45280cbSGreg Kurz      */
802f45280cbSGreg Kurz     blk_drain(blk);
803f21d96d0SKevin Wolf     bdrv_root_unref_child(blk->root);
804f21d96d0SKevin Wolf     blk->root = NULL;
8051c95f7e1SMax Reitz }
8061c95f7e1SMax Reitz 
8071c95f7e1SMax Reitz /*
8080c3c36d6SMax Reitz  * Associates a new BlockDriverState with @blk.
8090c3c36d6SMax Reitz  */
810d7086422SKevin Wolf int blk_insert_bs(BlockBackend *blk, BlockDriverState *bs, Error **errp)
8110c3c36d6SMax Reitz {
812c89bcf3aSAlberto Garcia     ThrottleGroupMember *tgm = &blk->public.throttle_group_member;
813b441dc71SAlberto Garcia     bdrv_ref(bs);
814132ada80SKevin Wolf     blk->root = bdrv_root_attach_child(bs, "root", &child_root, blk->ctx,
815d7086422SKevin Wolf                                        blk->perm, blk->shared_perm, blk, errp);
816d7086422SKevin Wolf     if (blk->root == NULL) {
817d7086422SKevin Wolf         return -EPERM;
818d7086422SKevin Wolf     }
8193301f6c6SMax Reitz 
8203301f6c6SMax Reitz     notifier_list_notify(&blk->insert_bs_notifiers, blk);
821c89bcf3aSAlberto Garcia     if (tgm->throttle_state) {
822c89bcf3aSAlberto Garcia         throttle_group_detach_aio_context(tgm);
823c89bcf3aSAlberto Garcia         throttle_group_attach_aio_context(tgm, bdrv_get_aio_context(bs));
8247ca7f0f6SKevin Wolf     }
825d7086422SKevin Wolf 
826d7086422SKevin Wolf     return 0;
8270c3c36d6SMax Reitz }
8280c3c36d6SMax Reitz 
829981776b3SKevin Wolf /*
830981776b3SKevin Wolf  * Sets the permission bitmasks that the user of the BlockBackend needs.
831981776b3SKevin Wolf  */
832981776b3SKevin Wolf int blk_set_perm(BlockBackend *blk, uint64_t perm, uint64_t shared_perm,
833981776b3SKevin Wolf                  Error **errp)
834981776b3SKevin Wolf {
835981776b3SKevin Wolf     int ret;
836981776b3SKevin Wolf 
837d35ff5e6SKevin Wolf     if (blk->root && !blk->disable_perm) {
838981776b3SKevin Wolf         ret = bdrv_child_try_set_perm(blk->root, perm, shared_perm, errp);
839981776b3SKevin Wolf         if (ret < 0) {
840981776b3SKevin Wolf             return ret;
841981776b3SKevin Wolf         }
842981776b3SKevin Wolf     }
843981776b3SKevin Wolf 
844981776b3SKevin Wolf     blk->perm = perm;
845981776b3SKevin Wolf     blk->shared_perm = shared_perm;
846981776b3SKevin Wolf 
847981776b3SKevin Wolf     return 0;
848981776b3SKevin Wolf }
849981776b3SKevin Wolf 
850887354bdSKevin Wolf void blk_get_perm(BlockBackend *blk, uint64_t *perm, uint64_t *shared_perm)
851887354bdSKevin Wolf {
852887354bdSKevin Wolf     *perm = blk->perm;
853887354bdSKevin Wolf     *shared_perm = blk->shared_perm;
854887354bdSKevin Wolf }
855887354bdSKevin Wolf 
856d09ea2d2SThomas Huth /*
857d09ea2d2SThomas Huth  * Attach device model @dev to @blk.
858d09ea2d2SThomas Huth  * Return 0 on success, -EBUSY when a device model is attached already.
859d09ea2d2SThomas Huth  */
860d09ea2d2SThomas Huth int blk_attach_dev(BlockBackend *blk, DeviceState *dev)
861a7f53e26SMarkus Armbruster {
862a7f53e26SMarkus Armbruster     if (blk->dev) {
863a7f53e26SMarkus Armbruster         return -EBUSY;
864a7f53e26SMarkus Armbruster     }
865d35ff5e6SKevin Wolf 
866d35ff5e6SKevin Wolf     /* While migration is still incoming, we don't need to apply the
867d35ff5e6SKevin Wolf      * permissions of guest device BlockBackends. We might still have a block
868d35ff5e6SKevin Wolf      * job or NBD server writing to the image for storage migration. */
869d35ff5e6SKevin Wolf     if (runstate_check(RUN_STATE_INMIGRATE)) {
870d35ff5e6SKevin Wolf         blk->disable_perm = true;
871d35ff5e6SKevin Wolf     }
872d35ff5e6SKevin Wolf 
87384ebe375SMarkus Armbruster     blk_ref(blk);
874a7f53e26SMarkus Armbruster     blk->dev = dev;
875373340b2SMax Reitz     blk_iostatus_reset(blk);
876d35ff5e6SKevin Wolf 
877a7f53e26SMarkus Armbruster     return 0;
878a7f53e26SMarkus Armbruster }
879a7f53e26SMarkus Armbruster 
880a7f53e26SMarkus Armbruster /*
881a7f53e26SMarkus Armbruster  * Detach device model @dev from @blk.
882a7f53e26SMarkus Armbruster  * @dev must be currently attached to @blk.
883a7f53e26SMarkus Armbruster  */
884d09ea2d2SThomas Huth void blk_detach_dev(BlockBackend *blk, DeviceState *dev)
885a7f53e26SMarkus Armbruster {
886a7f53e26SMarkus Armbruster     assert(blk->dev == dev);
887a7f53e26SMarkus Armbruster     blk->dev = NULL;
888a7f53e26SMarkus Armbruster     blk->dev_ops = NULL;
889a7f53e26SMarkus Armbruster     blk->dev_opaque = NULL;
89068e9ec01SMax Reitz     blk->guest_block_size = 512;
891981776b3SKevin Wolf     blk_set_perm(blk, 0, BLK_PERM_ALL, &error_abort);
89284ebe375SMarkus Armbruster     blk_unref(blk);
893a7f53e26SMarkus Armbruster }
894a7f53e26SMarkus Armbruster 
895a7f53e26SMarkus Armbruster /*
896a7f53e26SMarkus Armbruster  * Return the device model attached to @blk if any, else null.
897a7f53e26SMarkus Armbruster  */
898d09ea2d2SThomas Huth DeviceState *blk_get_attached_dev(BlockBackend *blk)
899a7f53e26SMarkus Armbruster {
900a7f53e26SMarkus Armbruster     return blk->dev;
901a7f53e26SMarkus Armbruster }
902a7f53e26SMarkus Armbruster 
9032d76e724SKevin Wolf /* Return the qdev ID, or if no ID is assigned the QOM path, of the block
9042d76e724SKevin Wolf  * device attached to the BlockBackend. */
90577beef83SKevin Wolf char *blk_get_attached_dev_id(BlockBackend *blk)
9062d76e724SKevin Wolf {
907d09ea2d2SThomas Huth     DeviceState *dev = blk->dev;
9082d76e724SKevin Wolf 
9092d76e724SKevin Wolf     if (!dev) {
9102d76e724SKevin Wolf         return g_strdup("");
9112d76e724SKevin Wolf     } else if (dev->id) {
9122d76e724SKevin Wolf         return g_strdup(dev->id);
9132d76e724SKevin Wolf     }
914602414d1SLiam Merwick 
915602414d1SLiam Merwick     return object_get_canonical_path(OBJECT(dev)) ?: g_strdup("");
9162d76e724SKevin Wolf }
9172d76e724SKevin Wolf 
918a7f53e26SMarkus Armbruster /*
9191c89e1faSKevin Wolf  * Return the BlockBackend which has the device model @dev attached if it
9201c89e1faSKevin Wolf  * exists, else null.
9211c89e1faSKevin Wolf  *
9221c89e1faSKevin Wolf  * @dev must not be null.
9231c89e1faSKevin Wolf  */
9241c89e1faSKevin Wolf BlockBackend *blk_by_dev(void *dev)
9251c89e1faSKevin Wolf {
9261c89e1faSKevin Wolf     BlockBackend *blk = NULL;
9271c89e1faSKevin Wolf 
9281c89e1faSKevin Wolf     assert(dev != NULL);
9291c89e1faSKevin Wolf     while ((blk = blk_all_next(blk)) != NULL) {
9301c89e1faSKevin Wolf         if (blk->dev == dev) {
9311c89e1faSKevin Wolf             return blk;
9321c89e1faSKevin Wolf         }
9331c89e1faSKevin Wolf     }
9341c89e1faSKevin Wolf     return NULL;
9351c89e1faSKevin Wolf }
9361c89e1faSKevin Wolf 
9371c89e1faSKevin Wolf /*
938a7f53e26SMarkus Armbruster  * Set @blk's device model callbacks to @ops.
939a7f53e26SMarkus Armbruster  * @opaque is the opaque argument to pass to the callbacks.
940a7f53e26SMarkus Armbruster  * This is for use by device models.
941a7f53e26SMarkus Armbruster  */
942a7f53e26SMarkus Armbruster void blk_set_dev_ops(BlockBackend *blk, const BlockDevOps *ops,
943a7f53e26SMarkus Armbruster                      void *opaque)
944a7f53e26SMarkus Armbruster {
945a7f53e26SMarkus Armbruster     blk->dev_ops = ops;
946a7f53e26SMarkus Armbruster     blk->dev_opaque = opaque;
947f4d9cc88SJohn Snow 
948f4d9cc88SJohn Snow     /* Are we currently quiesced? Should we enforce this right now? */
949f4d9cc88SJohn Snow     if (blk->quiesce_counter && ops->drained_begin) {
950f4d9cc88SJohn Snow         ops->drained_begin(opaque);
951f4d9cc88SJohn Snow     }
952a7f53e26SMarkus Armbruster }
953a7f53e26SMarkus Armbruster 
954a7f53e26SMarkus Armbruster /*
955a7f53e26SMarkus Armbruster  * Notify @blk's attached device model of media change.
95639829a01SKevin Wolf  *
95739829a01SKevin Wolf  * If @load is true, notify of media load. This action can fail, meaning that
95839829a01SKevin Wolf  * the medium cannot be loaded. @errp is set then.
95939829a01SKevin Wolf  *
96039829a01SKevin Wolf  * If @load is false, notify of media eject. This can never fail.
96139829a01SKevin Wolf  *
962a7f53e26SMarkus Armbruster  * Also send DEVICE_TRAY_MOVED events as appropriate.
963a7f53e26SMarkus Armbruster  */
96439829a01SKevin Wolf void blk_dev_change_media_cb(BlockBackend *blk, bool load, Error **errp)
965a7f53e26SMarkus Armbruster {
966a7f53e26SMarkus Armbruster     if (blk->dev_ops && blk->dev_ops->change_media_cb) {
967f1f57066SMax Reitz         bool tray_was_open, tray_is_open;
96839829a01SKevin Wolf         Error *local_err = NULL;
969a7f53e26SMarkus Armbruster 
970f1f57066SMax Reitz         tray_was_open = blk_dev_is_tray_open(blk);
97139829a01SKevin Wolf         blk->dev_ops->change_media_cb(blk->dev_opaque, load, &local_err);
97239829a01SKevin Wolf         if (local_err) {
97339829a01SKevin Wolf             assert(load == true);
97439829a01SKevin Wolf             error_propagate(errp, local_err);
97539829a01SKevin Wolf             return;
97639829a01SKevin Wolf         }
977f1f57066SMax Reitz         tray_is_open = blk_dev_is_tray_open(blk);
978f1f57066SMax Reitz 
979f1f57066SMax Reitz         if (tray_was_open != tray_is_open) {
9802d76e724SKevin Wolf             char *id = blk_get_attached_dev_id(blk);
9813ab72385SPeter Xu             qapi_event_send_device_tray_moved(blk_name(blk), id, tray_is_open);
9822d76e724SKevin Wolf             g_free(id);
983a7f53e26SMarkus Armbruster         }
984a7f53e26SMarkus Armbruster     }
985a7f53e26SMarkus Armbruster }
986a7f53e26SMarkus Armbruster 
9875c8cab48SKevin Wolf static void blk_root_change_media(BdrvChild *child, bool load)
9885c8cab48SKevin Wolf {
98939829a01SKevin Wolf     blk_dev_change_media_cb(child->opaque, load, NULL);
9905c8cab48SKevin Wolf }
9915c8cab48SKevin Wolf 
992a7f53e26SMarkus Armbruster /*
993a7f53e26SMarkus Armbruster  * Does @blk's attached device model have removable media?
994a7f53e26SMarkus Armbruster  * %true if no device model is attached.
995a7f53e26SMarkus Armbruster  */
996a7f53e26SMarkus Armbruster bool blk_dev_has_removable_media(BlockBackend *blk)
997a7f53e26SMarkus Armbruster {
998a7f53e26SMarkus Armbruster     return !blk->dev || (blk->dev_ops && blk->dev_ops->change_media_cb);
999a7f53e26SMarkus Armbruster }
1000a7f53e26SMarkus Armbruster 
1001a7f53e26SMarkus Armbruster /*
10028f3a73bcSMax Reitz  * Does @blk's attached device model have a tray?
10038f3a73bcSMax Reitz  */
10048f3a73bcSMax Reitz bool blk_dev_has_tray(BlockBackend *blk)
10058f3a73bcSMax Reitz {
10068f3a73bcSMax Reitz     return blk->dev_ops && blk->dev_ops->is_tray_open;
10078f3a73bcSMax Reitz }
10088f3a73bcSMax Reitz 
10098f3a73bcSMax Reitz /*
1010a7f53e26SMarkus Armbruster  * Notify @blk's attached device model of a media eject request.
1011a7f53e26SMarkus Armbruster  * If @force is true, the medium is about to be yanked out forcefully.
1012a7f53e26SMarkus Armbruster  */
1013a7f53e26SMarkus Armbruster void blk_dev_eject_request(BlockBackend *blk, bool force)
1014a7f53e26SMarkus Armbruster {
1015a7f53e26SMarkus Armbruster     if (blk->dev_ops && blk->dev_ops->eject_request_cb) {
1016a7f53e26SMarkus Armbruster         blk->dev_ops->eject_request_cb(blk->dev_opaque, force);
1017a7f53e26SMarkus Armbruster     }
1018a7f53e26SMarkus Armbruster }
1019a7f53e26SMarkus Armbruster 
1020a7f53e26SMarkus Armbruster /*
1021a7f53e26SMarkus Armbruster  * Does @blk's attached device model have a tray, and is it open?
1022a7f53e26SMarkus Armbruster  */
1023a7f53e26SMarkus Armbruster bool blk_dev_is_tray_open(BlockBackend *blk)
1024a7f53e26SMarkus Armbruster {
10258f3a73bcSMax Reitz     if (blk_dev_has_tray(blk)) {
1026a7f53e26SMarkus Armbruster         return blk->dev_ops->is_tray_open(blk->dev_opaque);
1027a7f53e26SMarkus Armbruster     }
1028a7f53e26SMarkus Armbruster     return false;
1029a7f53e26SMarkus Armbruster }
1030a7f53e26SMarkus Armbruster 
1031a7f53e26SMarkus Armbruster /*
1032a7f53e26SMarkus Armbruster  * Does @blk's attached device model have the medium locked?
1033a7f53e26SMarkus Armbruster  * %false if the device model has no such lock.
1034a7f53e26SMarkus Armbruster  */
1035a7f53e26SMarkus Armbruster bool blk_dev_is_medium_locked(BlockBackend *blk)
1036a7f53e26SMarkus Armbruster {
1037a7f53e26SMarkus Armbruster     if (blk->dev_ops && blk->dev_ops->is_medium_locked) {
1038a7f53e26SMarkus Armbruster         return blk->dev_ops->is_medium_locked(blk->dev_opaque);
1039a7f53e26SMarkus Armbruster     }
1040a7f53e26SMarkus Armbruster     return false;
1041a7f53e26SMarkus Armbruster }
1042a7f53e26SMarkus Armbruster 
1043a7f53e26SMarkus Armbruster /*
1044a7f53e26SMarkus Armbruster  * Notify @blk's attached device model of a backend size change.
1045a7f53e26SMarkus Armbruster  */
10465c8cab48SKevin Wolf static void blk_root_resize(BdrvChild *child)
1047a7f53e26SMarkus Armbruster {
10485c8cab48SKevin Wolf     BlockBackend *blk = child->opaque;
10495c8cab48SKevin Wolf 
1050a7f53e26SMarkus Armbruster     if (blk->dev_ops && blk->dev_ops->resize_cb) {
1051a7f53e26SMarkus Armbruster         blk->dev_ops->resize_cb(blk->dev_opaque);
1052a7f53e26SMarkus Armbruster     }
1053a7f53e26SMarkus Armbruster }
1054a7f53e26SMarkus Armbruster 
10554be74634SMarkus Armbruster void blk_iostatus_enable(BlockBackend *blk)
10564be74634SMarkus Armbruster {
1057373340b2SMax Reitz     blk->iostatus_enabled = true;
1058373340b2SMax Reitz     blk->iostatus = BLOCK_DEVICE_IO_STATUS_OK;
1059373340b2SMax Reitz }
1060373340b2SMax Reitz 
1061373340b2SMax Reitz /* The I/O status is only enabled if the drive explicitly
1062373340b2SMax Reitz  * enables it _and_ the VM is configured to stop on errors */
1063373340b2SMax Reitz bool blk_iostatus_is_enabled(const BlockBackend *blk)
1064373340b2SMax Reitz {
1065373340b2SMax Reitz     return (blk->iostatus_enabled &&
1066373340b2SMax Reitz            (blk->on_write_error == BLOCKDEV_ON_ERROR_ENOSPC ||
1067373340b2SMax Reitz             blk->on_write_error == BLOCKDEV_ON_ERROR_STOP   ||
1068373340b2SMax Reitz             blk->on_read_error == BLOCKDEV_ON_ERROR_STOP));
1069373340b2SMax Reitz }
1070373340b2SMax Reitz 
1071373340b2SMax Reitz BlockDeviceIoStatus blk_iostatus(const BlockBackend *blk)
1072373340b2SMax Reitz {
1073373340b2SMax Reitz     return blk->iostatus;
1074373340b2SMax Reitz }
1075373340b2SMax Reitz 
1076373340b2SMax Reitz void blk_iostatus_disable(BlockBackend *blk)
1077373340b2SMax Reitz {
1078373340b2SMax Reitz     blk->iostatus_enabled = false;
1079373340b2SMax Reitz }
1080373340b2SMax Reitz 
1081373340b2SMax Reitz void blk_iostatus_reset(BlockBackend *blk)
1082373340b2SMax Reitz {
1083373340b2SMax Reitz     if (blk_iostatus_is_enabled(blk)) {
1084373340b2SMax Reitz         blk->iostatus = BLOCK_DEVICE_IO_STATUS_OK;
1085373340b2SMax Reitz     }
1086373340b2SMax Reitz }
1087373340b2SMax Reitz 
1088373340b2SMax Reitz void blk_iostatus_set_err(BlockBackend *blk, int error)
1089373340b2SMax Reitz {
1090373340b2SMax Reitz     assert(blk_iostatus_is_enabled(blk));
1091373340b2SMax Reitz     if (blk->iostatus == BLOCK_DEVICE_IO_STATUS_OK) {
1092373340b2SMax Reitz         blk->iostatus = error == ENOSPC ? BLOCK_DEVICE_IO_STATUS_NOSPACE :
1093373340b2SMax Reitz                                           BLOCK_DEVICE_IO_STATUS_FAILED;
1094373340b2SMax Reitz     }
10954be74634SMarkus Armbruster }
10964be74634SMarkus Armbruster 
1097c10c9d96SKevin Wolf void blk_set_allow_write_beyond_eof(BlockBackend *blk, bool allow)
1098c10c9d96SKevin Wolf {
1099c10c9d96SKevin Wolf     blk->allow_write_beyond_eof = allow;
1100c10c9d96SKevin Wolf }
1101c10c9d96SKevin Wolf 
1102980b0f94SKevin Wolf void blk_set_allow_aio_context_change(BlockBackend *blk, bool allow)
1103980b0f94SKevin Wolf {
1104980b0f94SKevin Wolf     blk->allow_aio_context_change = allow;
1105980b0f94SKevin Wolf }
1106980b0f94SKevin Wolf 
1107cf312932SKevin Wolf void blk_set_disable_request_queuing(BlockBackend *blk, bool disable)
1108cf312932SKevin Wolf {
1109cf312932SKevin Wolf     blk->disable_request_queuing = disable;
1110cf312932SKevin Wolf }
1111cf312932SKevin Wolf 
1112e7f7d676SMax Reitz static int blk_check_byte_request(BlockBackend *blk, int64_t offset,
1113e7f7d676SMax Reitz                                   size_t size)
1114e7f7d676SMax Reitz {
1115e7f7d676SMax Reitz     int64_t len;
1116e7f7d676SMax Reitz 
1117e7f7d676SMax Reitz     if (size > INT_MAX) {
1118e7f7d676SMax Reitz         return -EIO;
1119e7f7d676SMax Reitz     }
1120e7f7d676SMax Reitz 
1121c09ba36cSMax Reitz     if (!blk_is_available(blk)) {
1122e7f7d676SMax Reitz         return -ENOMEDIUM;
1123e7f7d676SMax Reitz     }
1124e7f7d676SMax Reitz 
1125c10c9d96SKevin Wolf     if (offset < 0) {
1126c10c9d96SKevin Wolf         return -EIO;
1127c10c9d96SKevin Wolf     }
1128c10c9d96SKevin Wolf 
1129c10c9d96SKevin Wolf     if (!blk->allow_write_beyond_eof) {
1130e7f7d676SMax Reitz         len = blk_getlength(blk);
1131e7f7d676SMax Reitz         if (len < 0) {
1132e7f7d676SMax Reitz             return len;
1133e7f7d676SMax Reitz         }
1134e7f7d676SMax Reitz 
1135e7f7d676SMax Reitz         if (offset > len || len - offset < size) {
1136e7f7d676SMax Reitz             return -EIO;
1137e7f7d676SMax Reitz         }
1138c10c9d96SKevin Wolf     }
1139e7f7d676SMax Reitz 
1140e7f7d676SMax Reitz     return 0;
1141e7f7d676SMax Reitz }
1142e7f7d676SMax Reitz 
11437f16476fSKevin Wolf /* To be called between exactly one pair of blk_inc/dec_in_flight() */
1144cf312932SKevin Wolf static void coroutine_fn blk_wait_while_drained(BlockBackend *blk)
1145cf312932SKevin Wolf {
11467f16476fSKevin Wolf     assert(blk->in_flight > 0);
11477f16476fSKevin Wolf 
1148cf312932SKevin Wolf     if (blk->quiesce_counter && !blk->disable_request_queuing) {
11497f16476fSKevin Wolf         blk_dec_in_flight(blk);
1150cf312932SKevin Wolf         qemu_co_queue_wait(&blk->queued_requests, NULL);
11517f16476fSKevin Wolf         blk_inc_in_flight(blk);
1152cf312932SKevin Wolf     }
1153cf312932SKevin Wolf }
1154cf312932SKevin Wolf 
1155fbb92b67SKevin Wolf /* To be called between exactly one pair of blk_inc/dec_in_flight() */
1156fbb92b67SKevin Wolf static int coroutine_fn
1157fbb92b67SKevin Wolf blk_do_preadv(BlockBackend *blk, int64_t offset, unsigned int bytes,
1158fbb92b67SKevin Wolf               QEMUIOVector *qiov, BdrvRequestFlags flags)
11594be74634SMarkus Armbruster {
11601e98fefdSKevin Wolf     int ret;
1161cf312932SKevin Wolf     BlockDriverState *bs;
11621e98fefdSKevin Wolf 
1163cf312932SKevin Wolf     blk_wait_while_drained(blk);
1164cf312932SKevin Wolf 
1165cf312932SKevin Wolf     /* Call blk_bs() only after waiting, the graph may have changed */
1166cf312932SKevin Wolf     bs = blk_bs(blk);
116799723548SPaolo Bonzini     trace_blk_co_preadv(blk, bs, offset, bytes, flags);
11681e98fefdSKevin Wolf 
11691e98fefdSKevin Wolf     ret = blk_check_byte_request(blk, offset, bytes);
1170e7f7d676SMax Reitz     if (ret < 0) {
1171e7f7d676SMax Reitz         return ret;
1172e7f7d676SMax Reitz     }
1173e7f7d676SMax Reitz 
117499723548SPaolo Bonzini     bdrv_inc_in_flight(bs);
117599723548SPaolo Bonzini 
1176441565b2SKevin Wolf     /* throttling disk I/O */
1177022cdc9fSManos Pitsidianakis     if (blk->public.throttle_group_member.throttle_state) {
1178022cdc9fSManos Pitsidianakis         throttle_group_co_io_limits_intercept(&blk->public.throttle_group_member,
1179022cdc9fSManos Pitsidianakis                 bytes, false);
1180441565b2SKevin Wolf     }
1181441565b2SKevin Wolf 
118299723548SPaolo Bonzini     ret = bdrv_co_preadv(blk->root, offset, bytes, qiov, flags);
118399723548SPaolo Bonzini     bdrv_dec_in_flight(bs);
118499723548SPaolo Bonzini     return ret;
11851bf1cbc9SKevin Wolf }
11861bf1cbc9SKevin Wolf 
1187fbb92b67SKevin Wolf int coroutine_fn blk_co_preadv(BlockBackend *blk, int64_t offset,
1188fbb92b67SKevin Wolf                                unsigned int bytes, QEMUIOVector *qiov,
1189fbb92b67SKevin Wolf                                BdrvRequestFlags flags)
1190fbb92b67SKevin Wolf {
1191fbb92b67SKevin Wolf     int ret;
1192fbb92b67SKevin Wolf 
1193fbb92b67SKevin Wolf     blk_inc_in_flight(blk);
1194fbb92b67SKevin Wolf     ret = blk_do_preadv(blk, offset, bytes, qiov, flags);
1195fbb92b67SKevin Wolf     blk_dec_in_flight(blk);
1196fbb92b67SKevin Wolf 
1197fbb92b67SKevin Wolf     return ret;
1198fbb92b67SKevin Wolf }
1199fbb92b67SKevin Wolf 
1200fbb92b67SKevin Wolf /* To be called between exactly one pair of blk_inc/dec_in_flight() */
1201fbb92b67SKevin Wolf static int coroutine_fn
1202fbb92b67SKevin Wolf blk_do_pwritev_part(BlockBackend *blk, int64_t offset, unsigned int bytes,
1203b3016864SVladimir Sementsov-Ogievskiy                     QEMUIOVector *qiov, size_t qiov_offset,
1204a8823a3bSKevin Wolf                     BdrvRequestFlags flags)
1205a8823a3bSKevin Wolf {
1206bfd18d1eSKevin Wolf     int ret;
1207cf312932SKevin Wolf     BlockDriverState *bs;
1208bfd18d1eSKevin Wolf 
1209cf312932SKevin Wolf     blk_wait_while_drained(blk);
1210cf312932SKevin Wolf 
1211cf312932SKevin Wolf     /* Call blk_bs() only after waiting, the graph may have changed */
1212cf312932SKevin Wolf     bs = blk_bs(blk);
121399723548SPaolo Bonzini     trace_blk_co_pwritev(blk, bs, offset, bytes, flags);
12141e98fefdSKevin Wolf 
1215bfd18d1eSKevin Wolf     ret = blk_check_byte_request(blk, offset, bytes);
1216a8823a3bSKevin Wolf     if (ret < 0) {
1217a8823a3bSKevin Wolf         return ret;
1218a8823a3bSKevin Wolf     }
1219a8823a3bSKevin Wolf 
122099723548SPaolo Bonzini     bdrv_inc_in_flight(bs);
1221441565b2SKevin Wolf     /* throttling disk I/O */
1222022cdc9fSManos Pitsidianakis     if (blk->public.throttle_group_member.throttle_state) {
1223022cdc9fSManos Pitsidianakis         throttle_group_co_io_limits_intercept(&blk->public.throttle_group_member,
1224022cdc9fSManos Pitsidianakis                 bytes, true);
1225441565b2SKevin Wolf     }
1226441565b2SKevin Wolf 
1227bfd18d1eSKevin Wolf     if (!blk->enable_write_cache) {
1228bfd18d1eSKevin Wolf         flags |= BDRV_REQ_FUA;
1229bfd18d1eSKevin Wolf     }
1230bfd18d1eSKevin Wolf 
1231b3016864SVladimir Sementsov-Ogievskiy     ret = bdrv_co_pwritev_part(blk->root, offset, bytes, qiov, qiov_offset,
1232b3016864SVladimir Sementsov-Ogievskiy                                flags);
123399723548SPaolo Bonzini     bdrv_dec_in_flight(bs);
123499723548SPaolo Bonzini     return ret;
1235a8823a3bSKevin Wolf }
1236a8823a3bSKevin Wolf 
1237fbb92b67SKevin Wolf int coroutine_fn blk_co_pwritev_part(BlockBackend *blk, int64_t offset,
1238fbb92b67SKevin Wolf                                      unsigned int bytes,
1239fbb92b67SKevin Wolf                                      QEMUIOVector *qiov, size_t qiov_offset,
1240fbb92b67SKevin Wolf                                      BdrvRequestFlags flags)
1241fbb92b67SKevin Wolf {
1242fbb92b67SKevin Wolf     int ret;
1243fbb92b67SKevin Wolf 
1244fbb92b67SKevin Wolf     blk_inc_in_flight(blk);
1245fbb92b67SKevin Wolf     ret = blk_do_pwritev_part(blk, offset, bytes, qiov, qiov_offset, flags);
1246fbb92b67SKevin Wolf     blk_dec_in_flight(blk);
1247fbb92b67SKevin Wolf 
1248fbb92b67SKevin Wolf     return ret;
1249fbb92b67SKevin Wolf }
1250fbb92b67SKevin Wolf 
1251b3016864SVladimir Sementsov-Ogievskiy int coroutine_fn blk_co_pwritev(BlockBackend *blk, int64_t offset,
1252b3016864SVladimir Sementsov-Ogievskiy                                 unsigned int bytes, QEMUIOVector *qiov,
1253b3016864SVladimir Sementsov-Ogievskiy                                 BdrvRequestFlags flags)
1254b3016864SVladimir Sementsov-Ogievskiy {
1255b3016864SVladimir Sementsov-Ogievskiy     return blk_co_pwritev_part(blk, offset, bytes, qiov, 0, flags);
1256b3016864SVladimir Sementsov-Ogievskiy }
1257b3016864SVladimir Sementsov-Ogievskiy 
12581bf1cbc9SKevin Wolf typedef struct BlkRwCo {
12591bf1cbc9SKevin Wolf     BlockBackend *blk;
12601bf1cbc9SKevin Wolf     int64_t offset;
1261c060332cSDeepa Srinivasan     void *iobuf;
12621bf1cbc9SKevin Wolf     int ret;
12631bf1cbc9SKevin Wolf     BdrvRequestFlags flags;
12641bf1cbc9SKevin Wolf } BlkRwCo;
12651bf1cbc9SKevin Wolf 
12661bf1cbc9SKevin Wolf static void blk_read_entry(void *opaque)
12671bf1cbc9SKevin Wolf {
12681bf1cbc9SKevin Wolf     BlkRwCo *rwco = opaque;
1269c060332cSDeepa Srinivasan     QEMUIOVector *qiov = rwco->iobuf;
12701bf1cbc9SKevin Wolf 
1271fbb92b67SKevin Wolf     rwco->ret = blk_do_preadv(rwco->blk, rwco->offset, qiov->size,
1272c060332cSDeepa Srinivasan                               qiov, rwco->flags);
12734720cbeeSKevin Wolf     aio_wait_kick();
12741bf1cbc9SKevin Wolf }
12751bf1cbc9SKevin Wolf 
1276a8823a3bSKevin Wolf static void blk_write_entry(void *opaque)
1277a8823a3bSKevin Wolf {
1278a8823a3bSKevin Wolf     BlkRwCo *rwco = opaque;
1279c060332cSDeepa Srinivasan     QEMUIOVector *qiov = rwco->iobuf;
1280a8823a3bSKevin Wolf 
1281fbb92b67SKevin Wolf     rwco->ret = blk_do_pwritev_part(rwco->blk, rwco->offset, qiov->size,
1282fbb92b67SKevin Wolf                                     qiov, 0, rwco->flags);
12834720cbeeSKevin Wolf     aio_wait_kick();
1284a8823a3bSKevin Wolf }
1285a8823a3bSKevin Wolf 
1286a55d3fbaSKevin Wolf static int blk_prw(BlockBackend *blk, int64_t offset, uint8_t *buf,
1287a55d3fbaSKevin Wolf                    int64_t bytes, CoroutineEntry co_entry,
1288fc1453cdSKevin Wolf                    BdrvRequestFlags flags)
12891bf1cbc9SKevin Wolf {
1290ae5a9592SVladimir Sementsov-Ogievskiy     QEMUIOVector qiov = QEMU_IOVEC_INIT_BUF(qiov, buf, bytes);
1291ae5a9592SVladimir Sementsov-Ogievskiy     BlkRwCo rwco = {
12921bf1cbc9SKevin Wolf         .blk    = blk,
1293a55d3fbaSKevin Wolf         .offset = offset,
1294c060332cSDeepa Srinivasan         .iobuf  = &qiov,
1295fc1453cdSKevin Wolf         .flags  = flags,
12961bf1cbc9SKevin Wolf         .ret    = NOT_DONE,
12971bf1cbc9SKevin Wolf     };
12981bf1cbc9SKevin Wolf 
1299fbb92b67SKevin Wolf     blk_inc_in_flight(blk);
130035f106e6SPaolo Bonzini     if (qemu_in_coroutine()) {
130135f106e6SPaolo Bonzini         /* Fast-path if already in coroutine context */
130235f106e6SPaolo Bonzini         co_entry(&rwco);
130335f106e6SPaolo Bonzini     } else {
130435f106e6SPaolo Bonzini         Coroutine *co = qemu_coroutine_create(co_entry, &rwco);
1305e92f0e19SFam Zheng         bdrv_coroutine_enter(blk_bs(blk), co);
130688b062c2SPaolo Bonzini         BDRV_POLL_WHILE(blk_bs(blk), rwco.ret == NOT_DONE);
130735f106e6SPaolo Bonzini     }
1308fbb92b67SKevin Wolf     blk_dec_in_flight(blk);
13091bf1cbc9SKevin Wolf 
13101bf1cbc9SKevin Wolf     return rwco.ret;
13114be74634SMarkus Armbruster }
13124be74634SMarkus Armbruster 
1313d004bd52SEric Blake int blk_pwrite_zeroes(BlockBackend *blk, int64_t offset,
1314f5a5ca79SManos Pitsidianakis                       int bytes, BdrvRequestFlags flags)
13150df89e8eSKevin Wolf {
1316f5a5ca79SManos Pitsidianakis     return blk_prw(blk, offset, NULL, bytes, blk_write_entry,
131716aaf975SKevin Wolf                    flags | BDRV_REQ_ZERO_WRITE);
13180df89e8eSKevin Wolf }
13190df89e8eSKevin Wolf 
1320720ff280SKevin Wolf int blk_make_zero(BlockBackend *blk, BdrvRequestFlags flags)
1321720ff280SKevin Wolf {
1322720ff280SKevin Wolf     return bdrv_make_zero(blk->root, flags);
1323720ff280SKevin Wolf }
1324720ff280SKevin Wolf 
1325c90e2a9cSKevin Wolf void blk_inc_in_flight(BlockBackend *blk)
132633f2a757SStefan Hajnoczi {
132733f2a757SStefan Hajnoczi     atomic_inc(&blk->in_flight);
132833f2a757SStefan Hajnoczi }
132933f2a757SStefan Hajnoczi 
1330c90e2a9cSKevin Wolf void blk_dec_in_flight(BlockBackend *blk)
133133f2a757SStefan Hajnoczi {
133233f2a757SStefan Hajnoczi     atomic_dec(&blk->in_flight);
1333cfe29d82SKevin Wolf     aio_wait_kick();
133433f2a757SStefan Hajnoczi }
133533f2a757SStefan Hajnoczi 
1336e7f7d676SMax Reitz static void error_callback_bh(void *opaque)
1337e7f7d676SMax Reitz {
1338e7f7d676SMax Reitz     struct BlockBackendAIOCB *acb = opaque;
133999723548SPaolo Bonzini 
134033f2a757SStefan Hajnoczi     blk_dec_in_flight(acb->blk);
1341e7f7d676SMax Reitz     acb->common.cb(acb->common.opaque, acb->ret);
1342e7f7d676SMax Reitz     qemu_aio_unref(acb);
1343e7f7d676SMax Reitz }
1344e7f7d676SMax Reitz 
1345ca78ecfaSPeter Lieven BlockAIOCB *blk_abort_aio_request(BlockBackend *blk,
1346ca78ecfaSPeter Lieven                                   BlockCompletionFunc *cb,
1347e7f7d676SMax Reitz                                   void *opaque, int ret)
1348e7f7d676SMax Reitz {
1349e7f7d676SMax Reitz     struct BlockBackendAIOCB *acb;
1350e7f7d676SMax Reitz 
135133f2a757SStefan Hajnoczi     blk_inc_in_flight(blk);
1352e7f7d676SMax Reitz     acb = blk_aio_get(&block_backend_aiocb_info, blk, cb, opaque);
13534981bdecSMax Reitz     acb->blk = blk;
1354e7f7d676SMax Reitz     acb->ret = ret;
1355e7f7d676SMax Reitz 
1356e4ec5ad4SPavel Dovgalyuk     replay_bh_schedule_oneshot_event(blk_get_aio_context(blk),
1357e4ec5ad4SPavel Dovgalyuk                                      error_callback_bh, acb);
1358e7f7d676SMax Reitz     return &acb->common;
1359e7f7d676SMax Reitz }
1360e7f7d676SMax Reitz 
136157d6a428SKevin Wolf typedef struct BlkAioEmAIOCB {
136257d6a428SKevin Wolf     BlockAIOCB common;
136357d6a428SKevin Wolf     BlkRwCo rwco;
13647fa84cd8SKevin Wolf     int bytes;
136557d6a428SKevin Wolf     bool has_returned;
136657d6a428SKevin Wolf } BlkAioEmAIOCB;
136757d6a428SKevin Wolf 
136857d6a428SKevin Wolf static const AIOCBInfo blk_aio_em_aiocb_info = {
136957d6a428SKevin Wolf     .aiocb_size         = sizeof(BlkAioEmAIOCB),
137057d6a428SKevin Wolf };
137157d6a428SKevin Wolf 
137257d6a428SKevin Wolf static void blk_aio_complete(BlkAioEmAIOCB *acb)
137357d6a428SKevin Wolf {
137457d6a428SKevin Wolf     if (acb->has_returned) {
137557d6a428SKevin Wolf         acb->common.cb(acb->common.opaque, acb->rwco.ret);
137646aaf2a5SKevin Wolf         blk_dec_in_flight(acb->rwco.blk);
137757d6a428SKevin Wolf         qemu_aio_unref(acb);
137857d6a428SKevin Wolf     }
137957d6a428SKevin Wolf }
138057d6a428SKevin Wolf 
138157d6a428SKevin Wolf static void blk_aio_complete_bh(void *opaque)
138257d6a428SKevin Wolf {
1383fffb6e12SPaolo Bonzini     BlkAioEmAIOCB *acb = opaque;
1384fffb6e12SPaolo Bonzini     assert(acb->has_returned);
1385fffb6e12SPaolo Bonzini     blk_aio_complete(acb);
138657d6a428SKevin Wolf }
138757d6a428SKevin Wolf 
13887fa84cd8SKevin Wolf static BlockAIOCB *blk_aio_prwv(BlockBackend *blk, int64_t offset, int bytes,
1389c060332cSDeepa Srinivasan                                 void *iobuf, CoroutineEntry co_entry,
139057d6a428SKevin Wolf                                 BdrvRequestFlags flags,
139157d6a428SKevin Wolf                                 BlockCompletionFunc *cb, void *opaque)
139257d6a428SKevin Wolf {
139357d6a428SKevin Wolf     BlkAioEmAIOCB *acb;
139457d6a428SKevin Wolf     Coroutine *co;
139557d6a428SKevin Wolf 
139633f2a757SStefan Hajnoczi     blk_inc_in_flight(blk);
139757d6a428SKevin Wolf     acb = blk_aio_get(&blk_aio_em_aiocb_info, blk, cb, opaque);
139857d6a428SKevin Wolf     acb->rwco = (BlkRwCo) {
139957d6a428SKevin Wolf         .blk    = blk,
140057d6a428SKevin Wolf         .offset = offset,
1401c060332cSDeepa Srinivasan         .iobuf  = iobuf,
140257d6a428SKevin Wolf         .flags  = flags,
140357d6a428SKevin Wolf         .ret    = NOT_DONE,
140457d6a428SKevin Wolf     };
14057fa84cd8SKevin Wolf     acb->bytes = bytes;
140657d6a428SKevin Wolf     acb->has_returned = false;
140757d6a428SKevin Wolf 
14080b8b8753SPaolo Bonzini     co = qemu_coroutine_create(co_entry, acb);
1409e92f0e19SFam Zheng     bdrv_coroutine_enter(blk_bs(blk), co);
141057d6a428SKevin Wolf 
141157d6a428SKevin Wolf     acb->has_returned = true;
141257d6a428SKevin Wolf     if (acb->rwco.ret != NOT_DONE) {
1413e4ec5ad4SPavel Dovgalyuk         replay_bh_schedule_oneshot_event(blk_get_aio_context(blk),
1414fffb6e12SPaolo Bonzini                                          blk_aio_complete_bh, acb);
141557d6a428SKevin Wolf     }
141657d6a428SKevin Wolf 
141757d6a428SKevin Wolf     return &acb->common;
141857d6a428SKevin Wolf }
141957d6a428SKevin Wolf 
142057d6a428SKevin Wolf static void blk_aio_read_entry(void *opaque)
142157d6a428SKevin Wolf {
142257d6a428SKevin Wolf     BlkAioEmAIOCB *acb = opaque;
142357d6a428SKevin Wolf     BlkRwCo *rwco = &acb->rwco;
1424c060332cSDeepa Srinivasan     QEMUIOVector *qiov = rwco->iobuf;
142557d6a428SKevin Wolf 
1426c060332cSDeepa Srinivasan     assert(qiov->size == acb->bytes);
1427fbb92b67SKevin Wolf     rwco->ret = blk_do_preadv(rwco->blk, rwco->offset, acb->bytes,
1428c060332cSDeepa Srinivasan                               qiov, rwco->flags);
142957d6a428SKevin Wolf     blk_aio_complete(acb);
143057d6a428SKevin Wolf }
143157d6a428SKevin Wolf 
143257d6a428SKevin Wolf static void blk_aio_write_entry(void *opaque)
143357d6a428SKevin Wolf {
143457d6a428SKevin Wolf     BlkAioEmAIOCB *acb = opaque;
143557d6a428SKevin Wolf     BlkRwCo *rwco = &acb->rwco;
1436c060332cSDeepa Srinivasan     QEMUIOVector *qiov = rwco->iobuf;
143757d6a428SKevin Wolf 
1438c060332cSDeepa Srinivasan     assert(!qiov || qiov->size == acb->bytes);
1439fbb92b67SKevin Wolf     rwco->ret = blk_do_pwritev_part(rwco->blk, rwco->offset, acb->bytes,
1440fbb92b67SKevin Wolf                                     qiov, 0, rwco->flags);
144157d6a428SKevin Wolf     blk_aio_complete(acb);
144257d6a428SKevin Wolf }
144357d6a428SKevin Wolf 
1444d004bd52SEric Blake BlockAIOCB *blk_aio_pwrite_zeroes(BlockBackend *blk, int64_t offset,
1445983a1600SEric Blake                                   int count, BdrvRequestFlags flags,
14464be74634SMarkus Armbruster                                   BlockCompletionFunc *cb, void *opaque)
14474be74634SMarkus Armbruster {
1448983a1600SEric Blake     return blk_aio_prwv(blk, offset, count, NULL, blk_aio_write_entry,
1449983a1600SEric Blake                         flags | BDRV_REQ_ZERO_WRITE, cb, opaque);
14504be74634SMarkus Armbruster }
14514be74634SMarkus Armbruster 
14524be74634SMarkus Armbruster int blk_pread(BlockBackend *blk, int64_t offset, void *buf, int count)
14534be74634SMarkus Armbruster {
1454a55d3fbaSKevin Wolf     int ret = blk_prw(blk, offset, buf, count, blk_read_entry, 0);
1455e7f7d676SMax Reitz     if (ret < 0) {
1456e7f7d676SMax Reitz         return ret;
1457e7f7d676SMax Reitz     }
1458a55d3fbaSKevin Wolf     return count;
14594be74634SMarkus Armbruster }
14604be74634SMarkus Armbruster 
14618341f00dSEric Blake int blk_pwrite(BlockBackend *blk, int64_t offset, const void *buf, int count,
14628341f00dSEric Blake                BdrvRequestFlags flags)
14634be74634SMarkus Armbruster {
14648341f00dSEric Blake     int ret = blk_prw(blk, offset, (void *) buf, count, blk_write_entry,
14658341f00dSEric Blake                       flags);
1466e7f7d676SMax Reitz     if (ret < 0) {
1467e7f7d676SMax Reitz         return ret;
1468e7f7d676SMax Reitz     }
1469a55d3fbaSKevin Wolf     return count;
14704be74634SMarkus Armbruster }
14714be74634SMarkus Armbruster 
14724be74634SMarkus Armbruster int64_t blk_getlength(BlockBackend *blk)
14734be74634SMarkus Armbruster {
1474c09ba36cSMax Reitz     if (!blk_is_available(blk)) {
1475c09ba36cSMax Reitz         return -ENOMEDIUM;
1476c09ba36cSMax Reitz     }
1477c09ba36cSMax Reitz 
1478f21d96d0SKevin Wolf     return bdrv_getlength(blk_bs(blk));
14794be74634SMarkus Armbruster }
14804be74634SMarkus Armbruster 
14814be74634SMarkus Armbruster void blk_get_geometry(BlockBackend *blk, uint64_t *nb_sectors_ptr)
14824be74634SMarkus Armbruster {
1483f21d96d0SKevin Wolf     if (!blk_bs(blk)) {
1484a46fc9c9SMax Reitz         *nb_sectors_ptr = 0;
1485a46fc9c9SMax Reitz     } else {
1486f21d96d0SKevin Wolf         bdrv_get_geometry(blk_bs(blk), nb_sectors_ptr);
14874be74634SMarkus Armbruster     }
1488a46fc9c9SMax Reitz }
14894be74634SMarkus Armbruster 
14901ef01253SMax Reitz int64_t blk_nb_sectors(BlockBackend *blk)
14911ef01253SMax Reitz {
1492c09ba36cSMax Reitz     if (!blk_is_available(blk)) {
1493c09ba36cSMax Reitz         return -ENOMEDIUM;
1494c09ba36cSMax Reitz     }
1495c09ba36cSMax Reitz 
1496f21d96d0SKevin Wolf     return bdrv_nb_sectors(blk_bs(blk));
14971ef01253SMax Reitz }
14981ef01253SMax Reitz 
149960cb2fa7SEric Blake BlockAIOCB *blk_aio_preadv(BlockBackend *blk, int64_t offset,
150060cb2fa7SEric Blake                            QEMUIOVector *qiov, BdrvRequestFlags flags,
150160cb2fa7SEric Blake                            BlockCompletionFunc *cb, void *opaque)
150260cb2fa7SEric Blake {
150360cb2fa7SEric Blake     return blk_aio_prwv(blk, offset, qiov->size, qiov,
150460cb2fa7SEric Blake                         blk_aio_read_entry, flags, cb, opaque);
150560cb2fa7SEric Blake }
150660cb2fa7SEric Blake 
150760cb2fa7SEric Blake BlockAIOCB *blk_aio_pwritev(BlockBackend *blk, int64_t offset,
150860cb2fa7SEric Blake                             QEMUIOVector *qiov, BdrvRequestFlags flags,
150960cb2fa7SEric Blake                             BlockCompletionFunc *cb, void *opaque)
151060cb2fa7SEric Blake {
151160cb2fa7SEric Blake     return blk_aio_prwv(blk, offset, qiov->size, qiov,
151260cb2fa7SEric Blake                         blk_aio_write_entry, flags, cb, opaque);
151360cb2fa7SEric Blake }
151460cb2fa7SEric Blake 
15154be74634SMarkus Armbruster void blk_aio_cancel(BlockAIOCB *acb)
15164be74634SMarkus Armbruster {
15174be74634SMarkus Armbruster     bdrv_aio_cancel(acb);
15184be74634SMarkus Armbruster }
15194be74634SMarkus Armbruster 
15204be74634SMarkus Armbruster void blk_aio_cancel_async(BlockAIOCB *acb)
15214be74634SMarkus Armbruster {
15224be74634SMarkus Armbruster     bdrv_aio_cancel_async(acb);
15234be74634SMarkus Armbruster }
15244be74634SMarkus Armbruster 
1525fbb92b67SKevin Wolf /* To be called between exactly one pair of blk_inc/dec_in_flight() */
1526fbb92b67SKevin Wolf static int coroutine_fn
1527fbb92b67SKevin Wolf blk_do_ioctl(BlockBackend *blk, unsigned long int req, void *buf)
15284be74634SMarkus Armbruster {
1529cf312932SKevin Wolf     blk_wait_while_drained(blk);
1530cf312932SKevin Wolf 
1531c09ba36cSMax Reitz     if (!blk_is_available(blk)) {
1532c09ba36cSMax Reitz         return -ENOMEDIUM;
1533c09ba36cSMax Reitz     }
1534c09ba36cSMax Reitz 
153548af776aSKevin Wolf     return bdrv_co_ioctl(blk_bs(blk), req, buf);
153648af776aSKevin Wolf }
153748af776aSKevin Wolf 
153848af776aSKevin Wolf static void blk_ioctl_entry(void *opaque)
153948af776aSKevin Wolf {
154048af776aSKevin Wolf     BlkRwCo *rwco = opaque;
1541c060332cSDeepa Srinivasan     QEMUIOVector *qiov = rwco->iobuf;
1542c060332cSDeepa Srinivasan 
1543fbb92b67SKevin Wolf     rwco->ret = blk_do_ioctl(rwco->blk, rwco->offset, qiov->iov[0].iov_base);
15444720cbeeSKevin Wolf     aio_wait_kick();
154548af776aSKevin Wolf }
154648af776aSKevin Wolf 
154748af776aSKevin Wolf int blk_ioctl(BlockBackend *blk, unsigned long int req, void *buf)
154848af776aSKevin Wolf {
154948af776aSKevin Wolf     return blk_prw(blk, req, buf, 0, blk_ioctl_entry, 0);
155048af776aSKevin Wolf }
155148af776aSKevin Wolf 
155248af776aSKevin Wolf static void blk_aio_ioctl_entry(void *opaque)
155348af776aSKevin Wolf {
155448af776aSKevin Wolf     BlkAioEmAIOCB *acb = opaque;
155548af776aSKevin Wolf     BlkRwCo *rwco = &acb->rwco;
155648af776aSKevin Wolf 
1557fbb92b67SKevin Wolf     rwco->ret = blk_do_ioctl(rwco->blk, rwco->offset, rwco->iobuf);
1558c060332cSDeepa Srinivasan 
155948af776aSKevin Wolf     blk_aio_complete(acb);
15604be74634SMarkus Armbruster }
15614be74634SMarkus Armbruster 
15624be74634SMarkus Armbruster BlockAIOCB *blk_aio_ioctl(BlockBackend *blk, unsigned long int req, void *buf,
15634be74634SMarkus Armbruster                           BlockCompletionFunc *cb, void *opaque)
15644be74634SMarkus Armbruster {
1565c060332cSDeepa Srinivasan     return blk_aio_prwv(blk, req, 0, buf, blk_aio_ioctl_entry, 0, cb, opaque);
15664be74634SMarkus Armbruster }
15674be74634SMarkus Armbruster 
1568fbb92b67SKevin Wolf /* To be called between exactly one pair of blk_inc/dec_in_flight() */
1569fbb92b67SKevin Wolf static int coroutine_fn
1570fbb92b67SKevin Wolf blk_do_pdiscard(BlockBackend *blk, int64_t offset, int bytes)
15712bb0dce7SMax Reitz {
1572cf312932SKevin Wolf     int ret;
1573cf312932SKevin Wolf 
1574cf312932SKevin Wolf     blk_wait_while_drained(blk);
1575cf312932SKevin Wolf 
1576cf312932SKevin Wolf     ret = blk_check_byte_request(blk, offset, bytes);
1577e7f7d676SMax Reitz     if (ret < 0) {
1578e7f7d676SMax Reitz         return ret;
1579e7f7d676SMax Reitz     }
1580e7f7d676SMax Reitz 
15810b9fd3f4SFam Zheng     return bdrv_co_pdiscard(blk->root, offset, bytes);
15822bb0dce7SMax Reitz }
15832bb0dce7SMax Reitz 
1584564806c5SKevin Wolf static void blk_aio_pdiscard_entry(void *opaque)
1585564806c5SKevin Wolf {
1586564806c5SKevin Wolf     BlkAioEmAIOCB *acb = opaque;
1587564806c5SKevin Wolf     BlkRwCo *rwco = &acb->rwco;
1588564806c5SKevin Wolf 
1589fbb92b67SKevin Wolf     rwco->ret = blk_do_pdiscard(rwco->blk, rwco->offset, acb->bytes);
1590564806c5SKevin Wolf     blk_aio_complete(acb);
1591564806c5SKevin Wolf }
1592564806c5SKevin Wolf 
1593564806c5SKevin Wolf BlockAIOCB *blk_aio_pdiscard(BlockBackend *blk,
1594564806c5SKevin Wolf                              int64_t offset, int bytes,
1595564806c5SKevin Wolf                              BlockCompletionFunc *cb, void *opaque)
1596564806c5SKevin Wolf {
1597564806c5SKevin Wolf     return blk_aio_prwv(blk, offset, bytes, NULL, blk_aio_pdiscard_entry, 0,
1598564806c5SKevin Wolf                         cb, opaque);
1599564806c5SKevin Wolf }
1600564806c5SKevin Wolf 
1601fbb92b67SKevin Wolf int coroutine_fn blk_co_pdiscard(BlockBackend *blk, int64_t offset, int bytes)
1602fbb92b67SKevin Wolf {
1603fbb92b67SKevin Wolf     int ret;
1604fbb92b67SKevin Wolf 
1605fbb92b67SKevin Wolf     blk_inc_in_flight(blk);
1606fbb92b67SKevin Wolf     ret = blk_do_pdiscard(blk, offset, bytes);
1607fbb92b67SKevin Wolf     blk_dec_in_flight(blk);
1608fbb92b67SKevin Wolf 
1609fbb92b67SKevin Wolf     return ret;
1610fbb92b67SKevin Wolf }
1611fbb92b67SKevin Wolf 
1612564806c5SKevin Wolf static void blk_pdiscard_entry(void *opaque)
1613564806c5SKevin Wolf {
1614564806c5SKevin Wolf     BlkRwCo *rwco = opaque;
1615564806c5SKevin Wolf     QEMUIOVector *qiov = rwco->iobuf;
1616564806c5SKevin Wolf 
1617fbb92b67SKevin Wolf     rwco->ret = blk_do_pdiscard(rwco->blk, rwco->offset, qiov->size);
1618564806c5SKevin Wolf     aio_wait_kick();
1619564806c5SKevin Wolf }
1620564806c5SKevin Wolf 
1621564806c5SKevin Wolf int blk_pdiscard(BlockBackend *blk, int64_t offset, int bytes)
1622564806c5SKevin Wolf {
1623564806c5SKevin Wolf     return blk_prw(blk, offset, NULL, bytes, blk_pdiscard_entry, 0);
1624564806c5SKevin Wolf }
1625564806c5SKevin Wolf 
1626fbb92b67SKevin Wolf /* To be called between exactly one pair of blk_inc/dec_in_flight() */
1627fbb92b67SKevin Wolf static int coroutine_fn blk_do_flush(BlockBackend *blk)
16282bb0dce7SMax Reitz {
1629cf312932SKevin Wolf     blk_wait_while_drained(blk);
1630cf312932SKevin Wolf 
1631c09ba36cSMax Reitz     if (!blk_is_available(blk)) {
1632c09ba36cSMax Reitz         return -ENOMEDIUM;
1633c09ba36cSMax Reitz     }
1634c09ba36cSMax Reitz 
1635f21d96d0SKevin Wolf     return bdrv_co_flush(blk_bs(blk));
16362bb0dce7SMax Reitz }
16372bb0dce7SMax Reitz 
1638564806c5SKevin Wolf static void blk_aio_flush_entry(void *opaque)
1639564806c5SKevin Wolf {
1640564806c5SKevin Wolf     BlkAioEmAIOCB *acb = opaque;
1641564806c5SKevin Wolf     BlkRwCo *rwco = &acb->rwco;
1642564806c5SKevin Wolf 
1643fbb92b67SKevin Wolf     rwco->ret = blk_do_flush(rwco->blk);
1644564806c5SKevin Wolf     blk_aio_complete(acb);
1645564806c5SKevin Wolf }
1646564806c5SKevin Wolf 
1647564806c5SKevin Wolf BlockAIOCB *blk_aio_flush(BlockBackend *blk,
1648564806c5SKevin Wolf                           BlockCompletionFunc *cb, void *opaque)
1649564806c5SKevin Wolf {
1650564806c5SKevin Wolf     return blk_aio_prwv(blk, 0, 0, NULL, blk_aio_flush_entry, 0, cb, opaque);
1651564806c5SKevin Wolf }
1652564806c5SKevin Wolf 
1653fbb92b67SKevin Wolf int coroutine_fn blk_co_flush(BlockBackend *blk)
1654fbb92b67SKevin Wolf {
1655fbb92b67SKevin Wolf     int ret;
1656fbb92b67SKevin Wolf 
1657fbb92b67SKevin Wolf     blk_inc_in_flight(blk);
1658fbb92b67SKevin Wolf     ret = blk_do_flush(blk);
1659fbb92b67SKevin Wolf     blk_dec_in_flight(blk);
1660fbb92b67SKevin Wolf 
1661fbb92b67SKevin Wolf     return ret;
1662fbb92b67SKevin Wolf }
1663fbb92b67SKevin Wolf 
1664be07a889SKevin Wolf static void blk_flush_entry(void *opaque)
16654be74634SMarkus Armbruster {
1666be07a889SKevin Wolf     BlkRwCo *rwco = opaque;
1667fbb92b67SKevin Wolf     rwco->ret = blk_do_flush(rwco->blk);
16684720cbeeSKevin Wolf     aio_wait_kick();
1669c09ba36cSMax Reitz }
1670c09ba36cSMax Reitz 
1671be07a889SKevin Wolf int blk_flush(BlockBackend *blk)
1672be07a889SKevin Wolf {
1673be07a889SKevin Wolf     return blk_prw(blk, 0, NULL, 0, blk_flush_entry, 0);
16744be74634SMarkus Armbruster }
16754be74634SMarkus Armbruster 
167697b0385aSAlexander Yarygin void blk_drain(BlockBackend *blk)
167797b0385aSAlexander Yarygin {
167833f2a757SStefan Hajnoczi     BlockDriverState *bs = blk_bs(blk);
167933f2a757SStefan Hajnoczi 
168033f2a757SStefan Hajnoczi     if (bs) {
168133f2a757SStefan Hajnoczi         bdrv_drained_begin(bs);
168233f2a757SStefan Hajnoczi     }
168333f2a757SStefan Hajnoczi 
168433f2a757SStefan Hajnoczi     /* We may have -ENOMEDIUM completions in flight */
1685cfe29d82SKevin Wolf     AIO_WAIT_WHILE(blk_get_aio_context(blk),
168633f2a757SStefan Hajnoczi                    atomic_mb_read(&blk->in_flight) > 0);
168733f2a757SStefan Hajnoczi 
168833f2a757SStefan Hajnoczi     if (bs) {
168933f2a757SStefan Hajnoczi         bdrv_drained_end(bs);
169097b0385aSAlexander Yarygin     }
1691a46fc9c9SMax Reitz }
169297b0385aSAlexander Yarygin 
16934be74634SMarkus Armbruster void blk_drain_all(void)
16944be74634SMarkus Armbruster {
169533f2a757SStefan Hajnoczi     BlockBackend *blk = NULL;
169633f2a757SStefan Hajnoczi 
169733f2a757SStefan Hajnoczi     bdrv_drain_all_begin();
169833f2a757SStefan Hajnoczi 
169933f2a757SStefan Hajnoczi     while ((blk = blk_all_next(blk)) != NULL) {
170033f2a757SStefan Hajnoczi         AioContext *ctx = blk_get_aio_context(blk);
170133f2a757SStefan Hajnoczi 
170233f2a757SStefan Hajnoczi         aio_context_acquire(ctx);
170333f2a757SStefan Hajnoczi 
170433f2a757SStefan Hajnoczi         /* We may have -ENOMEDIUM completions in flight */
1705cfe29d82SKevin Wolf         AIO_WAIT_WHILE(ctx, atomic_mb_read(&blk->in_flight) > 0);
170633f2a757SStefan Hajnoczi 
170733f2a757SStefan Hajnoczi         aio_context_release(ctx);
170833f2a757SStefan Hajnoczi     }
170933f2a757SStefan Hajnoczi 
171033f2a757SStefan Hajnoczi     bdrv_drain_all_end();
17114be74634SMarkus Armbruster }
17124be74634SMarkus Armbruster 
1713373340b2SMax Reitz void blk_set_on_error(BlockBackend *blk, BlockdevOnError on_read_error,
1714373340b2SMax Reitz                       BlockdevOnError on_write_error)
1715373340b2SMax Reitz {
1716373340b2SMax Reitz     blk->on_read_error = on_read_error;
1717373340b2SMax Reitz     blk->on_write_error = on_write_error;
1718373340b2SMax Reitz }
1719373340b2SMax Reitz 
17204be74634SMarkus Armbruster BlockdevOnError blk_get_on_error(BlockBackend *blk, bool is_read)
17214be74634SMarkus Armbruster {
1722373340b2SMax Reitz     return is_read ? blk->on_read_error : blk->on_write_error;
17234be74634SMarkus Armbruster }
17244be74634SMarkus Armbruster 
17254be74634SMarkus Armbruster BlockErrorAction blk_get_error_action(BlockBackend *blk, bool is_read,
17264be74634SMarkus Armbruster                                       int error)
17274be74634SMarkus Armbruster {
1728373340b2SMax Reitz     BlockdevOnError on_err = blk_get_on_error(blk, is_read);
1729373340b2SMax Reitz 
1730373340b2SMax Reitz     switch (on_err) {
1731373340b2SMax Reitz     case BLOCKDEV_ON_ERROR_ENOSPC:
1732373340b2SMax Reitz         return (error == ENOSPC) ?
1733373340b2SMax Reitz                BLOCK_ERROR_ACTION_STOP : BLOCK_ERROR_ACTION_REPORT;
1734373340b2SMax Reitz     case BLOCKDEV_ON_ERROR_STOP:
1735373340b2SMax Reitz         return BLOCK_ERROR_ACTION_STOP;
1736373340b2SMax Reitz     case BLOCKDEV_ON_ERROR_REPORT:
1737373340b2SMax Reitz         return BLOCK_ERROR_ACTION_REPORT;
1738373340b2SMax Reitz     case BLOCKDEV_ON_ERROR_IGNORE:
1739373340b2SMax Reitz         return BLOCK_ERROR_ACTION_IGNORE;
17408c398252SKevin Wolf     case BLOCKDEV_ON_ERROR_AUTO:
1741373340b2SMax Reitz     default:
1742373340b2SMax Reitz         abort();
1743373340b2SMax Reitz     }
17444be74634SMarkus Armbruster }
17454be74634SMarkus Armbruster 
1746373340b2SMax Reitz static void send_qmp_error_event(BlockBackend *blk,
1747373340b2SMax Reitz                                  BlockErrorAction action,
1748373340b2SMax Reitz                                  bool is_read, int error)
1749373340b2SMax Reitz {
1750373340b2SMax Reitz     IoOperationType optype;
1751bfe1a14cSKevin Wolf     BlockDriverState *bs = blk_bs(blk);
1752373340b2SMax Reitz 
1753373340b2SMax Reitz     optype = is_read ? IO_OPERATION_TYPE_READ : IO_OPERATION_TYPE_WRITE;
1754bfe1a14cSKevin Wolf     qapi_event_send_block_io_error(blk_name(blk), !!bs,
1755bfe1a14cSKevin Wolf                                    bs ? bdrv_get_node_name(bs) : NULL, optype,
17562bf7e10fSKevin Wolf                                    action, blk_iostatus_is_enabled(blk),
17573ab72385SPeter Xu                                    error == ENOSPC, strerror(error));
1758373340b2SMax Reitz }
1759373340b2SMax Reitz 
1760373340b2SMax Reitz /* This is done by device models because, while the block layer knows
1761373340b2SMax Reitz  * about the error, it does not know whether an operation comes from
1762373340b2SMax Reitz  * the device or the block layer (from a job, for example).
1763373340b2SMax Reitz  */
17644be74634SMarkus Armbruster void blk_error_action(BlockBackend *blk, BlockErrorAction action,
17654be74634SMarkus Armbruster                       bool is_read, int error)
17664be74634SMarkus Armbruster {
1767373340b2SMax Reitz     assert(error >= 0);
1768373340b2SMax Reitz 
1769373340b2SMax Reitz     if (action == BLOCK_ERROR_ACTION_STOP) {
1770373340b2SMax Reitz         /* First set the iostatus, so that "info block" returns an iostatus
1771373340b2SMax Reitz          * that matches the events raised so far (an additional error iostatus
1772373340b2SMax Reitz          * is fine, but not a lost one).
1773373340b2SMax Reitz          */
1774373340b2SMax Reitz         blk_iostatus_set_err(blk, error);
1775373340b2SMax Reitz 
1776373340b2SMax Reitz         /* Then raise the request to stop the VM and the event.
1777373340b2SMax Reitz          * qemu_system_vmstop_request_prepare has two effects.  First,
1778373340b2SMax Reitz          * it ensures that the STOP event always comes after the
1779373340b2SMax Reitz          * BLOCK_IO_ERROR event.  Second, it ensures that even if management
1780373340b2SMax Reitz          * can observe the STOP event and do a "cont" before the STOP
1781373340b2SMax Reitz          * event is issued, the VM will not stop.  In this case, vm_start()
1782373340b2SMax Reitz          * also ensures that the STOP/RESUME pair of events is emitted.
1783373340b2SMax Reitz          */
1784373340b2SMax Reitz         qemu_system_vmstop_request_prepare();
1785373340b2SMax Reitz         send_qmp_error_event(blk, action, is_read, error);
1786373340b2SMax Reitz         qemu_system_vmstop_request(RUN_STATE_IO_ERROR);
1787373340b2SMax Reitz     } else {
1788373340b2SMax Reitz         send_qmp_error_event(blk, action, is_read, error);
1789373340b2SMax Reitz     }
17904be74634SMarkus Armbruster }
17914be74634SMarkus Armbruster 
179296710565SLi Qiang bool blk_is_read_only(BlockBackend *blk)
17934be74634SMarkus Armbruster {
1794f21d96d0SKevin Wolf     BlockDriverState *bs = blk_bs(blk);
1795f21d96d0SKevin Wolf 
1796f21d96d0SKevin Wolf     if (bs) {
1797f21d96d0SKevin Wolf         return bdrv_is_read_only(bs);
1798061959e8SMax Reitz     } else {
1799061959e8SMax Reitz         return blk->root_state.read_only;
1800061959e8SMax Reitz     }
18014be74634SMarkus Armbruster }
18024be74634SMarkus Armbruster 
180396710565SLi Qiang bool blk_is_sg(BlockBackend *blk)
18044be74634SMarkus Armbruster {
1805f21d96d0SKevin Wolf     BlockDriverState *bs = blk_bs(blk);
1806f21d96d0SKevin Wolf 
1807f21d96d0SKevin Wolf     if (!bs) {
180896710565SLi Qiang         return false;
1809a46fc9c9SMax Reitz     }
1810a46fc9c9SMax Reitz 
1811f21d96d0SKevin Wolf     return bdrv_is_sg(bs);
18124be74634SMarkus Armbruster }
18134be74634SMarkus Armbruster 
181496710565SLi Qiang bool blk_enable_write_cache(BlockBackend *blk)
18154be74634SMarkus Armbruster {
1816bfd18d1eSKevin Wolf     return blk->enable_write_cache;
18174be74634SMarkus Armbruster }
18184be74634SMarkus Armbruster 
18194be74634SMarkus Armbruster void blk_set_enable_write_cache(BlockBackend *blk, bool wce)
18204be74634SMarkus Armbruster {
1821bfd18d1eSKevin Wolf     blk->enable_write_cache = wce;
18224be74634SMarkus Armbruster }
18234be74634SMarkus Armbruster 
18242bb0dce7SMax Reitz void blk_invalidate_cache(BlockBackend *blk, Error **errp)
18252bb0dce7SMax Reitz {
1826f21d96d0SKevin Wolf     BlockDriverState *bs = blk_bs(blk);
1827f21d96d0SKevin Wolf 
1828f21d96d0SKevin Wolf     if (!bs) {
1829c09ba36cSMax Reitz         error_setg(errp, "Device '%s' has no medium", blk->name);
1830c09ba36cSMax Reitz         return;
1831c09ba36cSMax Reitz     }
1832c09ba36cSMax Reitz 
1833f21d96d0SKevin Wolf     bdrv_invalidate_cache(bs, errp);
18342bb0dce7SMax Reitz }
18352bb0dce7SMax Reitz 
1836e031f750SMax Reitz bool blk_is_inserted(BlockBackend *blk)
18374be74634SMarkus Armbruster {
1838f21d96d0SKevin Wolf     BlockDriverState *bs = blk_bs(blk);
1839f21d96d0SKevin Wolf 
1840f21d96d0SKevin Wolf     return bs && bdrv_is_inserted(bs);
1841db0284f8SMax Reitz }
1842db0284f8SMax Reitz 
1843db0284f8SMax Reitz bool blk_is_available(BlockBackend *blk)
1844db0284f8SMax Reitz {
1845db0284f8SMax Reitz     return blk_is_inserted(blk) && !blk_dev_is_tray_open(blk);
18464be74634SMarkus Armbruster }
18474be74634SMarkus Armbruster 
18484be74634SMarkus Armbruster void blk_lock_medium(BlockBackend *blk, bool locked)
18494be74634SMarkus Armbruster {
1850f21d96d0SKevin Wolf     BlockDriverState *bs = blk_bs(blk);
1851f21d96d0SKevin Wolf 
1852f21d96d0SKevin Wolf     if (bs) {
1853f21d96d0SKevin Wolf         bdrv_lock_medium(bs, locked);
18544be74634SMarkus Armbruster     }
1855a46fc9c9SMax Reitz }
18564be74634SMarkus Armbruster 
18574be74634SMarkus Armbruster void blk_eject(BlockBackend *blk, bool eject_flag)
18584be74634SMarkus Armbruster {
1859f21d96d0SKevin Wolf     BlockDriverState *bs = blk_bs(blk);
18602d76e724SKevin Wolf     char *id;
18612d76e724SKevin Wolf 
1862f21d96d0SKevin Wolf     if (bs) {
1863f21d96d0SKevin Wolf         bdrv_eject(bs, eject_flag);
1864c47ee043SJohn Snow     }
18652d76e724SKevin Wolf 
1866c47ee043SJohn Snow     /* Whether or not we ejected on the backend,
1867c47ee043SJohn Snow      * the frontend experienced a tray event. */
18682d76e724SKevin Wolf     id = blk_get_attached_dev_id(blk);
18692d76e724SKevin Wolf     qapi_event_send_device_tray_moved(blk_name(blk), id,
18703ab72385SPeter Xu                                       eject_flag);
18712d76e724SKevin Wolf     g_free(id);
1872a46fc9c9SMax Reitz }
18734be74634SMarkus Armbruster 
18744be74634SMarkus Armbruster int blk_get_flags(BlockBackend *blk)
18754be74634SMarkus Armbruster {
1876f21d96d0SKevin Wolf     BlockDriverState *bs = blk_bs(blk);
1877f21d96d0SKevin Wolf 
1878f21d96d0SKevin Wolf     if (bs) {
1879f21d96d0SKevin Wolf         return bdrv_get_flags(bs);
1880061959e8SMax Reitz     } else {
1881061959e8SMax Reitz         return blk->root_state.open_flags;
1882061959e8SMax Reitz     }
18834be74634SMarkus Armbruster }
18844be74634SMarkus Armbruster 
18854841211eSEric Blake /* Returns the minimum request alignment, in bytes; guaranteed nonzero */
18864841211eSEric Blake uint32_t blk_get_request_alignment(BlockBackend *blk)
18874841211eSEric Blake {
18884841211eSEric Blake     BlockDriverState *bs = blk_bs(blk);
18894841211eSEric Blake     return bs ? bs->bl.request_alignment : BDRV_SECTOR_SIZE;
18904841211eSEric Blake }
18914841211eSEric Blake 
18925def6b80SEric Blake /* Returns the maximum transfer length, in bytes; guaranteed nonzero */
18935def6b80SEric Blake uint32_t blk_get_max_transfer(BlockBackend *blk)
1894454057b7SPeter Lieven {
1895f21d96d0SKevin Wolf     BlockDriverState *bs = blk_bs(blk);
18965def6b80SEric Blake     uint32_t max = 0;
1897f21d96d0SKevin Wolf 
1898f21d96d0SKevin Wolf     if (bs) {
18995def6b80SEric Blake         max = bs->bl.max_transfer;
1900a46fc9c9SMax Reitz     }
19015def6b80SEric Blake     return MIN_NON_ZERO(max, INT_MAX);
1902454057b7SPeter Lieven }
1903454057b7SPeter Lieven 
1904648296e0SStefan Hajnoczi int blk_get_max_iov(BlockBackend *blk)
1905648296e0SStefan Hajnoczi {
1906f21d96d0SKevin Wolf     return blk->root->bs->bl.max_iov;
1907648296e0SStefan Hajnoczi }
1908648296e0SStefan Hajnoczi 
19094be74634SMarkus Armbruster void blk_set_guest_block_size(BlockBackend *blk, int align)
19104be74634SMarkus Armbruster {
191168e9ec01SMax Reitz     blk->guest_block_size = align;
19124be74634SMarkus Armbruster }
19134be74634SMarkus Armbruster 
1914f1c17521SPaolo Bonzini void *blk_try_blockalign(BlockBackend *blk, size_t size)
1915f1c17521SPaolo Bonzini {
1916f21d96d0SKevin Wolf     return qemu_try_blockalign(blk ? blk_bs(blk) : NULL, size);
1917f1c17521SPaolo Bonzini }
1918f1c17521SPaolo Bonzini 
19194be74634SMarkus Armbruster void *blk_blockalign(BlockBackend *blk, size_t size)
19204be74634SMarkus Armbruster {
1921f21d96d0SKevin Wolf     return qemu_blockalign(blk ? blk_bs(blk) : NULL, size);
19224be74634SMarkus Armbruster }
19234be74634SMarkus Armbruster 
19244be74634SMarkus Armbruster bool blk_op_is_blocked(BlockBackend *blk, BlockOpType op, Error **errp)
19254be74634SMarkus Armbruster {
1926f21d96d0SKevin Wolf     BlockDriverState *bs = blk_bs(blk);
1927f21d96d0SKevin Wolf 
1928f21d96d0SKevin Wolf     if (!bs) {
1929a46fc9c9SMax Reitz         return false;
1930a46fc9c9SMax Reitz     }
1931a46fc9c9SMax Reitz 
1932f21d96d0SKevin Wolf     return bdrv_op_is_blocked(bs, op, errp);
19334be74634SMarkus Armbruster }
19344be74634SMarkus Armbruster 
19354be74634SMarkus Armbruster void blk_op_unblock(BlockBackend *blk, BlockOpType op, Error *reason)
19364be74634SMarkus Armbruster {
1937f21d96d0SKevin Wolf     BlockDriverState *bs = blk_bs(blk);
1938f21d96d0SKevin Wolf 
1939f21d96d0SKevin Wolf     if (bs) {
1940f21d96d0SKevin Wolf         bdrv_op_unblock(bs, op, reason);
19414be74634SMarkus Armbruster     }
1942a46fc9c9SMax Reitz }
19434be74634SMarkus Armbruster 
19444be74634SMarkus Armbruster void blk_op_block_all(BlockBackend *blk, Error *reason)
19454be74634SMarkus Armbruster {
1946f21d96d0SKevin Wolf     BlockDriverState *bs = blk_bs(blk);
1947f21d96d0SKevin Wolf 
1948f21d96d0SKevin Wolf     if (bs) {
1949f21d96d0SKevin Wolf         bdrv_op_block_all(bs, reason);
19504be74634SMarkus Armbruster     }
1951a46fc9c9SMax Reitz }
19524be74634SMarkus Armbruster 
19534be74634SMarkus Armbruster void blk_op_unblock_all(BlockBackend *blk, Error *reason)
19544be74634SMarkus Armbruster {
1955f21d96d0SKevin Wolf     BlockDriverState *bs = blk_bs(blk);
1956f21d96d0SKevin Wolf 
1957f21d96d0SKevin Wolf     if (bs) {
1958f21d96d0SKevin Wolf         bdrv_op_unblock_all(bs, reason);
19594be74634SMarkus Armbruster     }
1960a46fc9c9SMax Reitz }
19614be74634SMarkus Armbruster 
19624be74634SMarkus Armbruster AioContext *blk_get_aio_context(BlockBackend *blk)
19634be74634SMarkus Armbruster {
1964d861ab3aSKevin Wolf     BlockDriverState *bs = blk_bs(blk);
1965d861ab3aSKevin Wolf 
1966d861ab3aSKevin Wolf     if (bs) {
1967132ada80SKevin Wolf         AioContext *ctx = bdrv_get_aio_context(blk_bs(blk));
1968132ada80SKevin Wolf         assert(ctx == blk->ctx);
19694981bdecSMax Reitz     }
19704981bdecSMax Reitz 
1971d861ab3aSKevin Wolf     return blk->ctx;
1972d861ab3aSKevin Wolf }
1973d861ab3aSKevin Wolf 
19744981bdecSMax Reitz static AioContext *blk_aiocb_get_aio_context(BlockAIOCB *acb)
19754981bdecSMax Reitz {
19764981bdecSMax Reitz     BlockBackendAIOCB *blk_acb = DO_UPCAST(BlockBackendAIOCB, common, acb);
19774981bdecSMax Reitz     return blk_get_aio_context(blk_acb->blk);
19784be74634SMarkus Armbruster }
19794be74634SMarkus Armbruster 
198097896a48SKevin Wolf static int blk_do_set_aio_context(BlockBackend *blk, AioContext *new_context,
198197896a48SKevin Wolf                                   bool update_root_node, Error **errp)
19824be74634SMarkus Armbruster {
1983f21d96d0SKevin Wolf     BlockDriverState *bs = blk_bs(blk);
1984c61791fcSManos Pitsidianakis     ThrottleGroupMember *tgm = &blk->public.throttle_group_member;
198597896a48SKevin Wolf     int ret;
1986f21d96d0SKevin Wolf 
1987f21d96d0SKevin Wolf     if (bs) {
198897896a48SKevin Wolf         if (update_root_node) {
198997896a48SKevin Wolf             ret = bdrv_child_try_set_aio_context(bs, new_context, blk->root,
199097896a48SKevin Wolf                                                  errp);
199197896a48SKevin Wolf             if (ret < 0) {
199297896a48SKevin Wolf                 return ret;
199397896a48SKevin Wolf             }
199497896a48SKevin Wolf         }
1995c61791fcSManos Pitsidianakis         if (tgm->throttle_state) {
1996dc868fb0SStefan Hajnoczi             bdrv_drained_begin(bs);
1997c61791fcSManos Pitsidianakis             throttle_group_detach_aio_context(tgm);
1998c61791fcSManos Pitsidianakis             throttle_group_attach_aio_context(tgm, new_context);
1999dc868fb0SStefan Hajnoczi             bdrv_drained_end(bs);
20007ca7f0f6SKevin Wolf         }
200138475269SKevin Wolf     }
200238475269SKevin Wolf 
2003d861ab3aSKevin Wolf     blk->ctx = new_context;
200497896a48SKevin Wolf     return 0;
200597896a48SKevin Wolf }
200697896a48SKevin Wolf 
200797896a48SKevin Wolf int blk_set_aio_context(BlockBackend *blk, AioContext *new_context,
200897896a48SKevin Wolf                         Error **errp)
200938475269SKevin Wolf {
201097896a48SKevin Wolf     return blk_do_set_aio_context(blk, new_context, true, errp);
201138475269SKevin Wolf }
201238475269SKevin Wolf 
201338475269SKevin Wolf static bool blk_root_can_set_aio_ctx(BdrvChild *child, AioContext *ctx,
201438475269SKevin Wolf                                      GSList **ignore, Error **errp)
201538475269SKevin Wolf {
201638475269SKevin Wolf     BlockBackend *blk = child->opaque;
201738475269SKevin Wolf 
2018980b0f94SKevin Wolf     if (blk->allow_aio_context_change) {
2019980b0f94SKevin Wolf         return true;
2020980b0f94SKevin Wolf     }
2021980b0f94SKevin Wolf 
202238475269SKevin Wolf     /* Only manually created BlockBackends that are not attached to anything
202338475269SKevin Wolf      * can change their AioContext without updating their user. */
202438475269SKevin Wolf     if (!blk->name || blk->dev) {
202538475269SKevin Wolf         /* TODO Add BB name/QOM path */
202638475269SKevin Wolf         error_setg(errp, "Cannot change iothread of active block backend");
202738475269SKevin Wolf         return false;
202838475269SKevin Wolf     }
202938475269SKevin Wolf 
203038475269SKevin Wolf     return true;
203138475269SKevin Wolf }
203238475269SKevin Wolf 
203338475269SKevin Wolf static void blk_root_set_aio_ctx(BdrvChild *child, AioContext *ctx,
203438475269SKevin Wolf                                  GSList **ignore)
203538475269SKevin Wolf {
203638475269SKevin Wolf     BlockBackend *blk = child->opaque;
203797896a48SKevin Wolf     blk_do_set_aio_context(blk, ctx, false, &error_abort);
203838475269SKevin Wolf }
20394be74634SMarkus Armbruster 
20402019ba0aSMax Reitz void blk_add_aio_context_notifier(BlockBackend *blk,
20412019ba0aSMax Reitz         void (*attached_aio_context)(AioContext *new_context, void *opaque),
20422019ba0aSMax Reitz         void (*detach_aio_context)(void *opaque), void *opaque)
20432019ba0aSMax Reitz {
2044d03654eaSStefan Hajnoczi     BlockBackendAioNotifier *notifier;
2045f21d96d0SKevin Wolf     BlockDriverState *bs = blk_bs(blk);
2046f21d96d0SKevin Wolf 
2047d03654eaSStefan Hajnoczi     notifier = g_new(BlockBackendAioNotifier, 1);
2048d03654eaSStefan Hajnoczi     notifier->attached_aio_context = attached_aio_context;
2049d03654eaSStefan Hajnoczi     notifier->detach_aio_context = detach_aio_context;
2050d03654eaSStefan Hajnoczi     notifier->opaque = opaque;
2051d03654eaSStefan Hajnoczi     QLIST_INSERT_HEAD(&blk->aio_notifiers, notifier, list);
2052d03654eaSStefan Hajnoczi 
2053f21d96d0SKevin Wolf     if (bs) {
2054f21d96d0SKevin Wolf         bdrv_add_aio_context_notifier(bs, attached_aio_context,
20552019ba0aSMax Reitz                                       detach_aio_context, opaque);
20562019ba0aSMax Reitz     }
2057a46fc9c9SMax Reitz }
20582019ba0aSMax Reitz 
20592019ba0aSMax Reitz void blk_remove_aio_context_notifier(BlockBackend *blk,
20602019ba0aSMax Reitz                                      void (*attached_aio_context)(AioContext *,
20612019ba0aSMax Reitz                                                                   void *),
20622019ba0aSMax Reitz                                      void (*detach_aio_context)(void *),
20632019ba0aSMax Reitz                                      void *opaque)
20642019ba0aSMax Reitz {
2065d03654eaSStefan Hajnoczi     BlockBackendAioNotifier *notifier;
2066f21d96d0SKevin Wolf     BlockDriverState *bs = blk_bs(blk);
2067f21d96d0SKevin Wolf 
2068f21d96d0SKevin Wolf     if (bs) {
2069f21d96d0SKevin Wolf         bdrv_remove_aio_context_notifier(bs, attached_aio_context,
20702019ba0aSMax Reitz                                          detach_aio_context, opaque);
20712019ba0aSMax Reitz     }
2072d03654eaSStefan Hajnoczi 
2073d03654eaSStefan Hajnoczi     QLIST_FOREACH(notifier, &blk->aio_notifiers, list) {
2074d03654eaSStefan Hajnoczi         if (notifier->attached_aio_context == attached_aio_context &&
2075d03654eaSStefan Hajnoczi             notifier->detach_aio_context == detach_aio_context &&
2076d03654eaSStefan Hajnoczi             notifier->opaque == opaque) {
2077d03654eaSStefan Hajnoczi             QLIST_REMOVE(notifier, list);
2078d03654eaSStefan Hajnoczi             g_free(notifier);
2079d03654eaSStefan Hajnoczi             return;
2080d03654eaSStefan Hajnoczi         }
2081d03654eaSStefan Hajnoczi     }
2082d03654eaSStefan Hajnoczi 
2083d03654eaSStefan Hajnoczi     abort();
2084a46fc9c9SMax Reitz }
20852019ba0aSMax Reitz 
20863301f6c6SMax Reitz void blk_add_remove_bs_notifier(BlockBackend *blk, Notifier *notify)
20873301f6c6SMax Reitz {
20883301f6c6SMax Reitz     notifier_list_add(&blk->remove_bs_notifiers, notify);
20893301f6c6SMax Reitz }
20903301f6c6SMax Reitz 
20913301f6c6SMax Reitz void blk_add_insert_bs_notifier(BlockBackend *blk, Notifier *notify)
20923301f6c6SMax Reitz {
20933301f6c6SMax Reitz     notifier_list_add(&blk->insert_bs_notifiers, notify);
20943301f6c6SMax Reitz }
20953301f6c6SMax Reitz 
20964be74634SMarkus Armbruster void blk_io_plug(BlockBackend *blk)
20974be74634SMarkus Armbruster {
2098f21d96d0SKevin Wolf     BlockDriverState *bs = blk_bs(blk);
2099f21d96d0SKevin Wolf 
2100f21d96d0SKevin Wolf     if (bs) {
2101f21d96d0SKevin Wolf         bdrv_io_plug(bs);
21024be74634SMarkus Armbruster     }
2103a46fc9c9SMax Reitz }
21044be74634SMarkus Armbruster 
21054be74634SMarkus Armbruster void blk_io_unplug(BlockBackend *blk)
21064be74634SMarkus Armbruster {
2107f21d96d0SKevin Wolf     BlockDriverState *bs = blk_bs(blk);
2108f21d96d0SKevin Wolf 
2109f21d96d0SKevin Wolf     if (bs) {
2110f21d96d0SKevin Wolf         bdrv_io_unplug(bs);
21114be74634SMarkus Armbruster     }
2112a46fc9c9SMax Reitz }
21134be74634SMarkus Armbruster 
21144be74634SMarkus Armbruster BlockAcctStats *blk_get_stats(BlockBackend *blk)
21154be74634SMarkus Armbruster {
21167f0e9da6SMax Reitz     return &blk->stats;
21174be74634SMarkus Armbruster }
21184be74634SMarkus Armbruster 
21194be74634SMarkus Armbruster void *blk_aio_get(const AIOCBInfo *aiocb_info, BlockBackend *blk,
21204be74634SMarkus Armbruster                   BlockCompletionFunc *cb, void *opaque)
21214be74634SMarkus Armbruster {
21224be74634SMarkus Armbruster     return qemu_aio_get(aiocb_info, blk_bs(blk), cb, opaque);
21234be74634SMarkus Armbruster }
21241ef01253SMax Reitz 
2125d004bd52SEric Blake int coroutine_fn blk_co_pwrite_zeroes(BlockBackend *blk, int64_t offset,
2126f5a5ca79SManos Pitsidianakis                                       int bytes, BdrvRequestFlags flags)
21271ef01253SMax Reitz {
2128f5a5ca79SManos Pitsidianakis     return blk_co_pwritev(blk, offset, bytes, NULL,
212916aaf975SKevin Wolf                           flags | BDRV_REQ_ZERO_WRITE);
21301ef01253SMax Reitz }
21311ef01253SMax Reitz 
2132fe5c1355SPavel Butsykin int blk_pwrite_compressed(BlockBackend *blk, int64_t offset, const void *buf,
2133fe5c1355SPavel Butsykin                           int count)
21341ef01253SMax Reitz {
213535fadca8SPavel Butsykin     return blk_prw(blk, offset, (void *) buf, count, blk_write_entry,
213635fadca8SPavel Butsykin                    BDRV_REQ_WRITE_COMPRESSED);
21371ef01253SMax Reitz }
21381ef01253SMax Reitz 
2139c80d8b06SMax Reitz int blk_truncate(BlockBackend *blk, int64_t offset, bool exact,
2140*8c6242b6SKevin Wolf                  PreallocMode prealloc, BdrvRequestFlags flags, Error **errp)
21411ef01253SMax Reitz {
2142c09ba36cSMax Reitz     if (!blk_is_available(blk)) {
2143ed3d2ec9SMax Reitz         error_setg(errp, "No medium inserted");
2144c09ba36cSMax Reitz         return -ENOMEDIUM;
2145c09ba36cSMax Reitz     }
2146c09ba36cSMax Reitz 
2147*8c6242b6SKevin Wolf     return bdrv_truncate(blk->root, offset, exact, prealloc, flags, errp);
21481ef01253SMax Reitz }
21491ef01253SMax Reitz 
21501ef01253SMax Reitz int blk_save_vmstate(BlockBackend *blk, const uint8_t *buf,
21511ef01253SMax Reitz                      int64_t pos, int size)
21521ef01253SMax Reitz {
2153bfd18d1eSKevin Wolf     int ret;
2154bfd18d1eSKevin Wolf 
2155c09ba36cSMax Reitz     if (!blk_is_available(blk)) {
2156c09ba36cSMax Reitz         return -ENOMEDIUM;
2157c09ba36cSMax Reitz     }
2158c09ba36cSMax Reitz 
2159bfd18d1eSKevin Wolf     ret = bdrv_save_vmstate(blk_bs(blk), buf, pos, size);
2160bfd18d1eSKevin Wolf     if (ret < 0) {
2161bfd18d1eSKevin Wolf         return ret;
2162bfd18d1eSKevin Wolf     }
2163bfd18d1eSKevin Wolf 
2164bfd18d1eSKevin Wolf     if (ret == size && !blk->enable_write_cache) {
2165bfd18d1eSKevin Wolf         ret = bdrv_flush(blk_bs(blk));
2166bfd18d1eSKevin Wolf     }
2167bfd18d1eSKevin Wolf 
2168bfd18d1eSKevin Wolf     return ret < 0 ? ret : size;
21691ef01253SMax Reitz }
21701ef01253SMax Reitz 
21711ef01253SMax Reitz int blk_load_vmstate(BlockBackend *blk, uint8_t *buf, int64_t pos, int size)
21721ef01253SMax Reitz {
2173c09ba36cSMax Reitz     if (!blk_is_available(blk)) {
2174c09ba36cSMax Reitz         return -ENOMEDIUM;
2175c09ba36cSMax Reitz     }
2176c09ba36cSMax Reitz 
2177f21d96d0SKevin Wolf     return bdrv_load_vmstate(blk_bs(blk), buf, pos, size);
21781ef01253SMax Reitz }
2179f0272c4dSEkaterina Tumanova 
2180f0272c4dSEkaterina Tumanova int blk_probe_blocksizes(BlockBackend *blk, BlockSizes *bsz)
2181f0272c4dSEkaterina Tumanova {
2182c09ba36cSMax Reitz     if (!blk_is_available(blk)) {
2183c09ba36cSMax Reitz         return -ENOMEDIUM;
2184c09ba36cSMax Reitz     }
2185c09ba36cSMax Reitz 
2186f21d96d0SKevin Wolf     return bdrv_probe_blocksizes(blk_bs(blk), bsz);
2187f0272c4dSEkaterina Tumanova }
2188f0272c4dSEkaterina Tumanova 
2189f0272c4dSEkaterina Tumanova int blk_probe_geometry(BlockBackend *blk, HDGeometry *geo)
2190f0272c4dSEkaterina Tumanova {
2191c09ba36cSMax Reitz     if (!blk_is_available(blk)) {
2192c09ba36cSMax Reitz         return -ENOMEDIUM;
2193c09ba36cSMax Reitz     }
2194c09ba36cSMax Reitz 
2195f21d96d0SKevin Wolf     return bdrv_probe_geometry(blk_bs(blk), geo);
2196f0272c4dSEkaterina Tumanova }
2197281d22d8SMax Reitz 
2198281d22d8SMax Reitz /*
2199281d22d8SMax Reitz  * Updates the BlockBackendRootState object with data from the currently
2200281d22d8SMax Reitz  * attached BlockDriverState.
2201281d22d8SMax Reitz  */
2202281d22d8SMax Reitz void blk_update_root_state(BlockBackend *blk)
2203281d22d8SMax Reitz {
2204f21d96d0SKevin Wolf     assert(blk->root);
2205281d22d8SMax Reitz 
2206f21d96d0SKevin Wolf     blk->root_state.open_flags    = blk->root->bs->open_flags;
2207f21d96d0SKevin Wolf     blk->root_state.read_only     = blk->root->bs->read_only;
2208f21d96d0SKevin Wolf     blk->root_state.detect_zeroes = blk->root->bs->detect_zeroes;
2209281d22d8SMax Reitz }
2210281d22d8SMax Reitz 
221138cb18f5SMax Reitz /*
2212b85114f8SKevin Wolf  * Returns the detect-zeroes setting to be used for bdrv_open() of a
2213b85114f8SKevin Wolf  * BlockDriverState which is supposed to inherit the root state.
221438cb18f5SMax Reitz  */
2215b85114f8SKevin Wolf bool blk_get_detect_zeroes_from_root_state(BlockBackend *blk)
221638cb18f5SMax Reitz {
2217b85114f8SKevin Wolf     return blk->root_state.detect_zeroes;
221838cb18f5SMax Reitz }
221938cb18f5SMax Reitz 
222038cb18f5SMax Reitz /*
222138cb18f5SMax Reitz  * Returns the flags to be used for bdrv_open() of a BlockDriverState which is
222238cb18f5SMax Reitz  * supposed to inherit the root state.
222338cb18f5SMax Reitz  */
222438cb18f5SMax Reitz int blk_get_open_flags_from_root_state(BlockBackend *blk)
222538cb18f5SMax Reitz {
222638cb18f5SMax Reitz     int bs_flags;
222738cb18f5SMax Reitz 
222838cb18f5SMax Reitz     bs_flags = blk->root_state.read_only ? 0 : BDRV_O_RDWR;
222938cb18f5SMax Reitz     bs_flags |= blk->root_state.open_flags & ~BDRV_O_RDWR;
223038cb18f5SMax Reitz 
223138cb18f5SMax Reitz     return bs_flags;
223238cb18f5SMax Reitz }
223338cb18f5SMax Reitz 
2234281d22d8SMax Reitz BlockBackendRootState *blk_get_root_state(BlockBackend *blk)
2235281d22d8SMax Reitz {
2236281d22d8SMax Reitz     return &blk->root_state;
2237281d22d8SMax Reitz }
22381393f212SMax Reitz 
22391393f212SMax Reitz int blk_commit_all(void)
22401393f212SMax Reitz {
2241fe1a9cbcSMax Reitz     BlockBackend *blk = NULL;
2242fe1a9cbcSMax Reitz 
2243fe1a9cbcSMax Reitz     while ((blk = blk_all_next(blk)) != NULL) {
2244fe1a9cbcSMax Reitz         AioContext *aio_context = blk_get_aio_context(blk);
2245fe1a9cbcSMax Reitz 
2246fe1a9cbcSMax Reitz         aio_context_acquire(aio_context);
2247f21d96d0SKevin Wolf         if (blk_is_inserted(blk) && blk->root->bs->backing) {
2248f21d96d0SKevin Wolf             int ret = bdrv_commit(blk->root->bs);
2249fe1a9cbcSMax Reitz             if (ret < 0) {
2250fe1a9cbcSMax Reitz                 aio_context_release(aio_context);
2251fe1a9cbcSMax Reitz                 return ret;
2252fe1a9cbcSMax Reitz             }
2253fe1a9cbcSMax Reitz         }
2254fe1a9cbcSMax Reitz         aio_context_release(aio_context);
2255fe1a9cbcSMax Reitz     }
2256fe1a9cbcSMax Reitz     return 0;
2257fe1a9cbcSMax Reitz }
2258fe1a9cbcSMax Reitz 
225997148076SKevin Wolf 
226097148076SKevin Wolf /* throttling disk I/O limits */
226197148076SKevin Wolf void blk_set_io_limits(BlockBackend *blk, ThrottleConfig *cfg)
226297148076SKevin Wolf {
2263022cdc9fSManos Pitsidianakis     throttle_group_config(&blk->public.throttle_group_member, cfg);
226497148076SKevin Wolf }
226597148076SKevin Wolf 
226697148076SKevin Wolf void blk_io_limits_disable(BlockBackend *blk)
226797148076SKevin Wolf {
226848bf7ea8SAlberto Garcia     BlockDriverState *bs = blk_bs(blk);
226948bf7ea8SAlberto Garcia     ThrottleGroupMember *tgm = &blk->public.throttle_group_member;
227048bf7ea8SAlberto Garcia     assert(tgm->throttle_state);
227148bf7ea8SAlberto Garcia     if (bs) {
227248bf7ea8SAlberto Garcia         bdrv_drained_begin(bs);
227348bf7ea8SAlberto Garcia     }
227448bf7ea8SAlberto Garcia     throttle_group_unregister_tgm(tgm);
227548bf7ea8SAlberto Garcia     if (bs) {
227648bf7ea8SAlberto Garcia         bdrv_drained_end(bs);
227748bf7ea8SAlberto Garcia     }
227897148076SKevin Wolf }
227997148076SKevin Wolf 
228097148076SKevin Wolf /* should be called before blk_set_io_limits if a limit is set */
228197148076SKevin Wolf void blk_io_limits_enable(BlockBackend *blk, const char *group)
228297148076SKevin Wolf {
2283022cdc9fSManos Pitsidianakis     assert(!blk->public.throttle_group_member.throttle_state);
2284c61791fcSManos Pitsidianakis     throttle_group_register_tgm(&blk->public.throttle_group_member,
2285c61791fcSManos Pitsidianakis                                 group, blk_get_aio_context(blk));
228697148076SKevin Wolf }
228797148076SKevin Wolf 
228897148076SKevin Wolf void blk_io_limits_update_group(BlockBackend *blk, const char *group)
228997148076SKevin Wolf {
229097148076SKevin Wolf     /* this BB is not part of any group */
2291022cdc9fSManos Pitsidianakis     if (!blk->public.throttle_group_member.throttle_state) {
229297148076SKevin Wolf         return;
229397148076SKevin Wolf     }
229497148076SKevin Wolf 
229597148076SKevin Wolf     /* this BB is a part of the same group than the one we want */
2296022cdc9fSManos Pitsidianakis     if (!g_strcmp0(throttle_group_get_name(&blk->public.throttle_group_member),
2297022cdc9fSManos Pitsidianakis                 group)) {
229897148076SKevin Wolf         return;
229997148076SKevin Wolf     }
230097148076SKevin Wolf 
230197148076SKevin Wolf     /* need to change the group this bs belong to */
230297148076SKevin Wolf     blk_io_limits_disable(blk);
230397148076SKevin Wolf     blk_io_limits_enable(blk, group);
230497148076SKevin Wolf }
2305c2066af0SKevin Wolf 
2306c2066af0SKevin Wolf static void blk_root_drained_begin(BdrvChild *child)
2307c2066af0SKevin Wolf {
2308c2066af0SKevin Wolf     BlockBackend *blk = child->opaque;
2309c2066af0SKevin Wolf 
2310f4d9cc88SJohn Snow     if (++blk->quiesce_counter == 1) {
2311f4d9cc88SJohn Snow         if (blk->dev_ops && blk->dev_ops->drained_begin) {
2312f4d9cc88SJohn Snow             blk->dev_ops->drained_begin(blk->dev_opaque);
2313f4d9cc88SJohn Snow         }
2314f4d9cc88SJohn Snow     }
2315f4d9cc88SJohn Snow 
231636fe1331SKevin Wolf     /* Note that blk->root may not be accessible here yet if we are just
231736fe1331SKevin Wolf      * attaching to a BlockDriverState that is drained. Use child instead. */
231836fe1331SKevin Wolf 
2319022cdc9fSManos Pitsidianakis     if (atomic_fetch_inc(&blk->public.throttle_group_member.io_limits_disabled) == 0) {
2320022cdc9fSManos Pitsidianakis         throttle_group_restart_tgm(&blk->public.throttle_group_member);
2321c2066af0SKevin Wolf     }
2322c2066af0SKevin Wolf }
2323c2066af0SKevin Wolf 
2324fe5258a5SKevin Wolf static bool blk_root_drained_poll(BdrvChild *child)
2325fe5258a5SKevin Wolf {
2326fe5258a5SKevin Wolf     BlockBackend *blk = child->opaque;
2327fe5258a5SKevin Wolf     assert(blk->quiesce_counter);
2328fe5258a5SKevin Wolf     return !!blk->in_flight;
2329fe5258a5SKevin Wolf }
2330fe5258a5SKevin Wolf 
2331e037c09cSMax Reitz static void blk_root_drained_end(BdrvChild *child, int *drained_end_counter)
2332c2066af0SKevin Wolf {
2333c2066af0SKevin Wolf     BlockBackend *blk = child->opaque;
2334f4d9cc88SJohn Snow     assert(blk->quiesce_counter);
2335c2066af0SKevin Wolf 
2336022cdc9fSManos Pitsidianakis     assert(blk->public.throttle_group_member.io_limits_disabled);
2337022cdc9fSManos Pitsidianakis     atomic_dec(&blk->public.throttle_group_member.io_limits_disabled);
2338f4d9cc88SJohn Snow 
2339f4d9cc88SJohn Snow     if (--blk->quiesce_counter == 0) {
2340f4d9cc88SJohn Snow         if (blk->dev_ops && blk->dev_ops->drained_end) {
2341f4d9cc88SJohn Snow             blk->dev_ops->drained_end(blk->dev_opaque);
2342f4d9cc88SJohn Snow         }
2343cf312932SKevin Wolf         while (qemu_co_enter_next(&blk->queued_requests, NULL)) {
2344cf312932SKevin Wolf             /* Resume all queued requests */
2345cf312932SKevin Wolf         }
2346f4d9cc88SJohn Snow     }
2347c2066af0SKevin Wolf }
234823d0ba93SFam Zheng 
234923d0ba93SFam Zheng void blk_register_buf(BlockBackend *blk, void *host, size_t size)
235023d0ba93SFam Zheng {
235123d0ba93SFam Zheng     bdrv_register_buf(blk_bs(blk), host, size);
235223d0ba93SFam Zheng }
235323d0ba93SFam Zheng 
235423d0ba93SFam Zheng void blk_unregister_buf(BlockBackend *blk, void *host)
235523d0ba93SFam Zheng {
235623d0ba93SFam Zheng     bdrv_unregister_buf(blk_bs(blk), host);
235723d0ba93SFam Zheng }
2358b5679fa4SFam Zheng 
2359b5679fa4SFam Zheng int coroutine_fn blk_co_copy_range(BlockBackend *blk_in, int64_t off_in,
2360b5679fa4SFam Zheng                                    BlockBackend *blk_out, int64_t off_out,
236167b51fb9SVladimir Sementsov-Ogievskiy                                    int bytes, BdrvRequestFlags read_flags,
236267b51fb9SVladimir Sementsov-Ogievskiy                                    BdrvRequestFlags write_flags)
2363b5679fa4SFam Zheng {
2364b5679fa4SFam Zheng     int r;
2365b5679fa4SFam Zheng     r = blk_check_byte_request(blk_in, off_in, bytes);
2366b5679fa4SFam Zheng     if (r) {
2367b5679fa4SFam Zheng         return r;
2368b5679fa4SFam Zheng     }
2369b5679fa4SFam Zheng     r = blk_check_byte_request(blk_out, off_out, bytes);
2370b5679fa4SFam Zheng     if (r) {
2371b5679fa4SFam Zheng         return r;
2372b5679fa4SFam Zheng     }
2373b5679fa4SFam Zheng     return bdrv_co_copy_range(blk_in->root, off_in,
2374b5679fa4SFam Zheng                               blk_out->root, off_out,
237567b51fb9SVladimir Sementsov-Ogievskiy                               bytes, read_flags, write_flags);
2376b5679fa4SFam Zheng }
23775d3b4e99SVladimir Sementsov-Ogievskiy 
23785d3b4e99SVladimir Sementsov-Ogievskiy const BdrvChild *blk_root(BlockBackend *blk)
23795d3b4e99SVladimir Sementsov-Ogievskiy {
23805d3b4e99SVladimir Sementsov-Ogievskiy     return blk->root;
23815d3b4e99SVladimir Sementsov-Ogievskiy }
2382