xref: /openbmc/qemu/block/block-backend.c (revision 9a71b9de)
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 
1233cdc69d3SMax Reitz static void blk_root_inherit_options(BdrvChildRole role, bool parent_is_format,
124272c02eaSMax Reitz                                      int *child_flags, QDict *child_options,
125f21d96d0SKevin Wolf                                      int parent_flags, QDict *parent_options)
126f21d96d0SKevin Wolf {
127f21d96d0SKevin Wolf     /* We're not supposed to call this function for root nodes */
128f21d96d0SKevin Wolf     abort();
129f21d96d0SKevin Wolf }
130c2066af0SKevin Wolf static void blk_root_drained_begin(BdrvChild *child);
131fe5258a5SKevin Wolf static bool blk_root_drained_poll(BdrvChild *child);
132e037c09cSMax Reitz static void blk_root_drained_end(BdrvChild *child, int *drained_end_counter);
133f21d96d0SKevin Wolf 
1345c8cab48SKevin Wolf static void blk_root_change_media(BdrvChild *child, bool load);
1355c8cab48SKevin Wolf static void blk_root_resize(BdrvChild *child);
1365c8cab48SKevin Wolf 
13738475269SKevin Wolf static bool blk_root_can_set_aio_ctx(BdrvChild *child, AioContext *ctx,
13838475269SKevin Wolf                                      GSList **ignore, Error **errp);
13938475269SKevin Wolf static void blk_root_set_aio_ctx(BdrvChild *child, AioContext *ctx,
14038475269SKevin Wolf                                  GSList **ignore);
14138475269SKevin Wolf 
142b5411555SKevin Wolf static char *blk_root_get_parent_desc(BdrvChild *child)
143b5411555SKevin Wolf {
144b5411555SKevin Wolf     BlockBackend *blk = child->opaque;
145b5411555SKevin Wolf     char *dev_id;
146b5411555SKevin Wolf 
147b5411555SKevin Wolf     if (blk->name) {
148b5411555SKevin Wolf         return g_strdup(blk->name);
149b5411555SKevin Wolf     }
150b5411555SKevin Wolf 
151b5411555SKevin Wolf     dev_id = blk_get_attached_dev_id(blk);
152b5411555SKevin Wolf     if (*dev_id) {
153b5411555SKevin Wolf         return dev_id;
154b5411555SKevin Wolf     } else {
155b5411555SKevin Wolf         /* TODO Callback into the BB owner for something more detailed */
156b5411555SKevin Wolf         g_free(dev_id);
157b5411555SKevin Wolf         return g_strdup("a block device");
158b5411555SKevin Wolf     }
159b5411555SKevin Wolf }
160b5411555SKevin Wolf 
1614c265bf9SKevin Wolf static const char *blk_root_get_name(BdrvChild *child)
1624c265bf9SKevin Wolf {
1634c265bf9SKevin Wolf     return blk_name(child->opaque);
1644c265bf9SKevin Wolf }
1654c265bf9SKevin Wolf 
1665f7772c4SFam Zheng static void blk_vm_state_changed(void *opaque, int running, RunState state)
1675f7772c4SFam Zheng {
1685f7772c4SFam Zheng     Error *local_err = NULL;
1695f7772c4SFam Zheng     BlockBackend *blk = opaque;
1705f7772c4SFam Zheng 
1715f7772c4SFam Zheng     if (state == RUN_STATE_INMIGRATE) {
1725f7772c4SFam Zheng         return;
1735f7772c4SFam Zheng     }
1745f7772c4SFam Zheng 
1755f7772c4SFam Zheng     qemu_del_vm_change_state_handler(blk->vmsh);
1765f7772c4SFam Zheng     blk->vmsh = NULL;
1775f7772c4SFam Zheng     blk_set_perm(blk, blk->perm, blk->shared_perm, &local_err);
1785f7772c4SFam Zheng     if (local_err) {
1795f7772c4SFam Zheng         error_report_err(local_err);
1805f7772c4SFam Zheng     }
1815f7772c4SFam Zheng }
1825f7772c4SFam Zheng 
1834417ab7aSKevin Wolf /*
1844417ab7aSKevin Wolf  * Notifies the user of the BlockBackend that migration has completed. qdev
1854417ab7aSKevin Wolf  * devices can tighten their permissions in response (specifically revoke
1864417ab7aSKevin Wolf  * shared write permissions that we needed for storage migration).
1874417ab7aSKevin Wolf  *
1884417ab7aSKevin Wolf  * If an error is returned, the VM cannot be allowed to be resumed.
1894417ab7aSKevin Wolf  */
1904417ab7aSKevin Wolf static void blk_root_activate(BdrvChild *child, Error **errp)
1914417ab7aSKevin Wolf {
1924417ab7aSKevin Wolf     BlockBackend *blk = child->opaque;
1934417ab7aSKevin Wolf     Error *local_err = NULL;
1944417ab7aSKevin Wolf 
1954417ab7aSKevin Wolf     if (!blk->disable_perm) {
1964417ab7aSKevin Wolf         return;
1974417ab7aSKevin Wolf     }
1984417ab7aSKevin Wolf 
1994417ab7aSKevin Wolf     blk->disable_perm = false;
2004417ab7aSKevin Wolf 
2015f7772c4SFam Zheng     blk_set_perm(blk, blk->perm, BLK_PERM_ALL, &local_err);
2025f7772c4SFam Zheng     if (local_err) {
2035f7772c4SFam Zheng         error_propagate(errp, local_err);
2045f7772c4SFam Zheng         blk->disable_perm = true;
2055f7772c4SFam Zheng         return;
2065f7772c4SFam Zheng     }
2075f7772c4SFam Zheng 
2085f7772c4SFam Zheng     if (runstate_check(RUN_STATE_INMIGRATE)) {
2095f7772c4SFam Zheng         /* Activation can happen when migration process is still active, for
2105f7772c4SFam Zheng          * example when nbd_server_add is called during non-shared storage
2115f7772c4SFam Zheng          * migration. Defer the shared_perm update to migration completion. */
2125f7772c4SFam Zheng         if (!blk->vmsh) {
2135f7772c4SFam Zheng             blk->vmsh = qemu_add_vm_change_state_handler(blk_vm_state_changed,
2145f7772c4SFam Zheng                                                          blk);
2155f7772c4SFam Zheng         }
2165f7772c4SFam Zheng         return;
2175f7772c4SFam Zheng     }
2185f7772c4SFam Zheng 
2194417ab7aSKevin Wolf     blk_set_perm(blk, blk->perm, blk->shared_perm, &local_err);
2204417ab7aSKevin Wolf     if (local_err) {
2214417ab7aSKevin Wolf         error_propagate(errp, local_err);
2224417ab7aSKevin Wolf         blk->disable_perm = true;
2234417ab7aSKevin Wolf         return;
2244417ab7aSKevin Wolf     }
2254417ab7aSKevin Wolf }
2264417ab7aSKevin Wolf 
227ca2e2144SFam Zheng void blk_set_force_allow_inactivate(BlockBackend *blk)
228ca2e2144SFam Zheng {
229ca2e2144SFam Zheng     blk->force_allow_inactivate = true;
230ca2e2144SFam Zheng }
231ca2e2144SFam Zheng 
232c16de8f5SFam Zheng static bool blk_can_inactivate(BlockBackend *blk)
233c16de8f5SFam Zheng {
234ca2e2144SFam Zheng     /* If it is a guest device, inactivate is ok. */
235c16de8f5SFam Zheng     if (blk->dev || blk_name(blk)[0]) {
236c16de8f5SFam Zheng         return true;
237c16de8f5SFam Zheng     }
238c16de8f5SFam Zheng 
239ca2e2144SFam Zheng     /* Inactivating means no more writes to the image can be done,
240ca2e2144SFam Zheng      * even if those writes would be changes invisible to the
241ca2e2144SFam Zheng      * guest.  For block job BBs that satisfy this, we can just allow
242ca2e2144SFam Zheng      * it.  This is the case for mirror job source, which is required
243ca2e2144SFam Zheng      * by libvirt non-shared block migration. */
244ca2e2144SFam Zheng     if (!(blk->perm & (BLK_PERM_WRITE | BLK_PERM_WRITE_UNCHANGED))) {
245ca2e2144SFam Zheng         return true;
246ca2e2144SFam Zheng     }
247ca2e2144SFam Zheng 
248ca2e2144SFam Zheng     return blk->force_allow_inactivate;
249c16de8f5SFam Zheng }
250c16de8f5SFam Zheng 
251cfa1a572SKevin Wolf static int blk_root_inactivate(BdrvChild *child)
252cfa1a572SKevin Wolf {
253cfa1a572SKevin Wolf     BlockBackend *blk = child->opaque;
254cfa1a572SKevin Wolf 
255cfa1a572SKevin Wolf     if (blk->disable_perm) {
256cfa1a572SKevin Wolf         return 0;
257cfa1a572SKevin Wolf     }
258cfa1a572SKevin Wolf 
259c16de8f5SFam Zheng     if (!blk_can_inactivate(blk)) {
260cfa1a572SKevin Wolf         return -EPERM;
261cfa1a572SKevin Wolf     }
262cfa1a572SKevin Wolf 
263cfa1a572SKevin Wolf     blk->disable_perm = true;
264cfa1a572SKevin Wolf     if (blk->root) {
265cfa1a572SKevin Wolf         bdrv_child_try_set_perm(blk->root, 0, BLK_PERM_ALL, &error_abort);
266cfa1a572SKevin Wolf     }
267cfa1a572SKevin Wolf 
268cfa1a572SKevin Wolf     return 0;
269cfa1a572SKevin Wolf }
270cfa1a572SKevin Wolf 
271d03654eaSStefan Hajnoczi static void blk_root_attach(BdrvChild *child)
272d03654eaSStefan Hajnoczi {
273d03654eaSStefan Hajnoczi     BlockBackend *blk = child->opaque;
274d03654eaSStefan Hajnoczi     BlockBackendAioNotifier *notifier;
275d03654eaSStefan Hajnoczi 
276d03654eaSStefan Hajnoczi     trace_blk_root_attach(child, blk, child->bs);
277d03654eaSStefan Hajnoczi 
278d03654eaSStefan Hajnoczi     QLIST_FOREACH(notifier, &blk->aio_notifiers, list) {
279d03654eaSStefan Hajnoczi         bdrv_add_aio_context_notifier(child->bs,
280d03654eaSStefan Hajnoczi                 notifier->attached_aio_context,
281d03654eaSStefan Hajnoczi                 notifier->detach_aio_context,
282d03654eaSStefan Hajnoczi                 notifier->opaque);
283d03654eaSStefan Hajnoczi     }
284d03654eaSStefan Hajnoczi }
285d03654eaSStefan Hajnoczi 
286d03654eaSStefan Hajnoczi static void blk_root_detach(BdrvChild *child)
287d03654eaSStefan Hajnoczi {
288d03654eaSStefan Hajnoczi     BlockBackend *blk = child->opaque;
289d03654eaSStefan Hajnoczi     BlockBackendAioNotifier *notifier;
290d03654eaSStefan Hajnoczi 
291d03654eaSStefan Hajnoczi     trace_blk_root_detach(child, blk, child->bs);
292d03654eaSStefan Hajnoczi 
293d03654eaSStefan Hajnoczi     QLIST_FOREACH(notifier, &blk->aio_notifiers, list) {
294d03654eaSStefan Hajnoczi         bdrv_remove_aio_context_notifier(child->bs,
295d03654eaSStefan Hajnoczi                 notifier->attached_aio_context,
296d03654eaSStefan Hajnoczi                 notifier->detach_aio_context,
297d03654eaSStefan Hajnoczi                 notifier->opaque);
298d03654eaSStefan Hajnoczi     }
299d03654eaSStefan Hajnoczi }
300d03654eaSStefan Hajnoczi 
301bd86fb99SMax Reitz static const BdrvChildClass child_root = {
302f21d96d0SKevin Wolf     .inherit_options    = blk_root_inherit_options,
303c2066af0SKevin Wolf 
3045c8cab48SKevin Wolf     .change_media       = blk_root_change_media,
3055c8cab48SKevin Wolf     .resize             = blk_root_resize,
3064c265bf9SKevin Wolf     .get_name           = blk_root_get_name,
307b5411555SKevin Wolf     .get_parent_desc    = blk_root_get_parent_desc,
3085c8cab48SKevin Wolf 
309c2066af0SKevin Wolf     .drained_begin      = blk_root_drained_begin,
310fe5258a5SKevin Wolf     .drained_poll       = blk_root_drained_poll,
311c2066af0SKevin Wolf     .drained_end        = blk_root_drained_end,
3124417ab7aSKevin Wolf 
3134417ab7aSKevin Wolf     .activate           = blk_root_activate,
314cfa1a572SKevin Wolf     .inactivate         = blk_root_inactivate,
315d03654eaSStefan Hajnoczi 
316d03654eaSStefan Hajnoczi     .attach             = blk_root_attach,
317d03654eaSStefan Hajnoczi     .detach             = blk_root_detach,
31838475269SKevin Wolf 
31938475269SKevin Wolf     .can_set_aio_ctx    = blk_root_can_set_aio_ctx,
32038475269SKevin Wolf     .set_aio_ctx        = blk_root_set_aio_ctx,
321f21d96d0SKevin Wolf };
322f21d96d0SKevin Wolf 
32326f54e9aSMarkus Armbruster /*
324efaa7c4eSMax Reitz  * Create a new BlockBackend with a reference count of one.
3256d0eb64dSKevin Wolf  *
3266d0eb64dSKevin Wolf  * @perm is a bitmasks of BLK_PERM_* constants which describes the permissions
3276d0eb64dSKevin Wolf  * to request for a block driver node that is attached to this BlockBackend.
3286d0eb64dSKevin Wolf  * @shared_perm is a bitmask which describes which permissions may be granted
3296d0eb64dSKevin Wolf  * to other users of the attached node.
3306d0eb64dSKevin Wolf  * Both sets of permissions can be changed later using blk_set_perm().
3316d0eb64dSKevin Wolf  *
33226f54e9aSMarkus Armbruster  * Return the new BlockBackend on success, null on failure.
33326f54e9aSMarkus Armbruster  */
334d861ab3aSKevin Wolf BlockBackend *blk_new(AioContext *ctx, uint64_t perm, uint64_t shared_perm)
33526f54e9aSMarkus Armbruster {
33626f54e9aSMarkus Armbruster     BlockBackend *blk;
33726f54e9aSMarkus Armbruster 
33826f54e9aSMarkus Armbruster     blk = g_new0(BlockBackend, 1);
33926f54e9aSMarkus Armbruster     blk->refcnt = 1;
340d861ab3aSKevin Wolf     blk->ctx = ctx;
3416d0eb64dSKevin Wolf     blk->perm = perm;
3426d0eb64dSKevin Wolf     blk->shared_perm = shared_perm;
3430c3169dfSKevin Wolf     blk_set_enable_write_cache(blk, true);
3440c3169dfSKevin Wolf 
345cb53460bSKevin Wolf     blk->on_read_error = BLOCKDEV_ON_ERROR_REPORT;
346cb53460bSKevin Wolf     blk->on_write_error = BLOCKDEV_ON_ERROR_ENOSPC;
347cb53460bSKevin Wolf 
3489caa6f3dSPaolo Bonzini     block_acct_init(&blk->stats);
34927ccdd52SKevin Wolf 
350cf312932SKevin Wolf     qemu_co_queue_init(&blk->queued_requests);
3513301f6c6SMax Reitz     notifier_list_init(&blk->remove_bs_notifiers);
3523301f6c6SMax Reitz     notifier_list_init(&blk->insert_bs_notifiers);
353d03654eaSStefan Hajnoczi     QLIST_INIT(&blk->aio_notifiers);
35427ccdd52SKevin Wolf 
3552cf22d6aSMax Reitz     QTAILQ_INSERT_TAIL(&block_backends, blk, link);
35626f54e9aSMarkus Armbruster     return blk;
35726f54e9aSMarkus Armbruster }
35826f54e9aSMarkus Armbruster 
3597e7d56d9SMarkus Armbruster /*
360a3aeeab5SEric Blake  * Create a new BlockBackend connected to an existing BlockDriverState.
361a3aeeab5SEric Blake  *
362a3aeeab5SEric Blake  * @perm is a bitmasks of BLK_PERM_* constants which describes the
363a3aeeab5SEric Blake  * permissions to request for @bs that is attached to this
364a3aeeab5SEric Blake  * BlockBackend.  @shared_perm is a bitmask which describes which
365a3aeeab5SEric Blake  * permissions may be granted to other users of the attached node.
366a3aeeab5SEric Blake  * Both sets of permissions can be changed later using blk_set_perm().
367a3aeeab5SEric Blake  *
368a3aeeab5SEric Blake  * Return the new BlockBackend on success, null on failure.
369a3aeeab5SEric Blake  */
370a3aeeab5SEric Blake BlockBackend *blk_new_with_bs(BlockDriverState *bs, uint64_t perm,
371a3aeeab5SEric Blake                               uint64_t shared_perm, Error **errp)
372a3aeeab5SEric Blake {
373a3aeeab5SEric Blake     BlockBackend *blk = blk_new(bdrv_get_aio_context(bs), perm, shared_perm);
374a3aeeab5SEric Blake 
375a3aeeab5SEric Blake     if (blk_insert_bs(blk, bs, errp) < 0) {
376a3aeeab5SEric Blake         blk_unref(blk);
377a3aeeab5SEric Blake         return NULL;
378a3aeeab5SEric Blake     }
379a3aeeab5SEric Blake     return blk;
380a3aeeab5SEric Blake }
381a3aeeab5SEric Blake 
382a3aeeab5SEric Blake /*
38328eb9b12SMax Reitz  * Creates a new BlockBackend, opens a new BlockDriverState, and connects both.
384d861ab3aSKevin Wolf  * The new BlockBackend is in the main AioContext.
385ca49a4fdSMax Reitz  *
386ca49a4fdSMax Reitz  * Just as with bdrv_open(), after having called this function the reference to
387ca49a4fdSMax Reitz  * @options belongs to the block layer (even on failure).
388ca49a4fdSMax Reitz  *
389ca49a4fdSMax Reitz  * TODO: Remove @filename and @flags; it should be possible to specify a whole
390ca49a4fdSMax Reitz  * BDS tree just by specifying the @options QDict (or @reference,
391ca49a4fdSMax Reitz  * alternatively). At the time of adding this function, this is not possible,
392ca49a4fdSMax Reitz  * though, so callers of this function have to be able to specify @filename and
393ca49a4fdSMax Reitz  * @flags.
394ca49a4fdSMax Reitz  */
395efaa7c4eSMax Reitz BlockBackend *blk_new_open(const char *filename, const char *reference,
396efaa7c4eSMax Reitz                            QDict *options, int flags, Error **errp)
397ca49a4fdSMax Reitz {
398ca49a4fdSMax Reitz     BlockBackend *blk;
39928eb9b12SMax Reitz     BlockDriverState *bs;
4001f4ad7d3SKevin Wolf     uint64_t perm = 0;
401ca49a4fdSMax Reitz 
402c62d32f5SKevin Wolf     /* blk_new_open() is mainly used in .bdrv_create implementations and the
403c62d32f5SKevin Wolf      * tools where sharing isn't a concern because the BDS stays private, so we
404c62d32f5SKevin Wolf      * just request permission according to the flags.
405c62d32f5SKevin Wolf      *
406c62d32f5SKevin Wolf      * The exceptions are xen_disk and blockdev_init(); in these cases, the
407c62d32f5SKevin Wolf      * caller of blk_new_open() doesn't make use of the permissions, but they
408c62d32f5SKevin Wolf      * shouldn't hurt either. We can still share everything here because the
409c62d32f5SKevin Wolf      * guest devices will add their own blockers if they can't share. */
4101f4ad7d3SKevin Wolf     if ((flags & BDRV_O_NO_IO) == 0) {
4111f4ad7d3SKevin Wolf         perm |= BLK_PERM_CONSISTENT_READ;
412c62d32f5SKevin Wolf         if (flags & BDRV_O_RDWR) {
413c62d32f5SKevin Wolf             perm |= BLK_PERM_WRITE;
414c62d32f5SKevin Wolf         }
4151f4ad7d3SKevin Wolf     }
416c62d32f5SKevin Wolf     if (flags & BDRV_O_RESIZE) {
417c62d32f5SKevin Wolf         perm |= BLK_PERM_RESIZE;
418c62d32f5SKevin Wolf     }
419c62d32f5SKevin Wolf 
420d861ab3aSKevin Wolf     blk = blk_new(qemu_get_aio_context(), perm, BLK_PERM_ALL);
4215b363937SMax Reitz     bs = bdrv_open(filename, reference, options, flags, errp);
4225b363937SMax Reitz     if (!bs) {
423ca49a4fdSMax Reitz         blk_unref(blk);
424ca49a4fdSMax Reitz         return NULL;
425ca49a4fdSMax Reitz     }
426ca49a4fdSMax Reitz 
4271f38f04eSMax Reitz     blk->root = bdrv_root_attach_child(bs, "root", &child_root,
4281f38f04eSMax Reitz                                        BDRV_CHILD_FILTERED | BDRV_CHILD_PRIMARY,
4291f38f04eSMax Reitz                                        blk->ctx, perm, BLK_PERM_ALL, blk, errp);
43050bfbe93SFam Zheng     if (!blk->root) {
43150bfbe93SFam Zheng         blk_unref(blk);
43250bfbe93SFam Zheng         return NULL;
43350bfbe93SFam Zheng     }
43472e775c7SKevin Wolf 
435ca49a4fdSMax Reitz     return blk;
436ca49a4fdSMax Reitz }
437ca49a4fdSMax Reitz 
43826f54e9aSMarkus Armbruster static void blk_delete(BlockBackend *blk)
43926f54e9aSMarkus Armbruster {
44026f54e9aSMarkus Armbruster     assert(!blk->refcnt);
441e5e78550SMax Reitz     assert(!blk->name);
442a7f53e26SMarkus Armbruster     assert(!blk->dev);
443022cdc9fSManos Pitsidianakis     if (blk->public.throttle_group_member.throttle_state) {
4441606e4cfSEric Blake         blk_io_limits_disable(blk);
4451606e4cfSEric Blake     }
446f21d96d0SKevin Wolf     if (blk->root) {
44713855c6bSMax Reitz         blk_remove_bs(blk);
4487e7d56d9SMarkus Armbruster     }
4495f7772c4SFam Zheng     if (blk->vmsh) {
4505f7772c4SFam Zheng         qemu_del_vm_change_state_handler(blk->vmsh);
4515f7772c4SFam Zheng         blk->vmsh = NULL;
4525f7772c4SFam Zheng     }
4533301f6c6SMax Reitz     assert(QLIST_EMPTY(&blk->remove_bs_notifiers.notifiers));
4543301f6c6SMax Reitz     assert(QLIST_EMPTY(&blk->insert_bs_notifiers.notifiers));
455d03654eaSStefan Hajnoczi     assert(QLIST_EMPTY(&blk->aio_notifiers));
4562cf22d6aSMax Reitz     QTAILQ_REMOVE(&block_backends, blk, link);
45718e46a03SMarkus Armbruster     drive_info_del(blk->legacy_dinfo);
458979e9b03SAlberto Garcia     block_acct_cleanup(&blk->stats);
45926f54e9aSMarkus Armbruster     g_free(blk);
46026f54e9aSMarkus Armbruster }
46126f54e9aSMarkus Armbruster 
4628fb3c76cSMarkus Armbruster static void drive_info_del(DriveInfo *dinfo)
4638fb3c76cSMarkus Armbruster {
4648fb3c76cSMarkus Armbruster     if (!dinfo) {
4658fb3c76cSMarkus Armbruster         return;
4668fb3c76cSMarkus Armbruster     }
4678fb3c76cSMarkus Armbruster     qemu_opts_del(dinfo->opts);
4688fb3c76cSMarkus Armbruster     g_free(dinfo);
4698fb3c76cSMarkus Armbruster }
4708fb3c76cSMarkus Armbruster 
471f636ae85SAlberto Garcia int blk_get_refcnt(BlockBackend *blk)
472f636ae85SAlberto Garcia {
473f636ae85SAlberto Garcia     return blk ? blk->refcnt : 0;
474f636ae85SAlberto Garcia }
475f636ae85SAlberto Garcia 
47626f54e9aSMarkus Armbruster /*
47726f54e9aSMarkus Armbruster  * Increment @blk's reference count.
47826f54e9aSMarkus Armbruster  * @blk must not be null.
47926f54e9aSMarkus Armbruster  */
48026f54e9aSMarkus Armbruster void blk_ref(BlockBackend *blk)
48126f54e9aSMarkus Armbruster {
4825ca9d21bSKevin Wolf     assert(blk->refcnt > 0);
48326f54e9aSMarkus Armbruster     blk->refcnt++;
48426f54e9aSMarkus Armbruster }
48526f54e9aSMarkus Armbruster 
48626f54e9aSMarkus Armbruster /*
48726f54e9aSMarkus Armbruster  * Decrement @blk's reference count.
48826f54e9aSMarkus Armbruster  * If this drops it to zero, destroy @blk.
48926f54e9aSMarkus Armbruster  * For convenience, do nothing if @blk is null.
49026f54e9aSMarkus Armbruster  */
49126f54e9aSMarkus Armbruster void blk_unref(BlockBackend *blk)
49226f54e9aSMarkus Armbruster {
49326f54e9aSMarkus Armbruster     if (blk) {
49426f54e9aSMarkus Armbruster         assert(blk->refcnt > 0);
4955ca9d21bSKevin Wolf         if (blk->refcnt > 1) {
4965ca9d21bSKevin Wolf             blk->refcnt--;
4975ca9d21bSKevin Wolf         } else {
4985ca9d21bSKevin Wolf             blk_drain(blk);
4995ca9d21bSKevin Wolf             /* blk_drain() cannot resurrect blk, nobody held a reference */
5005ca9d21bSKevin Wolf             assert(blk->refcnt == 1);
5015ca9d21bSKevin Wolf             blk->refcnt = 0;
50226f54e9aSMarkus Armbruster             blk_delete(blk);
50326f54e9aSMarkus Armbruster         }
50426f54e9aSMarkus Armbruster     }
50526f54e9aSMarkus Armbruster }
50626f54e9aSMarkus Armbruster 
5072cf22d6aSMax Reitz /*
5082cf22d6aSMax Reitz  * Behaves similarly to blk_next() but iterates over all BlockBackends, even the
5092cf22d6aSMax Reitz  * ones which are hidden (i.e. are not referenced by the monitor).
5102cf22d6aSMax Reitz  */
511a429b9b5SKevin Wolf BlockBackend *blk_all_next(BlockBackend *blk)
5122cf22d6aSMax Reitz {
5132cf22d6aSMax Reitz     return blk ? QTAILQ_NEXT(blk, link)
5142cf22d6aSMax Reitz                : QTAILQ_FIRST(&block_backends);
5152cf22d6aSMax Reitz }
5162cf22d6aSMax Reitz 
517d8da3cefSMax Reitz void blk_remove_all_bs(void)
518d8da3cefSMax Reitz {
51974d1b8fcSMax Reitz     BlockBackend *blk = NULL;
520d8da3cefSMax Reitz 
5212cf22d6aSMax Reitz     while ((blk = blk_all_next(blk)) != NULL) {
522d8da3cefSMax Reitz         AioContext *ctx = blk_get_aio_context(blk);
523d8da3cefSMax Reitz 
524d8da3cefSMax Reitz         aio_context_acquire(ctx);
525f21d96d0SKevin Wolf         if (blk->root) {
526d8da3cefSMax Reitz             blk_remove_bs(blk);
527d8da3cefSMax Reitz         }
528d8da3cefSMax Reitz         aio_context_release(ctx);
529d8da3cefSMax Reitz     }
530d8da3cefSMax Reitz }
531d8da3cefSMax Reitz 
53226f54e9aSMarkus Armbruster /*
5339492b0b9SMax Reitz  * Return the monitor-owned BlockBackend after @blk.
53426f54e9aSMarkus Armbruster  * If @blk is null, return the first one.
53526f54e9aSMarkus Armbruster  * Else, return @blk's next sibling, which may be null.
53626f54e9aSMarkus Armbruster  *
53726f54e9aSMarkus Armbruster  * To iterate over all BlockBackends, do
53826f54e9aSMarkus Armbruster  * for (blk = blk_next(NULL); blk; blk = blk_next(blk)) {
53926f54e9aSMarkus Armbruster  *     ...
54026f54e9aSMarkus Armbruster  * }
54126f54e9aSMarkus Armbruster  */
54226f54e9aSMarkus Armbruster BlockBackend *blk_next(BlockBackend *blk)
54326f54e9aSMarkus Armbruster {
5449492b0b9SMax Reitz     return blk ? QTAILQ_NEXT(blk, monitor_link)
5459492b0b9SMax Reitz                : QTAILQ_FIRST(&monitor_block_backends);
54626f54e9aSMarkus Armbruster }
54726f54e9aSMarkus Armbruster 
5487c8eece4SKevin Wolf /* Iterates over all top-level BlockDriverStates, i.e. BDSs that are owned by
5497c8eece4SKevin Wolf  * the monitor or attached to a BlockBackend */
55088be7b4bSKevin Wolf BlockDriverState *bdrv_next(BdrvNextIterator *it)
5517c8eece4SKevin Wolf {
5525e003f17SMax Reitz     BlockDriverState *bs, *old_bs;
5535e003f17SMax Reitz 
5545e003f17SMax Reitz     /* Must be called from the main loop */
5555e003f17SMax Reitz     assert(qemu_get_current_aio_context() == qemu_get_aio_context());
556981f4f57SMax Reitz 
5577c8eece4SKevin Wolf     /* First, return all root nodes of BlockBackends. In order to avoid
5587c8eece4SKevin Wolf      * returning a BDS twice when multiple BBs refer to it, we only return it
5597c8eece4SKevin Wolf      * if the BB is the first one in the parent list of the BDS. */
5607c8eece4SKevin Wolf     if (it->phase == BDRV_NEXT_BACKEND_ROOTS) {
5615e003f17SMax Reitz         BlockBackend *old_blk = it->blk;
5625e003f17SMax Reitz 
5635e003f17SMax Reitz         old_bs = old_blk ? blk_bs(old_blk) : NULL;
5645e003f17SMax Reitz 
565981f4f57SMax Reitz         do {
5667c8eece4SKevin Wolf             it->blk = blk_all_next(it->blk);
56788be7b4bSKevin Wolf             bs = it->blk ? blk_bs(it->blk) : NULL;
56888be7b4bSKevin Wolf         } while (it->blk && (bs == NULL || bdrv_first_blk(bs) != it->blk));
569981f4f57SMax Reitz 
5705e003f17SMax Reitz         if (it->blk) {
5715e003f17SMax Reitz             blk_ref(it->blk);
5725e003f17SMax Reitz         }
5735e003f17SMax Reitz         blk_unref(old_blk);
5745e003f17SMax Reitz 
57588be7b4bSKevin Wolf         if (bs) {
5765e003f17SMax Reitz             bdrv_ref(bs);
5775e003f17SMax Reitz             bdrv_unref(old_bs);
57888be7b4bSKevin Wolf             return bs;
5797c8eece4SKevin Wolf         }
5807c8eece4SKevin Wolf         it->phase = BDRV_NEXT_MONITOR_OWNED;
5815e003f17SMax Reitz     } else {
5825e003f17SMax Reitz         old_bs = it->bs;
5837c8eece4SKevin Wolf     }
5847c8eece4SKevin Wolf 
5857c8eece4SKevin Wolf     /* Then return the monitor-owned BDSes without a BB attached. Ignore all
5867c8eece4SKevin Wolf      * BDSes that are attached to a BlockBackend here; they have been handled
5877c8eece4SKevin Wolf      * by the above block already */
5887c8eece4SKevin Wolf     do {
5897c8eece4SKevin Wolf         it->bs = bdrv_next_monitor_owned(it->bs);
59088be7b4bSKevin Wolf         bs = it->bs;
59188be7b4bSKevin Wolf     } while (bs && bdrv_has_blk(bs));
5927c8eece4SKevin Wolf 
5935e003f17SMax Reitz     if (bs) {
5945e003f17SMax Reitz         bdrv_ref(bs);
5955e003f17SMax Reitz     }
5965e003f17SMax Reitz     bdrv_unref(old_bs);
5975e003f17SMax Reitz 
59888be7b4bSKevin Wolf     return bs;
59988be7b4bSKevin Wolf }
60088be7b4bSKevin Wolf 
6015e003f17SMax Reitz static void bdrv_next_reset(BdrvNextIterator *it)
60288be7b4bSKevin Wolf {
60388be7b4bSKevin Wolf     *it = (BdrvNextIterator) {
60488be7b4bSKevin Wolf         .phase = BDRV_NEXT_BACKEND_ROOTS,
60588be7b4bSKevin Wolf     };
6065e003f17SMax Reitz }
60788be7b4bSKevin Wolf 
6085e003f17SMax Reitz BlockDriverState *bdrv_first(BdrvNextIterator *it)
6095e003f17SMax Reitz {
6105e003f17SMax Reitz     bdrv_next_reset(it);
61188be7b4bSKevin Wolf     return bdrv_next(it);
612981f4f57SMax Reitz }
613981f4f57SMax Reitz 
6145e003f17SMax Reitz /* Must be called when aborting a bdrv_next() iteration before
6155e003f17SMax Reitz  * bdrv_next() returns NULL */
6165e003f17SMax Reitz void bdrv_next_cleanup(BdrvNextIterator *it)
6175e003f17SMax Reitz {
6185e003f17SMax Reitz     /* Must be called from the main loop */
6195e003f17SMax Reitz     assert(qemu_get_current_aio_context() == qemu_get_aio_context());
6205e003f17SMax Reitz 
6215e003f17SMax Reitz     if (it->phase == BDRV_NEXT_BACKEND_ROOTS) {
6225e003f17SMax Reitz         if (it->blk) {
6235e003f17SMax Reitz             bdrv_unref(blk_bs(it->blk));
6245e003f17SMax Reitz             blk_unref(it->blk);
6255e003f17SMax Reitz         }
6265e003f17SMax Reitz     } else {
6275e003f17SMax Reitz         bdrv_unref(it->bs);
6285e003f17SMax Reitz     }
6295e003f17SMax Reitz 
6305e003f17SMax Reitz     bdrv_next_reset(it);
6315e003f17SMax Reitz }
6325e003f17SMax Reitz 
633981f4f57SMax Reitz /*
634e5e78550SMax Reitz  * Add a BlockBackend into the list of backends referenced by the monitor, with
635e5e78550SMax Reitz  * the given @name acting as the handle for the monitor.
636e5e78550SMax Reitz  * Strictly for use by blockdev.c.
637e5e78550SMax Reitz  *
638e5e78550SMax Reitz  * @name must not be null or empty.
639e5e78550SMax Reitz  *
640e5e78550SMax Reitz  * Returns true on success and false on failure. In the latter case, an Error
641e5e78550SMax Reitz  * object is returned through @errp.
642e5e78550SMax Reitz  */
643e5e78550SMax Reitz bool monitor_add_blk(BlockBackend *blk, const char *name, Error **errp)
644e5e78550SMax Reitz {
645e5e78550SMax Reitz     assert(!blk->name);
646e5e78550SMax Reitz     assert(name && name[0]);
647e5e78550SMax Reitz 
648e5e78550SMax Reitz     if (!id_wellformed(name)) {
649e5e78550SMax Reitz         error_setg(errp, "Invalid device name");
650e5e78550SMax Reitz         return false;
651e5e78550SMax Reitz     }
652e5e78550SMax Reitz     if (blk_by_name(name)) {
653e5e78550SMax Reitz         error_setg(errp, "Device with id '%s' already exists", name);
654e5e78550SMax Reitz         return false;
655e5e78550SMax Reitz     }
656e5e78550SMax Reitz     if (bdrv_find_node(name)) {
657e5e78550SMax Reitz         error_setg(errp,
658e5e78550SMax Reitz                    "Device name '%s' conflicts with an existing node name",
659e5e78550SMax Reitz                    name);
660e5e78550SMax Reitz         return false;
661e5e78550SMax Reitz     }
662e5e78550SMax Reitz 
663e5e78550SMax Reitz     blk->name = g_strdup(name);
664e5e78550SMax Reitz     QTAILQ_INSERT_TAIL(&monitor_block_backends, blk, monitor_link);
665e5e78550SMax Reitz     return true;
666e5e78550SMax Reitz }
667e5e78550SMax Reitz 
668e5e78550SMax Reitz /*
669e5e78550SMax Reitz  * Remove a BlockBackend from the list of backends referenced by the monitor.
670e5e78550SMax Reitz  * Strictly for use by blockdev.c.
671e5e78550SMax Reitz  */
672e5e78550SMax Reitz void monitor_remove_blk(BlockBackend *blk)
673e5e78550SMax Reitz {
674e5e78550SMax Reitz     if (!blk->name) {
675e5e78550SMax Reitz         return;
676e5e78550SMax Reitz     }
677e5e78550SMax Reitz 
678e5e78550SMax Reitz     QTAILQ_REMOVE(&monitor_block_backends, blk, monitor_link);
679e5e78550SMax Reitz     g_free(blk->name);
680e5e78550SMax Reitz     blk->name = NULL;
681e5e78550SMax Reitz }
682e5e78550SMax Reitz 
683e5e78550SMax Reitz /*
6847e7d56d9SMarkus Armbruster  * Return @blk's name, a non-null string.
685e5e78550SMax Reitz  * Returns an empty string iff @blk is not referenced by the monitor.
68626f54e9aSMarkus Armbruster  */
6870731a50fSKrzysztof Kozlowski const char *blk_name(const BlockBackend *blk)
68826f54e9aSMarkus Armbruster {
689e5e78550SMax Reitz     return blk->name ?: "";
69026f54e9aSMarkus Armbruster }
69126f54e9aSMarkus Armbruster 
69226f54e9aSMarkus Armbruster /*
69326f54e9aSMarkus Armbruster  * Return the BlockBackend with name @name if it exists, else null.
69426f54e9aSMarkus Armbruster  * @name must not be null.
69526f54e9aSMarkus Armbruster  */
69626f54e9aSMarkus Armbruster BlockBackend *blk_by_name(const char *name)
69726f54e9aSMarkus Armbruster {
69874d1b8fcSMax Reitz     BlockBackend *blk = NULL;
69926f54e9aSMarkus Armbruster 
70026f54e9aSMarkus Armbruster     assert(name);
70174d1b8fcSMax Reitz     while ((blk = blk_next(blk)) != NULL) {
70226f54e9aSMarkus Armbruster         if (!strcmp(name, blk->name)) {
70326f54e9aSMarkus Armbruster             return blk;
70426f54e9aSMarkus Armbruster         }
70526f54e9aSMarkus Armbruster     }
70626f54e9aSMarkus Armbruster     return NULL;
70726f54e9aSMarkus Armbruster }
7087e7d56d9SMarkus Armbruster 
7097e7d56d9SMarkus Armbruster /*
7107e7d56d9SMarkus Armbruster  * Return the BlockDriverState attached to @blk if any, else null.
7117e7d56d9SMarkus Armbruster  */
7127e7d56d9SMarkus Armbruster BlockDriverState *blk_bs(BlockBackend *blk)
7137e7d56d9SMarkus Armbruster {
714f21d96d0SKevin Wolf     return blk->root ? blk->root->bs : NULL;
7157e7d56d9SMarkus Armbruster }
7167e7d56d9SMarkus Armbruster 
7177c8eece4SKevin Wolf static BlockBackend *bdrv_first_blk(BlockDriverState *bs)
718dde33812SKevin Wolf {
719dde33812SKevin Wolf     BdrvChild *child;
720dde33812SKevin Wolf     QLIST_FOREACH(child, &bs->parents, next_parent) {
721bd86fb99SMax Reitz         if (child->klass == &child_root) {
7227c8eece4SKevin Wolf             return child->opaque;
723dde33812SKevin Wolf         }
724dde33812SKevin Wolf     }
725dde33812SKevin Wolf 
7267c8eece4SKevin Wolf     return NULL;
7277c8eece4SKevin Wolf }
7287c8eece4SKevin Wolf 
7297c8eece4SKevin Wolf /*
7307c8eece4SKevin Wolf  * Returns true if @bs has an associated BlockBackend.
7317c8eece4SKevin Wolf  */
7327c8eece4SKevin Wolf bool bdrv_has_blk(BlockDriverState *bs)
7337c8eece4SKevin Wolf {
7347c8eece4SKevin Wolf     return bdrv_first_blk(bs) != NULL;
735dde33812SKevin Wolf }
736dde33812SKevin Wolf 
737dde33812SKevin Wolf /*
738b6c1bae5SKevin Wolf  * Returns true if @bs has only BlockBackends as parents.
739b6c1bae5SKevin Wolf  */
740b6c1bae5SKevin Wolf bool bdrv_is_root_node(BlockDriverState *bs)
741b6c1bae5SKevin Wolf {
742b6c1bae5SKevin Wolf     BdrvChild *c;
743b6c1bae5SKevin Wolf 
744b6c1bae5SKevin Wolf     QLIST_FOREACH(c, &bs->parents, next_parent) {
745bd86fb99SMax Reitz         if (c->klass != &child_root) {
746b6c1bae5SKevin Wolf             return false;
747b6c1bae5SKevin Wolf         }
748b6c1bae5SKevin Wolf     }
749b6c1bae5SKevin Wolf 
750b6c1bae5SKevin Wolf     return true;
751b6c1bae5SKevin Wolf }
752b6c1bae5SKevin Wolf 
753b6c1bae5SKevin Wolf /*
75418e46a03SMarkus Armbruster  * Return @blk's DriveInfo if any, else null.
75518e46a03SMarkus Armbruster  */
75618e46a03SMarkus Armbruster DriveInfo *blk_legacy_dinfo(BlockBackend *blk)
75718e46a03SMarkus Armbruster {
75818e46a03SMarkus Armbruster     return blk->legacy_dinfo;
75918e46a03SMarkus Armbruster }
76018e46a03SMarkus Armbruster 
76118e46a03SMarkus Armbruster /*
76218e46a03SMarkus Armbruster  * Set @blk's DriveInfo to @dinfo, and return it.
76318e46a03SMarkus Armbruster  * @blk must not have a DriveInfo set already.
76418e46a03SMarkus Armbruster  * No other BlockBackend may have the same DriveInfo set.
76518e46a03SMarkus Armbruster  */
76618e46a03SMarkus Armbruster DriveInfo *blk_set_legacy_dinfo(BlockBackend *blk, DriveInfo *dinfo)
76718e46a03SMarkus Armbruster {
76818e46a03SMarkus Armbruster     assert(!blk->legacy_dinfo);
76918e46a03SMarkus Armbruster     return blk->legacy_dinfo = dinfo;
77018e46a03SMarkus Armbruster }
77118e46a03SMarkus Armbruster 
77218e46a03SMarkus Armbruster /*
77318e46a03SMarkus Armbruster  * Return the BlockBackend with DriveInfo @dinfo.
77418e46a03SMarkus Armbruster  * It must exist.
77518e46a03SMarkus Armbruster  */
77618e46a03SMarkus Armbruster BlockBackend *blk_by_legacy_dinfo(DriveInfo *dinfo)
77718e46a03SMarkus Armbruster {
77874d1b8fcSMax Reitz     BlockBackend *blk = NULL;
77918e46a03SMarkus Armbruster 
78074d1b8fcSMax Reitz     while ((blk = blk_next(blk)) != NULL) {
78118e46a03SMarkus Armbruster         if (blk->legacy_dinfo == dinfo) {
78218e46a03SMarkus Armbruster             return blk;
78318e46a03SMarkus Armbruster         }
78418e46a03SMarkus Armbruster     }
78518e46a03SMarkus Armbruster     abort();
78618e46a03SMarkus Armbruster }
78718e46a03SMarkus Armbruster 
78818e46a03SMarkus Armbruster /*
789f2cd875dSKevin Wolf  * Returns a pointer to the publicly accessible fields of @blk.
790f2cd875dSKevin Wolf  */
791f2cd875dSKevin Wolf BlockBackendPublic *blk_get_public(BlockBackend *blk)
792f2cd875dSKevin Wolf {
793f2cd875dSKevin Wolf     return &blk->public;
794f2cd875dSKevin Wolf }
795f2cd875dSKevin Wolf 
796f2cd875dSKevin Wolf /*
797f2cd875dSKevin Wolf  * Returns a BlockBackend given the associated @public fields.
798f2cd875dSKevin Wolf  */
799f2cd875dSKevin Wolf BlockBackend *blk_by_public(BlockBackendPublic *public)
800f2cd875dSKevin Wolf {
801f2cd875dSKevin Wolf     return container_of(public, BlockBackend, public);
802f2cd875dSKevin Wolf }
803f2cd875dSKevin Wolf 
804f2cd875dSKevin Wolf /*
8051c95f7e1SMax Reitz  * Disassociates the currently associated BlockDriverState from @blk.
8061c95f7e1SMax Reitz  */
8071c95f7e1SMax Reitz void blk_remove_bs(BlockBackend *blk)
8081c95f7e1SMax Reitz {
809c89bcf3aSAlberto Garcia     ThrottleGroupMember *tgm = &blk->public.throttle_group_member;
810632a7735SZhengui     BlockDriverState *bs;
811e6cada92SGreg Kurz     BdrvChild *root;
812022cdc9fSManos Pitsidianakis 
8133301f6c6SMax Reitz     notifier_list_notify(&blk->remove_bs_notifiers, blk);
814c89bcf3aSAlberto Garcia     if (tgm->throttle_state) {
815632a7735SZhengui         bs = blk_bs(blk);
816632a7735SZhengui         bdrv_drained_begin(bs);
817c89bcf3aSAlberto Garcia         throttle_group_detach_aio_context(tgm);
818c89bcf3aSAlberto Garcia         throttle_group_attach_aio_context(tgm, qemu_get_aio_context());
819632a7735SZhengui         bdrv_drained_end(bs);
8207ca7f0f6SKevin Wolf     }
8213301f6c6SMax Reitz 
8221c95f7e1SMax Reitz     blk_update_root_state(blk);
8231c95f7e1SMax Reitz 
824f45280cbSGreg Kurz     /* bdrv_root_unref_child() will cause blk->root to become stale and may
825f45280cbSGreg Kurz      * switch to a completion coroutine later on. Let's drain all I/O here
826f45280cbSGreg Kurz      * to avoid that and a potential QEMU crash.
827f45280cbSGreg Kurz      */
828f45280cbSGreg Kurz     blk_drain(blk);
829e6cada92SGreg Kurz     root = blk->root;
830f21d96d0SKevin Wolf     blk->root = NULL;
831e6cada92SGreg Kurz     bdrv_root_unref_child(root);
8321c95f7e1SMax Reitz }
8331c95f7e1SMax Reitz 
8341c95f7e1SMax Reitz /*
8350c3c36d6SMax Reitz  * Associates a new BlockDriverState with @blk.
8360c3c36d6SMax Reitz  */
837d7086422SKevin Wolf int blk_insert_bs(BlockBackend *blk, BlockDriverState *bs, Error **errp)
8380c3c36d6SMax Reitz {
839c89bcf3aSAlberto Garcia     ThrottleGroupMember *tgm = &blk->public.throttle_group_member;
840b441dc71SAlberto Garcia     bdrv_ref(bs);
8411f38f04eSMax Reitz     blk->root = bdrv_root_attach_child(bs, "root", &child_root,
8421f38f04eSMax Reitz                                        BDRV_CHILD_FILTERED | BDRV_CHILD_PRIMARY,
8431f38f04eSMax Reitz                                        blk->ctx, blk->perm, blk->shared_perm,
8441f38f04eSMax Reitz                                        blk, errp);
845d7086422SKevin Wolf     if (blk->root == NULL) {
846d7086422SKevin Wolf         return -EPERM;
847d7086422SKevin Wolf     }
8483301f6c6SMax Reitz 
8493301f6c6SMax Reitz     notifier_list_notify(&blk->insert_bs_notifiers, blk);
850c89bcf3aSAlberto Garcia     if (tgm->throttle_state) {
851c89bcf3aSAlberto Garcia         throttle_group_detach_aio_context(tgm);
852c89bcf3aSAlberto Garcia         throttle_group_attach_aio_context(tgm, bdrv_get_aio_context(bs));
8537ca7f0f6SKevin Wolf     }
854d7086422SKevin Wolf 
855d7086422SKevin Wolf     return 0;
8560c3c36d6SMax Reitz }
8570c3c36d6SMax Reitz 
858981776b3SKevin Wolf /*
859981776b3SKevin Wolf  * Sets the permission bitmasks that the user of the BlockBackend needs.
860981776b3SKevin Wolf  */
861981776b3SKevin Wolf int blk_set_perm(BlockBackend *blk, uint64_t perm, uint64_t shared_perm,
862981776b3SKevin Wolf                  Error **errp)
863981776b3SKevin Wolf {
864981776b3SKevin Wolf     int ret;
865981776b3SKevin Wolf 
866d35ff5e6SKevin Wolf     if (blk->root && !blk->disable_perm) {
867981776b3SKevin Wolf         ret = bdrv_child_try_set_perm(blk->root, perm, shared_perm, errp);
868981776b3SKevin Wolf         if (ret < 0) {
869981776b3SKevin Wolf             return ret;
870981776b3SKevin Wolf         }
871981776b3SKevin Wolf     }
872981776b3SKevin Wolf 
873981776b3SKevin Wolf     blk->perm = perm;
874981776b3SKevin Wolf     blk->shared_perm = shared_perm;
875981776b3SKevin Wolf 
876981776b3SKevin Wolf     return 0;
877981776b3SKevin Wolf }
878981776b3SKevin Wolf 
879887354bdSKevin Wolf void blk_get_perm(BlockBackend *blk, uint64_t *perm, uint64_t *shared_perm)
880887354bdSKevin Wolf {
881887354bdSKevin Wolf     *perm = blk->perm;
882887354bdSKevin Wolf     *shared_perm = blk->shared_perm;
883887354bdSKevin Wolf }
884887354bdSKevin Wolf 
885d09ea2d2SThomas Huth /*
886d09ea2d2SThomas Huth  * Attach device model @dev to @blk.
887d09ea2d2SThomas Huth  * Return 0 on success, -EBUSY when a device model is attached already.
888d09ea2d2SThomas Huth  */
889d09ea2d2SThomas Huth int blk_attach_dev(BlockBackend *blk, DeviceState *dev)
890a7f53e26SMarkus Armbruster {
891a7f53e26SMarkus Armbruster     if (blk->dev) {
892a7f53e26SMarkus Armbruster         return -EBUSY;
893a7f53e26SMarkus Armbruster     }
894d35ff5e6SKevin Wolf 
895d35ff5e6SKevin Wolf     /* While migration is still incoming, we don't need to apply the
896d35ff5e6SKevin Wolf      * permissions of guest device BlockBackends. We might still have a block
897d35ff5e6SKevin Wolf      * job or NBD server writing to the image for storage migration. */
898d35ff5e6SKevin Wolf     if (runstate_check(RUN_STATE_INMIGRATE)) {
899d35ff5e6SKevin Wolf         blk->disable_perm = true;
900d35ff5e6SKevin Wolf     }
901d35ff5e6SKevin Wolf 
90284ebe375SMarkus Armbruster     blk_ref(blk);
903a7f53e26SMarkus Armbruster     blk->dev = dev;
904373340b2SMax Reitz     blk_iostatus_reset(blk);
905d35ff5e6SKevin Wolf 
906a7f53e26SMarkus Armbruster     return 0;
907a7f53e26SMarkus Armbruster }
908a7f53e26SMarkus Armbruster 
909a7f53e26SMarkus Armbruster /*
910a7f53e26SMarkus Armbruster  * Detach device model @dev from @blk.
911a7f53e26SMarkus Armbruster  * @dev must be currently attached to @blk.
912a7f53e26SMarkus Armbruster  */
913d09ea2d2SThomas Huth void blk_detach_dev(BlockBackend *blk, DeviceState *dev)
914a7f53e26SMarkus Armbruster {
915a7f53e26SMarkus Armbruster     assert(blk->dev == dev);
916a7f53e26SMarkus Armbruster     blk->dev = NULL;
917a7f53e26SMarkus Armbruster     blk->dev_ops = NULL;
918a7f53e26SMarkus Armbruster     blk->dev_opaque = NULL;
91968e9ec01SMax Reitz     blk->guest_block_size = 512;
920981776b3SKevin Wolf     blk_set_perm(blk, 0, BLK_PERM_ALL, &error_abort);
92184ebe375SMarkus Armbruster     blk_unref(blk);
922a7f53e26SMarkus Armbruster }
923a7f53e26SMarkus Armbruster 
924a7f53e26SMarkus Armbruster /*
925a7f53e26SMarkus Armbruster  * Return the device model attached to @blk if any, else null.
926a7f53e26SMarkus Armbruster  */
927d09ea2d2SThomas Huth DeviceState *blk_get_attached_dev(BlockBackend *blk)
928a7f53e26SMarkus Armbruster {
929a7f53e26SMarkus Armbruster     return blk->dev;
930a7f53e26SMarkus Armbruster }
931a7f53e26SMarkus Armbruster 
9322d76e724SKevin Wolf /* Return the qdev ID, or if no ID is assigned the QOM path, of the block
9332d76e724SKevin Wolf  * device attached to the BlockBackend. */
93477beef83SKevin Wolf char *blk_get_attached_dev_id(BlockBackend *blk)
9352d76e724SKevin Wolf {
936d09ea2d2SThomas Huth     DeviceState *dev = blk->dev;
9372d76e724SKevin Wolf 
9382d76e724SKevin Wolf     if (!dev) {
9392d76e724SKevin Wolf         return g_strdup("");
9402d76e724SKevin Wolf     } else if (dev->id) {
9412d76e724SKevin Wolf         return g_strdup(dev->id);
9422d76e724SKevin Wolf     }
943602414d1SLiam Merwick 
944602414d1SLiam Merwick     return object_get_canonical_path(OBJECT(dev)) ?: g_strdup("");
9452d76e724SKevin Wolf }
9462d76e724SKevin Wolf 
947a7f53e26SMarkus Armbruster /*
9481c89e1faSKevin Wolf  * Return the BlockBackend which has the device model @dev attached if it
9491c89e1faSKevin Wolf  * exists, else null.
9501c89e1faSKevin Wolf  *
9511c89e1faSKevin Wolf  * @dev must not be null.
9521c89e1faSKevin Wolf  */
9531c89e1faSKevin Wolf BlockBackend *blk_by_dev(void *dev)
9541c89e1faSKevin Wolf {
9551c89e1faSKevin Wolf     BlockBackend *blk = NULL;
9561c89e1faSKevin Wolf 
9571c89e1faSKevin Wolf     assert(dev != NULL);
9581c89e1faSKevin Wolf     while ((blk = blk_all_next(blk)) != NULL) {
9591c89e1faSKevin Wolf         if (blk->dev == dev) {
9601c89e1faSKevin Wolf             return blk;
9611c89e1faSKevin Wolf         }
9621c89e1faSKevin Wolf     }
9631c89e1faSKevin Wolf     return NULL;
9641c89e1faSKevin Wolf }
9651c89e1faSKevin Wolf 
9661c89e1faSKevin Wolf /*
967a7f53e26SMarkus Armbruster  * Set @blk's device model callbacks to @ops.
968a7f53e26SMarkus Armbruster  * @opaque is the opaque argument to pass to the callbacks.
969a7f53e26SMarkus Armbruster  * This is for use by device models.
970a7f53e26SMarkus Armbruster  */
971a7f53e26SMarkus Armbruster void blk_set_dev_ops(BlockBackend *blk, const BlockDevOps *ops,
972a7f53e26SMarkus Armbruster                      void *opaque)
973a7f53e26SMarkus Armbruster {
974a7f53e26SMarkus Armbruster     blk->dev_ops = ops;
975a7f53e26SMarkus Armbruster     blk->dev_opaque = opaque;
976f4d9cc88SJohn Snow 
977f4d9cc88SJohn Snow     /* Are we currently quiesced? Should we enforce this right now? */
978f4d9cc88SJohn Snow     if (blk->quiesce_counter && ops->drained_begin) {
979f4d9cc88SJohn Snow         ops->drained_begin(opaque);
980f4d9cc88SJohn Snow     }
981a7f53e26SMarkus Armbruster }
982a7f53e26SMarkus Armbruster 
983a7f53e26SMarkus Armbruster /*
984a7f53e26SMarkus Armbruster  * Notify @blk's attached device model of media change.
98539829a01SKevin Wolf  *
98639829a01SKevin Wolf  * If @load is true, notify of media load. This action can fail, meaning that
98739829a01SKevin Wolf  * the medium cannot be loaded. @errp is set then.
98839829a01SKevin Wolf  *
98939829a01SKevin Wolf  * If @load is false, notify of media eject. This can never fail.
99039829a01SKevin Wolf  *
991a7f53e26SMarkus Armbruster  * Also send DEVICE_TRAY_MOVED events as appropriate.
992a7f53e26SMarkus Armbruster  */
99339829a01SKevin Wolf void blk_dev_change_media_cb(BlockBackend *blk, bool load, Error **errp)
994a7f53e26SMarkus Armbruster {
995a7f53e26SMarkus Armbruster     if (blk->dev_ops && blk->dev_ops->change_media_cb) {
996f1f57066SMax Reitz         bool tray_was_open, tray_is_open;
99739829a01SKevin Wolf         Error *local_err = NULL;
998a7f53e26SMarkus Armbruster 
999f1f57066SMax Reitz         tray_was_open = blk_dev_is_tray_open(blk);
100039829a01SKevin Wolf         blk->dev_ops->change_media_cb(blk->dev_opaque, load, &local_err);
100139829a01SKevin Wolf         if (local_err) {
100239829a01SKevin Wolf             assert(load == true);
100339829a01SKevin Wolf             error_propagate(errp, local_err);
100439829a01SKevin Wolf             return;
100539829a01SKevin Wolf         }
1006f1f57066SMax Reitz         tray_is_open = blk_dev_is_tray_open(blk);
1007f1f57066SMax Reitz 
1008f1f57066SMax Reitz         if (tray_was_open != tray_is_open) {
10092d76e724SKevin Wolf             char *id = blk_get_attached_dev_id(blk);
10103ab72385SPeter Xu             qapi_event_send_device_tray_moved(blk_name(blk), id, tray_is_open);
10112d76e724SKevin Wolf             g_free(id);
1012a7f53e26SMarkus Armbruster         }
1013a7f53e26SMarkus Armbruster     }
1014a7f53e26SMarkus Armbruster }
1015a7f53e26SMarkus Armbruster 
10165c8cab48SKevin Wolf static void blk_root_change_media(BdrvChild *child, bool load)
10175c8cab48SKevin Wolf {
101839829a01SKevin Wolf     blk_dev_change_media_cb(child->opaque, load, NULL);
10195c8cab48SKevin Wolf }
10205c8cab48SKevin Wolf 
1021a7f53e26SMarkus Armbruster /*
1022a7f53e26SMarkus Armbruster  * Does @blk's attached device model have removable media?
1023a7f53e26SMarkus Armbruster  * %true if no device model is attached.
1024a7f53e26SMarkus Armbruster  */
1025a7f53e26SMarkus Armbruster bool blk_dev_has_removable_media(BlockBackend *blk)
1026a7f53e26SMarkus Armbruster {
1027a7f53e26SMarkus Armbruster     return !blk->dev || (blk->dev_ops && blk->dev_ops->change_media_cb);
1028a7f53e26SMarkus Armbruster }
1029a7f53e26SMarkus Armbruster 
1030a7f53e26SMarkus Armbruster /*
10318f3a73bcSMax Reitz  * Does @blk's attached device model have a tray?
10328f3a73bcSMax Reitz  */
10338f3a73bcSMax Reitz bool blk_dev_has_tray(BlockBackend *blk)
10348f3a73bcSMax Reitz {
10358f3a73bcSMax Reitz     return blk->dev_ops && blk->dev_ops->is_tray_open;
10368f3a73bcSMax Reitz }
10378f3a73bcSMax Reitz 
10388f3a73bcSMax Reitz /*
1039a7f53e26SMarkus Armbruster  * Notify @blk's attached device model of a media eject request.
1040a7f53e26SMarkus Armbruster  * If @force is true, the medium is about to be yanked out forcefully.
1041a7f53e26SMarkus Armbruster  */
1042a7f53e26SMarkus Armbruster void blk_dev_eject_request(BlockBackend *blk, bool force)
1043a7f53e26SMarkus Armbruster {
1044a7f53e26SMarkus Armbruster     if (blk->dev_ops && blk->dev_ops->eject_request_cb) {
1045a7f53e26SMarkus Armbruster         blk->dev_ops->eject_request_cb(blk->dev_opaque, force);
1046a7f53e26SMarkus Armbruster     }
1047a7f53e26SMarkus Armbruster }
1048a7f53e26SMarkus Armbruster 
1049a7f53e26SMarkus Armbruster /*
1050a7f53e26SMarkus Armbruster  * Does @blk's attached device model have a tray, and is it open?
1051a7f53e26SMarkus Armbruster  */
1052a7f53e26SMarkus Armbruster bool blk_dev_is_tray_open(BlockBackend *blk)
1053a7f53e26SMarkus Armbruster {
10548f3a73bcSMax Reitz     if (blk_dev_has_tray(blk)) {
1055a7f53e26SMarkus Armbruster         return blk->dev_ops->is_tray_open(blk->dev_opaque);
1056a7f53e26SMarkus Armbruster     }
1057a7f53e26SMarkus Armbruster     return false;
1058a7f53e26SMarkus Armbruster }
1059a7f53e26SMarkus Armbruster 
1060a7f53e26SMarkus Armbruster /*
1061a7f53e26SMarkus Armbruster  * Does @blk's attached device model have the medium locked?
1062a7f53e26SMarkus Armbruster  * %false if the device model has no such lock.
1063a7f53e26SMarkus Armbruster  */
1064a7f53e26SMarkus Armbruster bool blk_dev_is_medium_locked(BlockBackend *blk)
1065a7f53e26SMarkus Armbruster {
1066a7f53e26SMarkus Armbruster     if (blk->dev_ops && blk->dev_ops->is_medium_locked) {
1067a7f53e26SMarkus Armbruster         return blk->dev_ops->is_medium_locked(blk->dev_opaque);
1068a7f53e26SMarkus Armbruster     }
1069a7f53e26SMarkus Armbruster     return false;
1070a7f53e26SMarkus Armbruster }
1071a7f53e26SMarkus Armbruster 
1072a7f53e26SMarkus Armbruster /*
1073a7f53e26SMarkus Armbruster  * Notify @blk's attached device model of a backend size change.
1074a7f53e26SMarkus Armbruster  */
10755c8cab48SKevin Wolf static void blk_root_resize(BdrvChild *child)
1076a7f53e26SMarkus Armbruster {
10775c8cab48SKevin Wolf     BlockBackend *blk = child->opaque;
10785c8cab48SKevin Wolf 
1079a7f53e26SMarkus Armbruster     if (blk->dev_ops && blk->dev_ops->resize_cb) {
1080a7f53e26SMarkus Armbruster         blk->dev_ops->resize_cb(blk->dev_opaque);
1081a7f53e26SMarkus Armbruster     }
1082a7f53e26SMarkus Armbruster }
1083a7f53e26SMarkus Armbruster 
10844be74634SMarkus Armbruster void blk_iostatus_enable(BlockBackend *blk)
10854be74634SMarkus Armbruster {
1086373340b2SMax Reitz     blk->iostatus_enabled = true;
1087373340b2SMax Reitz     blk->iostatus = BLOCK_DEVICE_IO_STATUS_OK;
1088373340b2SMax Reitz }
1089373340b2SMax Reitz 
1090373340b2SMax Reitz /* The I/O status is only enabled if the drive explicitly
1091373340b2SMax Reitz  * enables it _and_ the VM is configured to stop on errors */
1092373340b2SMax Reitz bool blk_iostatus_is_enabled(const BlockBackend *blk)
1093373340b2SMax Reitz {
1094373340b2SMax Reitz     return (blk->iostatus_enabled &&
1095373340b2SMax Reitz            (blk->on_write_error == BLOCKDEV_ON_ERROR_ENOSPC ||
1096373340b2SMax Reitz             blk->on_write_error == BLOCKDEV_ON_ERROR_STOP   ||
1097373340b2SMax Reitz             blk->on_read_error == BLOCKDEV_ON_ERROR_STOP));
1098373340b2SMax Reitz }
1099373340b2SMax Reitz 
1100373340b2SMax Reitz BlockDeviceIoStatus blk_iostatus(const BlockBackend *blk)
1101373340b2SMax Reitz {
1102373340b2SMax Reitz     return blk->iostatus;
1103373340b2SMax Reitz }
1104373340b2SMax Reitz 
1105373340b2SMax Reitz void blk_iostatus_disable(BlockBackend *blk)
1106373340b2SMax Reitz {
1107373340b2SMax Reitz     blk->iostatus_enabled = false;
1108373340b2SMax Reitz }
1109373340b2SMax Reitz 
1110373340b2SMax Reitz void blk_iostatus_reset(BlockBackend *blk)
1111373340b2SMax Reitz {
1112373340b2SMax Reitz     if (blk_iostatus_is_enabled(blk)) {
1113373340b2SMax Reitz         blk->iostatus = BLOCK_DEVICE_IO_STATUS_OK;
1114373340b2SMax Reitz     }
1115373340b2SMax Reitz }
1116373340b2SMax Reitz 
1117373340b2SMax Reitz void blk_iostatus_set_err(BlockBackend *blk, int error)
1118373340b2SMax Reitz {
1119373340b2SMax Reitz     assert(blk_iostatus_is_enabled(blk));
1120373340b2SMax Reitz     if (blk->iostatus == BLOCK_DEVICE_IO_STATUS_OK) {
1121373340b2SMax Reitz         blk->iostatus = error == ENOSPC ? BLOCK_DEVICE_IO_STATUS_NOSPACE :
1122373340b2SMax Reitz                                           BLOCK_DEVICE_IO_STATUS_FAILED;
1123373340b2SMax Reitz     }
11244be74634SMarkus Armbruster }
11254be74634SMarkus Armbruster 
1126c10c9d96SKevin Wolf void blk_set_allow_write_beyond_eof(BlockBackend *blk, bool allow)
1127c10c9d96SKevin Wolf {
1128c10c9d96SKevin Wolf     blk->allow_write_beyond_eof = allow;
1129c10c9d96SKevin Wolf }
1130c10c9d96SKevin Wolf 
1131980b0f94SKevin Wolf void blk_set_allow_aio_context_change(BlockBackend *blk, bool allow)
1132980b0f94SKevin Wolf {
1133980b0f94SKevin Wolf     blk->allow_aio_context_change = allow;
1134980b0f94SKevin Wolf }
1135980b0f94SKevin Wolf 
1136cf312932SKevin Wolf void blk_set_disable_request_queuing(BlockBackend *blk, bool disable)
1137cf312932SKevin Wolf {
1138cf312932SKevin Wolf     blk->disable_request_queuing = disable;
1139cf312932SKevin Wolf }
1140cf312932SKevin Wolf 
1141e7f7d676SMax Reitz static int blk_check_byte_request(BlockBackend *blk, int64_t offset,
1142e7f7d676SMax Reitz                                   size_t size)
1143e7f7d676SMax Reitz {
1144e7f7d676SMax Reitz     int64_t len;
1145e7f7d676SMax Reitz 
1146e7f7d676SMax Reitz     if (size > INT_MAX) {
1147e7f7d676SMax Reitz         return -EIO;
1148e7f7d676SMax Reitz     }
1149e7f7d676SMax Reitz 
1150c09ba36cSMax Reitz     if (!blk_is_available(blk)) {
1151e7f7d676SMax Reitz         return -ENOMEDIUM;
1152e7f7d676SMax Reitz     }
1153e7f7d676SMax Reitz 
1154c10c9d96SKevin Wolf     if (offset < 0) {
1155c10c9d96SKevin Wolf         return -EIO;
1156c10c9d96SKevin Wolf     }
1157c10c9d96SKevin Wolf 
1158c10c9d96SKevin Wolf     if (!blk->allow_write_beyond_eof) {
1159e7f7d676SMax Reitz         len = blk_getlength(blk);
1160e7f7d676SMax Reitz         if (len < 0) {
1161e7f7d676SMax Reitz             return len;
1162e7f7d676SMax Reitz         }
1163e7f7d676SMax Reitz 
1164e7f7d676SMax Reitz         if (offset > len || len - offset < size) {
1165e7f7d676SMax Reitz             return -EIO;
1166e7f7d676SMax Reitz         }
1167c10c9d96SKevin Wolf     }
1168e7f7d676SMax Reitz 
1169e7f7d676SMax Reitz     return 0;
1170e7f7d676SMax Reitz }
1171e7f7d676SMax Reitz 
11727f16476fSKevin Wolf /* To be called between exactly one pair of blk_inc/dec_in_flight() */
1173cf312932SKevin Wolf static void coroutine_fn blk_wait_while_drained(BlockBackend *blk)
1174cf312932SKevin Wolf {
11757f16476fSKevin Wolf     assert(blk->in_flight > 0);
11767f16476fSKevin Wolf 
1177cf312932SKevin Wolf     if (blk->quiesce_counter && !blk->disable_request_queuing) {
11787f16476fSKevin Wolf         blk_dec_in_flight(blk);
1179cf312932SKevin Wolf         qemu_co_queue_wait(&blk->queued_requests, NULL);
11807f16476fSKevin Wolf         blk_inc_in_flight(blk);
1181cf312932SKevin Wolf     }
1182cf312932SKevin Wolf }
1183cf312932SKevin Wolf 
1184fbb92b67SKevin Wolf /* To be called between exactly one pair of blk_inc/dec_in_flight() */
1185fbb92b67SKevin Wolf static int coroutine_fn
1186fbb92b67SKevin Wolf blk_do_preadv(BlockBackend *blk, int64_t offset, unsigned int bytes,
1187fbb92b67SKevin Wolf               QEMUIOVector *qiov, BdrvRequestFlags flags)
11884be74634SMarkus Armbruster {
11891e98fefdSKevin Wolf     int ret;
1190cf312932SKevin Wolf     BlockDriverState *bs;
11911e98fefdSKevin Wolf 
1192cf312932SKevin Wolf     blk_wait_while_drained(blk);
1193cf312932SKevin Wolf 
1194cf312932SKevin Wolf     /* Call blk_bs() only after waiting, the graph may have changed */
1195cf312932SKevin Wolf     bs = blk_bs(blk);
119699723548SPaolo Bonzini     trace_blk_co_preadv(blk, bs, offset, bytes, flags);
11971e98fefdSKevin Wolf 
11981e98fefdSKevin Wolf     ret = blk_check_byte_request(blk, offset, bytes);
1199e7f7d676SMax Reitz     if (ret < 0) {
1200e7f7d676SMax Reitz         return ret;
1201e7f7d676SMax Reitz     }
1202e7f7d676SMax Reitz 
120399723548SPaolo Bonzini     bdrv_inc_in_flight(bs);
120499723548SPaolo Bonzini 
1205441565b2SKevin Wolf     /* throttling disk I/O */
1206022cdc9fSManos Pitsidianakis     if (blk->public.throttle_group_member.throttle_state) {
1207022cdc9fSManos Pitsidianakis         throttle_group_co_io_limits_intercept(&blk->public.throttle_group_member,
1208022cdc9fSManos Pitsidianakis                 bytes, false);
1209441565b2SKevin Wolf     }
1210441565b2SKevin Wolf 
121199723548SPaolo Bonzini     ret = bdrv_co_preadv(blk->root, offset, bytes, qiov, flags);
121299723548SPaolo Bonzini     bdrv_dec_in_flight(bs);
121399723548SPaolo Bonzini     return ret;
12141bf1cbc9SKevin Wolf }
12151bf1cbc9SKevin Wolf 
1216fbb92b67SKevin Wolf int coroutine_fn blk_co_preadv(BlockBackend *blk, int64_t offset,
1217fbb92b67SKevin Wolf                                unsigned int bytes, QEMUIOVector *qiov,
1218fbb92b67SKevin Wolf                                BdrvRequestFlags flags)
1219fbb92b67SKevin Wolf {
1220fbb92b67SKevin Wolf     int ret;
1221fbb92b67SKevin Wolf 
1222fbb92b67SKevin Wolf     blk_inc_in_flight(blk);
1223fbb92b67SKevin Wolf     ret = blk_do_preadv(blk, offset, bytes, qiov, flags);
1224fbb92b67SKevin Wolf     blk_dec_in_flight(blk);
1225fbb92b67SKevin Wolf 
1226fbb92b67SKevin Wolf     return ret;
1227fbb92b67SKevin Wolf }
1228fbb92b67SKevin Wolf 
1229fbb92b67SKevin Wolf /* To be called between exactly one pair of blk_inc/dec_in_flight() */
1230fbb92b67SKevin Wolf static int coroutine_fn
1231fbb92b67SKevin Wolf blk_do_pwritev_part(BlockBackend *blk, int64_t offset, unsigned int bytes,
1232b3016864SVladimir Sementsov-Ogievskiy                     QEMUIOVector *qiov, size_t qiov_offset,
1233a8823a3bSKevin Wolf                     BdrvRequestFlags flags)
1234a8823a3bSKevin Wolf {
1235bfd18d1eSKevin Wolf     int ret;
1236cf312932SKevin Wolf     BlockDriverState *bs;
1237bfd18d1eSKevin Wolf 
1238cf312932SKevin Wolf     blk_wait_while_drained(blk);
1239cf312932SKevin Wolf 
1240cf312932SKevin Wolf     /* Call blk_bs() only after waiting, the graph may have changed */
1241cf312932SKevin Wolf     bs = blk_bs(blk);
124299723548SPaolo Bonzini     trace_blk_co_pwritev(blk, bs, offset, bytes, flags);
12431e98fefdSKevin Wolf 
1244bfd18d1eSKevin Wolf     ret = blk_check_byte_request(blk, offset, bytes);
1245a8823a3bSKevin Wolf     if (ret < 0) {
1246a8823a3bSKevin Wolf         return ret;
1247a8823a3bSKevin Wolf     }
1248a8823a3bSKevin Wolf 
124999723548SPaolo Bonzini     bdrv_inc_in_flight(bs);
1250441565b2SKevin Wolf     /* throttling disk I/O */
1251022cdc9fSManos Pitsidianakis     if (blk->public.throttle_group_member.throttle_state) {
1252022cdc9fSManos Pitsidianakis         throttle_group_co_io_limits_intercept(&blk->public.throttle_group_member,
1253022cdc9fSManos Pitsidianakis                 bytes, true);
1254441565b2SKevin Wolf     }
1255441565b2SKevin Wolf 
1256bfd18d1eSKevin Wolf     if (!blk->enable_write_cache) {
1257bfd18d1eSKevin Wolf         flags |= BDRV_REQ_FUA;
1258bfd18d1eSKevin Wolf     }
1259bfd18d1eSKevin Wolf 
1260b3016864SVladimir Sementsov-Ogievskiy     ret = bdrv_co_pwritev_part(blk->root, offset, bytes, qiov, qiov_offset,
1261b3016864SVladimir Sementsov-Ogievskiy                                flags);
126299723548SPaolo Bonzini     bdrv_dec_in_flight(bs);
126399723548SPaolo Bonzini     return ret;
1264a8823a3bSKevin Wolf }
1265a8823a3bSKevin Wolf 
1266fbb92b67SKevin Wolf int coroutine_fn blk_co_pwritev_part(BlockBackend *blk, int64_t offset,
1267fbb92b67SKevin Wolf                                      unsigned int bytes,
1268fbb92b67SKevin Wolf                                      QEMUIOVector *qiov, size_t qiov_offset,
1269fbb92b67SKevin Wolf                                      BdrvRequestFlags flags)
1270fbb92b67SKevin Wolf {
1271fbb92b67SKevin Wolf     int ret;
1272fbb92b67SKevin Wolf 
1273fbb92b67SKevin Wolf     blk_inc_in_flight(blk);
1274fbb92b67SKevin Wolf     ret = blk_do_pwritev_part(blk, offset, bytes, qiov, qiov_offset, flags);
1275fbb92b67SKevin Wolf     blk_dec_in_flight(blk);
1276fbb92b67SKevin Wolf 
1277fbb92b67SKevin Wolf     return ret;
1278fbb92b67SKevin Wolf }
1279fbb92b67SKevin Wolf 
1280b3016864SVladimir Sementsov-Ogievskiy int coroutine_fn blk_co_pwritev(BlockBackend *blk, int64_t offset,
1281b3016864SVladimir Sementsov-Ogievskiy                                 unsigned int bytes, QEMUIOVector *qiov,
1282b3016864SVladimir Sementsov-Ogievskiy                                 BdrvRequestFlags flags)
1283b3016864SVladimir Sementsov-Ogievskiy {
1284b3016864SVladimir Sementsov-Ogievskiy     return blk_co_pwritev_part(blk, offset, bytes, qiov, 0, flags);
1285b3016864SVladimir Sementsov-Ogievskiy }
1286b3016864SVladimir Sementsov-Ogievskiy 
12871bf1cbc9SKevin Wolf typedef struct BlkRwCo {
12881bf1cbc9SKevin Wolf     BlockBackend *blk;
12891bf1cbc9SKevin Wolf     int64_t offset;
1290c060332cSDeepa Srinivasan     void *iobuf;
12911bf1cbc9SKevin Wolf     int ret;
12921bf1cbc9SKevin Wolf     BdrvRequestFlags flags;
12931bf1cbc9SKevin Wolf } BlkRwCo;
12941bf1cbc9SKevin Wolf 
12951bf1cbc9SKevin Wolf static void blk_read_entry(void *opaque)
12961bf1cbc9SKevin Wolf {
12971bf1cbc9SKevin Wolf     BlkRwCo *rwco = opaque;
1298c060332cSDeepa Srinivasan     QEMUIOVector *qiov = rwco->iobuf;
12991bf1cbc9SKevin Wolf 
1300fbb92b67SKevin Wolf     rwco->ret = blk_do_preadv(rwco->blk, rwco->offset, qiov->size,
1301c060332cSDeepa Srinivasan                               qiov, rwco->flags);
13024720cbeeSKevin Wolf     aio_wait_kick();
13031bf1cbc9SKevin Wolf }
13041bf1cbc9SKevin Wolf 
1305a8823a3bSKevin Wolf static void blk_write_entry(void *opaque)
1306a8823a3bSKevin Wolf {
1307a8823a3bSKevin Wolf     BlkRwCo *rwco = opaque;
1308c060332cSDeepa Srinivasan     QEMUIOVector *qiov = rwco->iobuf;
1309a8823a3bSKevin Wolf 
1310fbb92b67SKevin Wolf     rwco->ret = blk_do_pwritev_part(rwco->blk, rwco->offset, qiov->size,
1311fbb92b67SKevin Wolf                                     qiov, 0, rwco->flags);
13124720cbeeSKevin Wolf     aio_wait_kick();
1313a8823a3bSKevin Wolf }
1314a8823a3bSKevin Wolf 
1315a55d3fbaSKevin Wolf static int blk_prw(BlockBackend *blk, int64_t offset, uint8_t *buf,
1316a55d3fbaSKevin Wolf                    int64_t bytes, CoroutineEntry co_entry,
1317fc1453cdSKevin Wolf                    BdrvRequestFlags flags)
13181bf1cbc9SKevin Wolf {
1319ae5a9592SVladimir Sementsov-Ogievskiy     QEMUIOVector qiov = QEMU_IOVEC_INIT_BUF(qiov, buf, bytes);
1320ae5a9592SVladimir Sementsov-Ogievskiy     BlkRwCo rwco = {
13211bf1cbc9SKevin Wolf         .blk    = blk,
1322a55d3fbaSKevin Wolf         .offset = offset,
1323c060332cSDeepa Srinivasan         .iobuf  = &qiov,
1324fc1453cdSKevin Wolf         .flags  = flags,
13251bf1cbc9SKevin Wolf         .ret    = NOT_DONE,
13261bf1cbc9SKevin Wolf     };
13271bf1cbc9SKevin Wolf 
1328fbb92b67SKevin Wolf     blk_inc_in_flight(blk);
132935f106e6SPaolo Bonzini     if (qemu_in_coroutine()) {
133035f106e6SPaolo Bonzini         /* Fast-path if already in coroutine context */
133135f106e6SPaolo Bonzini         co_entry(&rwco);
133235f106e6SPaolo Bonzini     } else {
133335f106e6SPaolo Bonzini         Coroutine *co = qemu_coroutine_create(co_entry, &rwco);
1334e92f0e19SFam Zheng         bdrv_coroutine_enter(blk_bs(blk), co);
133588b062c2SPaolo Bonzini         BDRV_POLL_WHILE(blk_bs(blk), rwco.ret == NOT_DONE);
133635f106e6SPaolo Bonzini     }
1337fbb92b67SKevin Wolf     blk_dec_in_flight(blk);
13381bf1cbc9SKevin Wolf 
13391bf1cbc9SKevin Wolf     return rwco.ret;
13404be74634SMarkus Armbruster }
13414be74634SMarkus Armbruster 
1342d004bd52SEric Blake int blk_pwrite_zeroes(BlockBackend *blk, int64_t offset,
1343f5a5ca79SManos Pitsidianakis                       int bytes, BdrvRequestFlags flags)
13440df89e8eSKevin Wolf {
1345f5a5ca79SManos Pitsidianakis     return blk_prw(blk, offset, NULL, bytes, blk_write_entry,
134616aaf975SKevin Wolf                    flags | BDRV_REQ_ZERO_WRITE);
13470df89e8eSKevin Wolf }
13480df89e8eSKevin Wolf 
1349720ff280SKevin Wolf int blk_make_zero(BlockBackend *blk, BdrvRequestFlags flags)
1350720ff280SKevin Wolf {
1351720ff280SKevin Wolf     return bdrv_make_zero(blk->root, flags);
1352720ff280SKevin Wolf }
1353720ff280SKevin Wolf 
1354c90e2a9cSKevin Wolf void blk_inc_in_flight(BlockBackend *blk)
135533f2a757SStefan Hajnoczi {
135633f2a757SStefan Hajnoczi     atomic_inc(&blk->in_flight);
135733f2a757SStefan Hajnoczi }
135833f2a757SStefan Hajnoczi 
1359c90e2a9cSKevin Wolf void blk_dec_in_flight(BlockBackend *blk)
136033f2a757SStefan Hajnoczi {
136133f2a757SStefan Hajnoczi     atomic_dec(&blk->in_flight);
1362cfe29d82SKevin Wolf     aio_wait_kick();
136333f2a757SStefan Hajnoczi }
136433f2a757SStefan Hajnoczi 
1365e7f7d676SMax Reitz static void error_callback_bh(void *opaque)
1366e7f7d676SMax Reitz {
1367e7f7d676SMax Reitz     struct BlockBackendAIOCB *acb = opaque;
136899723548SPaolo Bonzini 
136933f2a757SStefan Hajnoczi     blk_dec_in_flight(acb->blk);
1370e7f7d676SMax Reitz     acb->common.cb(acb->common.opaque, acb->ret);
1371e7f7d676SMax Reitz     qemu_aio_unref(acb);
1372e7f7d676SMax Reitz }
1373e7f7d676SMax Reitz 
1374ca78ecfaSPeter Lieven BlockAIOCB *blk_abort_aio_request(BlockBackend *blk,
1375ca78ecfaSPeter Lieven                                   BlockCompletionFunc *cb,
1376e7f7d676SMax Reitz                                   void *opaque, int ret)
1377e7f7d676SMax Reitz {
1378e7f7d676SMax Reitz     struct BlockBackendAIOCB *acb;
1379e7f7d676SMax Reitz 
138033f2a757SStefan Hajnoczi     blk_inc_in_flight(blk);
1381e7f7d676SMax Reitz     acb = blk_aio_get(&block_backend_aiocb_info, blk, cb, opaque);
13824981bdecSMax Reitz     acb->blk = blk;
1383e7f7d676SMax Reitz     acb->ret = ret;
1384e7f7d676SMax Reitz 
1385e4ec5ad4SPavel Dovgalyuk     replay_bh_schedule_oneshot_event(blk_get_aio_context(blk),
1386e4ec5ad4SPavel Dovgalyuk                                      error_callback_bh, acb);
1387e7f7d676SMax Reitz     return &acb->common;
1388e7f7d676SMax Reitz }
1389e7f7d676SMax Reitz 
139057d6a428SKevin Wolf typedef struct BlkAioEmAIOCB {
139157d6a428SKevin Wolf     BlockAIOCB common;
139257d6a428SKevin Wolf     BlkRwCo rwco;
13937fa84cd8SKevin Wolf     int bytes;
139457d6a428SKevin Wolf     bool has_returned;
139557d6a428SKevin Wolf } BlkAioEmAIOCB;
139657d6a428SKevin Wolf 
13971d719ddcSStefan Hajnoczi static AioContext *blk_aio_em_aiocb_get_aio_context(BlockAIOCB *acb_)
13981d719ddcSStefan Hajnoczi {
13991d719ddcSStefan Hajnoczi     BlkAioEmAIOCB *acb = container_of(acb_, BlkAioEmAIOCB, common);
14001d719ddcSStefan Hajnoczi 
14011d719ddcSStefan Hajnoczi     return blk_get_aio_context(acb->rwco.blk);
14021d719ddcSStefan Hajnoczi }
14031d719ddcSStefan Hajnoczi 
140457d6a428SKevin Wolf static const AIOCBInfo blk_aio_em_aiocb_info = {
140557d6a428SKevin Wolf     .aiocb_size         = sizeof(BlkAioEmAIOCB),
14061d719ddcSStefan Hajnoczi     .get_aio_context    = blk_aio_em_aiocb_get_aio_context,
140757d6a428SKevin Wolf };
140857d6a428SKevin Wolf 
140957d6a428SKevin Wolf static void blk_aio_complete(BlkAioEmAIOCB *acb)
141057d6a428SKevin Wolf {
141157d6a428SKevin Wolf     if (acb->has_returned) {
141257d6a428SKevin Wolf         acb->common.cb(acb->common.opaque, acb->rwco.ret);
141346aaf2a5SKevin Wolf         blk_dec_in_flight(acb->rwco.blk);
141457d6a428SKevin Wolf         qemu_aio_unref(acb);
141557d6a428SKevin Wolf     }
141657d6a428SKevin Wolf }
141757d6a428SKevin Wolf 
141857d6a428SKevin Wolf static void blk_aio_complete_bh(void *opaque)
141957d6a428SKevin Wolf {
1420fffb6e12SPaolo Bonzini     BlkAioEmAIOCB *acb = opaque;
1421fffb6e12SPaolo Bonzini     assert(acb->has_returned);
1422fffb6e12SPaolo Bonzini     blk_aio_complete(acb);
142357d6a428SKevin Wolf }
142457d6a428SKevin Wolf 
14257fa84cd8SKevin Wolf static BlockAIOCB *blk_aio_prwv(BlockBackend *blk, int64_t offset, int bytes,
1426c060332cSDeepa Srinivasan                                 void *iobuf, CoroutineEntry co_entry,
142757d6a428SKevin Wolf                                 BdrvRequestFlags flags,
142857d6a428SKevin Wolf                                 BlockCompletionFunc *cb, void *opaque)
142957d6a428SKevin Wolf {
143057d6a428SKevin Wolf     BlkAioEmAIOCB *acb;
143157d6a428SKevin Wolf     Coroutine *co;
143257d6a428SKevin Wolf 
143333f2a757SStefan Hajnoczi     blk_inc_in_flight(blk);
143457d6a428SKevin Wolf     acb = blk_aio_get(&blk_aio_em_aiocb_info, blk, cb, opaque);
143557d6a428SKevin Wolf     acb->rwco = (BlkRwCo) {
143657d6a428SKevin Wolf         .blk    = blk,
143757d6a428SKevin Wolf         .offset = offset,
1438c060332cSDeepa Srinivasan         .iobuf  = iobuf,
143957d6a428SKevin Wolf         .flags  = flags,
144057d6a428SKevin Wolf         .ret    = NOT_DONE,
144157d6a428SKevin Wolf     };
14427fa84cd8SKevin Wolf     acb->bytes = bytes;
144357d6a428SKevin Wolf     acb->has_returned = false;
144457d6a428SKevin Wolf 
14450b8b8753SPaolo Bonzini     co = qemu_coroutine_create(co_entry, acb);
1446e92f0e19SFam Zheng     bdrv_coroutine_enter(blk_bs(blk), co);
144757d6a428SKevin Wolf 
144857d6a428SKevin Wolf     acb->has_returned = true;
144957d6a428SKevin Wolf     if (acb->rwco.ret != NOT_DONE) {
1450e4ec5ad4SPavel Dovgalyuk         replay_bh_schedule_oneshot_event(blk_get_aio_context(blk),
1451fffb6e12SPaolo Bonzini                                          blk_aio_complete_bh, acb);
145257d6a428SKevin Wolf     }
145357d6a428SKevin Wolf 
145457d6a428SKevin Wolf     return &acb->common;
145557d6a428SKevin Wolf }
145657d6a428SKevin Wolf 
145757d6a428SKevin Wolf static void blk_aio_read_entry(void *opaque)
145857d6a428SKevin Wolf {
145957d6a428SKevin Wolf     BlkAioEmAIOCB *acb = opaque;
146057d6a428SKevin Wolf     BlkRwCo *rwco = &acb->rwco;
1461c060332cSDeepa Srinivasan     QEMUIOVector *qiov = rwco->iobuf;
146257d6a428SKevin Wolf 
1463c060332cSDeepa Srinivasan     assert(qiov->size == acb->bytes);
1464fbb92b67SKevin Wolf     rwco->ret = blk_do_preadv(rwco->blk, rwco->offset, acb->bytes,
1465c060332cSDeepa Srinivasan                               qiov, rwco->flags);
146657d6a428SKevin Wolf     blk_aio_complete(acb);
146757d6a428SKevin Wolf }
146857d6a428SKevin Wolf 
146957d6a428SKevin Wolf static void blk_aio_write_entry(void *opaque)
147057d6a428SKevin Wolf {
147157d6a428SKevin Wolf     BlkAioEmAIOCB *acb = opaque;
147257d6a428SKevin Wolf     BlkRwCo *rwco = &acb->rwco;
1473c060332cSDeepa Srinivasan     QEMUIOVector *qiov = rwco->iobuf;
147457d6a428SKevin Wolf 
1475c060332cSDeepa Srinivasan     assert(!qiov || qiov->size == acb->bytes);
1476fbb92b67SKevin Wolf     rwco->ret = blk_do_pwritev_part(rwco->blk, rwco->offset, acb->bytes,
1477fbb92b67SKevin Wolf                                     qiov, 0, rwco->flags);
147857d6a428SKevin Wolf     blk_aio_complete(acb);
147957d6a428SKevin Wolf }
148057d6a428SKevin Wolf 
1481d004bd52SEric Blake BlockAIOCB *blk_aio_pwrite_zeroes(BlockBackend *blk, int64_t offset,
1482983a1600SEric Blake                                   int count, BdrvRequestFlags flags,
14834be74634SMarkus Armbruster                                   BlockCompletionFunc *cb, void *opaque)
14844be74634SMarkus Armbruster {
1485983a1600SEric Blake     return blk_aio_prwv(blk, offset, count, NULL, blk_aio_write_entry,
1486983a1600SEric Blake                         flags | BDRV_REQ_ZERO_WRITE, cb, opaque);
14874be74634SMarkus Armbruster }
14884be74634SMarkus Armbruster 
14894be74634SMarkus Armbruster int blk_pread(BlockBackend *blk, int64_t offset, void *buf, int count)
14904be74634SMarkus Armbruster {
1491a55d3fbaSKevin Wolf     int ret = blk_prw(blk, offset, buf, count, blk_read_entry, 0);
1492e7f7d676SMax Reitz     if (ret < 0) {
1493e7f7d676SMax Reitz         return ret;
1494e7f7d676SMax Reitz     }
1495a55d3fbaSKevin Wolf     return count;
14964be74634SMarkus Armbruster }
14974be74634SMarkus Armbruster 
14988341f00dSEric Blake int blk_pwrite(BlockBackend *blk, int64_t offset, const void *buf, int count,
14998341f00dSEric Blake                BdrvRequestFlags flags)
15004be74634SMarkus Armbruster {
15018341f00dSEric Blake     int ret = blk_prw(blk, offset, (void *) buf, count, blk_write_entry,
15028341f00dSEric Blake                       flags);
1503e7f7d676SMax Reitz     if (ret < 0) {
1504e7f7d676SMax Reitz         return ret;
1505e7f7d676SMax Reitz     }
1506a55d3fbaSKevin Wolf     return count;
15074be74634SMarkus Armbruster }
15084be74634SMarkus Armbruster 
15094be74634SMarkus Armbruster int64_t blk_getlength(BlockBackend *blk)
15104be74634SMarkus Armbruster {
1511c09ba36cSMax Reitz     if (!blk_is_available(blk)) {
1512c09ba36cSMax Reitz         return -ENOMEDIUM;
1513c09ba36cSMax Reitz     }
1514c09ba36cSMax Reitz 
1515f21d96d0SKevin Wolf     return bdrv_getlength(blk_bs(blk));
15164be74634SMarkus Armbruster }
15174be74634SMarkus Armbruster 
15184be74634SMarkus Armbruster void blk_get_geometry(BlockBackend *blk, uint64_t *nb_sectors_ptr)
15194be74634SMarkus Armbruster {
1520f21d96d0SKevin Wolf     if (!blk_bs(blk)) {
1521a46fc9c9SMax Reitz         *nb_sectors_ptr = 0;
1522a46fc9c9SMax Reitz     } else {
1523f21d96d0SKevin Wolf         bdrv_get_geometry(blk_bs(blk), nb_sectors_ptr);
15244be74634SMarkus Armbruster     }
1525a46fc9c9SMax Reitz }
15264be74634SMarkus Armbruster 
15271ef01253SMax Reitz int64_t blk_nb_sectors(BlockBackend *blk)
15281ef01253SMax Reitz {
1529c09ba36cSMax Reitz     if (!blk_is_available(blk)) {
1530c09ba36cSMax Reitz         return -ENOMEDIUM;
1531c09ba36cSMax Reitz     }
1532c09ba36cSMax Reitz 
1533f21d96d0SKevin Wolf     return bdrv_nb_sectors(blk_bs(blk));
15341ef01253SMax Reitz }
15351ef01253SMax Reitz 
153660cb2fa7SEric Blake BlockAIOCB *blk_aio_preadv(BlockBackend *blk, int64_t offset,
153760cb2fa7SEric Blake                            QEMUIOVector *qiov, BdrvRequestFlags flags,
153860cb2fa7SEric Blake                            BlockCompletionFunc *cb, void *opaque)
153960cb2fa7SEric Blake {
154060cb2fa7SEric Blake     return blk_aio_prwv(blk, offset, qiov->size, qiov,
154160cb2fa7SEric Blake                         blk_aio_read_entry, flags, cb, opaque);
154260cb2fa7SEric Blake }
154360cb2fa7SEric Blake 
154460cb2fa7SEric Blake BlockAIOCB *blk_aio_pwritev(BlockBackend *blk, int64_t offset,
154560cb2fa7SEric Blake                             QEMUIOVector *qiov, BdrvRequestFlags flags,
154660cb2fa7SEric Blake                             BlockCompletionFunc *cb, void *opaque)
154760cb2fa7SEric Blake {
154860cb2fa7SEric Blake     return blk_aio_prwv(blk, offset, qiov->size, qiov,
154960cb2fa7SEric Blake                         blk_aio_write_entry, flags, cb, opaque);
155060cb2fa7SEric Blake }
155160cb2fa7SEric Blake 
15524be74634SMarkus Armbruster void blk_aio_cancel(BlockAIOCB *acb)
15534be74634SMarkus Armbruster {
15544be74634SMarkus Armbruster     bdrv_aio_cancel(acb);
15554be74634SMarkus Armbruster }
15564be74634SMarkus Armbruster 
15574be74634SMarkus Armbruster void blk_aio_cancel_async(BlockAIOCB *acb)
15584be74634SMarkus Armbruster {
15594be74634SMarkus Armbruster     bdrv_aio_cancel_async(acb);
15604be74634SMarkus Armbruster }
15614be74634SMarkus Armbruster 
1562fbb92b67SKevin Wolf /* To be called between exactly one pair of blk_inc/dec_in_flight() */
1563fbb92b67SKevin Wolf static int coroutine_fn
1564fbb92b67SKevin Wolf blk_do_ioctl(BlockBackend *blk, unsigned long int req, void *buf)
15654be74634SMarkus Armbruster {
1566cf312932SKevin Wolf     blk_wait_while_drained(blk);
1567cf312932SKevin Wolf 
1568c09ba36cSMax Reitz     if (!blk_is_available(blk)) {
1569c09ba36cSMax Reitz         return -ENOMEDIUM;
1570c09ba36cSMax Reitz     }
1571c09ba36cSMax Reitz 
157248af776aSKevin Wolf     return bdrv_co_ioctl(blk_bs(blk), req, buf);
157348af776aSKevin Wolf }
157448af776aSKevin Wolf 
157548af776aSKevin Wolf static void blk_ioctl_entry(void *opaque)
157648af776aSKevin Wolf {
157748af776aSKevin Wolf     BlkRwCo *rwco = opaque;
1578c060332cSDeepa Srinivasan     QEMUIOVector *qiov = rwco->iobuf;
1579c060332cSDeepa Srinivasan 
1580fbb92b67SKevin Wolf     rwco->ret = blk_do_ioctl(rwco->blk, rwco->offset, qiov->iov[0].iov_base);
15814720cbeeSKevin Wolf     aio_wait_kick();
158248af776aSKevin Wolf }
158348af776aSKevin Wolf 
158448af776aSKevin Wolf int blk_ioctl(BlockBackend *blk, unsigned long int req, void *buf)
158548af776aSKevin Wolf {
158648af776aSKevin Wolf     return blk_prw(blk, req, buf, 0, blk_ioctl_entry, 0);
158748af776aSKevin Wolf }
158848af776aSKevin Wolf 
158948af776aSKevin Wolf static void blk_aio_ioctl_entry(void *opaque)
159048af776aSKevin Wolf {
159148af776aSKevin Wolf     BlkAioEmAIOCB *acb = opaque;
159248af776aSKevin Wolf     BlkRwCo *rwco = &acb->rwco;
159348af776aSKevin Wolf 
1594fbb92b67SKevin Wolf     rwco->ret = blk_do_ioctl(rwco->blk, rwco->offset, rwco->iobuf);
1595c060332cSDeepa Srinivasan 
159648af776aSKevin Wolf     blk_aio_complete(acb);
15974be74634SMarkus Armbruster }
15984be74634SMarkus Armbruster 
15994be74634SMarkus Armbruster BlockAIOCB *blk_aio_ioctl(BlockBackend *blk, unsigned long int req, void *buf,
16004be74634SMarkus Armbruster                           BlockCompletionFunc *cb, void *opaque)
16014be74634SMarkus Armbruster {
1602c060332cSDeepa Srinivasan     return blk_aio_prwv(blk, req, 0, buf, blk_aio_ioctl_entry, 0, cb, opaque);
16034be74634SMarkus Armbruster }
16044be74634SMarkus Armbruster 
1605fbb92b67SKevin Wolf /* To be called between exactly one pair of blk_inc/dec_in_flight() */
1606fbb92b67SKevin Wolf static int coroutine_fn
1607fbb92b67SKevin Wolf blk_do_pdiscard(BlockBackend *blk, int64_t offset, int bytes)
16082bb0dce7SMax Reitz {
1609cf312932SKevin Wolf     int ret;
1610cf312932SKevin Wolf 
1611cf312932SKevin Wolf     blk_wait_while_drained(blk);
1612cf312932SKevin Wolf 
1613cf312932SKevin Wolf     ret = blk_check_byte_request(blk, offset, bytes);
1614e7f7d676SMax Reitz     if (ret < 0) {
1615e7f7d676SMax Reitz         return ret;
1616e7f7d676SMax Reitz     }
1617e7f7d676SMax Reitz 
16180b9fd3f4SFam Zheng     return bdrv_co_pdiscard(blk->root, offset, bytes);
16192bb0dce7SMax Reitz }
16202bb0dce7SMax Reitz 
1621564806c5SKevin Wolf static void blk_aio_pdiscard_entry(void *opaque)
1622564806c5SKevin Wolf {
1623564806c5SKevin Wolf     BlkAioEmAIOCB *acb = opaque;
1624564806c5SKevin Wolf     BlkRwCo *rwco = &acb->rwco;
1625564806c5SKevin Wolf 
1626fbb92b67SKevin Wolf     rwco->ret = blk_do_pdiscard(rwco->blk, rwco->offset, acb->bytes);
1627564806c5SKevin Wolf     blk_aio_complete(acb);
1628564806c5SKevin Wolf }
1629564806c5SKevin Wolf 
1630564806c5SKevin Wolf BlockAIOCB *blk_aio_pdiscard(BlockBackend *blk,
1631564806c5SKevin Wolf                              int64_t offset, int bytes,
1632564806c5SKevin Wolf                              BlockCompletionFunc *cb, void *opaque)
1633564806c5SKevin Wolf {
1634564806c5SKevin Wolf     return blk_aio_prwv(blk, offset, bytes, NULL, blk_aio_pdiscard_entry, 0,
1635564806c5SKevin Wolf                         cb, opaque);
1636564806c5SKevin Wolf }
1637564806c5SKevin Wolf 
1638fbb92b67SKevin Wolf int coroutine_fn blk_co_pdiscard(BlockBackend *blk, int64_t offset, int bytes)
1639fbb92b67SKevin Wolf {
1640fbb92b67SKevin Wolf     int ret;
1641fbb92b67SKevin Wolf 
1642fbb92b67SKevin Wolf     blk_inc_in_flight(blk);
1643fbb92b67SKevin Wolf     ret = blk_do_pdiscard(blk, offset, bytes);
1644fbb92b67SKevin Wolf     blk_dec_in_flight(blk);
1645fbb92b67SKevin Wolf 
1646fbb92b67SKevin Wolf     return ret;
1647fbb92b67SKevin Wolf }
1648fbb92b67SKevin Wolf 
1649564806c5SKevin Wolf static void blk_pdiscard_entry(void *opaque)
1650564806c5SKevin Wolf {
1651564806c5SKevin Wolf     BlkRwCo *rwco = opaque;
1652564806c5SKevin Wolf     QEMUIOVector *qiov = rwco->iobuf;
1653564806c5SKevin Wolf 
1654fbb92b67SKevin Wolf     rwco->ret = blk_do_pdiscard(rwco->blk, rwco->offset, qiov->size);
1655564806c5SKevin Wolf     aio_wait_kick();
1656564806c5SKevin Wolf }
1657564806c5SKevin Wolf 
1658564806c5SKevin Wolf int blk_pdiscard(BlockBackend *blk, int64_t offset, int bytes)
1659564806c5SKevin Wolf {
1660564806c5SKevin Wolf     return blk_prw(blk, offset, NULL, bytes, blk_pdiscard_entry, 0);
1661564806c5SKevin Wolf }
1662564806c5SKevin Wolf 
1663fbb92b67SKevin Wolf /* To be called between exactly one pair of blk_inc/dec_in_flight() */
1664fbb92b67SKevin Wolf static int coroutine_fn blk_do_flush(BlockBackend *blk)
16652bb0dce7SMax Reitz {
1666cf312932SKevin Wolf     blk_wait_while_drained(blk);
1667cf312932SKevin Wolf 
1668c09ba36cSMax Reitz     if (!blk_is_available(blk)) {
1669c09ba36cSMax Reitz         return -ENOMEDIUM;
1670c09ba36cSMax Reitz     }
1671c09ba36cSMax Reitz 
1672f21d96d0SKevin Wolf     return bdrv_co_flush(blk_bs(blk));
16732bb0dce7SMax Reitz }
16742bb0dce7SMax Reitz 
1675564806c5SKevin Wolf static void blk_aio_flush_entry(void *opaque)
1676564806c5SKevin Wolf {
1677564806c5SKevin Wolf     BlkAioEmAIOCB *acb = opaque;
1678564806c5SKevin Wolf     BlkRwCo *rwco = &acb->rwco;
1679564806c5SKevin Wolf 
1680fbb92b67SKevin Wolf     rwco->ret = blk_do_flush(rwco->blk);
1681564806c5SKevin Wolf     blk_aio_complete(acb);
1682564806c5SKevin Wolf }
1683564806c5SKevin Wolf 
1684564806c5SKevin Wolf BlockAIOCB *blk_aio_flush(BlockBackend *blk,
1685564806c5SKevin Wolf                           BlockCompletionFunc *cb, void *opaque)
1686564806c5SKevin Wolf {
1687564806c5SKevin Wolf     return blk_aio_prwv(blk, 0, 0, NULL, blk_aio_flush_entry, 0, cb, opaque);
1688564806c5SKevin Wolf }
1689564806c5SKevin Wolf 
1690fbb92b67SKevin Wolf int coroutine_fn blk_co_flush(BlockBackend *blk)
1691fbb92b67SKevin Wolf {
1692fbb92b67SKevin Wolf     int ret;
1693fbb92b67SKevin Wolf 
1694fbb92b67SKevin Wolf     blk_inc_in_flight(blk);
1695fbb92b67SKevin Wolf     ret = blk_do_flush(blk);
1696fbb92b67SKevin Wolf     blk_dec_in_flight(blk);
1697fbb92b67SKevin Wolf 
1698fbb92b67SKevin Wolf     return ret;
1699fbb92b67SKevin Wolf }
1700fbb92b67SKevin Wolf 
1701be07a889SKevin Wolf static void blk_flush_entry(void *opaque)
17024be74634SMarkus Armbruster {
1703be07a889SKevin Wolf     BlkRwCo *rwco = opaque;
1704fbb92b67SKevin Wolf     rwco->ret = blk_do_flush(rwco->blk);
17054720cbeeSKevin Wolf     aio_wait_kick();
1706c09ba36cSMax Reitz }
1707c09ba36cSMax Reitz 
1708be07a889SKevin Wolf int blk_flush(BlockBackend *blk)
1709be07a889SKevin Wolf {
1710be07a889SKevin Wolf     return blk_prw(blk, 0, NULL, 0, blk_flush_entry, 0);
17114be74634SMarkus Armbruster }
17124be74634SMarkus Armbruster 
171397b0385aSAlexander Yarygin void blk_drain(BlockBackend *blk)
171497b0385aSAlexander Yarygin {
171533f2a757SStefan Hajnoczi     BlockDriverState *bs = blk_bs(blk);
171633f2a757SStefan Hajnoczi 
171733f2a757SStefan Hajnoczi     if (bs) {
171833f2a757SStefan Hajnoczi         bdrv_drained_begin(bs);
171933f2a757SStefan Hajnoczi     }
172033f2a757SStefan Hajnoczi 
172133f2a757SStefan Hajnoczi     /* We may have -ENOMEDIUM completions in flight */
1722cfe29d82SKevin Wolf     AIO_WAIT_WHILE(blk_get_aio_context(blk),
172333f2a757SStefan Hajnoczi                    atomic_mb_read(&blk->in_flight) > 0);
172433f2a757SStefan Hajnoczi 
172533f2a757SStefan Hajnoczi     if (bs) {
172633f2a757SStefan Hajnoczi         bdrv_drained_end(bs);
172797b0385aSAlexander Yarygin     }
1728a46fc9c9SMax Reitz }
172997b0385aSAlexander Yarygin 
17304be74634SMarkus Armbruster void blk_drain_all(void)
17314be74634SMarkus Armbruster {
173233f2a757SStefan Hajnoczi     BlockBackend *blk = NULL;
173333f2a757SStefan Hajnoczi 
173433f2a757SStefan Hajnoczi     bdrv_drain_all_begin();
173533f2a757SStefan Hajnoczi 
173633f2a757SStefan Hajnoczi     while ((blk = blk_all_next(blk)) != NULL) {
173733f2a757SStefan Hajnoczi         AioContext *ctx = blk_get_aio_context(blk);
173833f2a757SStefan Hajnoczi 
173933f2a757SStefan Hajnoczi         aio_context_acquire(ctx);
174033f2a757SStefan Hajnoczi 
174133f2a757SStefan Hajnoczi         /* We may have -ENOMEDIUM completions in flight */
1742cfe29d82SKevin Wolf         AIO_WAIT_WHILE(ctx, atomic_mb_read(&blk->in_flight) > 0);
174333f2a757SStefan Hajnoczi 
174433f2a757SStefan Hajnoczi         aio_context_release(ctx);
174533f2a757SStefan Hajnoczi     }
174633f2a757SStefan Hajnoczi 
174733f2a757SStefan Hajnoczi     bdrv_drain_all_end();
17484be74634SMarkus Armbruster }
17494be74634SMarkus Armbruster 
1750373340b2SMax Reitz void blk_set_on_error(BlockBackend *blk, BlockdevOnError on_read_error,
1751373340b2SMax Reitz                       BlockdevOnError on_write_error)
1752373340b2SMax Reitz {
1753373340b2SMax Reitz     blk->on_read_error = on_read_error;
1754373340b2SMax Reitz     blk->on_write_error = on_write_error;
1755373340b2SMax Reitz }
1756373340b2SMax Reitz 
17574be74634SMarkus Armbruster BlockdevOnError blk_get_on_error(BlockBackend *blk, bool is_read)
17584be74634SMarkus Armbruster {
1759373340b2SMax Reitz     return is_read ? blk->on_read_error : blk->on_write_error;
17604be74634SMarkus Armbruster }
17614be74634SMarkus Armbruster 
17624be74634SMarkus Armbruster BlockErrorAction blk_get_error_action(BlockBackend *blk, bool is_read,
17634be74634SMarkus Armbruster                                       int error)
17644be74634SMarkus Armbruster {
1765373340b2SMax Reitz     BlockdevOnError on_err = blk_get_on_error(blk, is_read);
1766373340b2SMax Reitz 
1767373340b2SMax Reitz     switch (on_err) {
1768373340b2SMax Reitz     case BLOCKDEV_ON_ERROR_ENOSPC:
1769373340b2SMax Reitz         return (error == ENOSPC) ?
1770373340b2SMax Reitz                BLOCK_ERROR_ACTION_STOP : BLOCK_ERROR_ACTION_REPORT;
1771373340b2SMax Reitz     case BLOCKDEV_ON_ERROR_STOP:
1772373340b2SMax Reitz         return BLOCK_ERROR_ACTION_STOP;
1773373340b2SMax Reitz     case BLOCKDEV_ON_ERROR_REPORT:
1774373340b2SMax Reitz         return BLOCK_ERROR_ACTION_REPORT;
1775373340b2SMax Reitz     case BLOCKDEV_ON_ERROR_IGNORE:
1776373340b2SMax Reitz         return BLOCK_ERROR_ACTION_IGNORE;
17778c398252SKevin Wolf     case BLOCKDEV_ON_ERROR_AUTO:
1778373340b2SMax Reitz     default:
1779373340b2SMax Reitz         abort();
1780373340b2SMax Reitz     }
17814be74634SMarkus Armbruster }
17824be74634SMarkus Armbruster 
1783373340b2SMax Reitz static void send_qmp_error_event(BlockBackend *blk,
1784373340b2SMax Reitz                                  BlockErrorAction action,
1785373340b2SMax Reitz                                  bool is_read, int error)
1786373340b2SMax Reitz {
1787373340b2SMax Reitz     IoOperationType optype;
1788bfe1a14cSKevin Wolf     BlockDriverState *bs = blk_bs(blk);
1789373340b2SMax Reitz 
1790373340b2SMax Reitz     optype = is_read ? IO_OPERATION_TYPE_READ : IO_OPERATION_TYPE_WRITE;
1791bfe1a14cSKevin Wolf     qapi_event_send_block_io_error(blk_name(blk), !!bs,
1792bfe1a14cSKevin Wolf                                    bs ? bdrv_get_node_name(bs) : NULL, optype,
17932bf7e10fSKevin Wolf                                    action, blk_iostatus_is_enabled(blk),
17943ab72385SPeter Xu                                    error == ENOSPC, strerror(error));
1795373340b2SMax Reitz }
1796373340b2SMax Reitz 
1797373340b2SMax Reitz /* This is done by device models because, while the block layer knows
1798373340b2SMax Reitz  * about the error, it does not know whether an operation comes from
1799373340b2SMax Reitz  * the device or the block layer (from a job, for example).
1800373340b2SMax Reitz  */
18014be74634SMarkus Armbruster void blk_error_action(BlockBackend *blk, BlockErrorAction action,
18024be74634SMarkus Armbruster                       bool is_read, int error)
18034be74634SMarkus Armbruster {
1804373340b2SMax Reitz     assert(error >= 0);
1805373340b2SMax Reitz 
1806373340b2SMax Reitz     if (action == BLOCK_ERROR_ACTION_STOP) {
1807373340b2SMax Reitz         /* First set the iostatus, so that "info block" returns an iostatus
1808373340b2SMax Reitz          * that matches the events raised so far (an additional error iostatus
1809373340b2SMax Reitz          * is fine, but not a lost one).
1810373340b2SMax Reitz          */
1811373340b2SMax Reitz         blk_iostatus_set_err(blk, error);
1812373340b2SMax Reitz 
1813373340b2SMax Reitz         /* Then raise the request to stop the VM and the event.
1814373340b2SMax Reitz          * qemu_system_vmstop_request_prepare has two effects.  First,
1815373340b2SMax Reitz          * it ensures that the STOP event always comes after the
1816373340b2SMax Reitz          * BLOCK_IO_ERROR event.  Second, it ensures that even if management
1817373340b2SMax Reitz          * can observe the STOP event and do a "cont" before the STOP
1818373340b2SMax Reitz          * event is issued, the VM will not stop.  In this case, vm_start()
1819373340b2SMax Reitz          * also ensures that the STOP/RESUME pair of events is emitted.
1820373340b2SMax Reitz          */
1821373340b2SMax Reitz         qemu_system_vmstop_request_prepare();
1822373340b2SMax Reitz         send_qmp_error_event(blk, action, is_read, error);
1823373340b2SMax Reitz         qemu_system_vmstop_request(RUN_STATE_IO_ERROR);
1824373340b2SMax Reitz     } else {
1825373340b2SMax Reitz         send_qmp_error_event(blk, action, is_read, error);
1826373340b2SMax Reitz     }
18274be74634SMarkus Armbruster }
18284be74634SMarkus Armbruster 
182996710565SLi Qiang bool blk_is_read_only(BlockBackend *blk)
18304be74634SMarkus Armbruster {
1831f21d96d0SKevin Wolf     BlockDriverState *bs = blk_bs(blk);
1832f21d96d0SKevin Wolf 
1833f21d96d0SKevin Wolf     if (bs) {
1834f21d96d0SKevin Wolf         return bdrv_is_read_only(bs);
1835061959e8SMax Reitz     } else {
1836061959e8SMax Reitz         return blk->root_state.read_only;
1837061959e8SMax Reitz     }
18384be74634SMarkus Armbruster }
18394be74634SMarkus Armbruster 
184096710565SLi Qiang bool blk_is_sg(BlockBackend *blk)
18414be74634SMarkus Armbruster {
1842f21d96d0SKevin Wolf     BlockDriverState *bs = blk_bs(blk);
1843f21d96d0SKevin Wolf 
1844f21d96d0SKevin Wolf     if (!bs) {
184596710565SLi Qiang         return false;
1846a46fc9c9SMax Reitz     }
1847a46fc9c9SMax Reitz 
1848f21d96d0SKevin Wolf     return bdrv_is_sg(bs);
18494be74634SMarkus Armbruster }
18504be74634SMarkus Armbruster 
185196710565SLi Qiang bool blk_enable_write_cache(BlockBackend *blk)
18524be74634SMarkus Armbruster {
1853bfd18d1eSKevin Wolf     return blk->enable_write_cache;
18544be74634SMarkus Armbruster }
18554be74634SMarkus Armbruster 
18564be74634SMarkus Armbruster void blk_set_enable_write_cache(BlockBackend *blk, bool wce)
18574be74634SMarkus Armbruster {
1858bfd18d1eSKevin Wolf     blk->enable_write_cache = wce;
18594be74634SMarkus Armbruster }
18604be74634SMarkus Armbruster 
18612bb0dce7SMax Reitz void blk_invalidate_cache(BlockBackend *blk, Error **errp)
18622bb0dce7SMax Reitz {
1863f21d96d0SKevin Wolf     BlockDriverState *bs = blk_bs(blk);
1864f21d96d0SKevin Wolf 
1865f21d96d0SKevin Wolf     if (!bs) {
1866c09ba36cSMax Reitz         error_setg(errp, "Device '%s' has no medium", blk->name);
1867c09ba36cSMax Reitz         return;
1868c09ba36cSMax Reitz     }
1869c09ba36cSMax Reitz 
1870f21d96d0SKevin Wolf     bdrv_invalidate_cache(bs, errp);
18712bb0dce7SMax Reitz }
18722bb0dce7SMax Reitz 
1873e031f750SMax Reitz bool blk_is_inserted(BlockBackend *blk)
18744be74634SMarkus Armbruster {
1875f21d96d0SKevin Wolf     BlockDriverState *bs = blk_bs(blk);
1876f21d96d0SKevin Wolf 
1877f21d96d0SKevin Wolf     return bs && bdrv_is_inserted(bs);
1878db0284f8SMax Reitz }
1879db0284f8SMax Reitz 
1880db0284f8SMax Reitz bool blk_is_available(BlockBackend *blk)
1881db0284f8SMax Reitz {
1882db0284f8SMax Reitz     return blk_is_inserted(blk) && !blk_dev_is_tray_open(blk);
18834be74634SMarkus Armbruster }
18844be74634SMarkus Armbruster 
18854be74634SMarkus Armbruster void blk_lock_medium(BlockBackend *blk, bool locked)
18864be74634SMarkus Armbruster {
1887f21d96d0SKevin Wolf     BlockDriverState *bs = blk_bs(blk);
1888f21d96d0SKevin Wolf 
1889f21d96d0SKevin Wolf     if (bs) {
1890f21d96d0SKevin Wolf         bdrv_lock_medium(bs, locked);
18914be74634SMarkus Armbruster     }
1892a46fc9c9SMax Reitz }
18934be74634SMarkus Armbruster 
18944be74634SMarkus Armbruster void blk_eject(BlockBackend *blk, bool eject_flag)
18954be74634SMarkus Armbruster {
1896f21d96d0SKevin Wolf     BlockDriverState *bs = blk_bs(blk);
18972d76e724SKevin Wolf     char *id;
18982d76e724SKevin Wolf 
1899f21d96d0SKevin Wolf     if (bs) {
1900f21d96d0SKevin Wolf         bdrv_eject(bs, eject_flag);
1901c47ee043SJohn Snow     }
19022d76e724SKevin Wolf 
1903c47ee043SJohn Snow     /* Whether or not we ejected on the backend,
1904c47ee043SJohn Snow      * the frontend experienced a tray event. */
19052d76e724SKevin Wolf     id = blk_get_attached_dev_id(blk);
19062d76e724SKevin Wolf     qapi_event_send_device_tray_moved(blk_name(blk), id,
19073ab72385SPeter Xu                                       eject_flag);
19082d76e724SKevin Wolf     g_free(id);
1909a46fc9c9SMax Reitz }
19104be74634SMarkus Armbruster 
19114be74634SMarkus Armbruster int blk_get_flags(BlockBackend *blk)
19124be74634SMarkus Armbruster {
1913f21d96d0SKevin Wolf     BlockDriverState *bs = blk_bs(blk);
1914f21d96d0SKevin Wolf 
1915f21d96d0SKevin Wolf     if (bs) {
1916f21d96d0SKevin Wolf         return bdrv_get_flags(bs);
1917061959e8SMax Reitz     } else {
1918061959e8SMax Reitz         return blk->root_state.open_flags;
1919061959e8SMax Reitz     }
19204be74634SMarkus Armbruster }
19214be74634SMarkus Armbruster 
19224841211eSEric Blake /* Returns the minimum request alignment, in bytes; guaranteed nonzero */
19234841211eSEric Blake uint32_t blk_get_request_alignment(BlockBackend *blk)
19244841211eSEric Blake {
19254841211eSEric Blake     BlockDriverState *bs = blk_bs(blk);
19264841211eSEric Blake     return bs ? bs->bl.request_alignment : BDRV_SECTOR_SIZE;
19274841211eSEric Blake }
19284841211eSEric Blake 
19295def6b80SEric Blake /* Returns the maximum transfer length, in bytes; guaranteed nonzero */
19305def6b80SEric Blake uint32_t blk_get_max_transfer(BlockBackend *blk)
1931454057b7SPeter Lieven {
1932f21d96d0SKevin Wolf     BlockDriverState *bs = blk_bs(blk);
19335def6b80SEric Blake     uint32_t max = 0;
1934f21d96d0SKevin Wolf 
1935f21d96d0SKevin Wolf     if (bs) {
19365def6b80SEric Blake         max = bs->bl.max_transfer;
1937a46fc9c9SMax Reitz     }
19385def6b80SEric Blake     return MIN_NON_ZERO(max, INT_MAX);
1939454057b7SPeter Lieven }
1940454057b7SPeter Lieven 
1941648296e0SStefan Hajnoczi int blk_get_max_iov(BlockBackend *blk)
1942648296e0SStefan Hajnoczi {
1943f21d96d0SKevin Wolf     return blk->root->bs->bl.max_iov;
1944648296e0SStefan Hajnoczi }
1945648296e0SStefan Hajnoczi 
19464be74634SMarkus Armbruster void blk_set_guest_block_size(BlockBackend *blk, int align)
19474be74634SMarkus Armbruster {
194868e9ec01SMax Reitz     blk->guest_block_size = align;
19494be74634SMarkus Armbruster }
19504be74634SMarkus Armbruster 
1951f1c17521SPaolo Bonzini void *blk_try_blockalign(BlockBackend *blk, size_t size)
1952f1c17521SPaolo Bonzini {
1953f21d96d0SKevin Wolf     return qemu_try_blockalign(blk ? blk_bs(blk) : NULL, size);
1954f1c17521SPaolo Bonzini }
1955f1c17521SPaolo Bonzini 
19564be74634SMarkus Armbruster void *blk_blockalign(BlockBackend *blk, size_t size)
19574be74634SMarkus Armbruster {
1958f21d96d0SKevin Wolf     return qemu_blockalign(blk ? blk_bs(blk) : NULL, size);
19594be74634SMarkus Armbruster }
19604be74634SMarkus Armbruster 
19614be74634SMarkus Armbruster bool blk_op_is_blocked(BlockBackend *blk, BlockOpType op, Error **errp)
19624be74634SMarkus Armbruster {
1963f21d96d0SKevin Wolf     BlockDriverState *bs = blk_bs(blk);
1964f21d96d0SKevin Wolf 
1965f21d96d0SKevin Wolf     if (!bs) {
1966a46fc9c9SMax Reitz         return false;
1967a46fc9c9SMax Reitz     }
1968a46fc9c9SMax Reitz 
1969f21d96d0SKevin Wolf     return bdrv_op_is_blocked(bs, op, errp);
19704be74634SMarkus Armbruster }
19714be74634SMarkus Armbruster 
19724be74634SMarkus Armbruster void blk_op_unblock(BlockBackend *blk, BlockOpType op, Error *reason)
19734be74634SMarkus Armbruster {
1974f21d96d0SKevin Wolf     BlockDriverState *bs = blk_bs(blk);
1975f21d96d0SKevin Wolf 
1976f21d96d0SKevin Wolf     if (bs) {
1977f21d96d0SKevin Wolf         bdrv_op_unblock(bs, op, reason);
19784be74634SMarkus Armbruster     }
1979a46fc9c9SMax Reitz }
19804be74634SMarkus Armbruster 
19814be74634SMarkus Armbruster void blk_op_block_all(BlockBackend *blk, Error *reason)
19824be74634SMarkus Armbruster {
1983f21d96d0SKevin Wolf     BlockDriverState *bs = blk_bs(blk);
1984f21d96d0SKevin Wolf 
1985f21d96d0SKevin Wolf     if (bs) {
1986f21d96d0SKevin Wolf         bdrv_op_block_all(bs, reason);
19874be74634SMarkus Armbruster     }
1988a46fc9c9SMax Reitz }
19894be74634SMarkus Armbruster 
19904be74634SMarkus Armbruster void blk_op_unblock_all(BlockBackend *blk, Error *reason)
19914be74634SMarkus Armbruster {
1992f21d96d0SKevin Wolf     BlockDriverState *bs = blk_bs(blk);
1993f21d96d0SKevin Wolf 
1994f21d96d0SKevin Wolf     if (bs) {
1995f21d96d0SKevin Wolf         bdrv_op_unblock_all(bs, reason);
19964be74634SMarkus Armbruster     }
1997a46fc9c9SMax Reitz }
19984be74634SMarkus Armbruster 
19994be74634SMarkus Armbruster AioContext *blk_get_aio_context(BlockBackend *blk)
20004be74634SMarkus Armbruster {
2001d861ab3aSKevin Wolf     BlockDriverState *bs = blk_bs(blk);
2002d861ab3aSKevin Wolf 
2003d861ab3aSKevin Wolf     if (bs) {
2004132ada80SKevin Wolf         AioContext *ctx = bdrv_get_aio_context(blk_bs(blk));
2005132ada80SKevin Wolf         assert(ctx == blk->ctx);
20064981bdecSMax Reitz     }
20074981bdecSMax Reitz 
2008d861ab3aSKevin Wolf     return blk->ctx;
2009d861ab3aSKevin Wolf }
2010d861ab3aSKevin Wolf 
20114981bdecSMax Reitz static AioContext *blk_aiocb_get_aio_context(BlockAIOCB *acb)
20124981bdecSMax Reitz {
20134981bdecSMax Reitz     BlockBackendAIOCB *blk_acb = DO_UPCAST(BlockBackendAIOCB, common, acb);
20144981bdecSMax Reitz     return blk_get_aio_context(blk_acb->blk);
20154be74634SMarkus Armbruster }
20164be74634SMarkus Armbruster 
201797896a48SKevin Wolf static int blk_do_set_aio_context(BlockBackend *blk, AioContext *new_context,
201897896a48SKevin Wolf                                   bool update_root_node, Error **errp)
20194be74634SMarkus Armbruster {
2020f21d96d0SKevin Wolf     BlockDriverState *bs = blk_bs(blk);
2021c61791fcSManos Pitsidianakis     ThrottleGroupMember *tgm = &blk->public.throttle_group_member;
202297896a48SKevin Wolf     int ret;
2023f21d96d0SKevin Wolf 
2024f21d96d0SKevin Wolf     if (bs) {
202597896a48SKevin Wolf         if (update_root_node) {
202697896a48SKevin Wolf             ret = bdrv_child_try_set_aio_context(bs, new_context, blk->root,
202797896a48SKevin Wolf                                                  errp);
202897896a48SKevin Wolf             if (ret < 0) {
202997896a48SKevin Wolf                 return ret;
203097896a48SKevin Wolf             }
203197896a48SKevin Wolf         }
2032c61791fcSManos Pitsidianakis         if (tgm->throttle_state) {
2033dc868fb0SStefan Hajnoczi             bdrv_drained_begin(bs);
2034c61791fcSManos Pitsidianakis             throttle_group_detach_aio_context(tgm);
2035c61791fcSManos Pitsidianakis             throttle_group_attach_aio_context(tgm, new_context);
2036dc868fb0SStefan Hajnoczi             bdrv_drained_end(bs);
20377ca7f0f6SKevin Wolf         }
203838475269SKevin Wolf     }
203938475269SKevin Wolf 
2040d861ab3aSKevin Wolf     blk->ctx = new_context;
204197896a48SKevin Wolf     return 0;
204297896a48SKevin Wolf }
204397896a48SKevin Wolf 
204497896a48SKevin Wolf int blk_set_aio_context(BlockBackend *blk, AioContext *new_context,
204597896a48SKevin Wolf                         Error **errp)
204638475269SKevin Wolf {
204797896a48SKevin Wolf     return blk_do_set_aio_context(blk, new_context, true, errp);
204838475269SKevin Wolf }
204938475269SKevin Wolf 
205038475269SKevin Wolf static bool blk_root_can_set_aio_ctx(BdrvChild *child, AioContext *ctx,
205138475269SKevin Wolf                                      GSList **ignore, Error **errp)
205238475269SKevin Wolf {
205338475269SKevin Wolf     BlockBackend *blk = child->opaque;
205438475269SKevin Wolf 
2055980b0f94SKevin Wolf     if (blk->allow_aio_context_change) {
2056980b0f94SKevin Wolf         return true;
2057980b0f94SKevin Wolf     }
2058980b0f94SKevin Wolf 
205938475269SKevin Wolf     /* Only manually created BlockBackends that are not attached to anything
206038475269SKevin Wolf      * can change their AioContext without updating their user. */
206138475269SKevin Wolf     if (!blk->name || blk->dev) {
206238475269SKevin Wolf         /* TODO Add BB name/QOM path */
206338475269SKevin Wolf         error_setg(errp, "Cannot change iothread of active block backend");
206438475269SKevin Wolf         return false;
206538475269SKevin Wolf     }
206638475269SKevin Wolf 
206738475269SKevin Wolf     return true;
206838475269SKevin Wolf }
206938475269SKevin Wolf 
207038475269SKevin Wolf static void blk_root_set_aio_ctx(BdrvChild *child, AioContext *ctx,
207138475269SKevin Wolf                                  GSList **ignore)
207238475269SKevin Wolf {
207338475269SKevin Wolf     BlockBackend *blk = child->opaque;
207497896a48SKevin Wolf     blk_do_set_aio_context(blk, ctx, false, &error_abort);
207538475269SKevin Wolf }
20764be74634SMarkus Armbruster 
20772019ba0aSMax Reitz void blk_add_aio_context_notifier(BlockBackend *blk,
20782019ba0aSMax Reitz         void (*attached_aio_context)(AioContext *new_context, void *opaque),
20792019ba0aSMax Reitz         void (*detach_aio_context)(void *opaque), void *opaque)
20802019ba0aSMax Reitz {
2081d03654eaSStefan Hajnoczi     BlockBackendAioNotifier *notifier;
2082f21d96d0SKevin Wolf     BlockDriverState *bs = blk_bs(blk);
2083f21d96d0SKevin Wolf 
2084d03654eaSStefan Hajnoczi     notifier = g_new(BlockBackendAioNotifier, 1);
2085d03654eaSStefan Hajnoczi     notifier->attached_aio_context = attached_aio_context;
2086d03654eaSStefan Hajnoczi     notifier->detach_aio_context = detach_aio_context;
2087d03654eaSStefan Hajnoczi     notifier->opaque = opaque;
2088d03654eaSStefan Hajnoczi     QLIST_INSERT_HEAD(&blk->aio_notifiers, notifier, list);
2089d03654eaSStefan Hajnoczi 
2090f21d96d0SKevin Wolf     if (bs) {
2091f21d96d0SKevin Wolf         bdrv_add_aio_context_notifier(bs, attached_aio_context,
20922019ba0aSMax Reitz                                       detach_aio_context, opaque);
20932019ba0aSMax Reitz     }
2094a46fc9c9SMax Reitz }
20952019ba0aSMax Reitz 
20962019ba0aSMax Reitz void blk_remove_aio_context_notifier(BlockBackend *blk,
20972019ba0aSMax Reitz                                      void (*attached_aio_context)(AioContext *,
20982019ba0aSMax Reitz                                                                   void *),
20992019ba0aSMax Reitz                                      void (*detach_aio_context)(void *),
21002019ba0aSMax Reitz                                      void *opaque)
21012019ba0aSMax Reitz {
2102d03654eaSStefan Hajnoczi     BlockBackendAioNotifier *notifier;
2103f21d96d0SKevin Wolf     BlockDriverState *bs = blk_bs(blk);
2104f21d96d0SKevin Wolf 
2105f21d96d0SKevin Wolf     if (bs) {
2106f21d96d0SKevin Wolf         bdrv_remove_aio_context_notifier(bs, attached_aio_context,
21072019ba0aSMax Reitz                                          detach_aio_context, opaque);
21082019ba0aSMax Reitz     }
2109d03654eaSStefan Hajnoczi 
2110d03654eaSStefan Hajnoczi     QLIST_FOREACH(notifier, &blk->aio_notifiers, list) {
2111d03654eaSStefan Hajnoczi         if (notifier->attached_aio_context == attached_aio_context &&
2112d03654eaSStefan Hajnoczi             notifier->detach_aio_context == detach_aio_context &&
2113d03654eaSStefan Hajnoczi             notifier->opaque == opaque) {
2114d03654eaSStefan Hajnoczi             QLIST_REMOVE(notifier, list);
2115d03654eaSStefan Hajnoczi             g_free(notifier);
2116d03654eaSStefan Hajnoczi             return;
2117d03654eaSStefan Hajnoczi         }
2118d03654eaSStefan Hajnoczi     }
2119d03654eaSStefan Hajnoczi 
2120d03654eaSStefan Hajnoczi     abort();
2121a46fc9c9SMax Reitz }
21222019ba0aSMax Reitz 
21233301f6c6SMax Reitz void blk_add_remove_bs_notifier(BlockBackend *blk, Notifier *notify)
21243301f6c6SMax Reitz {
21253301f6c6SMax Reitz     notifier_list_add(&blk->remove_bs_notifiers, notify);
21263301f6c6SMax Reitz }
21273301f6c6SMax Reitz 
21283301f6c6SMax Reitz void blk_add_insert_bs_notifier(BlockBackend *blk, Notifier *notify)
21293301f6c6SMax Reitz {
21303301f6c6SMax Reitz     notifier_list_add(&blk->insert_bs_notifiers, notify);
21313301f6c6SMax Reitz }
21323301f6c6SMax Reitz 
21334be74634SMarkus Armbruster void blk_io_plug(BlockBackend *blk)
21344be74634SMarkus Armbruster {
2135f21d96d0SKevin Wolf     BlockDriverState *bs = blk_bs(blk);
2136f21d96d0SKevin Wolf 
2137f21d96d0SKevin Wolf     if (bs) {
2138f21d96d0SKevin Wolf         bdrv_io_plug(bs);
21394be74634SMarkus Armbruster     }
2140a46fc9c9SMax Reitz }
21414be74634SMarkus Armbruster 
21424be74634SMarkus Armbruster void blk_io_unplug(BlockBackend *blk)
21434be74634SMarkus Armbruster {
2144f21d96d0SKevin Wolf     BlockDriverState *bs = blk_bs(blk);
2145f21d96d0SKevin Wolf 
2146f21d96d0SKevin Wolf     if (bs) {
2147f21d96d0SKevin Wolf         bdrv_io_unplug(bs);
21484be74634SMarkus Armbruster     }
2149a46fc9c9SMax Reitz }
21504be74634SMarkus Armbruster 
21514be74634SMarkus Armbruster BlockAcctStats *blk_get_stats(BlockBackend *blk)
21524be74634SMarkus Armbruster {
21537f0e9da6SMax Reitz     return &blk->stats;
21544be74634SMarkus Armbruster }
21554be74634SMarkus Armbruster 
21564be74634SMarkus Armbruster void *blk_aio_get(const AIOCBInfo *aiocb_info, BlockBackend *blk,
21574be74634SMarkus Armbruster                   BlockCompletionFunc *cb, void *opaque)
21584be74634SMarkus Armbruster {
21594be74634SMarkus Armbruster     return qemu_aio_get(aiocb_info, blk_bs(blk), cb, opaque);
21604be74634SMarkus Armbruster }
21611ef01253SMax Reitz 
2162d004bd52SEric Blake int coroutine_fn blk_co_pwrite_zeroes(BlockBackend *blk, int64_t offset,
2163f5a5ca79SManos Pitsidianakis                                       int bytes, BdrvRequestFlags flags)
21641ef01253SMax Reitz {
2165f5a5ca79SManos Pitsidianakis     return blk_co_pwritev(blk, offset, bytes, NULL,
216616aaf975SKevin Wolf                           flags | BDRV_REQ_ZERO_WRITE);
21671ef01253SMax Reitz }
21681ef01253SMax Reitz 
2169fe5c1355SPavel Butsykin int blk_pwrite_compressed(BlockBackend *blk, int64_t offset, const void *buf,
2170fe5c1355SPavel Butsykin                           int count)
21711ef01253SMax Reitz {
217235fadca8SPavel Butsykin     return blk_prw(blk, offset, (void *) buf, count, blk_write_entry,
217335fadca8SPavel Butsykin                    BDRV_REQ_WRITE_COMPRESSED);
21741ef01253SMax Reitz }
21751ef01253SMax Reitz 
2176c80d8b06SMax Reitz int blk_truncate(BlockBackend *blk, int64_t offset, bool exact,
21778c6242b6SKevin Wolf                  PreallocMode prealloc, BdrvRequestFlags flags, Error **errp)
21781ef01253SMax Reitz {
2179c09ba36cSMax Reitz     if (!blk_is_available(blk)) {
2180ed3d2ec9SMax Reitz         error_setg(errp, "No medium inserted");
2181c09ba36cSMax Reitz         return -ENOMEDIUM;
2182c09ba36cSMax Reitz     }
2183c09ba36cSMax Reitz 
21848c6242b6SKevin Wolf     return bdrv_truncate(blk->root, offset, exact, prealloc, flags, errp);
21851ef01253SMax Reitz }
21861ef01253SMax Reitz 
21871ef01253SMax Reitz int blk_save_vmstate(BlockBackend *blk, const uint8_t *buf,
21881ef01253SMax Reitz                      int64_t pos, int size)
21891ef01253SMax Reitz {
2190bfd18d1eSKevin Wolf     int ret;
2191bfd18d1eSKevin Wolf 
2192c09ba36cSMax Reitz     if (!blk_is_available(blk)) {
2193c09ba36cSMax Reitz         return -ENOMEDIUM;
2194c09ba36cSMax Reitz     }
2195c09ba36cSMax Reitz 
2196bfd18d1eSKevin Wolf     ret = bdrv_save_vmstate(blk_bs(blk), buf, pos, size);
2197bfd18d1eSKevin Wolf     if (ret < 0) {
2198bfd18d1eSKevin Wolf         return ret;
2199bfd18d1eSKevin Wolf     }
2200bfd18d1eSKevin Wolf 
2201bfd18d1eSKevin Wolf     if (ret == size && !blk->enable_write_cache) {
2202bfd18d1eSKevin Wolf         ret = bdrv_flush(blk_bs(blk));
2203bfd18d1eSKevin Wolf     }
2204bfd18d1eSKevin Wolf 
2205bfd18d1eSKevin Wolf     return ret < 0 ? ret : size;
22061ef01253SMax Reitz }
22071ef01253SMax Reitz 
22081ef01253SMax Reitz int blk_load_vmstate(BlockBackend *blk, uint8_t *buf, int64_t pos, int size)
22091ef01253SMax Reitz {
2210c09ba36cSMax Reitz     if (!blk_is_available(blk)) {
2211c09ba36cSMax Reitz         return -ENOMEDIUM;
2212c09ba36cSMax Reitz     }
2213c09ba36cSMax Reitz 
2214f21d96d0SKevin Wolf     return bdrv_load_vmstate(blk_bs(blk), buf, pos, size);
22151ef01253SMax Reitz }
2216f0272c4dSEkaterina Tumanova 
2217f0272c4dSEkaterina Tumanova int blk_probe_blocksizes(BlockBackend *blk, BlockSizes *bsz)
2218f0272c4dSEkaterina Tumanova {
2219c09ba36cSMax Reitz     if (!blk_is_available(blk)) {
2220c09ba36cSMax Reitz         return -ENOMEDIUM;
2221c09ba36cSMax Reitz     }
2222c09ba36cSMax Reitz 
2223f21d96d0SKevin Wolf     return bdrv_probe_blocksizes(blk_bs(blk), bsz);
2224f0272c4dSEkaterina Tumanova }
2225f0272c4dSEkaterina Tumanova 
2226f0272c4dSEkaterina Tumanova int blk_probe_geometry(BlockBackend *blk, HDGeometry *geo)
2227f0272c4dSEkaterina Tumanova {
2228c09ba36cSMax Reitz     if (!blk_is_available(blk)) {
2229c09ba36cSMax Reitz         return -ENOMEDIUM;
2230c09ba36cSMax Reitz     }
2231c09ba36cSMax Reitz 
2232f21d96d0SKevin Wolf     return bdrv_probe_geometry(blk_bs(blk), geo);
2233f0272c4dSEkaterina Tumanova }
2234281d22d8SMax Reitz 
2235281d22d8SMax Reitz /*
2236281d22d8SMax Reitz  * Updates the BlockBackendRootState object with data from the currently
2237281d22d8SMax Reitz  * attached BlockDriverState.
2238281d22d8SMax Reitz  */
2239281d22d8SMax Reitz void blk_update_root_state(BlockBackend *blk)
2240281d22d8SMax Reitz {
2241f21d96d0SKevin Wolf     assert(blk->root);
2242281d22d8SMax Reitz 
2243f21d96d0SKevin Wolf     blk->root_state.open_flags    = blk->root->bs->open_flags;
2244f21d96d0SKevin Wolf     blk->root_state.read_only     = blk->root->bs->read_only;
2245f21d96d0SKevin Wolf     blk->root_state.detect_zeroes = blk->root->bs->detect_zeroes;
2246281d22d8SMax Reitz }
2247281d22d8SMax Reitz 
224838cb18f5SMax Reitz /*
2249b85114f8SKevin Wolf  * Returns the detect-zeroes setting to be used for bdrv_open() of a
2250b85114f8SKevin Wolf  * BlockDriverState which is supposed to inherit the root state.
225138cb18f5SMax Reitz  */
2252b85114f8SKevin Wolf bool blk_get_detect_zeroes_from_root_state(BlockBackend *blk)
225338cb18f5SMax Reitz {
2254b85114f8SKevin Wolf     return blk->root_state.detect_zeroes;
225538cb18f5SMax Reitz }
225638cb18f5SMax Reitz 
225738cb18f5SMax Reitz /*
225838cb18f5SMax Reitz  * Returns the flags to be used for bdrv_open() of a BlockDriverState which is
225938cb18f5SMax Reitz  * supposed to inherit the root state.
226038cb18f5SMax Reitz  */
226138cb18f5SMax Reitz int blk_get_open_flags_from_root_state(BlockBackend *blk)
226238cb18f5SMax Reitz {
226338cb18f5SMax Reitz     int bs_flags;
226438cb18f5SMax Reitz 
226538cb18f5SMax Reitz     bs_flags = blk->root_state.read_only ? 0 : BDRV_O_RDWR;
226638cb18f5SMax Reitz     bs_flags |= blk->root_state.open_flags & ~BDRV_O_RDWR;
226738cb18f5SMax Reitz 
226838cb18f5SMax Reitz     return bs_flags;
226938cb18f5SMax Reitz }
227038cb18f5SMax Reitz 
2271281d22d8SMax Reitz BlockBackendRootState *blk_get_root_state(BlockBackend *blk)
2272281d22d8SMax Reitz {
2273281d22d8SMax Reitz     return &blk->root_state;
2274281d22d8SMax Reitz }
22751393f212SMax Reitz 
22761393f212SMax Reitz int blk_commit_all(void)
22771393f212SMax Reitz {
2278fe1a9cbcSMax Reitz     BlockBackend *blk = NULL;
2279fe1a9cbcSMax Reitz 
2280fe1a9cbcSMax Reitz     while ((blk = blk_all_next(blk)) != NULL) {
2281fe1a9cbcSMax Reitz         AioContext *aio_context = blk_get_aio_context(blk);
2282*9a71b9deSMax Reitz         BlockDriverState *unfiltered_bs = bdrv_skip_filters(blk_bs(blk));
2283fe1a9cbcSMax Reitz 
2284fe1a9cbcSMax Reitz         aio_context_acquire(aio_context);
2285*9a71b9deSMax Reitz         if (blk_is_inserted(blk) && bdrv_cow_child(unfiltered_bs)) {
2286*9a71b9deSMax Reitz             int ret;
2287*9a71b9deSMax Reitz 
2288*9a71b9deSMax Reitz             ret = bdrv_commit(unfiltered_bs);
2289fe1a9cbcSMax Reitz             if (ret < 0) {
2290fe1a9cbcSMax Reitz                 aio_context_release(aio_context);
2291fe1a9cbcSMax Reitz                 return ret;
2292fe1a9cbcSMax Reitz             }
2293fe1a9cbcSMax Reitz         }
2294fe1a9cbcSMax Reitz         aio_context_release(aio_context);
2295fe1a9cbcSMax Reitz     }
2296fe1a9cbcSMax Reitz     return 0;
2297fe1a9cbcSMax Reitz }
2298fe1a9cbcSMax Reitz 
229997148076SKevin Wolf 
230097148076SKevin Wolf /* throttling disk I/O limits */
230197148076SKevin Wolf void blk_set_io_limits(BlockBackend *blk, ThrottleConfig *cfg)
230297148076SKevin Wolf {
2303022cdc9fSManos Pitsidianakis     throttle_group_config(&blk->public.throttle_group_member, cfg);
230497148076SKevin Wolf }
230597148076SKevin Wolf 
230697148076SKevin Wolf void blk_io_limits_disable(BlockBackend *blk)
230797148076SKevin Wolf {
230848bf7ea8SAlberto Garcia     BlockDriverState *bs = blk_bs(blk);
230948bf7ea8SAlberto Garcia     ThrottleGroupMember *tgm = &blk->public.throttle_group_member;
231048bf7ea8SAlberto Garcia     assert(tgm->throttle_state);
231148bf7ea8SAlberto Garcia     if (bs) {
231248bf7ea8SAlberto Garcia         bdrv_drained_begin(bs);
231348bf7ea8SAlberto Garcia     }
231448bf7ea8SAlberto Garcia     throttle_group_unregister_tgm(tgm);
231548bf7ea8SAlberto Garcia     if (bs) {
231648bf7ea8SAlberto Garcia         bdrv_drained_end(bs);
231748bf7ea8SAlberto Garcia     }
231897148076SKevin Wolf }
231997148076SKevin Wolf 
232097148076SKevin Wolf /* should be called before blk_set_io_limits if a limit is set */
232197148076SKevin Wolf void blk_io_limits_enable(BlockBackend *blk, const char *group)
232297148076SKevin Wolf {
2323022cdc9fSManos Pitsidianakis     assert(!blk->public.throttle_group_member.throttle_state);
2324c61791fcSManos Pitsidianakis     throttle_group_register_tgm(&blk->public.throttle_group_member,
2325c61791fcSManos Pitsidianakis                                 group, blk_get_aio_context(blk));
232697148076SKevin Wolf }
232797148076SKevin Wolf 
232897148076SKevin Wolf void blk_io_limits_update_group(BlockBackend *blk, const char *group)
232997148076SKevin Wolf {
233097148076SKevin Wolf     /* this BB is not part of any group */
2331022cdc9fSManos Pitsidianakis     if (!blk->public.throttle_group_member.throttle_state) {
233297148076SKevin Wolf         return;
233397148076SKevin Wolf     }
233497148076SKevin Wolf 
233597148076SKevin Wolf     /* this BB is a part of the same group than the one we want */
2336022cdc9fSManos Pitsidianakis     if (!g_strcmp0(throttle_group_get_name(&blk->public.throttle_group_member),
2337022cdc9fSManos Pitsidianakis                 group)) {
233897148076SKevin Wolf         return;
233997148076SKevin Wolf     }
234097148076SKevin Wolf 
234197148076SKevin Wolf     /* need to change the group this bs belong to */
234297148076SKevin Wolf     blk_io_limits_disable(blk);
234397148076SKevin Wolf     blk_io_limits_enable(blk, group);
234497148076SKevin Wolf }
2345c2066af0SKevin Wolf 
2346c2066af0SKevin Wolf static void blk_root_drained_begin(BdrvChild *child)
2347c2066af0SKevin Wolf {
2348c2066af0SKevin Wolf     BlockBackend *blk = child->opaque;
2349c2066af0SKevin Wolf 
2350f4d9cc88SJohn Snow     if (++blk->quiesce_counter == 1) {
2351f4d9cc88SJohn Snow         if (blk->dev_ops && blk->dev_ops->drained_begin) {
2352f4d9cc88SJohn Snow             blk->dev_ops->drained_begin(blk->dev_opaque);
2353f4d9cc88SJohn Snow         }
2354f4d9cc88SJohn Snow     }
2355f4d9cc88SJohn Snow 
235636fe1331SKevin Wolf     /* Note that blk->root may not be accessible here yet if we are just
235736fe1331SKevin Wolf      * attaching to a BlockDriverState that is drained. Use child instead. */
235836fe1331SKevin Wolf 
2359022cdc9fSManos Pitsidianakis     if (atomic_fetch_inc(&blk->public.throttle_group_member.io_limits_disabled) == 0) {
2360022cdc9fSManos Pitsidianakis         throttle_group_restart_tgm(&blk->public.throttle_group_member);
2361c2066af0SKevin Wolf     }
2362c2066af0SKevin Wolf }
2363c2066af0SKevin Wolf 
2364fe5258a5SKevin Wolf static bool blk_root_drained_poll(BdrvChild *child)
2365fe5258a5SKevin Wolf {
2366fe5258a5SKevin Wolf     BlockBackend *blk = child->opaque;
2367fe5258a5SKevin Wolf     assert(blk->quiesce_counter);
2368fe5258a5SKevin Wolf     return !!blk->in_flight;
2369fe5258a5SKevin Wolf }
2370fe5258a5SKevin Wolf 
2371e037c09cSMax Reitz static void blk_root_drained_end(BdrvChild *child, int *drained_end_counter)
2372c2066af0SKevin Wolf {
2373c2066af0SKevin Wolf     BlockBackend *blk = child->opaque;
2374f4d9cc88SJohn Snow     assert(blk->quiesce_counter);
2375c2066af0SKevin Wolf 
2376022cdc9fSManos Pitsidianakis     assert(blk->public.throttle_group_member.io_limits_disabled);
2377022cdc9fSManos Pitsidianakis     atomic_dec(&blk->public.throttle_group_member.io_limits_disabled);
2378f4d9cc88SJohn Snow 
2379f4d9cc88SJohn Snow     if (--blk->quiesce_counter == 0) {
2380f4d9cc88SJohn Snow         if (blk->dev_ops && blk->dev_ops->drained_end) {
2381f4d9cc88SJohn Snow             blk->dev_ops->drained_end(blk->dev_opaque);
2382f4d9cc88SJohn Snow         }
2383cf312932SKevin Wolf         while (qemu_co_enter_next(&blk->queued_requests, NULL)) {
2384cf312932SKevin Wolf             /* Resume all queued requests */
2385cf312932SKevin Wolf         }
2386f4d9cc88SJohn Snow     }
2387c2066af0SKevin Wolf }
238823d0ba93SFam Zheng 
238923d0ba93SFam Zheng void blk_register_buf(BlockBackend *blk, void *host, size_t size)
239023d0ba93SFam Zheng {
239123d0ba93SFam Zheng     bdrv_register_buf(blk_bs(blk), host, size);
239223d0ba93SFam Zheng }
239323d0ba93SFam Zheng 
239423d0ba93SFam Zheng void blk_unregister_buf(BlockBackend *blk, void *host)
239523d0ba93SFam Zheng {
239623d0ba93SFam Zheng     bdrv_unregister_buf(blk_bs(blk), host);
239723d0ba93SFam Zheng }
2398b5679fa4SFam Zheng 
2399b5679fa4SFam Zheng int coroutine_fn blk_co_copy_range(BlockBackend *blk_in, int64_t off_in,
2400b5679fa4SFam Zheng                                    BlockBackend *blk_out, int64_t off_out,
240167b51fb9SVladimir Sementsov-Ogievskiy                                    int bytes, BdrvRequestFlags read_flags,
240267b51fb9SVladimir Sementsov-Ogievskiy                                    BdrvRequestFlags write_flags)
2403b5679fa4SFam Zheng {
2404b5679fa4SFam Zheng     int r;
2405b5679fa4SFam Zheng     r = blk_check_byte_request(blk_in, off_in, bytes);
2406b5679fa4SFam Zheng     if (r) {
2407b5679fa4SFam Zheng         return r;
2408b5679fa4SFam Zheng     }
2409b5679fa4SFam Zheng     r = blk_check_byte_request(blk_out, off_out, bytes);
2410b5679fa4SFam Zheng     if (r) {
2411b5679fa4SFam Zheng         return r;
2412b5679fa4SFam Zheng     }
2413b5679fa4SFam Zheng     return bdrv_co_copy_range(blk_in->root, off_in,
2414b5679fa4SFam Zheng                               blk_out->root, off_out,
241567b51fb9SVladimir Sementsov-Ogievskiy                               bytes, read_flags, write_flags);
2416b5679fa4SFam Zheng }
24175d3b4e99SVladimir Sementsov-Ogievskiy 
24185d3b4e99SVladimir Sementsov-Ogievskiy const BdrvChild *blk_root(BlockBackend *blk)
24195d3b4e99SVladimir Sementsov-Ogievskiy {
24205d3b4e99SVladimir Sementsov-Ogievskiy     return blk->root;
24215d3b4e99SVladimir Sementsov-Ogievskiy }
24222b7bbdbdSMax Reitz 
24232b7bbdbdSMax Reitz int blk_make_empty(BlockBackend *blk, Error **errp)
24242b7bbdbdSMax Reitz {
24252b7bbdbdSMax Reitz     if (!blk_is_available(blk)) {
24262b7bbdbdSMax Reitz         error_setg(errp, "No medium inserted");
24272b7bbdbdSMax Reitz         return -ENOMEDIUM;
24282b7bbdbdSMax Reitz     }
24292b7bbdbdSMax Reitz 
24302b7bbdbdSMax Reitz     return bdrv_make_empty(blk->root, errp);
24312b7bbdbdSMax Reitz }
2432