xref: /qemu/block/block-backend.c (revision 84ebe375)
126f54e9aSMarkus Armbruster /*
226f54e9aSMarkus Armbruster  * QEMU Block backends
326f54e9aSMarkus Armbruster  *
426f54e9aSMarkus Armbruster  * Copyright (C) 2014 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 
1326f54e9aSMarkus Armbruster #include "sysemu/block-backend.h"
1426f54e9aSMarkus Armbruster #include "block/block_int.h"
1518e46a03SMarkus Armbruster #include "sysemu/blockdev.h"
16a7f53e26SMarkus Armbruster #include "qapi-event.h"
17a7f53e26SMarkus Armbruster 
18a7f53e26SMarkus Armbruster /* Number of coroutines to reserve per attached device model */
19a7f53e26SMarkus Armbruster #define COROUTINE_POOL_RESERVATION 64
2026f54e9aSMarkus Armbruster 
2126f54e9aSMarkus Armbruster struct BlockBackend {
2226f54e9aSMarkus Armbruster     char *name;
2326f54e9aSMarkus Armbruster     int refcnt;
247e7d56d9SMarkus Armbruster     BlockDriverState *bs;
2526f8b3a8SMarkus Armbruster     DriveInfo *legacy_dinfo;    /* null unless created by drive_new() */
2626f54e9aSMarkus Armbruster     QTAILQ_ENTRY(BlockBackend) link; /* for blk_backends */
27a7f53e26SMarkus Armbruster 
28a7f53e26SMarkus Armbruster     void *dev;                  /* attached device model, if any */
29a7f53e26SMarkus Armbruster     /* TODO change to DeviceState when all users are qdevified */
30a7f53e26SMarkus Armbruster     const BlockDevOps *dev_ops;
31a7f53e26SMarkus Armbruster     void *dev_opaque;
3226f54e9aSMarkus Armbruster };
3326f54e9aSMarkus Armbruster 
348fb3c76cSMarkus Armbruster static void drive_info_del(DriveInfo *dinfo);
358fb3c76cSMarkus Armbruster 
367e7d56d9SMarkus Armbruster /* All the BlockBackends (except for hidden ones) */
3726f54e9aSMarkus Armbruster static QTAILQ_HEAD(, BlockBackend) blk_backends =
3826f54e9aSMarkus Armbruster     QTAILQ_HEAD_INITIALIZER(blk_backends);
3926f54e9aSMarkus Armbruster 
4026f54e9aSMarkus Armbruster /*
4126f54e9aSMarkus Armbruster  * Create a new BlockBackend with @name, with a reference count of one.
4226f54e9aSMarkus Armbruster  * @name must not be null or empty.
4326f54e9aSMarkus Armbruster  * Fail if a BlockBackend with this name already exists.
4426f54e9aSMarkus Armbruster  * Store an error through @errp on failure, unless it's null.
4526f54e9aSMarkus Armbruster  * Return the new BlockBackend on success, null on failure.
4626f54e9aSMarkus Armbruster  */
4726f54e9aSMarkus Armbruster BlockBackend *blk_new(const char *name, Error **errp)
4826f54e9aSMarkus Armbruster {
4926f54e9aSMarkus Armbruster     BlockBackend *blk;
5026f54e9aSMarkus Armbruster 
5126f54e9aSMarkus Armbruster     assert(name && name[0]);
527f06d47eSMarkus Armbruster     if (!id_wellformed(name)) {
537f06d47eSMarkus Armbruster         error_setg(errp, "Invalid device name");
547f06d47eSMarkus Armbruster         return NULL;
557f06d47eSMarkus Armbruster     }
5626f54e9aSMarkus Armbruster     if (blk_by_name(name)) {
5726f54e9aSMarkus Armbruster         error_setg(errp, "Device with id '%s' already exists", name);
5826f54e9aSMarkus Armbruster         return NULL;
5926f54e9aSMarkus Armbruster     }
607f06d47eSMarkus Armbruster     if (bdrv_find_node(name)) {
617f06d47eSMarkus Armbruster         error_setg(errp,
627f06d47eSMarkus Armbruster                    "Device name '%s' conflicts with an existing node name",
637f06d47eSMarkus Armbruster                    name);
647f06d47eSMarkus Armbruster         return NULL;
657f06d47eSMarkus Armbruster     }
6626f54e9aSMarkus Armbruster 
6726f54e9aSMarkus Armbruster     blk = g_new0(BlockBackend, 1);
6826f54e9aSMarkus Armbruster     blk->name = g_strdup(name);
6926f54e9aSMarkus Armbruster     blk->refcnt = 1;
7026f54e9aSMarkus Armbruster     QTAILQ_INSERT_TAIL(&blk_backends, blk, link);
7126f54e9aSMarkus Armbruster     return blk;
7226f54e9aSMarkus Armbruster }
7326f54e9aSMarkus Armbruster 
747e7d56d9SMarkus Armbruster /*
757e7d56d9SMarkus Armbruster  * Create a new BlockBackend with a new BlockDriverState attached.
767e7d56d9SMarkus Armbruster  * Otherwise just like blk_new(), which see.
777e7d56d9SMarkus Armbruster  */
787e7d56d9SMarkus Armbruster BlockBackend *blk_new_with_bs(const char *name, Error **errp)
797e7d56d9SMarkus Armbruster {
807e7d56d9SMarkus Armbruster     BlockBackend *blk;
817e7d56d9SMarkus Armbruster     BlockDriverState *bs;
827e7d56d9SMarkus Armbruster 
837e7d56d9SMarkus Armbruster     blk = blk_new(name, errp);
847e7d56d9SMarkus Armbruster     if (!blk) {
857e7d56d9SMarkus Armbruster         return NULL;
867e7d56d9SMarkus Armbruster     }
877e7d56d9SMarkus Armbruster 
887f06d47eSMarkus Armbruster     bs = bdrv_new_root();
897e7d56d9SMarkus Armbruster     blk->bs = bs;
907e7d56d9SMarkus Armbruster     bs->blk = blk;
917e7d56d9SMarkus Armbruster     return blk;
927e7d56d9SMarkus Armbruster }
937e7d56d9SMarkus Armbruster 
9426f54e9aSMarkus Armbruster static void blk_delete(BlockBackend *blk)
9526f54e9aSMarkus Armbruster {
9626f54e9aSMarkus Armbruster     assert(!blk->refcnt);
97a7f53e26SMarkus Armbruster     assert(!blk->dev);
987e7d56d9SMarkus Armbruster     if (blk->bs) {
999ba10c95SMarkus Armbruster         assert(blk->bs->blk == blk);
1007e7d56d9SMarkus Armbruster         blk->bs->blk = NULL;
1019ba10c95SMarkus Armbruster         bdrv_unref(blk->bs);
1027e7d56d9SMarkus Armbruster         blk->bs = NULL;
1037e7d56d9SMarkus Armbruster     }
1047e7d56d9SMarkus Armbruster     /* Avoid double-remove after blk_hide_on_behalf_of_do_drive_del() */
1057e7d56d9SMarkus Armbruster     if (blk->name[0]) {
10626f54e9aSMarkus Armbruster         QTAILQ_REMOVE(&blk_backends, blk, link);
1077e7d56d9SMarkus Armbruster     }
10826f54e9aSMarkus Armbruster     g_free(blk->name);
10918e46a03SMarkus Armbruster     drive_info_del(blk->legacy_dinfo);
11026f54e9aSMarkus Armbruster     g_free(blk);
11126f54e9aSMarkus Armbruster }
11226f54e9aSMarkus Armbruster 
1138fb3c76cSMarkus Armbruster static void drive_info_del(DriveInfo *dinfo)
1148fb3c76cSMarkus Armbruster {
1158fb3c76cSMarkus Armbruster     if (!dinfo) {
1168fb3c76cSMarkus Armbruster         return;
1178fb3c76cSMarkus Armbruster     }
1188fb3c76cSMarkus Armbruster     qemu_opts_del(dinfo->opts);
1198fb3c76cSMarkus Armbruster     g_free(dinfo->serial);
1208fb3c76cSMarkus Armbruster     g_free(dinfo);
1218fb3c76cSMarkus Armbruster }
1228fb3c76cSMarkus Armbruster 
12326f54e9aSMarkus Armbruster /*
12426f54e9aSMarkus Armbruster  * Increment @blk's reference count.
12526f54e9aSMarkus Armbruster  * @blk must not be null.
12626f54e9aSMarkus Armbruster  */
12726f54e9aSMarkus Armbruster void blk_ref(BlockBackend *blk)
12826f54e9aSMarkus Armbruster {
12926f54e9aSMarkus Armbruster     blk->refcnt++;
13026f54e9aSMarkus Armbruster }
13126f54e9aSMarkus Armbruster 
13226f54e9aSMarkus Armbruster /*
13326f54e9aSMarkus Armbruster  * Decrement @blk's reference count.
13426f54e9aSMarkus Armbruster  * If this drops it to zero, destroy @blk.
13526f54e9aSMarkus Armbruster  * For convenience, do nothing if @blk is null.
13626f54e9aSMarkus Armbruster  */
13726f54e9aSMarkus Armbruster void blk_unref(BlockBackend *blk)
13826f54e9aSMarkus Armbruster {
13926f54e9aSMarkus Armbruster     if (blk) {
14026f54e9aSMarkus Armbruster         assert(blk->refcnt > 0);
14126f54e9aSMarkus Armbruster         if (!--blk->refcnt) {
14226f54e9aSMarkus Armbruster             blk_delete(blk);
14326f54e9aSMarkus Armbruster         }
14426f54e9aSMarkus Armbruster     }
14526f54e9aSMarkus Armbruster }
14626f54e9aSMarkus Armbruster 
14726f54e9aSMarkus Armbruster /*
14826f54e9aSMarkus Armbruster  * Return the BlockBackend after @blk.
14926f54e9aSMarkus Armbruster  * If @blk is null, return the first one.
15026f54e9aSMarkus Armbruster  * Else, return @blk's next sibling, which may be null.
15126f54e9aSMarkus Armbruster  *
15226f54e9aSMarkus Armbruster  * To iterate over all BlockBackends, do
15326f54e9aSMarkus Armbruster  * for (blk = blk_next(NULL); blk; blk = blk_next(blk)) {
15426f54e9aSMarkus Armbruster  *     ...
15526f54e9aSMarkus Armbruster  * }
15626f54e9aSMarkus Armbruster  */
15726f54e9aSMarkus Armbruster BlockBackend *blk_next(BlockBackend *blk)
15826f54e9aSMarkus Armbruster {
15926f54e9aSMarkus Armbruster     return blk ? QTAILQ_NEXT(blk, link) : QTAILQ_FIRST(&blk_backends);
16026f54e9aSMarkus Armbruster }
16126f54e9aSMarkus Armbruster 
16226f54e9aSMarkus Armbruster /*
1637e7d56d9SMarkus Armbruster  * Return @blk's name, a non-null string.
1647e7d56d9SMarkus Armbruster  * Wart: the name is empty iff @blk has been hidden with
1657e7d56d9SMarkus Armbruster  * blk_hide_on_behalf_of_do_drive_del().
16626f54e9aSMarkus Armbruster  */
16726f54e9aSMarkus Armbruster const char *blk_name(BlockBackend *blk)
16826f54e9aSMarkus Armbruster {
16926f54e9aSMarkus Armbruster     return blk->name;
17026f54e9aSMarkus Armbruster }
17126f54e9aSMarkus Armbruster 
17226f54e9aSMarkus Armbruster /*
17326f54e9aSMarkus Armbruster  * Return the BlockBackend with name @name if it exists, else null.
17426f54e9aSMarkus Armbruster  * @name must not be null.
17526f54e9aSMarkus Armbruster  */
17626f54e9aSMarkus Armbruster BlockBackend *blk_by_name(const char *name)
17726f54e9aSMarkus Armbruster {
17826f54e9aSMarkus Armbruster     BlockBackend *blk;
17926f54e9aSMarkus Armbruster 
18026f54e9aSMarkus Armbruster     assert(name);
18126f54e9aSMarkus Armbruster     QTAILQ_FOREACH(blk, &blk_backends, link) {
18226f54e9aSMarkus Armbruster         if (!strcmp(name, blk->name)) {
18326f54e9aSMarkus Armbruster             return blk;
18426f54e9aSMarkus Armbruster         }
18526f54e9aSMarkus Armbruster     }
18626f54e9aSMarkus Armbruster     return NULL;
18726f54e9aSMarkus Armbruster }
1887e7d56d9SMarkus Armbruster 
1897e7d56d9SMarkus Armbruster /*
1907e7d56d9SMarkus Armbruster  * Return the BlockDriverState attached to @blk if any, else null.
1917e7d56d9SMarkus Armbruster  */
1927e7d56d9SMarkus Armbruster BlockDriverState *blk_bs(BlockBackend *blk)
1937e7d56d9SMarkus Armbruster {
1947e7d56d9SMarkus Armbruster     return blk->bs;
1957e7d56d9SMarkus Armbruster }
1967e7d56d9SMarkus Armbruster 
1977e7d56d9SMarkus Armbruster /*
19818e46a03SMarkus Armbruster  * Return @blk's DriveInfo if any, else null.
19918e46a03SMarkus Armbruster  */
20018e46a03SMarkus Armbruster DriveInfo *blk_legacy_dinfo(BlockBackend *blk)
20118e46a03SMarkus Armbruster {
20218e46a03SMarkus Armbruster     return blk->legacy_dinfo;
20318e46a03SMarkus Armbruster }
20418e46a03SMarkus Armbruster 
20518e46a03SMarkus Armbruster /*
20618e46a03SMarkus Armbruster  * Set @blk's DriveInfo to @dinfo, and return it.
20718e46a03SMarkus Armbruster  * @blk must not have a DriveInfo set already.
20818e46a03SMarkus Armbruster  * No other BlockBackend may have the same DriveInfo set.
20918e46a03SMarkus Armbruster  */
21018e46a03SMarkus Armbruster DriveInfo *blk_set_legacy_dinfo(BlockBackend *blk, DriveInfo *dinfo)
21118e46a03SMarkus Armbruster {
21218e46a03SMarkus Armbruster     assert(!blk->legacy_dinfo);
21318e46a03SMarkus Armbruster     return blk->legacy_dinfo = dinfo;
21418e46a03SMarkus Armbruster }
21518e46a03SMarkus Armbruster 
21618e46a03SMarkus Armbruster /*
21718e46a03SMarkus Armbruster  * Return the BlockBackend with DriveInfo @dinfo.
21818e46a03SMarkus Armbruster  * It must exist.
21918e46a03SMarkus Armbruster  */
22018e46a03SMarkus Armbruster BlockBackend *blk_by_legacy_dinfo(DriveInfo *dinfo)
22118e46a03SMarkus Armbruster {
22218e46a03SMarkus Armbruster     BlockBackend *blk;
22318e46a03SMarkus Armbruster 
22418e46a03SMarkus Armbruster     QTAILQ_FOREACH(blk, &blk_backends, link) {
22518e46a03SMarkus Armbruster         if (blk->legacy_dinfo == dinfo) {
22618e46a03SMarkus Armbruster             return blk;
22718e46a03SMarkus Armbruster         }
22818e46a03SMarkus Armbruster     }
22918e46a03SMarkus Armbruster     abort();
23018e46a03SMarkus Armbruster }
23118e46a03SMarkus Armbruster 
23218e46a03SMarkus Armbruster /*
2337e7d56d9SMarkus Armbruster  * Hide @blk.
2347e7d56d9SMarkus Armbruster  * @blk must not have been hidden already.
2357e7d56d9SMarkus Armbruster  * Make attached BlockDriverState, if any, anonymous.
2367e7d56d9SMarkus Armbruster  * Once hidden, @blk is invisible to all functions that don't receive
2377e7d56d9SMarkus Armbruster  * it as argument.  For example, blk_by_name() won't return it.
2387e7d56d9SMarkus Armbruster  * Strictly for use by do_drive_del().
2397e7d56d9SMarkus Armbruster  * TODO get rid of it!
2407e7d56d9SMarkus Armbruster  */
2417e7d56d9SMarkus Armbruster void blk_hide_on_behalf_of_do_drive_del(BlockBackend *blk)
2427e7d56d9SMarkus Armbruster {
2437e7d56d9SMarkus Armbruster     QTAILQ_REMOVE(&blk_backends, blk, link);
2447e7d56d9SMarkus Armbruster     blk->name[0] = 0;
2457e7d56d9SMarkus Armbruster     if (blk->bs) {
2467e7d56d9SMarkus Armbruster         bdrv_make_anon(blk->bs);
2477e7d56d9SMarkus Armbruster     }
2487e7d56d9SMarkus Armbruster }
2494be74634SMarkus Armbruster 
250a7f53e26SMarkus Armbruster /*
251a7f53e26SMarkus Armbruster  * Attach device model @dev to @blk.
252a7f53e26SMarkus Armbruster  * Return 0 on success, -EBUSY when a device model is attached already.
253a7f53e26SMarkus Armbruster  */
254a7f53e26SMarkus Armbruster int blk_attach_dev(BlockBackend *blk, void *dev)
255a7f53e26SMarkus Armbruster /* TODO change to DeviceState *dev when all users are qdevified */
256a7f53e26SMarkus Armbruster {
257a7f53e26SMarkus Armbruster     if (blk->dev) {
258a7f53e26SMarkus Armbruster         return -EBUSY;
259a7f53e26SMarkus Armbruster     }
260*84ebe375SMarkus Armbruster     blk_ref(blk);
261a7f53e26SMarkus Armbruster     blk->dev = dev;
262a7f53e26SMarkus Armbruster     bdrv_iostatus_reset(blk->bs);
263a7f53e26SMarkus Armbruster 
264a7f53e26SMarkus Armbruster     /* We're expecting I/O from the device so bump up coroutine pool size */
265a7f53e26SMarkus Armbruster     qemu_coroutine_adjust_pool_size(COROUTINE_POOL_RESERVATION);
266a7f53e26SMarkus Armbruster     return 0;
267a7f53e26SMarkus Armbruster }
268a7f53e26SMarkus Armbruster 
269a7f53e26SMarkus Armbruster /*
270a7f53e26SMarkus Armbruster  * Attach device model @dev to @blk.
271a7f53e26SMarkus Armbruster  * @blk must not have a device model attached already.
272a7f53e26SMarkus Armbruster  * TODO qdevified devices don't use this, remove when devices are qdevified
273a7f53e26SMarkus Armbruster  */
274a7f53e26SMarkus Armbruster void blk_attach_dev_nofail(BlockBackend *blk, void *dev)
275a7f53e26SMarkus Armbruster {
276a7f53e26SMarkus Armbruster     if (blk_attach_dev(blk, dev) < 0) {
277a7f53e26SMarkus Armbruster         abort();
278a7f53e26SMarkus Armbruster     }
279a7f53e26SMarkus Armbruster }
280a7f53e26SMarkus Armbruster 
281a7f53e26SMarkus Armbruster /*
282a7f53e26SMarkus Armbruster  * Detach device model @dev from @blk.
283a7f53e26SMarkus Armbruster  * @dev must be currently attached to @blk.
284a7f53e26SMarkus Armbruster  */
285a7f53e26SMarkus Armbruster void blk_detach_dev(BlockBackend *blk, void *dev)
286a7f53e26SMarkus Armbruster /* TODO change to DeviceState *dev when all users are qdevified */
287a7f53e26SMarkus Armbruster {
288a7f53e26SMarkus Armbruster     assert(blk->dev == dev);
289a7f53e26SMarkus Armbruster     blk->dev = NULL;
290a7f53e26SMarkus Armbruster     blk->dev_ops = NULL;
291a7f53e26SMarkus Armbruster     blk->dev_opaque = NULL;
292a7f53e26SMarkus Armbruster     bdrv_set_guest_block_size(blk->bs, 512);
293a7f53e26SMarkus Armbruster     qemu_coroutine_adjust_pool_size(-COROUTINE_POOL_RESERVATION);
294*84ebe375SMarkus Armbruster     blk_unref(blk);
295a7f53e26SMarkus Armbruster }
296a7f53e26SMarkus Armbruster 
297a7f53e26SMarkus Armbruster /*
298a7f53e26SMarkus Armbruster  * Return the device model attached to @blk if any, else null.
299a7f53e26SMarkus Armbruster  */
300a7f53e26SMarkus Armbruster void *blk_get_attached_dev(BlockBackend *blk)
301a7f53e26SMarkus Armbruster /* TODO change to return DeviceState * when all users are qdevified */
302a7f53e26SMarkus Armbruster {
303a7f53e26SMarkus Armbruster     return blk->dev;
304a7f53e26SMarkus Armbruster }
305a7f53e26SMarkus Armbruster 
306a7f53e26SMarkus Armbruster /*
307a7f53e26SMarkus Armbruster  * Set @blk's device model callbacks to @ops.
308a7f53e26SMarkus Armbruster  * @opaque is the opaque argument to pass to the callbacks.
309a7f53e26SMarkus Armbruster  * This is for use by device models.
310a7f53e26SMarkus Armbruster  */
311a7f53e26SMarkus Armbruster void blk_set_dev_ops(BlockBackend *blk, const BlockDevOps *ops,
312a7f53e26SMarkus Armbruster                      void *opaque)
313a7f53e26SMarkus Armbruster {
314a7f53e26SMarkus Armbruster     blk->dev_ops = ops;
315a7f53e26SMarkus Armbruster     blk->dev_opaque = opaque;
316a7f53e26SMarkus Armbruster }
317a7f53e26SMarkus Armbruster 
318a7f53e26SMarkus Armbruster /*
319a7f53e26SMarkus Armbruster  * Notify @blk's attached device model of media change.
320a7f53e26SMarkus Armbruster  * If @load is true, notify of media load.
321a7f53e26SMarkus Armbruster  * Else, notify of media eject.
322a7f53e26SMarkus Armbruster  * Also send DEVICE_TRAY_MOVED events as appropriate.
323a7f53e26SMarkus Armbruster  */
324a7f53e26SMarkus Armbruster void blk_dev_change_media_cb(BlockBackend *blk, bool load)
325a7f53e26SMarkus Armbruster {
326a7f53e26SMarkus Armbruster     if (blk->dev_ops && blk->dev_ops->change_media_cb) {
327a7f53e26SMarkus Armbruster         bool tray_was_closed = !blk_dev_is_tray_open(blk);
328a7f53e26SMarkus Armbruster 
329a7f53e26SMarkus Armbruster         blk->dev_ops->change_media_cb(blk->dev_opaque, load);
330a7f53e26SMarkus Armbruster         if (tray_was_closed) {
331a7f53e26SMarkus Armbruster             /* tray open */
332a7f53e26SMarkus Armbruster             qapi_event_send_device_tray_moved(blk_name(blk),
333a7f53e26SMarkus Armbruster                                               true, &error_abort);
334a7f53e26SMarkus Armbruster         }
335a7f53e26SMarkus Armbruster         if (load) {
336a7f53e26SMarkus Armbruster             /* tray close */
337a7f53e26SMarkus Armbruster             qapi_event_send_device_tray_moved(blk_name(blk),
338a7f53e26SMarkus Armbruster                                               false, &error_abort);
339a7f53e26SMarkus Armbruster         }
340a7f53e26SMarkus Armbruster     }
341a7f53e26SMarkus Armbruster }
342a7f53e26SMarkus Armbruster 
343a7f53e26SMarkus Armbruster /*
344a7f53e26SMarkus Armbruster  * Does @blk's attached device model have removable media?
345a7f53e26SMarkus Armbruster  * %true if no device model is attached.
346a7f53e26SMarkus Armbruster  */
347a7f53e26SMarkus Armbruster bool blk_dev_has_removable_media(BlockBackend *blk)
348a7f53e26SMarkus Armbruster {
349a7f53e26SMarkus Armbruster     return !blk->dev || (blk->dev_ops && blk->dev_ops->change_media_cb);
350a7f53e26SMarkus Armbruster }
351a7f53e26SMarkus Armbruster 
352a7f53e26SMarkus Armbruster /*
353a7f53e26SMarkus Armbruster  * Notify @blk's attached device model of a media eject request.
354a7f53e26SMarkus Armbruster  * If @force is true, the medium is about to be yanked out forcefully.
355a7f53e26SMarkus Armbruster  */
356a7f53e26SMarkus Armbruster void blk_dev_eject_request(BlockBackend *blk, bool force)
357a7f53e26SMarkus Armbruster {
358a7f53e26SMarkus Armbruster     if (blk->dev_ops && blk->dev_ops->eject_request_cb) {
359a7f53e26SMarkus Armbruster         blk->dev_ops->eject_request_cb(blk->dev_opaque, force);
360a7f53e26SMarkus Armbruster     }
361a7f53e26SMarkus Armbruster }
362a7f53e26SMarkus Armbruster 
363a7f53e26SMarkus Armbruster /*
364a7f53e26SMarkus Armbruster  * Does @blk's attached device model have a tray, and is it open?
365a7f53e26SMarkus Armbruster  */
366a7f53e26SMarkus Armbruster bool blk_dev_is_tray_open(BlockBackend *blk)
367a7f53e26SMarkus Armbruster {
368a7f53e26SMarkus Armbruster     if (blk->dev_ops && blk->dev_ops->is_tray_open) {
369a7f53e26SMarkus Armbruster         return blk->dev_ops->is_tray_open(blk->dev_opaque);
370a7f53e26SMarkus Armbruster     }
371a7f53e26SMarkus Armbruster     return false;
372a7f53e26SMarkus Armbruster }
373a7f53e26SMarkus Armbruster 
374a7f53e26SMarkus Armbruster /*
375a7f53e26SMarkus Armbruster  * Does @blk's attached device model have the medium locked?
376a7f53e26SMarkus Armbruster  * %false if the device model has no such lock.
377a7f53e26SMarkus Armbruster  */
378a7f53e26SMarkus Armbruster bool blk_dev_is_medium_locked(BlockBackend *blk)
379a7f53e26SMarkus Armbruster {
380a7f53e26SMarkus Armbruster     if (blk->dev_ops && blk->dev_ops->is_medium_locked) {
381a7f53e26SMarkus Armbruster         return blk->dev_ops->is_medium_locked(blk->dev_opaque);
382a7f53e26SMarkus Armbruster     }
383a7f53e26SMarkus Armbruster     return false;
384a7f53e26SMarkus Armbruster }
385a7f53e26SMarkus Armbruster 
386a7f53e26SMarkus Armbruster /*
387a7f53e26SMarkus Armbruster  * Notify @blk's attached device model of a backend size change.
388a7f53e26SMarkus Armbruster  */
389a7f53e26SMarkus Armbruster void blk_dev_resize_cb(BlockBackend *blk)
390a7f53e26SMarkus Armbruster {
391a7f53e26SMarkus Armbruster     if (blk->dev_ops && blk->dev_ops->resize_cb) {
392a7f53e26SMarkus Armbruster         blk->dev_ops->resize_cb(blk->dev_opaque);
393a7f53e26SMarkus Armbruster     }
394a7f53e26SMarkus Armbruster }
395a7f53e26SMarkus Armbruster 
3964be74634SMarkus Armbruster void blk_iostatus_enable(BlockBackend *blk)
3974be74634SMarkus Armbruster {
3984be74634SMarkus Armbruster     bdrv_iostatus_enable(blk->bs);
3994be74634SMarkus Armbruster }
4004be74634SMarkus Armbruster 
4014be74634SMarkus Armbruster int blk_read(BlockBackend *blk, int64_t sector_num, uint8_t *buf,
4024be74634SMarkus Armbruster              int nb_sectors)
4034be74634SMarkus Armbruster {
4044be74634SMarkus Armbruster     return bdrv_read(blk->bs, sector_num, buf, nb_sectors);
4054be74634SMarkus Armbruster }
4064be74634SMarkus Armbruster 
4074be74634SMarkus Armbruster int blk_read_unthrottled(BlockBackend *blk, int64_t sector_num, uint8_t *buf,
4084be74634SMarkus Armbruster                          int nb_sectors)
4094be74634SMarkus Armbruster {
4104be74634SMarkus Armbruster     return bdrv_read_unthrottled(blk->bs, sector_num, buf, nb_sectors);
4114be74634SMarkus Armbruster }
4124be74634SMarkus Armbruster 
4134be74634SMarkus Armbruster int blk_write(BlockBackend *blk, int64_t sector_num, const uint8_t *buf,
4144be74634SMarkus Armbruster               int nb_sectors)
4154be74634SMarkus Armbruster {
4164be74634SMarkus Armbruster     return bdrv_write(blk->bs, sector_num, buf, nb_sectors);
4174be74634SMarkus Armbruster }
4184be74634SMarkus Armbruster 
4194be74634SMarkus Armbruster BlockAIOCB *blk_aio_write_zeroes(BlockBackend *blk, int64_t sector_num,
4204be74634SMarkus Armbruster                                  int nb_sectors, BdrvRequestFlags flags,
4214be74634SMarkus Armbruster                                  BlockCompletionFunc *cb, void *opaque)
4224be74634SMarkus Armbruster {
4234be74634SMarkus Armbruster     return bdrv_aio_write_zeroes(blk->bs, sector_num, nb_sectors, flags,
4244be74634SMarkus Armbruster                                  cb, opaque);
4254be74634SMarkus Armbruster }
4264be74634SMarkus Armbruster 
4274be74634SMarkus Armbruster int blk_pread(BlockBackend *blk, int64_t offset, void *buf, int count)
4284be74634SMarkus Armbruster {
4294be74634SMarkus Armbruster     return bdrv_pread(blk->bs, offset, buf, count);
4304be74634SMarkus Armbruster }
4314be74634SMarkus Armbruster 
4324be74634SMarkus Armbruster int blk_pwrite(BlockBackend *blk, int64_t offset, const void *buf, int count)
4334be74634SMarkus Armbruster {
4344be74634SMarkus Armbruster     return bdrv_pwrite(blk->bs, offset, buf, count);
4354be74634SMarkus Armbruster }
4364be74634SMarkus Armbruster 
4374be74634SMarkus Armbruster int64_t blk_getlength(BlockBackend *blk)
4384be74634SMarkus Armbruster {
4394be74634SMarkus Armbruster     return bdrv_getlength(blk->bs);
4404be74634SMarkus Armbruster }
4414be74634SMarkus Armbruster 
4424be74634SMarkus Armbruster void blk_get_geometry(BlockBackend *blk, uint64_t *nb_sectors_ptr)
4434be74634SMarkus Armbruster {
4444be74634SMarkus Armbruster     bdrv_get_geometry(blk->bs, nb_sectors_ptr);
4454be74634SMarkus Armbruster }
4464be74634SMarkus Armbruster 
4474be74634SMarkus Armbruster BlockAIOCB *blk_aio_readv(BlockBackend *blk, int64_t sector_num,
4484be74634SMarkus Armbruster                           QEMUIOVector *iov, int nb_sectors,
4494be74634SMarkus Armbruster                           BlockCompletionFunc *cb, void *opaque)
4504be74634SMarkus Armbruster {
4514be74634SMarkus Armbruster     return bdrv_aio_readv(blk->bs, sector_num, iov, nb_sectors, cb, opaque);
4524be74634SMarkus Armbruster }
4534be74634SMarkus Armbruster 
4544be74634SMarkus Armbruster BlockAIOCB *blk_aio_writev(BlockBackend *blk, int64_t sector_num,
4554be74634SMarkus Armbruster                            QEMUIOVector *iov, int nb_sectors,
4564be74634SMarkus Armbruster                            BlockCompletionFunc *cb, void *opaque)
4574be74634SMarkus Armbruster {
4584be74634SMarkus Armbruster     return bdrv_aio_writev(blk->bs, sector_num, iov, nb_sectors, cb, opaque);
4594be74634SMarkus Armbruster }
4604be74634SMarkus Armbruster 
4614be74634SMarkus Armbruster BlockAIOCB *blk_aio_flush(BlockBackend *blk,
4624be74634SMarkus Armbruster                           BlockCompletionFunc *cb, void *opaque)
4634be74634SMarkus Armbruster {
4644be74634SMarkus Armbruster     return bdrv_aio_flush(blk->bs, cb, opaque);
4654be74634SMarkus Armbruster }
4664be74634SMarkus Armbruster 
4674be74634SMarkus Armbruster BlockAIOCB *blk_aio_discard(BlockBackend *blk,
4684be74634SMarkus Armbruster                             int64_t sector_num, int nb_sectors,
4694be74634SMarkus Armbruster                             BlockCompletionFunc *cb, void *opaque)
4704be74634SMarkus Armbruster {
4714be74634SMarkus Armbruster     return bdrv_aio_discard(blk->bs, sector_num, nb_sectors, cb, opaque);
4724be74634SMarkus Armbruster }
4734be74634SMarkus Armbruster 
4744be74634SMarkus Armbruster void blk_aio_cancel(BlockAIOCB *acb)
4754be74634SMarkus Armbruster {
4764be74634SMarkus Armbruster     bdrv_aio_cancel(acb);
4774be74634SMarkus Armbruster }
4784be74634SMarkus Armbruster 
4794be74634SMarkus Armbruster void blk_aio_cancel_async(BlockAIOCB *acb)
4804be74634SMarkus Armbruster {
4814be74634SMarkus Armbruster     bdrv_aio_cancel_async(acb);
4824be74634SMarkus Armbruster }
4834be74634SMarkus Armbruster 
4844be74634SMarkus Armbruster int blk_aio_multiwrite(BlockBackend *blk, BlockRequest *reqs, int num_reqs)
4854be74634SMarkus Armbruster {
4864be74634SMarkus Armbruster     return bdrv_aio_multiwrite(blk->bs, reqs, num_reqs);
4874be74634SMarkus Armbruster }
4884be74634SMarkus Armbruster 
4894be74634SMarkus Armbruster int blk_ioctl(BlockBackend *blk, unsigned long int req, void *buf)
4904be74634SMarkus Armbruster {
4914be74634SMarkus Armbruster     return bdrv_ioctl(blk->bs, req, buf);
4924be74634SMarkus Armbruster }
4934be74634SMarkus Armbruster 
4944be74634SMarkus Armbruster BlockAIOCB *blk_aio_ioctl(BlockBackend *blk, unsigned long int req, void *buf,
4954be74634SMarkus Armbruster                           BlockCompletionFunc *cb, void *opaque)
4964be74634SMarkus Armbruster {
4974be74634SMarkus Armbruster     return bdrv_aio_ioctl(blk->bs, req, buf, cb, opaque);
4984be74634SMarkus Armbruster }
4994be74634SMarkus Armbruster 
5004be74634SMarkus Armbruster int blk_flush(BlockBackend *blk)
5014be74634SMarkus Armbruster {
5024be74634SMarkus Armbruster     return bdrv_flush(blk->bs);
5034be74634SMarkus Armbruster }
5044be74634SMarkus Armbruster 
5054be74634SMarkus Armbruster int blk_flush_all(void)
5064be74634SMarkus Armbruster {
5074be74634SMarkus Armbruster     return bdrv_flush_all();
5084be74634SMarkus Armbruster }
5094be74634SMarkus Armbruster 
5104be74634SMarkus Armbruster void blk_drain_all(void)
5114be74634SMarkus Armbruster {
5124be74634SMarkus Armbruster     bdrv_drain_all();
5134be74634SMarkus Armbruster }
5144be74634SMarkus Armbruster 
5154be74634SMarkus Armbruster BlockdevOnError blk_get_on_error(BlockBackend *blk, bool is_read)
5164be74634SMarkus Armbruster {
5174be74634SMarkus Armbruster     return bdrv_get_on_error(blk->bs, is_read);
5184be74634SMarkus Armbruster }
5194be74634SMarkus Armbruster 
5204be74634SMarkus Armbruster BlockErrorAction blk_get_error_action(BlockBackend *blk, bool is_read,
5214be74634SMarkus Armbruster                                       int error)
5224be74634SMarkus Armbruster {
5234be74634SMarkus Armbruster     return bdrv_get_error_action(blk->bs, is_read, error);
5244be74634SMarkus Armbruster }
5254be74634SMarkus Armbruster 
5264be74634SMarkus Armbruster void blk_error_action(BlockBackend *blk, BlockErrorAction action,
5274be74634SMarkus Armbruster                       bool is_read, int error)
5284be74634SMarkus Armbruster {
5294be74634SMarkus Armbruster     bdrv_error_action(blk->bs, action, is_read, error);
5304be74634SMarkus Armbruster }
5314be74634SMarkus Armbruster 
5324be74634SMarkus Armbruster int blk_is_read_only(BlockBackend *blk)
5334be74634SMarkus Armbruster {
5344be74634SMarkus Armbruster     return bdrv_is_read_only(blk->bs);
5354be74634SMarkus Armbruster }
5364be74634SMarkus Armbruster 
5374be74634SMarkus Armbruster int blk_is_sg(BlockBackend *blk)
5384be74634SMarkus Armbruster {
5394be74634SMarkus Armbruster     return bdrv_is_sg(blk->bs);
5404be74634SMarkus Armbruster }
5414be74634SMarkus Armbruster 
5424be74634SMarkus Armbruster int blk_enable_write_cache(BlockBackend *blk)
5434be74634SMarkus Armbruster {
5444be74634SMarkus Armbruster     return bdrv_enable_write_cache(blk->bs);
5454be74634SMarkus Armbruster }
5464be74634SMarkus Armbruster 
5474be74634SMarkus Armbruster void blk_set_enable_write_cache(BlockBackend *blk, bool wce)
5484be74634SMarkus Armbruster {
5494be74634SMarkus Armbruster     bdrv_set_enable_write_cache(blk->bs, wce);
5504be74634SMarkus Armbruster }
5514be74634SMarkus Armbruster 
5524be74634SMarkus Armbruster int blk_is_inserted(BlockBackend *blk)
5534be74634SMarkus Armbruster {
5544be74634SMarkus Armbruster     return bdrv_is_inserted(blk->bs);
5554be74634SMarkus Armbruster }
5564be74634SMarkus Armbruster 
5574be74634SMarkus Armbruster void blk_lock_medium(BlockBackend *blk, bool locked)
5584be74634SMarkus Armbruster {
5594be74634SMarkus Armbruster     bdrv_lock_medium(blk->bs, locked);
5604be74634SMarkus Armbruster }
5614be74634SMarkus Armbruster 
5624be74634SMarkus Armbruster void blk_eject(BlockBackend *blk, bool eject_flag)
5634be74634SMarkus Armbruster {
5644be74634SMarkus Armbruster     bdrv_eject(blk->bs, eject_flag);
5654be74634SMarkus Armbruster }
5664be74634SMarkus Armbruster 
5674be74634SMarkus Armbruster int blk_get_flags(BlockBackend *blk)
5684be74634SMarkus Armbruster {
5694be74634SMarkus Armbruster     return bdrv_get_flags(blk->bs);
5704be74634SMarkus Armbruster }
5714be74634SMarkus Armbruster 
5724be74634SMarkus Armbruster void blk_set_guest_block_size(BlockBackend *blk, int align)
5734be74634SMarkus Armbruster {
5744be74634SMarkus Armbruster     bdrv_set_guest_block_size(blk->bs, align);
5754be74634SMarkus Armbruster }
5764be74634SMarkus Armbruster 
5774be74634SMarkus Armbruster void *blk_blockalign(BlockBackend *blk, size_t size)
5784be74634SMarkus Armbruster {
5794be74634SMarkus Armbruster     return qemu_blockalign(blk ? blk->bs : NULL, size);
5804be74634SMarkus Armbruster }
5814be74634SMarkus Armbruster 
5824be74634SMarkus Armbruster bool blk_op_is_blocked(BlockBackend *blk, BlockOpType op, Error **errp)
5834be74634SMarkus Armbruster {
5844be74634SMarkus Armbruster     return bdrv_op_is_blocked(blk->bs, op, errp);
5854be74634SMarkus Armbruster }
5864be74634SMarkus Armbruster 
5874be74634SMarkus Armbruster void blk_op_unblock(BlockBackend *blk, BlockOpType op, Error *reason)
5884be74634SMarkus Armbruster {
5894be74634SMarkus Armbruster     bdrv_op_unblock(blk->bs, op, reason);
5904be74634SMarkus Armbruster }
5914be74634SMarkus Armbruster 
5924be74634SMarkus Armbruster void blk_op_block_all(BlockBackend *blk, Error *reason)
5934be74634SMarkus Armbruster {
5944be74634SMarkus Armbruster     bdrv_op_block_all(blk->bs, reason);
5954be74634SMarkus Armbruster }
5964be74634SMarkus Armbruster 
5974be74634SMarkus Armbruster void blk_op_unblock_all(BlockBackend *blk, Error *reason)
5984be74634SMarkus Armbruster {
5994be74634SMarkus Armbruster     bdrv_op_unblock_all(blk->bs, reason);
6004be74634SMarkus Armbruster }
6014be74634SMarkus Armbruster 
6024be74634SMarkus Armbruster AioContext *blk_get_aio_context(BlockBackend *blk)
6034be74634SMarkus Armbruster {
6044be74634SMarkus Armbruster     return bdrv_get_aio_context(blk->bs);
6054be74634SMarkus Armbruster }
6064be74634SMarkus Armbruster 
6074be74634SMarkus Armbruster void blk_set_aio_context(BlockBackend *blk, AioContext *new_context)
6084be74634SMarkus Armbruster {
6094be74634SMarkus Armbruster     bdrv_set_aio_context(blk->bs, new_context);
6104be74634SMarkus Armbruster }
6114be74634SMarkus Armbruster 
6124be74634SMarkus Armbruster void blk_io_plug(BlockBackend *blk)
6134be74634SMarkus Armbruster {
6144be74634SMarkus Armbruster     bdrv_io_plug(blk->bs);
6154be74634SMarkus Armbruster }
6164be74634SMarkus Armbruster 
6174be74634SMarkus Armbruster void blk_io_unplug(BlockBackend *blk)
6184be74634SMarkus Armbruster {
6194be74634SMarkus Armbruster     bdrv_io_unplug(blk->bs);
6204be74634SMarkus Armbruster }
6214be74634SMarkus Armbruster 
6224be74634SMarkus Armbruster BlockAcctStats *blk_get_stats(BlockBackend *blk)
6234be74634SMarkus Armbruster {
6244be74634SMarkus Armbruster     return bdrv_get_stats(blk->bs);
6254be74634SMarkus Armbruster }
6264be74634SMarkus Armbruster 
6274be74634SMarkus Armbruster void *blk_aio_get(const AIOCBInfo *aiocb_info, BlockBackend *blk,
6284be74634SMarkus Armbruster                   BlockCompletionFunc *cb, void *opaque)
6294be74634SMarkus Armbruster {
6304be74634SMarkus Armbruster     return qemu_aio_get(aiocb_info, blk_bs(blk), cb, opaque);
6314be74634SMarkus Armbruster }
632