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