All of lore.kernel.org
 help / color / mirror / Atom feed
* [Qemu-devel] [PATCH v2 00/23] Split BlockBackend off BDS with an axe
@ 2014-09-13 15:00 Markus Armbruster
  2014-09-13 15:00 ` [Qemu-devel] [PATCH v2 01/23] block: Split bdrv_new_root() off bdrv_new() Markus Armbruster
                   ` (23 more replies)
  0 siblings, 24 replies; 56+ messages in thread
From: Markus Armbruster @ 2014-09-13 15:00 UTC (permalink / raw)
  To: qemu-devel; +Cc: kwolf, benoit.canet, stefanha

My last attempt got bogged down because I tried to do a reasonably
complete job, and the complexity proved more than I could handle with
the limited amount of uninterrupted time available.  This time, I'm
cutting BlockBackend off with an axe, leaving most of the work for
later.

Done in this series already:

* Introduce a BlockBackend type, and lift up BlockDriverState's
  device_name, device_list, dev, dev_ops, dev_opaque.  Much more
  remains to be lifted.

* Make BlockBackend own the DriveInfo.

* Wean hw/ off BlockDriverState, with two small exceptions.

* Fix blockdev-add not to create a bogus IDE drive (0,0).

* Take a few baby steps towards use of BlockBackend in monitor command
  code where appropriate.

Coming soon, hopefully:

* QMP command blockdev-del

* blockdev-add accepts node-name without id at top level

* Lift up more stuff

* More BlockBackend use in monitor command code

Depends on my
[PATCH 0/4] Block-related miscellaneous cleanups.
[PATCH] blockdev: Refuse to drive_del something added with blockdev-add
[PATCH 0/4] Miscellaneous block fixes

I know the diffstat looks intimidating.  I tried very hard to split
the patches so that the bigger ones do just one simple thing, and
mostly mechanically.

v2:
* General
  - Improved function comments [Kevin, Benoît]
  - Avoiding temporary badness around drive_del affects several
    patches up to PATCH 14/23, but by then the solution is basically
    v1's again, plus a simple bug fix.
* [PATCH 01/23] block: Split bdrv_new_root() off bdrv_new()
  - Call it bdrv_new_root() instead of bdrv_new_named(), because it'll
    lose its name parameter in PATCH 08.  In v1, it gets removed there.
  - Drop a condition that cannot be false due to prior assertion
* [PATCH 02/23] block: New BlockBackend
  - Commit message amended to explain when BlockBackends get created
    and destroyed [Kevin]
  - License reluctantly changed to LGPL2.1+ [Kevin]
  - Plug leak on error in blk_new() [Kevin]
  - g_assert() is silly, stick to plain assert() [Kevin]
  - Fix double-free when do_drive_del() leaves BDS destruction to
    blockdev_auto_del(), and user adds a BB with the same name in
    between [Kevin]
    Note: bug goes away later in v1
  - Plug a bunch of leaks on error in qemu-img.c [Kevin, Benoît]
    Note: bugs goes away later in v1
  - Update for "[PATCH 3/4] qemu-nbd: Destroy the BlockDriverState
    properly"
* [PATCH 03/23] block: Connect BlockBackend to BlockDriverState
  - Keep the double-free just mentioned fixed; commit message amended
    to explain the drive_del complications
    Basically move v1's solution from "[PATCH 14/23] hw: Convert from
    BlockDriverState to BlockBackend, mostly" here, plus a fix for
    invalid queue removal in blk_delete()
  - Cleanup extracted and posted separately as "[PATCH 1/4] blockdev:
    Disentangle BlockDriverState and DriveInfo creation" [Kevin]
  - Inline blk_attach_bs(), blk_detach_bs() into only callers
  - Rebase on PATCH 02's qemu-img.c leak fixes, basically reverting
    its error path complications
  - Update for "[PATCH 3/4] qemu-nbd: Destroy the BlockDriverState
    properly"
* [PATCH 04/23] block: Connect BlockBackend and DriveInfo
  - Bug fix extracted and posted separately as "[PATCH 2/4] block:
    Keep DriveInfo alive until BlockDriverState dies" [Kevin]
    Unlike v1, it takes care to preserve the guard against
    qemu_opts_del(NULL)
    Could only happen when drive_del'ing something created with
    blockdev-add, which is impossible since "[PATCH] blockdev: Refuse
    to drive_del something added with blockdev-add", but not obviously
    so
    Becomes obvious in PATCH 18, which duly drops the guard
  - Plug leak on error in drive_new() [Kevin]
* [PATCH 05/23] block: Code motion to get rid of stubs/blockdev.c
  - New; to separate some of the cleanup of the mess made in said
    extracted bug fix from the previous patch, to keep it more readable
* [PATCH 06/23] block: Make BlockBackend own its BlockDriverState
  - Update for "[PATCH 3/4] qemu-nbd: Destroy the BlockDriverState
    properly"
* [PATCH 07/23] block: Eliminate bdrv_states, use block_next() instead
  - Drop; it can break things when a root BDS outlives its BB, because
    something else is holding a reference to the BDS when the BB dies
* [PATCH 07/23] block: Eliminate bdrv_iterate(), use bdrv_next()
  - Fix accidental removal of a line [Benoît]
* [PATCH 08/23] block: Eliminate BlockDriverState member device_name[]
  - Commit message: typo fixed [Eric], clarified
  - Update for [PATCH 4/4] block: Improve message for device name
    clashing with node name
  - Ripple effects from drop of PATCH 07
  - Neater implementation of bdrv_get_device_name() [Benoît]
* [PATCH 09/23] block: Merge BlockBackend and BlockDriverState name
  spaces
  - Update for [PATCH 4/4] block: Improve message for device name
    clashing with node name
* [PATCH 10/23] block: Eliminate DriveInfo member bdrv, use
  - Commit message amended to explain the repetitive changes [Eric]
* [PATCH 11/23] block: Rename BlockDriverAIOCB* to BlockAIOCB*
* [PATCH 12/23] virtio-blk: Drop redundant VirtIOBlock member conf
* [PATCH 13/23] virtio-blk: Rename VirtIOBlkConf variables to conf
  - All three unchanged
* [PATCH 14/23] hw: Convert from BlockDriverState to BlockBackend,
  mostly
  - Less the stuff now in PATCH 03; see above
* [PATCH 15/23] ide: Complete conversion from BlockDriverState to
  BlockBackend
* [PATCH 16/23] pc87312: Drop unused members of PC87312State
  - Both unchanged
* [PATCH 17/23] blockdev: Drop superfluous DriveInfo member id
  - Trivial context change due to qemu_opts_del(NULL) guard mentioned
    above
* [PATCH 18/23] blockdev: Fix blockdev-add not to create IDE drive
  (0,0)
  - Since blockdev-add no longer creates a DriveInfo, the guard just
    mentioned is now obviously unnecessary; drop it
* [PATCH 19/23] blockdev: Drop DriveInfo member enable_auto_del
  - Update for [PATCH] blockdev: Refuse to drive_del something added
    with blockdev-add
* [PATCH 20/23] block/qapi: Convert qmp_query_block() to BlockBackend
* [PATCH 21/23] blockdev: Convert qmp_eject(), qmp_change_blockdev()
  to BlockBackend
  - Both unchanged
* [PATCH 22/23] block: Lift device model API into BlockBackend
  - Only comments and context differences
* [PATCH 23/23] block: Make device model's references to BlockBackend
  - Unchanged

Markus Armbruster (23):
  block: Split bdrv_new_root() off bdrv_new()
  block: New BlockBackend
  block: Connect BlockBackend to BlockDriverState
  block: Connect BlockBackend and DriveInfo
  block: Code motion to get rid of stubs/blockdev.c
  block: Make BlockBackend own its BlockDriverState
  block: Eliminate bdrv_iterate(), use bdrv_next()
  block: Eliminate BlockDriverState member device_name[]
  block: Merge BlockBackend and BlockDriverState name spaces
  block: Eliminate DriveInfo member bdrv, use blk_by_legacy_dinfo()
  block: Rename BlockDriverAIOCB* to BlockAIOCB*
  virtio-blk: Drop redundant VirtIOBlock member conf
  virtio-blk: Rename VirtIOBlkConf variables to conf
  hw: Convert from BlockDriverState to BlockBackend, mostly
  ide: Complete conversion from BlockDriverState to BlockBackend
  pc87312: Drop unused members of PC87312State
  blockdev: Drop superfluous DriveInfo member id
  blockdev: Fix blockdev-add not to create IDE drive (0,0)
  blockdev: Drop DriveInfo member enable_auto_del
  block/qapi: Convert qmp_query_block() to BlockBackend
  blockdev: Convert qmp_eject(), qmp_change_blockdev() to BlockBackend
  block: Lift device model API into BlockBackend
  block: Make device model's references to BlockBackend strong

 block-migration.c                        |  44 +--
 block.c                                  | 372 ++++++------------
 block/Makefile.objs                      |   2 +-
 block/archipelago.c                      |  30 +-
 block/backup.c                           |   2 +-
 block/blkdebug.c                         |  22 +-
 block/blkverify.c                        |  20 +-
 block/block-backend.c                    | 626 +++++++++++++++++++++++++++++++
 block/commit.c                           |   2 +-
 block/cow.c                              |   2 +-
 block/curl.c                             |   8 +-
 block/iscsi.c                            |  10 +-
 block/linux-aio.c                        |   8 +-
 block/mirror.c                           |   9 +-
 block/qapi.c                             |  27 +-
 block/qcow.c                             |   4 +-
 block/qcow2.c                            |   4 +-
 block/qed-gencb.c                        |   4 +-
 block/qed-table.c                        |  10 +-
 block/qed.c                              |  48 +--
 block/qed.h                              |  12 +-
 block/quorum.c                           |  42 +--
 block/raw-aio.h                          |   8 +-
 block/raw-posix.c                        |  32 +-
 block/raw-win32.c                        |  16 +-
 block/raw_bsd.c                          |   8 +-
 block/rbd.c                              |  58 +--
 block/sheepdog.c                         |   4 +-
 block/stream.c                           |   2 +-
 block/vdi.c                              |   2 +-
 block/vhdx.c                             |   2 +-
 block/vmdk.c                             |   4 +-
 block/vpc.c                              |   2 +-
 block/vvfat.c                            |   4 +-
 block/win32-aio.c                        |   8 +-
 blockdev.c                               | 193 ++++------
 blockjob.c                               |   7 +-
 dma-helpers.c                            |  69 ++--
 hw/arm/collie.c                          |  10 +-
 hw/arm/gumstix.c                         |   6 +-
 hw/arm/highbank.c                        |   2 +-
 hw/arm/mainstone.c                       |   8 +-
 hw/arm/musicpal.c                        |  13 +-
 hw/arm/nseries.c                         |   7 +-
 hw/arm/omap1.c                           |   4 +-
 hw/arm/omap2.c                           |   4 +-
 hw/arm/omap_sx1.c                        |  10 +-
 hw/arm/pxa2xx.c                          |   7 +-
 hw/arm/realview.c                        |   2 +-
 hw/arm/spitz.c                           |   6 +-
 hw/arm/tosa.c                            |   3 +-
 hw/arm/versatilepb.c                     |   5 +-
 hw/arm/vexpress.c                        |   5 +-
 hw/arm/xilinx_zynq.c                     |   5 +-
 hw/arm/z2.c                              |   8 +-
 hw/block/block.c                         |  23 +-
 hw/block/dataplane/virtio-blk.c          |  35 +-
 hw/block/dataplane/virtio-blk.h          |   2 +-
 hw/block/fdc.c                           |  74 ++--
 hw/block/hd-geometry.c                   |  24 +-
 hw/block/m25p80.c                        |  31 +-
 hw/block/nand.c                          |  50 +--
 hw/block/nvme.c                          |  17 +-
 hw/block/nvme.h                          |   2 +-
 hw/block/onenand.c                       |  67 ++--
 hw/block/pflash_cfi01.c                  |  24 +-
 hw/block/pflash_cfi02.c                  |  24 +-
 hw/block/virtio-blk.c                    | 149 ++++----
 hw/block/xen_disk.c                      |  86 +++--
 hw/core/qdev-properties-system.c         |  26 +-
 hw/core/qdev-properties.c                |   2 +-
 hw/cris/axis_dev88.c                     |   4 +-
 hw/display/tc6393xb.c                    |   4 +-
 hw/i386/pc.c                             |   2 +-
 hw/i386/pc_piix.c                        |   2 +-
 hw/i386/pc_sysfw.c                       |  10 +-
 hw/i386/xen/xen_platform.c               |   5 +-
 hw/ide/ahci.c                            |  33 +-
 hw/ide/ahci.h                            |   2 +-
 hw/ide/atapi.c                           |  33 +-
 hw/ide/cmd646.c                          |   2 +-
 hw/ide/core.c                            | 206 +++++-----
 hw/ide/ich.c                             |   2 +-
 hw/ide/internal.h                        |  16 +-
 hw/ide/isa.c                             |   2 +-
 hw/ide/macio.c                           |  54 +--
 hw/ide/microdrive.c                      |   4 +-
 hw/ide/mmio.c                            |   2 +-
 hw/ide/pci.c                             |   6 +-
 hw/ide/pci.h                             |   2 +-
 hw/ide/piix.c                            |   9 +-
 hw/ide/qdev.c                            |  13 +-
 hw/ide/via.c                             |   2 +-
 hw/isa/pc87312.c                         |   7 +-
 hw/lm32/lm32_boards.c                    |  14 +-
 hw/lm32/milkymist.c                      |   8 +-
 hw/microblaze/petalogix_ml605_mmu.c      |   6 +-
 hw/microblaze/petalogix_s3adsp1800_mmu.c |   6 +-
 hw/mips/mips_fulong2e.c                  |   2 +-
 hw/mips/mips_jazz.c                      |   2 +-
 hw/mips/mips_malta.c                     |   8 +-
 hw/mips/mips_r4k.c                       |   6 +-
 hw/nvram/spapr_nvram.c                   |  17 +-
 hw/pci/pci-hotplug-old.c                 |  10 +-
 hw/ppc/mac.h                             |   2 +-
 hw/ppc/mac_newworld.c                    |   2 +-
 hw/ppc/mac_oldworld.c                    |   2 +-
 hw/ppc/ppc405_boards.c                   |  27 +-
 hw/ppc/prep.c                            |   2 +-
 hw/ppc/spapr.c                           |   4 +-
 hw/ppc/virtex_ml507.c                    |   6 +-
 hw/s390x/s390-virtio-bus.c               |   2 +-
 hw/s390x/s390-virtio.c                   |   2 +-
 hw/s390x/virtio-ccw.c                    |   2 +-
 hw/scsi/megasas.c                        |  15 +-
 hw/scsi/scsi-bus.c                       |  11 +-
 hw/scsi/scsi-disk.c                      | 194 +++++-----
 hw/scsi/scsi-generic.c                   |  41 +-
 hw/sd/milkymist-memcard.c                |   7 +-
 hw/sd/omap_mmc.c                         |   8 +-
 hw/sd/pl181.c                            |   3 +-
 hw/sd/pxa2xx_mmci.c                      |   4 +-
 hw/sd/sd.c                               |  60 +--
 hw/sd/sdhci.c                            |   3 +-
 hw/sd/ssi-sd.c                           |   3 +-
 hw/sh4/r2d.c                             |   6 +-
 hw/sparc/sun4m.c                         |   2 +-
 hw/sparc64/sun4u.c                       |   2 +-
 hw/tpm/tpm_tis.c                         |   2 +-
 hw/tricore/tricore_testboard.c           |   2 +-
 hw/usb/dev-storage.c                     |  19 +-
 hw/virtio/virtio-pci.c                   |   2 +-
 hw/xen/xen_devconfig.c                   |   1 +
 hw/xenpv/xen_machine_pv.c                |   2 +-
 hw/xtensa/xtfpga.c                       |   5 +-
 include/block/aio.h                      |  12 +-
 include/block/block.h                    |  88 ++---
 include/block/block_int.h                |  44 +--
 include/block/blockjob.h                 |   4 +-
 include/block/qapi.h                     |   3 -
 include/block/thread-pool.h              |   4 +-
 include/hw/arm/omap.h                    |   4 +-
 include/hw/arm/pxa.h                     |   2 +-
 include/hw/block/block.h                 |   6 +-
 include/hw/block/flash.h                 |   6 +-
 include/hw/isa/pc87312.h                 |   3 -
 include/hw/qdev-properties.h             |   8 +-
 include/hw/scsi/scsi.h                   |   6 +-
 include/hw/sd.h                          |   2 +-
 include/hw/virtio/virtio-blk.h           |   9 +-
 include/monitor/monitor.h                |   4 +-
 include/qemu/typedefs.h                  |   2 +
 include/sysemu/block-backend.h           | 143 +++++++
 include/sysemu/blockdev.h                |  13 +-
 include/sysemu/dma.h                     |  26 +-
 monitor.c                                |  38 +-
 qemu-img.c                               | 150 ++++----
 qemu-io.c                                |  15 +-
 qemu-nbd.c                               |   8 +-
 stubs/Makefile.objs                      |   1 -
 stubs/blockdev.c                         |  12 -
 tests/test-thread-pool.c                 |   2 +-
 thread-pool.c                            |   8 +-
 trace-events                             |   8 +-
 164 files changed, 2345 insertions(+), 1698 deletions(-)
 create mode 100644 block/block-backend.c
 create mode 100644 include/sysemu/block-backend.h
 delete mode 100644 stubs/blockdev.c

-- 
1.9.3

^ permalink raw reply	[flat|nested] 56+ messages in thread

* [Qemu-devel] [PATCH v2 01/23] block: Split bdrv_new_root() off bdrv_new()
  2014-09-13 15:00 [Qemu-devel] [PATCH v2 00/23] Split BlockBackend off BDS with an axe Markus Armbruster
@ 2014-09-13 15:00 ` Markus Armbruster
  2014-09-13 20:45   ` Max Reitz
  2014-09-15 12:00   ` Benoît Canet
  2014-09-13 15:00 ` [Qemu-devel] [PATCH v2 02/23] block: New BlockBackend Markus Armbruster
                   ` (22 subsequent siblings)
  23 siblings, 2 replies; 56+ messages in thread
From: Markus Armbruster @ 2014-09-13 15:00 UTC (permalink / raw)
  To: qemu-devel; +Cc: kwolf, benoit.canet, stefanha

Creating an anonymous BDS can't fail.  Make that obvious.

Signed-off-by: Markus Armbruster <armbru@redhat.com>
---
 block.c               | 28 +++++++++++++++++++---------
 block/iscsi.c         |  2 +-
 block/vvfat.c         |  2 +-
 blockdev.c            |  2 +-
 hw/block/xen_disk.c   |  2 +-
 include/block/block.h |  3 ++-
 qemu-img.c            |  6 +++---
 qemu-io.c             |  2 +-
 qemu-nbd.c            |  2 +-
 9 files changed, 30 insertions(+), 19 deletions(-)

diff --git a/block.c b/block.c
index 02ea90f..4fe3b62 100644
--- a/block.c
+++ b/block.c
@@ -336,10 +336,11 @@ void bdrv_register(BlockDriver *bdrv)
 }
 
 /* create a new block device (by default it is empty) */
-BlockDriverState *bdrv_new(const char *device_name, Error **errp)
+BlockDriverState *bdrv_new_root(const char *device_name, Error **errp)
 {
     BlockDriverState *bs;
-    int i;
+
+    assert(*device_name);
 
     if (bdrv_find(device_name)) {
         error_setg(errp, "Device with id '%s' already exists",
@@ -353,12 +354,21 @@ BlockDriverState *bdrv_new(const char *device_name, Error **errp)
         return NULL;
     }
 
+    bs = bdrv_new();
+
+    pstrcpy(bs->device_name, sizeof(bs->device_name), device_name);
+    QTAILQ_INSERT_TAIL(&bdrv_states, bs, device_list);
+
+    return bs;
+}
+
+BlockDriverState *bdrv_new(void)
+{
+    BlockDriverState *bs;
+    int i;
+
     bs = g_new0(BlockDriverState, 1);
     QLIST_INIT(&bs->dirty_bitmaps);
-    pstrcpy(bs->device_name, sizeof(bs->device_name), device_name);
-    if (device_name[0] != '\0') {
-        QTAILQ_INSERT_TAIL(&bdrv_states, bs, device_list);
-    }
     for (i = 0; i < BLOCK_OP_TYPE_MAX; i++) {
         QLIST_INIT(&bs->op_blockers[i]);
     }
@@ -1219,7 +1229,7 @@ int bdrv_open_backing_file(BlockDriverState *bs, QDict *options, Error **errp)
         goto free_exit;
     }
 
-    backing_hd = bdrv_new("", errp);
+    backing_hd = bdrv_new();
 
     if (bs->backing_format[0] != '\0') {
         back_drv = bdrv_find_format(bs->backing_format);
@@ -1348,7 +1358,7 @@ int bdrv_append_temp_snapshot(BlockDriverState *bs, int flags, Error **errp)
     qdict_put(snapshot_options, "file.filename",
               qstring_from_str(tmp_filename));
 
-    bs_snapshot = bdrv_new("", &error_abort);
+    bs_snapshot = bdrv_new();
 
     ret = bdrv_open(&bs_snapshot, NULL, NULL, snapshot_options,
                     flags, bdrv_qcow2, &local_err);
@@ -1419,7 +1429,7 @@ int bdrv_open(BlockDriverState **pbs, const char *filename,
     if (*pbs) {
         bs = *pbs;
     } else {
-        bs = bdrv_new("", &error_abort);
+        bs = bdrv_new();
     }
 
     /* NULL means an empty set of options */
diff --git a/block/iscsi.c b/block/iscsi.c
index 3e19202..af3d0f6 100644
--- a/block/iscsi.c
+++ b/block/iscsi.c
@@ -1528,7 +1528,7 @@ static int iscsi_create(const char *filename, QemuOpts *opts, Error **errp)
     IscsiLun *iscsilun = NULL;
     QDict *bs_options;
 
-    bs = bdrv_new("", &error_abort);
+    bs = bdrv_new();
 
     /* Read out options */
     total_size =
diff --git a/block/vvfat.c b/block/vvfat.c
index 731e591..6c9fde0 100644
--- a/block/vvfat.c
+++ b/block/vvfat.c
@@ -2939,7 +2939,7 @@ static int enable_write_target(BDRVVVFATState *s, Error **errp)
     unlink(s->qcow_filename);
 #endif
 
-    bdrv_set_backing_hd(s->bs, bdrv_new("", &error_abort));
+    bdrv_set_backing_hd(s->bs, bdrv_new());
     s->bs->backing_hd->drv = &vvfat_write_target;
     s->bs->backing_hd->opaque = g_new(void *, 1);
     *(void**)s->bs->backing_hd->opaque = s;
diff --git a/blockdev.c b/blockdev.c
index 450f95c..c9463e3 100644
--- a/blockdev.c
+++ b/blockdev.c
@@ -463,7 +463,7 @@ static DriveInfo *blockdev_init(const char *file, QDict *bs_opts,
     }
 
     /* init */
-    bs = bdrv_new(qemu_opts_id(opts), errp);
+    bs = bdrv_new_root(qemu_opts_id(opts), errp);
     if (!bs) {
         goto early_err;
     }
diff --git a/hw/block/xen_disk.c b/hw/block/xen_disk.c
index 2dcef07..71f0953 100644
--- a/hw/block/xen_disk.c
+++ b/hw/block/xen_disk.c
@@ -856,7 +856,7 @@ static int blk_connect(struct XenDevice *xendev)
 
         /* setup via xenbus -> create new block driver instance */
         xen_be_printf(&blkdev->xendev, 2, "create new bdrv (xenbus setup)\n");
-        blkdev->bs = bdrv_new(blkdev->dev, NULL);
+        blkdev->bs = bdrv_new_root(blkdev->dev, NULL);
         if (!blkdev->bs) {
             return -1;
         }
diff --git a/include/block/block.h b/include/block/block.h
index 8f4ad16..6cabc98 100644
--- a/include/block/block.h
+++ b/include/block/block.h
@@ -203,7 +203,8 @@ BlockDriver *bdrv_find_whitelisted_format(const char *format_name,
 int bdrv_create(BlockDriver *drv, const char* filename,
                 QemuOpts *opts, Error **errp);
 int bdrv_create_file(const char *filename, QemuOpts *opts, Error **errp);
-BlockDriverState *bdrv_new(const char *device_name, Error **errp);
+BlockDriverState *bdrv_new_root(const char *device_name, Error **errp);
+BlockDriverState *bdrv_new(void);
 void bdrv_make_anon(BlockDriverState *bs);
 void bdrv_swap(BlockDriverState *bs_new, BlockDriverState *bs_old);
 void bdrv_append(BlockDriverState *bs_new, BlockDriverState *bs_top);
diff --git a/qemu-img.c b/qemu-img.c
index 91d1ac3..58d59d0 100644
--- a/qemu-img.c
+++ b/qemu-img.c
@@ -296,7 +296,7 @@ static BlockDriverState *bdrv_new_open(const char *id,
     Error *local_err = NULL;
     int ret;
 
-    bs = bdrv_new(id, &error_abort);
+    bs = bdrv_new_root(id, &error_abort);
 
     if (fmt) {
         drv = bdrv_find_format(fmt);
@@ -2425,7 +2425,7 @@ static int img_rebase(int argc, char **argv)
     if (!unsafe) {
         char backing_name[1024];
 
-        bs_old_backing = bdrv_new("old_backing", &error_abort);
+        bs_old_backing = bdrv_new_root("old_backing", &error_abort);
         bdrv_get_backing_filename(bs, backing_name, sizeof(backing_name));
         ret = bdrv_open(&bs_old_backing, backing_name, NULL, NULL, src_flags,
                         old_backing_drv, &local_err);
@@ -2436,7 +2436,7 @@ static int img_rebase(int argc, char **argv)
             goto out;
         }
         if (out_baseimg[0]) {
-            bs_new_backing = bdrv_new("new_backing", &error_abort);
+            bs_new_backing = bdrv_new_root("new_backing", &error_abort);
             ret = bdrv_open(&bs_new_backing, out_baseimg, NULL, NULL, src_flags,
                             new_backing_drv, &local_err);
             if (ret) {
diff --git a/qemu-io.c b/qemu-io.c
index d2ab694..24ca59c 100644
--- a/qemu-io.c
+++ b/qemu-io.c
@@ -58,7 +58,7 @@ static int openfile(char *name, int flags, int growable, QDict *opts)
         return 1;
     }
 
-    qemuio_bs = bdrv_new("hda", &error_abort);
+    qemuio_bs = bdrv_new_root("hda", &error_abort);
 
     if (growable) {
         flags |= BDRV_O_PROTOCOL;
diff --git a/qemu-nbd.c b/qemu-nbd.c
index f3cf8a2..24b8454 100644
--- a/qemu-nbd.c
+++ b/qemu-nbd.c
@@ -687,7 +687,7 @@ int main(int argc, char **argv)
         drv = NULL;
     }
 
-    bs = bdrv_new("hda", &error_abort);
+    bs = bdrv_new_root("hda", &error_abort);
 
     srcpath = argv[optind];
     ret = bdrv_open(&bs, srcpath, NULL, NULL, flags, drv, &local_err);
-- 
1.9.3

^ permalink raw reply related	[flat|nested] 56+ messages in thread

* [Qemu-devel] [PATCH v2 02/23] block: New BlockBackend
  2014-09-13 15:00 [Qemu-devel] [PATCH v2 00/23] Split BlockBackend off BDS with an axe Markus Armbruster
  2014-09-13 15:00 ` [Qemu-devel] [PATCH v2 01/23] block: Split bdrv_new_root() off bdrv_new() Markus Armbruster
@ 2014-09-13 15:00 ` Markus Armbruster
  2014-09-13 21:41   ` Max Reitz
  2014-09-15 13:02   ` Benoît Canet
  2014-09-13 15:00 ` [Qemu-devel] [PATCH v2 03/23] block: Connect BlockBackend to BlockDriverState Markus Armbruster
                   ` (21 subsequent siblings)
  23 siblings, 2 replies; 56+ messages in thread
From: Markus Armbruster @ 2014-09-13 15:00 UTC (permalink / raw)
  To: qemu-devel; +Cc: kwolf, benoit.canet, stefanha

A block device consists of a frontend device model and a backend.

A block backend has a tree of block drivers doing the actual work.
The tree is managed by the block layer.

We currently use a single abstraction BlockDriverState both for tree
nodes and the backend as a whole.  Drawbacks:

* Its API includes both stuff that makes sense only at the block
  backend level (root of the tree) and stuff that's only for use
  within the block layer.  This makes the API bigger and more complex
  than necessary.  Moreover, it's not obvious which interfaces are
  meant for device models, and which really aren't.

* Since device models keep a reference to their backend, the backend
  object can't just be destroyed.  But for media change, we need to
  replace the tree.  Our solution is to make the BlockDriverState
  generic, with actual driver state in a separate object, pointed to
  by member opaque.  That lets us replace the tree by deinitializing
  and reinitializing its root.  This special need of the root makes
  the data structure awkward everywhere in the tree.

The general plan is to separate the APIs into "block backend", for use
by device models, monitor and whatever other code dealing with block
backends, and "block driver", for use by the block layer and whatever
other code (if any) dealing with trees and tree nodes.

Code dealing with block backends, device models in particular, should
become completely oblivious of BlockDriverState.  This should let us
clean up both APIs, and the tree data structures.

This commit is a first step.  It creates a minimal "block backend"
API: type BlockBackend and functions to create, destroy and find them.

BlockBackend objects are created and destroyed exactly when root
BlockDriverState objects are created and destroyed.  "Root" in the
sense of "in bdrv_states".  They're not yet used for anything; that'll
come shortly.

BlockBackend is reference-counted.  Its reference count never exceeds
one so far, but that's going to change.

Signed-off-by: Markus Armbruster <armbru@redhat.com>
---
 block.c                        |   3 +-
 block/Makefile.objs            |   2 +-
 block/block-backend.c          | 119 +++++++++++++++++++++++++++++++++++++++++
 blockdev.c                     |  21 +++++++-
 hw/block/xen_disk.c            |  11 ++++
 include/qemu/typedefs.h        |   1 +
 include/sysemu/block-backend.h |  26 +++++++++
 qemu-img.c                     |  70 +++++++++++++++++++++---
 qemu-io.c                      |   8 +++
 qemu-nbd.c                     |   5 +-
 10 files changed, 253 insertions(+), 13 deletions(-)
 create mode 100644 block/block-backend.c
 create mode 100644 include/sysemu/block-backend.h

diff --git a/block.c b/block.c
index 4fe3b62..a05d0e3 100644
--- a/block.c
+++ b/block.c
@@ -2119,10 +2119,11 @@ static void bdrv_delete(BlockDriverState *bs)
 
     bdrv_close(bs);
 
+    drive_info_del(drive_get_by_blockdev(bs));
+
     /* remove from list, if necessary */
     bdrv_make_anon(bs);
 
-    drive_info_del(drive_get_by_blockdev(bs));
     g_free(bs);
 }
 
diff --git a/block/Makefile.objs b/block/Makefile.objs
index f45f939..a70140b 100644
--- a/block/Makefile.objs
+++ b/block/Makefile.objs
@@ -5,7 +5,7 @@ block-obj-y += qed-check.o
 block-obj-$(CONFIG_VHDX) += vhdx.o vhdx-endian.o vhdx-log.o
 block-obj-$(CONFIG_QUORUM) += quorum.o
 block-obj-y += parallels.o blkdebug.o blkverify.o
-block-obj-y += snapshot.o qapi.o
+block-obj-y += block-backend.o snapshot.o qapi.o
 block-obj-$(CONFIG_WIN32) += raw-win32.o win32-aio.o
 block-obj-$(CONFIG_POSIX) += raw-posix.o
 block-obj-$(CONFIG_LINUX_AIO) += linux-aio.o
diff --git a/block/block-backend.c b/block/block-backend.c
new file mode 100644
index 0000000..919dd4c
--- /dev/null
+++ b/block/block-backend.c
@@ -0,0 +1,119 @@
+/*
+ * QEMU Block backends
+ *
+ * Copyright (C) 2014 Red Hat, Inc.
+ *
+ * Authors:
+ *  Markus Armbruster <armbru@redhat.com>,
+ *
+ * This work is licensed under the terms of the GNU LGPL, version 2.1
+ * or later.  See the COPYING.LIB file in the top-level directory.
+ */
+
+#include "sysemu/block-backend.h"
+#include "block/block_int.h"
+
+struct BlockBackend {
+    char *name;
+    int refcnt;
+    QTAILQ_ENTRY(BlockBackend) link; /* for blk_backends */
+};
+
+/* All the BlockBackends */
+static QTAILQ_HEAD(, BlockBackend) blk_backends =
+    QTAILQ_HEAD_INITIALIZER(blk_backends);
+
+/*
+ * Create a new BlockBackend with @name, with a reference count of one.
+ * @name must not be null or empty.
+ * Fail if a BlockBackend with this name already exists.
+ * Store an error through @errp on failure, unless it's null.
+ * Return the new BlockBackend on success, null on failure.
+ */
+BlockBackend *blk_new(const char *name, Error **errp)
+{
+    BlockBackend *blk;
+
+    assert(name && name[0]);
+    if (blk_by_name(name)) {
+        error_setg(errp, "Device with id '%s' already exists", name);
+        return NULL;
+    }
+
+    blk = g_new0(BlockBackend, 1);
+    blk->name = g_strdup(name);
+    blk->refcnt = 1;
+    QTAILQ_INSERT_TAIL(&blk_backends, blk, link);
+    return blk;
+}
+
+static void blk_delete(BlockBackend *blk)
+{
+    assert(!blk->refcnt);
+    QTAILQ_REMOVE(&blk_backends, blk, link);
+    g_free(blk->name);
+    g_free(blk);
+}
+
+/*
+ * Increment @blk's reference count.
+ * @blk must not be null.
+ */
+void blk_ref(BlockBackend *blk)
+{
+    blk->refcnt++;
+}
+
+/*
+ * Decrement @blk's reference count.
+ * If this drops it to zero, destroy @blk.
+ * For convenience, do nothing if @blk is null.
+ */
+void blk_unref(BlockBackend *blk)
+{
+    if (blk) {
+        assert(blk->refcnt > 0);
+        if (!--blk->refcnt) {
+            blk_delete(blk);
+        }
+    }
+}
+
+/*
+ * Return the BlockBackend after @blk.
+ * If @blk is null, return the first one.
+ * Else, return @blk's next sibling, which may be null.
+ *
+ * To iterate over all BlockBackends, do
+ * for (blk = blk_next(NULL); blk; blk = blk_next(blk)) {
+ *     ...
+ * }
+ */
+BlockBackend *blk_next(BlockBackend *blk)
+{
+    return blk ? QTAILQ_NEXT(blk, link) : QTAILQ_FIRST(&blk_backends);
+}
+
+/*
+ * Return @blk's name, a non-null, non-empty string.
+ */
+const char *blk_name(BlockBackend *blk)
+{
+    return blk->name;
+}
+
+/*
+ * Return the BlockBackend with name @name if it exists, else null.
+ * @name must not be null.
+ */
+BlockBackend *blk_by_name(const char *name)
+{
+    BlockBackend *blk;
+
+    QTAILQ_FOREACH(blk, &blk_backends, link) {
+        if (!strcmp(name, blk->name)) {
+            return blk;
+        }
+    }
+    return NULL;
+}
diff --git a/blockdev.c b/blockdev.c
index c9463e3..5873205 100644
--- a/blockdev.c
+++ b/blockdev.c
@@ -30,6 +30,7 @@
  * THE SOFTWARE.
  */
 
+#include "sysemu/block-backend.h"
 #include "sysemu/blockdev.h"
 #include "hw/block/block.h"
 #include "block/blockjob.h"
@@ -227,6 +228,15 @@ void drive_info_del(DriveInfo *dinfo)
     if (dinfo->opts) {
         qemu_opts_del(dinfo->opts);
     }
+
+    /*
+     * Hairy special case: if do_drive_del() has made dinfo->bdrv
+     * anonymous, it also unref'ed the associated BlockBackend.
+     */
+    if (dinfo->bdrv->device_name[0]) {
+        blk_unref(blk_by_name(dinfo->bdrv->device_name));
+    }
+
     g_free(dinfo->id);
     QTAILQ_REMOVE(&drives, dinfo, next);
     g_free(dinfo->serial);
@@ -307,6 +317,7 @@ static DriveInfo *blockdev_init(const char *file, QDict *bs_opts,
     int ro = 0;
     int bdrv_flags = 0;
     int on_read_error, on_write_error;
+    BlockBackend *blk;
     BlockDriverState *bs;
     DriveInfo *dinfo;
     ThrottleConfig cfg;
@@ -463,9 +474,13 @@ static DriveInfo *blockdev_init(const char *file, QDict *bs_opts,
     }
 
     /* init */
+    blk = blk_new(qemu_opts_id(opts), errp);
+    if (!blk) {
+        goto early_err;
+    }
     bs = bdrv_new_root(qemu_opts_id(opts), errp);
     if (!bs) {
-        goto early_err;
+        goto bdrv_new_err;
     }
     bs->open_flags = snapshot ? BDRV_O_SNAPSHOT : 0;
     bs->read_only = ro;
@@ -531,6 +546,8 @@ static DriveInfo *blockdev_init(const char *file, QDict *bs_opts,
 
 err:
     bdrv_unref(bs);
+bdrv_new_err:
+    blk_unref(blk);
 early_err:
     qemu_opts_del(opts);
 err_no_opts:
@@ -1784,7 +1801,7 @@ int do_drive_del(Monitor *mon, const QDict *qdict, QObject **ret_data)
      */
     if (bdrv_get_attached_dev(bs)) {
         bdrv_make_anon(bs);
-
+        blk_unref(blk_by_name(id));
         /* Further I/O must not pause the guest */
         bdrv_set_on_error(bs, BLOCKDEV_ON_ERROR_REPORT,
                           BLOCKDEV_ON_ERROR_REPORT);
diff --git a/hw/block/xen_disk.c b/hw/block/xen_disk.c
index 71f0953..088e354 100644
--- a/hw/block/xen_disk.c
+++ b/hw/block/xen_disk.c
@@ -39,6 +39,7 @@
 #include "hw/xen/xen_backend.h"
 #include "xen_blkif.h"
 #include "sysemu/blockdev.h"
+#include "sysemu/block-backend.h"
 
 /* ------------------------------------------------------------- */
 
@@ -852,12 +853,18 @@ static int blk_connect(struct XenDevice *xendev)
     blkdev->dinfo = drive_get(IF_XEN, 0, index);
     if (!blkdev->dinfo) {
         Error *local_err = NULL;
+        BlockBackend *blk;
         BlockDriver *drv;
 
         /* setup via xenbus -> create new block driver instance */
         xen_be_printf(&blkdev->xendev, 2, "create new bdrv (xenbus setup)\n");
+        blk = blk_new(blkdev->dev, NULL);
+        if (!blk) {
+            return -1;
+        }
         blkdev->bs = bdrv_new_root(blkdev->dev, NULL);
         if (!blkdev->bs) {
+            blk_unref(blk);
             return -1;
         }
 
@@ -868,6 +875,7 @@ static int blk_connect(struct XenDevice *xendev)
                           error_get_pretty(local_err));
             error_free(local_err);
             bdrv_unref(blkdev->bs);
+            blk_unref(blk);
             blkdev->bs = NULL;
             return -1;
         }
@@ -983,6 +991,9 @@ static void blk_disconnect(struct XenDevice *xendev)
     if (blkdev->bs) {
         bdrv_detach_dev(blkdev->bs, blkdev);
         bdrv_unref(blkdev->bs);
+        if (!blkdev->dinfo) {
+            blk_unref(blk_by_name(blkdev->dev));
+        }
         blkdev->bs = NULL;
     }
     xen_be_unbind_evtchn(&blkdev->xendev);
diff --git a/include/qemu/typedefs.h b/include/qemu/typedefs.h
index 5f20b0e..198da2e 100644
--- a/include/qemu/typedefs.h
+++ b/include/qemu/typedefs.h
@@ -35,6 +35,7 @@ typedef struct MachineClass MachineClass;
 typedef struct NICInfo NICInfo;
 typedef struct HCIInfo HCIInfo;
 typedef struct AudioState AudioState;
+typedef struct BlockBackend BlockBackend;
 typedef struct BlockDriverState BlockDriverState;
 typedef struct DriveInfo DriveInfo;
 typedef struct DisplayState DisplayState;
diff --git a/include/sysemu/block-backend.h b/include/sysemu/block-backend.h
new file mode 100644
index 0000000..3f8371c
--- /dev/null
+++ b/include/sysemu/block-backend.h
@@ -0,0 +1,26 @@
+/*
+ * QEMU Block backends
+ *
+ * Copyright (C) 2014 Red Hat, Inc.
+ *
+ * Authors:
+ *  Markus Armbruster <armbru@redhat.com>,
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or
+ * later.  See the COPYING file in the top-level directory.
+ */
+
+#ifndef BLOCK_BACKEND_H
+#define BLOCK_BACKEND_H
+
+#include "qemu/typedefs.h"
+#include "qapi/error.h"
+
+BlockBackend *blk_new(const char *name, Error **errp);
+void blk_ref(BlockBackend *blk);
+void blk_unref(BlockBackend *blk);
+const char *blk_name(BlockBackend *blk);
+BlockBackend *blk_by_name(const char *name);
+BlockBackend *blk_next(BlockBackend *blk);
+
+#endif
diff --git a/qemu-img.c b/qemu-img.c
index 58d59d0..acb272e 100644
--- a/qemu-img.c
+++ b/qemu-img.c
@@ -29,6 +29,7 @@
 #include "qemu/error-report.h"
 #include "qemu/osdep.h"
 #include "sysemu/sysemu.h"
+#include "sysemu/block-backend.h"
 #include "block/block_int.h"
 #include "block/qapi.h"
 #include <getopt.h>
@@ -575,10 +576,11 @@ static int img_check(int argc, char **argv)
     int c, ret;
     OutputFormat output_format = OFORMAT_HUMAN;
     const char *filename, *fmt, *output, *cache;
+    BlockBackend *blk;
     BlockDriverState *bs;
     int fix = 0;
     int flags = BDRV_O_FLAGS | BDRV_O_CHECK;
-    ImageCheck *check;
+    ImageCheck *check = NULL;
     bool quiet = false;
 
     fmt = NULL;
@@ -649,9 +651,11 @@ static int img_check(int argc, char **argv)
         return 1;
     }
 
+    blk = blk_new("image", &error_abort);
     bs = bdrv_new_open("image", filename, fmt, flags, true, quiet);
     if (!bs) {
-        return 1;
+        ret = 1;
+        goto fail;
     }
 
     check = g_new0(ImageCheck, 1);
@@ -710,6 +714,7 @@ static int img_check(int argc, char **argv)
 fail:
     qapi_free_ImageCheck(check);
     bdrv_unref(bs);
+    blk_unref(blk);
 
     return ret;
 }
@@ -718,6 +723,7 @@ static int img_commit(int argc, char **argv)
 {
     int c, ret, flags;
     const char *filename, *fmt, *cache;
+    BlockBackend *blk;
     BlockDriverState *bs;
     bool quiet = false;
 
@@ -756,9 +762,11 @@ static int img_commit(int argc, char **argv)
         return 1;
     }
 
+    blk = blk_new("image", &error_abort);
     bs = bdrv_new_open("image", filename, fmt, flags, true, quiet);
     if (!bs) {
-        return 1;
+        ret = -1;
+        goto out;
     }
     ret = bdrv_commit(bs);
     switch(ret) {
@@ -779,7 +787,9 @@ static int img_commit(int argc, char **argv)
         break;
     }
 
+out:
     bdrv_unref(bs);
+    blk_unref(blk);
     if (ret) {
         return 1;
     }
@@ -942,6 +952,7 @@ static int check_empty_sectors(BlockDriverState *bs, int64_t sect_num,
 static int img_compare(int argc, char **argv)
 {
     const char *fmt1 = NULL, *fmt2 = NULL, *cache, *filename1, *filename2;
+    BlockBackend *blk1, *blk2;
     BlockDriverState *bs1, *bs2;
     int64_t total_sectors1, total_sectors2;
     uint8_t *buf1 = NULL, *buf2 = NULL;
@@ -1011,18 +1022,20 @@ static int img_compare(int argc, char **argv)
         goto out3;
     }
 
+    blk1 = blk_new("image 1", &error_abort);
     bs1 = bdrv_new_open("image 1", filename1, fmt1, flags, true, quiet);
     if (!bs1) {
         error_report("Can't open file %s", filename1);
         ret = 2;
-        goto out3;
+        goto out2;
     }
 
+    blk2 = blk_new("image 2", &error_abort);
     bs2 = bdrv_new_open("image 2", filename2, fmt2, flags, true, quiet);
     if (!bs2) {
         error_report("Can't open file %s", filename2);
         ret = 2;
-        goto out2;
+        goto out1;
     }
 
     buf1 = qemu_blockalign(bs1, IO_BUF_SIZE);
@@ -1183,11 +1196,14 @@ static int img_compare(int argc, char **argv)
     ret = 0;
 
 out:
-    bdrv_unref(bs2);
     qemu_vfree(buf1);
     qemu_vfree(buf2);
+out1:
+    bdrv_unref(bs2);
+    blk_unref(blk2);
 out2:
     bdrv_unref(bs1);
+    blk_unref(blk1);
 out3:
     qemu_progress_end();
     return ret;
@@ -1200,6 +1216,7 @@ static int img_convert(int argc, char **argv)
     int progress = 0, flags, src_flags;
     const char *fmt, *out_fmt, *cache, *src_cache, *out_baseimg, *out_filename;
     BlockDriver *drv, *proto_drv;
+    BlockBackend **blk = NULL, *out_blk = NULL;
     BlockDriverState **bs = NULL, *out_bs = NULL;
     int64_t total_sectors, nb_sectors, sector_num, bs_offset;
     int64_t *bs_sectors = NULL;
@@ -1354,6 +1371,7 @@ static int img_convert(int argc, char **argv)
 
     qemu_progress_print(0, 100);
 
+    blk = g_new0(BlockBackend *, bs_n);
     bs = g_new0(BlockDriverState *, bs_n);
     bs_sectors = g_new(int64_t, bs_n);
 
@@ -1361,6 +1379,7 @@ static int img_convert(int argc, char **argv)
     for (bs_i = 0; bs_i < bs_n; bs_i++) {
         char *id = bs_n > 1 ? g_strdup_printf("source %d", bs_i)
                             : g_strdup("source");
+        blk[bs_i] = blk_new(id, &error_abort);
         bs[bs_i] = bdrv_new_open(id, argv[optind + bs_i], fmt, src_flags,
                                  true, quiet);
         g_free(id);
@@ -1486,6 +1505,7 @@ static int img_convert(int argc, char **argv)
         goto out;
     }
 
+    out_blk = blk_new("target", &error_abort);
     out_bs = bdrv_new_open("target", out_filename, out_fmt, flags, true, quiet);
     if (!out_bs) {
         ret = -1;
@@ -1742,6 +1762,7 @@ out:
     if (out_bs) {
         bdrv_unref(out_bs);
     }
+    blk_unref(out_blk);
     if (bs) {
         for (bs_i = 0; bs_i < bs_n; bs_i++) {
             if (bs[bs_i]) {
@@ -1750,6 +1771,12 @@ out:
         }
         g_free(bs);
     }
+    if (blk) {
+        for (bs_i = 0; bs_i < bs_n; bs_i++) {
+            blk_unref(blk[bs_i]);
+        }
+        g_free(blk);
+    }
     g_free(bs_sectors);
 fail_getopt:
     g_free(options);
@@ -1858,6 +1885,7 @@ static ImageInfoList *collect_image_info_list(const char *filename,
     filenames = g_hash_table_new_full(g_str_hash, str_equal_func, NULL, NULL);
 
     while (filename) {
+        BlockBackend *blk;
         BlockDriverState *bs;
         ImageInfo *info;
         ImageInfoList *elem;
@@ -1869,9 +1897,11 @@ static ImageInfoList *collect_image_info_list(const char *filename,
         }
         g_hash_table_insert(filenames, (gpointer)filename, NULL);
 
+        blk = blk_new("image", &error_abort);
         bs = bdrv_new_open("image", filename, fmt,
                            BDRV_O_FLAGS | BDRV_O_NO_BACKING, false, false);
         if (!bs) {
+            blk_unref(blk);
             goto err;
         }
 
@@ -1880,6 +1910,7 @@ static ImageInfoList *collect_image_info_list(const char *filename,
             error_report("%s", error_get_pretty(err));
             error_free(err);
             bdrv_unref(bs);
+            blk_unref(blk);
             goto err;
         }
 
@@ -1889,6 +1920,7 @@ static ImageInfoList *collect_image_info_list(const char *filename,
         last = &elem->next;
 
         bdrv_unref(bs);
+        blk_unref(blk);
 
         filename = fmt = NULL;
         if (chain) {
@@ -2082,6 +2114,7 @@ static int img_map(int argc, char **argv)
 {
     int c;
     OutputFormat output_format = OFORMAT_HUMAN;
+    BlockBackend *blk;
     BlockDriverState *bs;
     const char *filename, *fmt, *output;
     int64_t length;
@@ -2130,9 +2163,11 @@ static int img_map(int argc, char **argv)
         return 1;
     }
 
+    blk = blk_new("image", &error_abort);
     bs = bdrv_new_open("image", filename, fmt, BDRV_O_FLAGS, true, false);
     if (!bs) {
-        return 1;
+        ret = -1;
+        goto out;
     }
 
     if (output_format == OFORMAT_HUMAN) {
@@ -2175,6 +2210,7 @@ static int img_map(int argc, char **argv)
 
 out:
     bdrv_unref(bs);
+    blk_unref(blk);
     return ret < 0;
 }
 
@@ -2185,6 +2221,7 @@ out:
 
 static int img_snapshot(int argc, char **argv)
 {
+    BlockBackend *blk;
     BlockDriverState *bs;
     QEMUSnapshotInfo sn;
     char *filename, *snapshot_name = NULL;
@@ -2250,9 +2287,11 @@ static int img_snapshot(int argc, char **argv)
     filename = argv[optind++];
 
     /* Open the image */
+    blk = blk_new("image", &error_abort);
     bs = bdrv_new_open("image", filename, NULL, bdrv_oflags, true, quiet);
     if (!bs) {
-        return 1;
+        ret = -1;
+        goto out;
     }
 
     /* Perform the requested action */
@@ -2296,7 +2335,9 @@ static int img_snapshot(int argc, char **argv)
     }
 
     /* Cleanup */
+out:
     bdrv_unref(bs);
+    blk_unref(blk);
     if (ret) {
         return 1;
     }
@@ -2305,6 +2346,7 @@ static int img_snapshot(int argc, char **argv)
 
 static int img_rebase(int argc, char **argv)
 {
+    BlockBackend *blk = NULL, *blk_old_backing = NULL, *blk_new_backing = NULL;
     BlockDriverState *bs = NULL, *bs_old_backing = NULL, *bs_new_backing = NULL;
     BlockDriver *old_backing_drv, *new_backing_drv;
     char *filename;
@@ -2393,6 +2435,7 @@ static int img_rebase(int argc, char **argv)
      * Ignore the old backing file for unsafe rebase in case we want to correct
      * the reference to a renamed or moved backing file.
      */
+    blk = blk_new("image", &error_abort);
     bs = bdrv_new_open("image", filename, fmt, flags, true, quiet);
     if (!bs) {
         ret = -1;
@@ -2425,6 +2468,7 @@ static int img_rebase(int argc, char **argv)
     if (!unsafe) {
         char backing_name[1024];
 
+        blk_old_backing = blk_new("old_backing", &error_abort);
         bs_old_backing = bdrv_new_root("old_backing", &error_abort);
         bdrv_get_backing_filename(bs, backing_name, sizeof(backing_name));
         ret = bdrv_open(&bs_old_backing, backing_name, NULL, NULL, src_flags,
@@ -2436,6 +2480,7 @@ static int img_rebase(int argc, char **argv)
             goto out;
         }
         if (out_baseimg[0]) {
+            blk_new_backing = blk_new("new_backing", &error_abort);
             bs_new_backing = bdrv_new_root("new_backing", &error_abort);
             ret = bdrv_open(&bs_new_backing, out_baseimg, NULL, NULL, src_flags,
                             new_backing_drv, &local_err);
@@ -2614,12 +2659,15 @@ out:
         if (bs_old_backing != NULL) {
             bdrv_unref(bs_old_backing);
         }
+        blk_unref(blk_old_backing);
         if (bs_new_backing != NULL) {
             bdrv_unref(bs_new_backing);
         }
+        blk_unref(blk_new_backing);
     }
 
     bdrv_unref(bs);
+    blk_unref(blk);
     if (ret) {
         return 1;
     }
@@ -2632,6 +2680,7 @@ static int img_resize(int argc, char **argv)
     const char *filename, *fmt, *size;
     int64_t n, total_size;
     bool quiet = false;
+    BlockBackend *blk = NULL;
     BlockDriverState *bs = NULL;
     QemuOpts *param;
     static QemuOptsList resize_options = {
@@ -2708,6 +2757,7 @@ static int img_resize(int argc, char **argv)
     n = qemu_opt_get_size(param, BLOCK_OPT_SIZE, 0);
     qemu_opts_del(param);
 
+    blk = blk_new("image", &error_abort);
     bs = bdrv_new_open("image", filename, fmt, BDRV_O_FLAGS | BDRV_O_RDWR,
                        true, quiet);
     if (!bs) {
@@ -2745,6 +2795,7 @@ out:
     if (bs) {
         bdrv_unref(bs);
     }
+    blk_unref(blk);
     if (ret) {
         return 1;
     }
@@ -2760,6 +2811,7 @@ static int img_amend(int argc, char **argv)
     const char *fmt = NULL, *filename, *cache;
     int flags;
     bool quiet = false;
+    BlockBackend *blk = NULL;
     BlockDriverState *bs = NULL;
 
     cache = BDRV_DEFAULT_CACHE;
@@ -2823,6 +2875,7 @@ static int img_amend(int argc, char **argv)
         goto out;
     }
 
+    blk = blk_new("image", &error_abort);
     bs = bdrv_new_open("image", filename, fmt, flags, true, quiet);
     if (!bs) {
         error_report("Could not open image '%s'", filename);
@@ -2856,6 +2909,7 @@ out:
     if (bs) {
         bdrv_unref(bs);
     }
+    blk_unref(blk);
     qemu_opts_del(opts);
     qemu_opts_free(create_opts);
     g_free(options);
diff --git a/qemu-io.c b/qemu-io.c
index 24ca59c..57090de 100644
--- a/qemu-io.c
+++ b/qemu-io.c
@@ -19,6 +19,7 @@
 #include "qemu/option.h"
 #include "qemu/config-file.h"
 #include "qemu/readline.h"
+#include "sysemu/block-backend.h"
 #include "block/block_int.h"
 #include "trace/control.h"
 
@@ -26,6 +27,7 @@
 
 static char *progname;
 
+static BlockBackend *qemuio_blk;
 static BlockDriverState *qemuio_bs;
 
 /* qemu-io commands passed using -c */
@@ -37,7 +39,9 @@ static ReadLineState *readline_state;
 static int close_f(BlockDriverState *bs, int argc, char **argv)
 {
     bdrv_unref(bs);
+    blk_unref(qemuio_blk);
     qemuio_bs = NULL;
+    qemuio_blk = NULL;
     return 0;
 }
 
@@ -58,6 +62,7 @@ static int openfile(char *name, int flags, int growable, QDict *opts)
         return 1;
     }
 
+    qemuio_blk = blk_new("hda", &error_abort);
     qemuio_bs = bdrv_new_root("hda", &error_abort);
 
     if (growable) {
@@ -70,7 +75,9 @@ static int openfile(char *name, int flags, int growable, QDict *opts)
                 error_get_pretty(local_err));
         error_free(local_err);
         bdrv_unref(qemuio_bs);
+        blk_unref(qemuio_blk);
         qemuio_bs = NULL;
+        qemuio_blk = NULL;
         return 1;
     }
 
@@ -479,6 +486,7 @@ int main(int argc, char **argv)
     if (qemuio_bs) {
         bdrv_unref(qemuio_bs);
     }
+    blk_unref(qemuio_blk);
     g_free(readline_state);
     return 0;
 }
diff --git a/qemu-nbd.c b/qemu-nbd.c
index 24b8454..ff95da6 100644
--- a/qemu-nbd.c
+++ b/qemu-nbd.c
@@ -17,7 +17,7 @@
  */
 
 #include "qemu-common.h"
-#include "block/block.h"
+#include "sysemu/block-backend.h"
 #include "block/block_int.h"
 #include "block/nbd.h"
 #include "qemu/main-loop.h"
@@ -384,6 +384,7 @@ static void nbd_accept(void *opaque)
 
 int main(int argc, char **argv)
 {
+    BlockBackend *blk;
     BlockDriverState *bs;
     BlockDriver *drv;
     off_t dev_offset = 0;
@@ -687,6 +688,7 @@ int main(int argc, char **argv)
         drv = NULL;
     }
 
+    blk = blk_new("hda", &error_abort);
     bs = bdrv_new_root("hda", &error_abort);
 
     srcpath = argv[optind];
@@ -770,6 +772,7 @@ int main(int argc, char **argv)
     } while (state != TERMINATED);
 
     bdrv_unref(bs);
+    blk_unref(blk);
     if (sockpath) {
         unlink(sockpath);
     }
-- 
1.9.3

^ permalink raw reply related	[flat|nested] 56+ messages in thread

* [Qemu-devel] [PATCH v2 03/23] block: Connect BlockBackend to BlockDriverState
  2014-09-13 15:00 [Qemu-devel] [PATCH v2 00/23] Split BlockBackend off BDS with an axe Markus Armbruster
  2014-09-13 15:00 ` [Qemu-devel] [PATCH v2 01/23] block: Split bdrv_new_root() off bdrv_new() Markus Armbruster
  2014-09-13 15:00 ` [Qemu-devel] [PATCH v2 02/23] block: New BlockBackend Markus Armbruster
@ 2014-09-13 15:00 ` Markus Armbruster
  2014-09-13 22:13   ` Max Reitz
  2014-09-15 15:00   ` Benoît Canet
  2014-09-13 15:00 ` [Qemu-devel] [PATCH v2 04/23] block: Connect BlockBackend and DriveInfo Markus Armbruster
                   ` (20 subsequent siblings)
  23 siblings, 2 replies; 56+ messages in thread
From: Markus Armbruster @ 2014-09-13 15:00 UTC (permalink / raw)
  To: qemu-devel; +Cc: kwolf, benoit.canet, stefanha

The pointer from BlockBackend to BlockDriverState is a strong
reference, managed with bdrv_ref() / bdrv_unref(), the back-pointer is
a weak one.

Convenience function blk_new_with_bs() creates a BlockBackend with its
BlockDriverState.  Callers have to unref both.  The commit after next
will relieve them of the need to unref the BlockDriverState.

Complication: due to the silly way drive_del works, we need a way to
hide a BlockBackend, just like bdrv_make_anon().  To emphasize its
"special" status, give the function a suitably off-putting name:
blk_hide_on_behalf_of_do_drive_del().  Unfortunately, hiding turns the
BlockBackend's name into the empty string.  Can't avoid that without
breaking the blk->bs->device_name equals blk->name invariant.

Signed-off-by: Markus Armbruster <armbru@redhat.com>
---
 block.c                        |  10 ++--
 block/block-backend.c          |  70 ++++++++++++++++++++++-
 blockdev.c                     |  26 +++------
 hw/block/xen_disk.c            |   8 +--
 include/block/block_int.h      |   2 +
 include/sysemu/block-backend.h |   5 ++
 qemu-img.c                     | 125 +++++++++++++++++++----------------------
 qemu-io.c                      |   4 +-
 qemu-nbd.c                     |   2 +-
 9 files changed, 152 insertions(+), 100 deletions(-)

diff --git a/block.c b/block.c
index a05d0e3..92f84d2 100644
--- a/block.c
+++ b/block.c
@@ -2032,7 +2032,7 @@ static void bdrv_move_feature_fields(BlockDriverState *bs_dest,
  * This will modify the BlockDriverState fields, and swap contents
  * between bs_new and bs_old. Both bs_new and bs_old are modified.
  *
- * bs_new is required to be anonymous.
+ * bs_new must be nameless and not attached to a BlockBackend.
  *
  * This function does not create any image files.
  */
@@ -2051,8 +2051,9 @@ void bdrv_swap(BlockDriverState *bs_new, BlockDriverState *bs_old)
         QTAILQ_REMOVE(&graph_bdrv_states, bs_old, node_list);
     }
 
-    /* bs_new must be anonymous and shouldn't have anything fancy enabled */
+    /* bs_new must be nameless and shouldn't have anything fancy enabled */
     assert(bs_new->device_name[0] == '\0');
+    assert(!bs_new->blk);
     assert(QLIST_EMPTY(&bs_new->dirty_bitmaps));
     assert(bs_new->job == NULL);
     assert(bs_new->dev == NULL);
@@ -2068,8 +2069,9 @@ void bdrv_swap(BlockDriverState *bs_new, BlockDriverState *bs_old)
     bdrv_move_feature_fields(bs_old, bs_new);
     bdrv_move_feature_fields(bs_new, &tmp);
 
-    /* bs_new shouldn't be in bdrv_states even after the swap!  */
+    /* bs_new must remain nameless and unattached */
     assert(bs_new->device_name[0] == '\0');
+    assert(!bs_new->blk);
 
     /* Check a few fields that should remain attached to the device */
     assert(bs_new->dev == NULL);
@@ -2096,7 +2098,7 @@ void bdrv_swap(BlockDriverState *bs_new, BlockDriverState *bs_old)
  * This will modify the BlockDriverState fields, and swap contents
  * between bs_new and bs_top. Both bs_new and bs_top are modified.
  *
- * bs_new is required to be anonymous.
+ * bs_new must be nameless and not attached to a BlockBackend.
  *
  * This function does not create any image files.
  */
diff --git a/block/block-backend.c b/block/block-backend.c
index 919dd4c..b118b38 100644
--- a/block/block-backend.c
+++ b/block/block-backend.c
@@ -16,10 +16,11 @@
 struct BlockBackend {
     char *name;
     int refcnt;
+    BlockDriverState *bs;
     QTAILQ_ENTRY(BlockBackend) link; /* for blk_backends */
 };
 
-/* All the BlockBackends */
+/* All the BlockBackends (except for hidden ones) */
 static QTAILQ_HEAD(, BlockBackend) blk_backends =
     QTAILQ_HEAD_INITIALIZER(blk_backends);
 
@@ -47,10 +48,43 @@ BlockBackend *blk_new(const char *name, Error **errp)
     return blk;
 }
 
+/*
+ * Create a new BlockBackend with a new BlockDriverState attached.
+ * Both have a reference count of one.  Caller owns *both* references.
+ * TODO Let caller own only the BlockBackend reference
+ * Otherwise just like blk_new(), which see.
+ */
+BlockBackend *blk_new_with_bs(const char *name, Error **errp)
+{
+    BlockBackend *blk;
+    BlockDriverState *bs;
+
+    blk = blk_new(name, errp);
+    if (!blk) {
+        return NULL;
+    }
+
+    bs = bdrv_new_root(name, errp);
+    if (!bs) {
+        blk_unref(blk);
+        return NULL;
+    }
+
+    blk->bs = bs;
+    bs->blk = blk;
+    return blk;
+}
+
 static void blk_delete(BlockBackend *blk)
 {
     assert(!blk->refcnt);
-    QTAILQ_REMOVE(&blk_backends, blk, link);
+    if (blk->bs) {
+        blk->bs->blk = NULL;
+        blk->bs = NULL;
+    }
+    if (blk->name[0]) {
+        QTAILQ_REMOVE(&blk_backends, blk, link);
+    }
     g_free(blk->name);
     g_free(blk);
 }
@@ -68,6 +102,8 @@ void blk_ref(BlockBackend *blk)
  * Decrement @blk's reference count.
  * If this drops it to zero, destroy @blk.
  * For convenience, do nothing if @blk is null.
+ * Does *not* touch the attached BlockDriverState's reference count.
+ * TODO Decrement it!
  */
 void blk_unref(BlockBackend *blk)
 {
@@ -95,7 +131,9 @@ BlockBackend *blk_next(BlockBackend *blk)
 }
 
 /*
- * Return @blk's name, a non-null, non-empty string.
+ * Return @blk's name, a non-null string.
+ * Wart: the name is empty iff @blk has been hidden with
+ * blk_hide_on_behalf_of_do_drive_del().
  */
 const char *blk_name(BlockBackend *blk)
 {
@@ -117,3 +155,29 @@ BlockBackend *blk_by_name(const char *name)
     }
     return NULL;
 }
+
+/*
+ * Return the BlockDriverState attached to @blk if any, else null.
+ */
+BlockDriverState *blk_bs(BlockBackend *blk)
+{
+    return blk->bs;
+}
+
+/*
+ * Hide @blk.
+ * @blk must not have been hidden already.
+ * Make attached BlockDriverState, if any, anonymous.
+ * Once hidden, @blk is invisible to all functions that don't receive
+ * it as argument.  For example, blk_by_name() won't return it.
+ * Strictly for use by do_drive_del().
+ * TODO get rid of it!
+ */
+void blk_hide_on_behalf_of_do_drive_del(BlockBackend *blk)
+{
+    QTAILQ_REMOVE(&blk_backends, blk, link);
+    blk->name[0] = 0;
+    if (blk->bs) {
+        bdrv_make_anon(blk->bs);
+    }
+}
diff --git a/blockdev.c b/blockdev.c
index 5873205..21f4c67 100644
--- a/blockdev.c
+++ b/blockdev.c
@@ -229,14 +229,7 @@ void drive_info_del(DriveInfo *dinfo)
         qemu_opts_del(dinfo->opts);
     }
 
-    /*
-     * Hairy special case: if do_drive_del() has made dinfo->bdrv
-     * anonymous, it also unref'ed the associated BlockBackend.
-     */
-    if (dinfo->bdrv->device_name[0]) {
-        blk_unref(blk_by_name(dinfo->bdrv->device_name));
-    }
-
+    blk_unref(blk_by_name(dinfo->bdrv->device_name));
     g_free(dinfo->id);
     QTAILQ_REMOVE(&drives, dinfo, next);
     g_free(dinfo->serial);
@@ -474,14 +467,11 @@ static DriveInfo *blockdev_init(const char *file, QDict *bs_opts,
     }
 
     /* init */
-    blk = blk_new(qemu_opts_id(opts), errp);
+    blk = blk_new_with_bs(qemu_opts_id(opts), errp);
     if (!blk) {
         goto early_err;
     }
-    bs = bdrv_new_root(qemu_opts_id(opts), errp);
-    if (!bs) {
-        goto bdrv_new_err;
-    }
+    bs = blk_bs(blk);
     bs->open_flags = snapshot ? BDRV_O_SNAPSHOT : 0;
     bs->read_only = ro;
     bs->detect_zeroes = detect_zeroes;
@@ -546,7 +536,6 @@ static DriveInfo *blockdev_init(const char *file, QDict *bs_opts,
 
 err:
     bdrv_unref(bs);
-bdrv_new_err:
     blk_unref(blk);
 early_err:
     qemu_opts_del(opts);
@@ -1761,16 +1750,18 @@ void qmp_block_set_io_throttle(const char *device, int64_t bps, int64_t bps_rd,
 int do_drive_del(Monitor *mon, const QDict *qdict, QObject **ret_data)
 {
     const char *id = qdict_get_str(qdict, "id");
+    BlockBackend *blk;
     BlockDriverState *bs;
     DriveInfo *dinfo;
     AioContext *aio_context;
     Error *local_err = NULL;
 
-    bs = bdrv_find(id);
-    if (!bs) {
+    blk = blk_by_name(id);
+    if (!blk) {
         error_report("Device '%s' not found", id);
         return -1;
     }
+    bs = blk_bs(blk);
 
     dinfo = drive_get_by_blockdev(bs);
     if (dinfo && !dinfo->enable_auto_del) {
@@ -1800,8 +1791,7 @@ int do_drive_del(Monitor *mon, const QDict *qdict, QObject **ret_data)
      * then we can just get rid of the block driver state right here.
      */
     if (bdrv_get_attached_dev(bs)) {
-        bdrv_make_anon(bs);
-        blk_unref(blk_by_name(id));
+        blk_hide_on_behalf_of_do_drive_del(blk);
         /* Further I/O must not pause the guest */
         bdrv_set_on_error(bs, BLOCKDEV_ON_ERROR_REPORT,
                           BLOCKDEV_ON_ERROR_REPORT);
diff --git a/hw/block/xen_disk.c b/hw/block/xen_disk.c
index 088e354..51f4f3a 100644
--- a/hw/block/xen_disk.c
+++ b/hw/block/xen_disk.c
@@ -858,15 +858,11 @@ static int blk_connect(struct XenDevice *xendev)
 
         /* setup via xenbus -> create new block driver instance */
         xen_be_printf(&blkdev->xendev, 2, "create new bdrv (xenbus setup)\n");
-        blk = blk_new(blkdev->dev, NULL);
+        blk = blk_new_with_bs(blkdev->dev, NULL);
         if (!blk) {
             return -1;
         }
-        blkdev->bs = bdrv_new_root(blkdev->dev, NULL);
-        if (!blkdev->bs) {
-            blk_unref(blk);
-            return -1;
-        }
+        blkdev->bs = blk_bs(blk);
 
         drv = bdrv_find_whitelisted_format(blkdev->fileproto, readonly);
         if (bdrv_open(&blkdev->bs, blkdev->filename, NULL, NULL, qflags,
diff --git a/include/block/block_int.h b/include/block/block_int.h
index 8a61215..a04c852 100644
--- a/include/block/block_int.h
+++ b/include/block/block_int.h
@@ -323,6 +323,8 @@ struct BlockDriverState {
     BlockDriver *drv; /* NULL means no media */
     void *opaque;
 
+    BlockBackend *blk;          /* owning backend, if any */
+
     void *dev;                  /* attached device model, if any */
     /* TODO change to DeviceState when all users are qdevified */
     const BlockDevOps *dev_ops;
diff --git a/include/sysemu/block-backend.h b/include/sysemu/block-backend.h
index 3f8371c..fa8f623 100644
--- a/include/sysemu/block-backend.h
+++ b/include/sysemu/block-backend.h
@@ -17,10 +17,15 @@
 #include "qapi/error.h"
 
 BlockBackend *blk_new(const char *name, Error **errp);
+BlockBackend *blk_new_with_bs(const char *name, Error **errp);
 void blk_ref(BlockBackend *blk);
 void blk_unref(BlockBackend *blk);
 const char *blk_name(BlockBackend *blk);
 BlockBackend *blk_by_name(const char *name);
 BlockBackend *blk_next(BlockBackend *blk);
 
+BlockDriverState *blk_bs(BlockBackend *blk);
+
+void blk_hide_on_behalf_of_do_drive_del(BlockBackend *blk);
+
 #endif
diff --git a/qemu-img.c b/qemu-img.c
index acb272e..206a513 100644
--- a/qemu-img.c
+++ b/qemu-img.c
@@ -284,20 +284,19 @@ static int print_block_option_help(const char *filename, const char *fmt)
     return 0;
 }
 
-static BlockDriverState *bdrv_new_open(const char *id,
-                                       const char *filename,
-                                       const char *fmt,
-                                       int flags,
-                                       bool require_io,
-                                       bool quiet)
+static BlockBackend *img_open(const char *id, const char *filename,
+                              const char *fmt, int flags,
+                              bool require_io, bool quiet)
 {
+    BlockBackend *blk;
     BlockDriverState *bs;
     BlockDriver *drv;
     char password[256];
     Error *local_err = NULL;
     int ret;
 
-    bs = bdrv_new_root(id, &error_abort);
+    blk = blk_new_with_bs(id, &error_abort);
+    bs = blk_bs(blk);
 
     if (fmt) {
         drv = bdrv_find_format(fmt);
@@ -328,9 +327,10 @@ static BlockDriverState *bdrv_new_open(const char *id,
             goto fail;
         }
     }
-    return bs;
+    return blk;
 fail:
     bdrv_unref(bs);
+    blk_unref(blk);
     return NULL;
 }
 
@@ -580,7 +580,7 @@ static int img_check(int argc, char **argv)
     BlockDriverState *bs;
     int fix = 0;
     int flags = BDRV_O_FLAGS | BDRV_O_CHECK;
-    ImageCheck *check = NULL;
+    ImageCheck *check;
     bool quiet = false;
 
     fmt = NULL;
@@ -651,12 +651,11 @@ static int img_check(int argc, char **argv)
         return 1;
     }
 
-    blk = blk_new("image", &error_abort);
-    bs = bdrv_new_open("image", filename, fmt, flags, true, quiet);
-    if (!bs) {
-        ret = 1;
-        goto fail;
+    blk = img_open("image", filename, fmt, flags, true, quiet);
+    if (!blk) {
+        return 1;
     }
+    bs = blk_bs(blk);
 
     check = g_new0(ImageCheck, 1);
     ret = collect_image_check(bs, check, filename, fmt, fix);
@@ -762,12 +761,12 @@ static int img_commit(int argc, char **argv)
         return 1;
     }
 
-    blk = blk_new("image", &error_abort);
-    bs = bdrv_new_open("image", filename, fmt, flags, true, quiet);
-    if (!bs) {
-        ret = -1;
-        goto out;
+    blk = img_open("image", filename, fmt, flags, true, quiet);
+    if (!blk) {
+        return 1;
     }
+    bs = blk_bs(blk);
+
     ret = bdrv_commit(bs);
     switch(ret) {
     case 0:
@@ -787,7 +786,6 @@ static int img_commit(int argc, char **argv)
         break;
     }
 
-out:
     bdrv_unref(bs);
     blk_unref(blk);
     if (ret) {
@@ -1022,21 +1020,21 @@ static int img_compare(int argc, char **argv)
         goto out3;
     }
 
-    blk1 = blk_new("image 1", &error_abort);
-    bs1 = bdrv_new_open("image 1", filename1, fmt1, flags, true, quiet);
-    if (!bs1) {
+    blk1 = img_open("image 1", filename1, fmt1, flags, true, quiet);
+    if (!blk1) {
         error_report("Can't open file %s", filename1);
         ret = 2;
-        goto out2;
+        goto out3;
     }
+    bs1 = blk_bs(blk1);
 
-    blk2 = blk_new("image 2", &error_abort);
-    bs2 = bdrv_new_open("image 2", filename2, fmt2, flags, true, quiet);
-    if (!bs2) {
+    blk2 = img_open("image 2", filename2, fmt2, flags, true, quiet);
+    if (!blk2) {
         error_report("Can't open file %s", filename2);
         ret = 2;
-        goto out1;
+        goto out2;
     }
+    bs2 = blk_bs(blk2);
 
     buf1 = qemu_blockalign(bs1, IO_BUF_SIZE);
     buf2 = qemu_blockalign(bs2, IO_BUF_SIZE);
@@ -1198,7 +1196,6 @@ static int img_compare(int argc, char **argv)
 out:
     qemu_vfree(buf1);
     qemu_vfree(buf2);
-out1:
     bdrv_unref(bs2);
     blk_unref(blk2);
 out2:
@@ -1379,15 +1376,15 @@ static int img_convert(int argc, char **argv)
     for (bs_i = 0; bs_i < bs_n; bs_i++) {
         char *id = bs_n > 1 ? g_strdup_printf("source %d", bs_i)
                             : g_strdup("source");
-        blk[bs_i] = blk_new(id, &error_abort);
-        bs[bs_i] = bdrv_new_open(id, argv[optind + bs_i], fmt, src_flags,
-                                 true, quiet);
+        blk[bs_i] = img_open(id, argv[optind + bs_i], fmt, src_flags,
+                             true, quiet);
         g_free(id);
-        if (!bs[bs_i]) {
+        if (!blk[bs_i]) {
             error_report("Could not open '%s'", argv[optind + bs_i]);
             ret = -1;
             goto out;
         }
+        bs[bs_i] = blk_bs(blk[bs_i]);
         bs_sectors[bs_i] = bdrv_nb_sectors(bs[bs_i]);
         if (bs_sectors[bs_i] < 0) {
             error_report("Could not get size of %s: %s",
@@ -1505,12 +1502,12 @@ static int img_convert(int argc, char **argv)
         goto out;
     }
 
-    out_blk = blk_new("target", &error_abort);
-    out_bs = bdrv_new_open("target", out_filename, out_fmt, flags, true, quiet);
-    if (!out_bs) {
+    out_blk = img_open("target", out_filename, out_fmt, flags, true, quiet);
+    if (!out_blk) {
         ret = -1;
         goto out;
     }
+    out_bs = blk_bs(out_blk);
 
     bs_i = 0;
     bs_offset = 0;
@@ -1897,13 +1894,12 @@ static ImageInfoList *collect_image_info_list(const char *filename,
         }
         g_hash_table_insert(filenames, (gpointer)filename, NULL);
 
-        blk = blk_new("image", &error_abort);
-        bs = bdrv_new_open("image", filename, fmt,
-                           BDRV_O_FLAGS | BDRV_O_NO_BACKING, false, false);
-        if (!bs) {
-            blk_unref(blk);
+        blk = img_open("image", filename, fmt,
+                       BDRV_O_FLAGS | BDRV_O_NO_BACKING, false, false);
+        if (!blk) {
             goto err;
         }
+        bs = blk_bs(blk);
 
         bdrv_query_image_info(bs, &info, &err);
         if (err) {
@@ -2163,12 +2159,11 @@ static int img_map(int argc, char **argv)
         return 1;
     }
 
-    blk = blk_new("image", &error_abort);
-    bs = bdrv_new_open("image", filename, fmt, BDRV_O_FLAGS, true, false);
-    if (!bs) {
-        ret = -1;
-        goto out;
+    blk = img_open("image", filename, fmt, BDRV_O_FLAGS, true, false);
+    if (!blk) {
+        return 1;
     }
+    bs = blk_bs(blk);
 
     if (output_format == OFORMAT_HUMAN) {
         printf("%-16s%-16s%-16s%s\n", "Offset", "Length", "Mapped to", "File");
@@ -2287,12 +2282,11 @@ static int img_snapshot(int argc, char **argv)
     filename = argv[optind++];
 
     /* Open the image */
-    blk = blk_new("image", &error_abort);
-    bs = bdrv_new_open("image", filename, NULL, bdrv_oflags, true, quiet);
-    if (!bs) {
-        ret = -1;
-        goto out;
+    blk = img_open("image", filename, NULL, bdrv_oflags, true, quiet);
+    if (!blk) {
+        return 1;
     }
+    bs = blk_bs(blk);
 
     /* Perform the requested action */
     switch(action) {
@@ -2335,7 +2329,6 @@ static int img_snapshot(int argc, char **argv)
     }
 
     /* Cleanup */
-out:
     bdrv_unref(bs);
     blk_unref(blk);
     if (ret) {
@@ -2435,12 +2428,12 @@ static int img_rebase(int argc, char **argv)
      * Ignore the old backing file for unsafe rebase in case we want to correct
      * the reference to a renamed or moved backing file.
      */
-    blk = blk_new("image", &error_abort);
-    bs = bdrv_new_open("image", filename, fmt, flags, true, quiet);
-    if (!bs) {
+    blk = img_open("image", filename, fmt, flags, true, quiet);
+    if (!blk) {
         ret = -1;
         goto out;
     }
+    bs = blk_bs(blk);
 
     /* Find the right drivers for the backing files */
     old_backing_drv = NULL;
@@ -2468,8 +2461,8 @@ static int img_rebase(int argc, char **argv)
     if (!unsafe) {
         char backing_name[1024];
 
-        blk_old_backing = blk_new("old_backing", &error_abort);
-        bs_old_backing = bdrv_new_root("old_backing", &error_abort);
+        blk_old_backing = blk_new_with_bs("old_backing", &error_abort);
+        bs_old_backing = blk_bs(blk_old_backing);
         bdrv_get_backing_filename(bs, backing_name, sizeof(backing_name));
         ret = bdrv_open(&bs_old_backing, backing_name, NULL, NULL, src_flags,
                         old_backing_drv, &local_err);
@@ -2480,8 +2473,8 @@ static int img_rebase(int argc, char **argv)
             goto out;
         }
         if (out_baseimg[0]) {
-            blk_new_backing = blk_new("new_backing", &error_abort);
-            bs_new_backing = bdrv_new_root("new_backing", &error_abort);
+            blk_new_backing = blk_new_with_bs("new_backing", &error_abort);
+            bs_new_backing = blk_bs(blk_new_backing);
             ret = bdrv_open(&bs_new_backing, out_baseimg, NULL, NULL, src_flags,
                             new_backing_drv, &local_err);
             if (ret) {
@@ -2757,13 +2750,13 @@ static int img_resize(int argc, char **argv)
     n = qemu_opt_get_size(param, BLOCK_OPT_SIZE, 0);
     qemu_opts_del(param);
 
-    blk = blk_new("image", &error_abort);
-    bs = bdrv_new_open("image", filename, fmt, BDRV_O_FLAGS | BDRV_O_RDWR,
-                       true, quiet);
-    if (!bs) {
+    blk = img_open("image", filename, fmt, BDRV_O_FLAGS | BDRV_O_RDWR,
+                   true, quiet);
+    if (!blk) {
         ret = -1;
         goto out;
     }
+    bs = blk_bs(blk);
 
     if (relative) {
         total_size = bdrv_getlength(bs) + n * relative;
@@ -2875,13 +2868,13 @@ static int img_amend(int argc, char **argv)
         goto out;
     }
 
-    blk = blk_new("image", &error_abort);
-    bs = bdrv_new_open("image", filename, fmt, flags, true, quiet);
-    if (!bs) {
+    blk = img_open("image", filename, fmt, flags, true, quiet);
+    if (!blk) {
         error_report("Could not open image '%s'", filename);
         ret = -1;
         goto out;
     }
+    bs = blk_bs(blk);
 
     fmt = bs->drv->format_name;
 
diff --git a/qemu-io.c b/qemu-io.c
index 57090de..ef1d3ea 100644
--- a/qemu-io.c
+++ b/qemu-io.c
@@ -62,8 +62,8 @@ static int openfile(char *name, int flags, int growable, QDict *opts)
         return 1;
     }
 
-    qemuio_blk = blk_new("hda", &error_abort);
-    qemuio_bs = bdrv_new_root("hda", &error_abort);
+    qemuio_blk = blk_new_with_bs("hda", &error_abort);
+    qemuio_bs = blk_bs(qemuio_blk);
 
     if (growable) {
         flags |= BDRV_O_PROTOCOL;
diff --git a/qemu-nbd.c b/qemu-nbd.c
index ff95da6..fa8a7d0 100644
--- a/qemu-nbd.c
+++ b/qemu-nbd.c
@@ -689,7 +689,7 @@ int main(int argc, char **argv)
     }
 
     blk = blk_new("hda", &error_abort);
-    bs = bdrv_new_root("hda", &error_abort);
+    bs = blk_bs(blk);
 
     srcpath = argv[optind];
     ret = bdrv_open(&bs, srcpath, NULL, NULL, flags, drv, &local_err);
-- 
1.9.3

^ permalink raw reply related	[flat|nested] 56+ messages in thread

* [Qemu-devel] [PATCH v2 04/23] block: Connect BlockBackend and DriveInfo
  2014-09-13 15:00 [Qemu-devel] [PATCH v2 00/23] Split BlockBackend off BDS with an axe Markus Armbruster
                   ` (2 preceding siblings ...)
  2014-09-13 15:00 ` [Qemu-devel] [PATCH v2 03/23] block: Connect BlockBackend to BlockDriverState Markus Armbruster
@ 2014-09-13 15:00 ` Markus Armbruster
  2014-09-16 12:38   ` Benoît Canet
  2014-09-13 15:00 ` [Qemu-devel] [PATCH v2 05/23] block: Code motion to get rid of stubs/blockdev.c Markus Armbruster
                   ` (19 subsequent siblings)
  23 siblings, 1 reply; 56+ messages in thread
From: Markus Armbruster @ 2014-09-13 15:00 UTC (permalink / raw)
  To: qemu-devel; +Cc: kwolf, benoit.canet, stefanha

Make the BlockBackend own the DriveInfo.  Change blockdev_init() to
return the BlockBackend instead of the DriveInfo.

Signed-off-by: Markus Armbruster <armbru@redhat.com>
---
 block.c                   |  3 --
 block/block-backend.c     | 38 ++++++++++++++++++++++++
 blockdev.c                | 73 ++++++++++++++++++++++++-----------------------
 include/sysemu/blockdev.h |  4 +++
 4 files changed, 79 insertions(+), 39 deletions(-)

diff --git a/block.c b/block.c
index 92f84d2..5708c7c 100644
--- a/block.c
+++ b/block.c
@@ -29,7 +29,6 @@
 #include "qemu/module.h"
 #include "qapi/qmp/qjson.h"
 #include "sysemu/sysemu.h"
-#include "sysemu/blockdev.h"    /* FIXME layering violation */
 #include "qemu/notify.h"
 #include "block/coroutine.h"
 #include "block/qapi.h"
@@ -2121,8 +2120,6 @@ static void bdrv_delete(BlockDriverState *bs)
 
     bdrv_close(bs);
 
-    drive_info_del(drive_get_by_blockdev(bs));
-
     /* remove from list, if necessary */
     bdrv_make_anon(bs);
 
diff --git a/block/block-backend.c b/block/block-backend.c
index b118b38..7b8c062 100644
--- a/block/block-backend.c
+++ b/block/block-backend.c
@@ -12,11 +12,13 @@
 
 #include "sysemu/block-backend.h"
 #include "block/block_int.h"
+#include "sysemu/blockdev.h"
 
 struct BlockBackend {
     char *name;
     int refcnt;
     BlockDriverState *bs;
+    DriveInfo *legacy_dinfo;
     QTAILQ_ENTRY(BlockBackend) link; /* for blk_backends */
 };
 
@@ -86,6 +88,7 @@ static void blk_delete(BlockBackend *blk)
         QTAILQ_REMOVE(&blk_backends, blk, link);
     }
     g_free(blk->name);
+    drive_info_del(blk->legacy_dinfo);
     g_free(blk);
 }
 
@@ -165,6 +168,41 @@ BlockDriverState *blk_bs(BlockBackend *blk)
 }
 
 /*
+ * Return @blk's DriveInfo if any, else null.
+ */
+DriveInfo *blk_legacy_dinfo(BlockBackend *blk)
+{
+    return blk->legacy_dinfo;
+}
+
+/*
+ * Set @blk's DriveInfo to @dinfo, and return it.
+ * @blk must not have a DriveInfo set already.
+ * No other BlockBackend may have the same DriveInfo set.
+ */
+DriveInfo *blk_set_legacy_dinfo(BlockBackend *blk, DriveInfo *dinfo)
+{
+    assert(!blk->legacy_dinfo);
+    return blk->legacy_dinfo = dinfo;
+}
+
+/*
+ * Return the BlockBackend with DriveInfo @dinfo.
+ * It must exist.
+ */
+BlockBackend *blk_by_legacy_dinfo(DriveInfo *dinfo)
+{
+    BlockBackend *blk;
+
+    QTAILQ_FOREACH(blk, &blk_backends, link) {
+        if (blk->legacy_dinfo == dinfo) {
+            return blk;
+        }
+    }
+    assert(0);
+}
+
+/*
  * Hide @blk.
  * @blk must not have been hidden already.
  * Make attached BlockDriverState, if any, anonymous.
diff --git a/blockdev.c b/blockdev.c
index 21f4c67..aec9f0e 100644
--- a/blockdev.c
+++ b/blockdev.c
@@ -47,8 +47,6 @@
 #include "trace.h"
 #include "sysemu/arch_init.h"
 
-static QTAILQ_HEAD(drivelist, DriveInfo) drives = QTAILQ_HEAD_INITIALIZER(drives);
-
 static const char *const if_name[IF_COUNT] = {
     [IF_NONE] = "none",
     [IF_IDE] = "ide",
@@ -89,7 +87,8 @@ static const int if_max_devs[IF_COUNT] = {
  */
 void blockdev_mark_auto_del(BlockDriverState *bs)
 {
-    DriveInfo *dinfo = drive_get_by_blockdev(bs);
+    BlockBackend *blk = bs->blk;
+    DriveInfo *dinfo = blk_legacy_dinfo(blk);
 
     if (dinfo && !dinfo->enable_auto_del) {
         return;
@@ -105,7 +104,8 @@ void blockdev_mark_auto_del(BlockDriverState *bs)
 
 void blockdev_auto_del(BlockDriverState *bs)
 {
-    DriveInfo *dinfo = drive_get_by_blockdev(bs);
+    BlockBackend *blk = bs->blk;
+    DriveInfo *dinfo = blk_legacy_dinfo(blk);
 
     if (dinfo && dinfo->auto_del) {
         drive_del(dinfo);
@@ -153,15 +153,15 @@ QemuOpts *drive_add(BlockInterfaceType type, int index, const char *file,
 
 DriveInfo *drive_get(BlockInterfaceType type, int bus, int unit)
 {
+    BlockBackend *blk;
     DriveInfo *dinfo;
 
-    /* seek interface, bus and unit */
-
-    QTAILQ_FOREACH(dinfo, &drives, next) {
-        if (dinfo->type == type &&
-	    dinfo->bus == bus &&
-	    dinfo->unit == unit)
+    for (blk = blk_next(NULL); blk; blk = blk_next(blk)) {
+        dinfo = blk_legacy_dinfo(blk);
+        if (dinfo && dinfo->type == type
+            && dinfo->bus == bus && dinfo->unit == unit) {
             return dinfo;
+        }
     }
 
     return NULL;
@@ -177,13 +177,15 @@ DriveInfo *drive_get_by_index(BlockInterfaceType type, int index)
 int drive_get_max_bus(BlockInterfaceType type)
 {
     int max_bus;
+    BlockBackend *blk;
     DriveInfo *dinfo;
 
     max_bus = -1;
-    QTAILQ_FOREACH(dinfo, &drives, next) {
-        if(dinfo->type == type &&
-           dinfo->bus > max_bus)
+    for (blk = blk_next(NULL); blk; blk = blk_next(blk)) {
+        dinfo = blk_legacy_dinfo(blk);
+        if (dinfo && dinfo->type == type && dinfo->bus > max_bus) {
             max_bus = dinfo->bus;
+        }
     }
     return max_bus;
 }
@@ -200,11 +202,11 @@ DriveInfo *drive_get_next(BlockInterfaceType type)
 
 DriveInfo *drive_get_by_blockdev(BlockDriverState *bs)
 {
-    DriveInfo *dinfo;
+    BlockBackend *blk;
 
-    QTAILQ_FOREACH(dinfo, &drives, next) {
-        if (dinfo->bdrv == bs) {
-            return dinfo;
+    for (blk = blk_next(NULL); blk; blk = blk_next(blk)) {
+        if (blk_bs(blk) == bs) {
+            return blk_legacy_dinfo(blk);
         }
     }
     return NULL;
@@ -218,6 +220,7 @@ static void bdrv_format_print(void *opaque, const char *name)
 void drive_del(DriveInfo *dinfo)
 {
     bdrv_unref(dinfo->bdrv);
+    blk_unref(blk_by_legacy_dinfo(dinfo));
 }
 
 void drive_info_del(DriveInfo *dinfo)
@@ -228,10 +231,7 @@ void drive_info_del(DriveInfo *dinfo)
     if (dinfo->opts) {
         qemu_opts_del(dinfo->opts);
     }
-
-    blk_unref(blk_by_name(dinfo->bdrv->device_name));
     g_free(dinfo->id);
-    QTAILQ_REMOVE(&drives, dinfo, next);
     g_free(dinfo->serial);
     g_free(dinfo);
 }
@@ -303,8 +303,8 @@ static bool check_throttle_config(ThrottleConfig *cfg, Error **errp)
 typedef enum { MEDIA_DISK, MEDIA_CDROM } DriveMediaType;
 
 /* Takes the ownership of bs_opts */
-static DriveInfo *blockdev_init(const char *file, QDict *bs_opts,
-                                Error **errp)
+static BlockBackend *blockdev_init(const char *file, QDict *bs_opts,
+                                   Error **errp)
 {
     const char *buf;
     int ro = 0;
@@ -487,7 +487,7 @@ static DriveInfo *blockdev_init(const char *file, QDict *bs_opts,
     dinfo = g_malloc0(sizeof(*dinfo));
     dinfo->id = g_strdup(qemu_opts_id(opts));
     dinfo->bdrv = bs;
-    QTAILQ_INSERT_TAIL(&drives, dinfo, next);
+    blk_set_legacy_dinfo(blk, dinfo);
 
     if (!file || !*file) {
         if (has_driver_specific_opts) {
@@ -495,7 +495,7 @@ static DriveInfo *blockdev_init(const char *file, QDict *bs_opts,
         } else {
             QDECREF(bs_opts);
             qemu_opts_del(opts);
-            return dinfo;
+            return blk;
         }
     }
     if (snapshot) {
@@ -532,7 +532,7 @@ static DriveInfo *blockdev_init(const char *file, QDict *bs_opts,
     QDECREF(bs_opts);
     qemu_opts_del(opts);
 
-    return dinfo;
+    return blk;
 
 err:
     bdrv_unref(bs);
@@ -639,6 +639,7 @@ QemuOptsList qemu_legacy_drive_opts = {
 DriveInfo *drive_new(QemuOpts *all_opts, BlockInterfaceType block_default_type)
 {
     const char *value;
+    BlockBackend *blk;
     DriveInfo *dinfo = NULL;
     QDict *bs_opts;
     QemuOpts *legacy_opts;
@@ -921,19 +922,18 @@ DriveInfo *drive_new(QemuOpts *all_opts, BlockInterfaceType block_default_type)
     }
 
     /* Actual block device init: Functionality shared with blockdev-add */
-    dinfo = blockdev_init(filename, bs_opts, &local_err);
+    blk = blockdev_init(filename, bs_opts, &local_err);
     bs_opts = NULL;
-    if (dinfo == NULL) {
-        if (local_err) {
-            error_report("%s", error_get_pretty(local_err));
-            error_free(local_err);
-        }
+    if (!blk) {
+        error_report("%s", error_get_pretty(local_err));
+        error_free(local_err);
         goto fail;
     } else {
         assert(!local_err);
     }
 
     /* Set legacy DriveInfo fields */
+    dinfo = blk_legacy_dinfo(blk);
     dinfo->enable_auto_del = true;
     dinfo->opts = all_opts;
 
@@ -1763,7 +1763,7 @@ int do_drive_del(Monitor *mon, const QDict *qdict, QObject **ret_data)
     }
     bs = blk_bs(blk);
 
-    dinfo = drive_get_by_blockdev(bs);
+    dinfo = blk_legacy_dinfo(blk);
     if (dinfo && !dinfo->enable_auto_del) {
         error_report("Deleting device added with blockdev-add"
                      " is not supported");
@@ -2488,7 +2488,7 @@ void qmp_change_backing_file(const char *device,
 void qmp_blockdev_add(BlockdevOptions *options, Error **errp)
 {
     QmpOutputVisitor *ov = qmp_output_visitor_new();
-    DriveInfo *dinfo;
+    BlockBackend *blk;
     QObject *obj;
     QDict *qdict;
     Error *local_err = NULL;
@@ -2526,14 +2526,15 @@ void qmp_blockdev_add(BlockdevOptions *options, Error **errp)
 
     qdict_flatten(qdict);
 
-    dinfo = blockdev_init(NULL, qdict, &local_err);
+    blk = blockdev_init(NULL, qdict, &local_err);
     if (local_err) {
         error_propagate(errp, local_err);
         goto fail;
     }
 
-    if (bdrv_key_required(dinfo->bdrv)) {
-        drive_del(dinfo);
+    if (bdrv_key_required(blk_bs(blk))) {
+        bdrv_unref(blk_bs(blk));
+        blk_unref(blk);
         error_setg(errp, "blockdev-add doesn't support encrypted devices");
         goto fail;
     }
diff --git a/include/sysemu/blockdev.h b/include/sysemu/blockdev.h
index abec381..1dc5906 100644
--- a/include/sysemu/blockdev.h
+++ b/include/sysemu/blockdev.h
@@ -45,6 +45,10 @@ struct DriveInfo {
     QTAILQ_ENTRY(DriveInfo) next;
 };
 
+DriveInfo *blk_legacy_dinfo(BlockBackend *blk);
+DriveInfo *blk_set_legacy_dinfo(BlockBackend *blk, DriveInfo *dinfo);
+BlockBackend *blk_by_legacy_dinfo(DriveInfo *dinfo);
+
 DriveInfo *drive_get(BlockInterfaceType type, int bus, int unit);
 DriveInfo *drive_get_by_index(BlockInterfaceType type, int index);
 int drive_get_max_bus(BlockInterfaceType type);
-- 
1.9.3

^ permalink raw reply related	[flat|nested] 56+ messages in thread

* [Qemu-devel] [PATCH v2 05/23] block: Code motion to get rid of stubs/blockdev.c
  2014-09-13 15:00 [Qemu-devel] [PATCH v2 00/23] Split BlockBackend off BDS with an axe Markus Armbruster
                   ` (3 preceding siblings ...)
  2014-09-13 15:00 ` [Qemu-devel] [PATCH v2 04/23] block: Connect BlockBackend and DriveInfo Markus Armbruster
@ 2014-09-13 15:00 ` Markus Armbruster
  2014-09-15  6:28   ` Fam Zheng
  2014-09-16 12:40   ` Benoît Canet
  2014-09-13 15:00 ` [Qemu-devel] [PATCH v2 06/23] block: Make BlockBackend own its BlockDriverState Markus Armbruster
                   ` (18 subsequent siblings)
  23 siblings, 2 replies; 56+ messages in thread
From: Markus Armbruster @ 2014-09-13 15:00 UTC (permalink / raw)
  To: qemu-devel; +Cc: kwolf, benoit.canet, stefanha

Signed-off-by: Markus Armbruster <armbru@redhat.com>
---
 block/block-backend.c     | 15 +++++++++++++++
 blockdev.c                | 13 -------------
 include/sysemu/blockdev.h |  1 -
 stubs/Makefile.objs       |  1 -
 stubs/blockdev.c          | 12 ------------
 5 files changed, 15 insertions(+), 27 deletions(-)
 delete mode 100644 stubs/blockdev.c

diff --git a/block/block-backend.c b/block/block-backend.c
index 7b8c062..0842abe 100644
--- a/block/block-backend.c
+++ b/block/block-backend.c
@@ -22,6 +22,8 @@ struct BlockBackend {
     QTAILQ_ENTRY(BlockBackend) link; /* for blk_backends */
 };
 
+static void drive_info_del(DriveInfo *dinfo);
+
 /* All the BlockBackends (except for hidden ones) */
 static QTAILQ_HEAD(, BlockBackend) blk_backends =
     QTAILQ_HEAD_INITIALIZER(blk_backends);
@@ -92,6 +94,19 @@ static void blk_delete(BlockBackend *blk)
     g_free(blk);
 }
 
+static void drive_info_del(DriveInfo *dinfo)
+{
+    if (!dinfo) {
+        return;
+    }
+    if (dinfo->opts) {
+        qemu_opts_del(dinfo->opts);
+    }
+    g_free(dinfo->id);
+    g_free(dinfo->serial);
+    g_free(dinfo);
+}
+
 /*
  * Increment @blk's reference count.
  * @blk must not be null.
diff --git a/blockdev.c b/blockdev.c
index aec9f0e..0ed108d 100644
--- a/blockdev.c
+++ b/blockdev.c
@@ -223,19 +223,6 @@ void drive_del(DriveInfo *dinfo)
     blk_unref(blk_by_legacy_dinfo(dinfo));
 }
 
-void drive_info_del(DriveInfo *dinfo)
-{
-    if (!dinfo) {
-        return;
-    }
-    if (dinfo->opts) {
-        qemu_opts_del(dinfo->opts);
-    }
-    g_free(dinfo->id);
-    g_free(dinfo->serial);
-    g_free(dinfo);
-}
-
 typedef struct {
     QEMUBH *bh;
     BlockDriverState *bs;
diff --git a/include/sysemu/blockdev.h b/include/sysemu/blockdev.h
index 1dc5906..2ed297b 100644
--- a/include/sysemu/blockdev.h
+++ b/include/sysemu/blockdev.h
@@ -60,7 +60,6 @@ QemuOpts *drive_add(BlockInterfaceType type, int index, const char *file,
                     const char *optstr);
 DriveInfo *drive_new(QemuOpts *arg, BlockInterfaceType block_default_type);
 void drive_del(DriveInfo *dinfo);
-void drive_info_del(DriveInfo *dinfo);
 
 /* device-hotplug */
 
diff --git a/stubs/Makefile.objs b/stubs/Makefile.objs
index c0b1f6a..5e347d0 100644
--- a/stubs/Makefile.objs
+++ b/stubs/Makefile.objs
@@ -1,6 +1,5 @@
 stub-obj-y += arch-query-cpu-def.o
 stub-obj-y += bdrv-commit-all.o
-stub-obj-y += blockdev.o
 stub-obj-y += chr-baum-init.o
 stub-obj-y += chr-msmouse.o
 stub-obj-y += chr-testdev.o
diff --git a/stubs/blockdev.c b/stubs/blockdev.c
deleted file mode 100644
index 5d0a79c..0000000
--- a/stubs/blockdev.c
+++ /dev/null
@@ -1,12 +0,0 @@
-#include <assert.h>
-#include "sysemu/blockdev.h"
-
-DriveInfo *drive_get_by_blockdev(BlockDriverState *bs)
-{
-    return NULL;
-}
-
-void drive_info_del(DriveInfo *dinfo)
-{
-    assert(!dinfo);
-}
-- 
1.9.3

^ permalink raw reply related	[flat|nested] 56+ messages in thread

* [Qemu-devel] [PATCH v2 06/23] block: Make BlockBackend own its BlockDriverState
  2014-09-13 15:00 [Qemu-devel] [PATCH v2 00/23] Split BlockBackend off BDS with an axe Markus Armbruster
                   ` (4 preceding siblings ...)
  2014-09-13 15:00 ` [Qemu-devel] [PATCH v2 05/23] block: Code motion to get rid of stubs/blockdev.c Markus Armbruster
@ 2014-09-13 15:00 ` Markus Armbruster
  2014-09-16 12:56   ` Benoît Canet
  2014-09-13 15:00 ` [Qemu-devel] [PATCH v2 07/23] block: Eliminate bdrv_iterate(), use bdrv_next() Markus Armbruster
                   ` (17 subsequent siblings)
  23 siblings, 1 reply; 56+ messages in thread
From: Markus Armbruster @ 2014-09-13 15:00 UTC (permalink / raw)
  To: qemu-devel; +Cc: kwolf, benoit.canet, stefanha

On BlockBackend destruction, unref its BlockDriverState.  Replaces the
callers' unrefs.

Signed-off-by: Markus Armbruster <armbru@redhat.com>
---
 block/block-backend.c |  6 ++----
 blockdev.c            |  7 ++-----
 hw/block/xen_disk.c   |  6 +++---
 qemu-img.c            | 35 +----------------------------------
 qemu-io.c             |  5 -----
 qemu-nbd.c            |  1 -
 6 files changed, 8 insertions(+), 52 deletions(-)

diff --git a/block/block-backend.c b/block/block-backend.c
index 0842abe..dfe2654 100644
--- a/block/block-backend.c
+++ b/block/block-backend.c
@@ -54,8 +54,6 @@ BlockBackend *blk_new(const char *name, Error **errp)
 
 /*
  * Create a new BlockBackend with a new BlockDriverState attached.
- * Both have a reference count of one.  Caller owns *both* references.
- * TODO Let caller own only the BlockBackend reference
  * Otherwise just like blk_new(), which see.
  */
 BlockBackend *blk_new_with_bs(const char *name, Error **errp)
@@ -83,7 +81,9 @@ static void blk_delete(BlockBackend *blk)
 {
     assert(!blk->refcnt);
     if (blk->bs) {
+        assert(blk->bs->blk == blk);
         blk->bs->blk = NULL;
+        bdrv_unref(blk->bs);
         blk->bs = NULL;
     }
     if (blk->name[0]) {
@@ -120,8 +120,6 @@ void blk_ref(BlockBackend *blk)
  * Decrement @blk's reference count.
  * If this drops it to zero, destroy @blk.
  * For convenience, do nothing if @blk is null.
- * Does *not* touch the attached BlockDriverState's reference count.
- * TODO Decrement it!
  */
 void blk_unref(BlockBackend *blk)
 {
diff --git a/blockdev.c b/blockdev.c
index 0ed108d..3a6fd46 100644
--- a/blockdev.c
+++ b/blockdev.c
@@ -108,7 +108,7 @@ void blockdev_auto_del(BlockDriverState *bs)
     DriveInfo *dinfo = blk_legacy_dinfo(blk);
 
     if (dinfo && dinfo->auto_del) {
-        drive_del(dinfo);
+        blk_unref(blk);
     }
 }
 
@@ -219,7 +219,6 @@ static void bdrv_format_print(void *opaque, const char *name)
 
 void drive_del(DriveInfo *dinfo)
 {
-    bdrv_unref(dinfo->bdrv);
     blk_unref(blk_by_legacy_dinfo(dinfo));
 }
 
@@ -522,7 +521,6 @@ static BlockBackend *blockdev_init(const char *file, QDict *bs_opts,
     return blk;
 
 err:
-    bdrv_unref(bs);
     blk_unref(blk);
 early_err:
     qemu_opts_del(opts);
@@ -1783,7 +1781,7 @@ int do_drive_del(Monitor *mon, const QDict *qdict, QObject **ret_data)
         bdrv_set_on_error(bs, BLOCKDEV_ON_ERROR_REPORT,
                           BLOCKDEV_ON_ERROR_REPORT);
     } else {
-        drive_del(dinfo);
+        blk_unref(blk);
     }
 
     aio_context_release(aio_context);
@@ -2520,7 +2518,6 @@ void qmp_blockdev_add(BlockdevOptions *options, Error **errp)
     }
 
     if (bdrv_key_required(blk_bs(blk))) {
-        bdrv_unref(blk_bs(blk));
         blk_unref(blk);
         error_setg(errp, "blockdev-add doesn't support encrypted devices");
         goto fail;
diff --git a/hw/block/xen_disk.c b/hw/block/xen_disk.c
index 51f4f3a..6d474b9 100644
--- a/hw/block/xen_disk.c
+++ b/hw/block/xen_disk.c
@@ -870,7 +870,6 @@ static int blk_connect(struct XenDevice *xendev)
             xen_be_printf(&blkdev->xendev, 0, "error: %s\n",
                           error_get_pretty(local_err));
             error_free(local_err);
-            bdrv_unref(blkdev->bs);
             blk_unref(blk);
             blkdev->bs = NULL;
             return -1;
@@ -886,7 +885,9 @@ static int blk_connect(struct XenDevice *xendev)
         }
         /* blkdev->bs is not create by us, we get a reference
          * so we can bdrv_unref() unconditionally */
-        bdrv_ref(blkdev->bs);
+        /* Except we don't bdrv_unref() anymore, we blk_unref().
+         * Conditionally, because we can't easily blk_ref() here.
+         * TODO Clean this up! */
     }
     bdrv_attach_dev_nofail(blkdev->bs, blkdev);
     blkdev->file_size = bdrv_getlength(blkdev->bs);
@@ -986,7 +987,6 @@ static void blk_disconnect(struct XenDevice *xendev)
 
     if (blkdev->bs) {
         bdrv_detach_dev(blkdev->bs, blkdev);
-        bdrv_unref(blkdev->bs);
         if (!blkdev->dinfo) {
             blk_unref(blk_by_name(blkdev->dev));
         }
diff --git a/qemu-img.c b/qemu-img.c
index 206a513..40bd129 100644
--- a/qemu-img.c
+++ b/qemu-img.c
@@ -329,7 +329,6 @@ static BlockBackend *img_open(const char *id, const char *filename,
     }
     return blk;
 fail:
-    bdrv_unref(bs);
     blk_unref(blk);
     return NULL;
 }
@@ -712,9 +711,7 @@ static int img_check(int argc, char **argv)
 
 fail:
     qapi_free_ImageCheck(check);
-    bdrv_unref(bs);
     blk_unref(blk);
-
     return ret;
 }
 
@@ -786,7 +783,6 @@ static int img_commit(int argc, char **argv)
         break;
     }
 
-    bdrv_unref(bs);
     blk_unref(blk);
     if (ret) {
         return 1;
@@ -1196,10 +1192,8 @@ static int img_compare(int argc, char **argv)
 out:
     qemu_vfree(buf1);
     qemu_vfree(buf2);
-    bdrv_unref(bs2);
     blk_unref(blk2);
 out2:
-    bdrv_unref(bs1);
     blk_unref(blk1);
 out3:
     qemu_progress_end();
@@ -1756,18 +1750,8 @@ out:
     if (sn_opts) {
         qemu_opts_del(sn_opts);
     }
-    if (out_bs) {
-        bdrv_unref(out_bs);
-    }
     blk_unref(out_blk);
-    if (bs) {
-        for (bs_i = 0; bs_i < bs_n; bs_i++) {
-            if (bs[bs_i]) {
-                bdrv_unref(bs[bs_i]);
-            }
-        }
-        g_free(bs);
-    }
+    g_free(bs);
     if (blk) {
         for (bs_i = 0; bs_i < bs_n; bs_i++) {
             blk_unref(blk[bs_i]);
@@ -1905,7 +1889,6 @@ static ImageInfoList *collect_image_info_list(const char *filename,
         if (err) {
             error_report("%s", error_get_pretty(err));
             error_free(err);
-            bdrv_unref(bs);
             blk_unref(blk);
             goto err;
         }
@@ -1915,7 +1898,6 @@ static ImageInfoList *collect_image_info_list(const char *filename,
         *last = elem;
         last = &elem->next;
 
-        bdrv_unref(bs);
         blk_unref(blk);
 
         filename = fmt = NULL;
@@ -2204,7 +2186,6 @@ static int img_map(int argc, char **argv)
     dump_map_entry(output_format, &curr, NULL);
 
 out:
-    bdrv_unref(bs);
     blk_unref(blk);
     return ret < 0;
 }
@@ -2329,7 +2310,6 @@ static int img_snapshot(int argc, char **argv)
     }
 
     /* Cleanup */
-    bdrv_unref(bs);
     blk_unref(blk);
     if (ret) {
         return 1;
@@ -2649,17 +2629,10 @@ out:
     qemu_progress_end();
     /* Cleanup */
     if (!unsafe) {
-        if (bs_old_backing != NULL) {
-            bdrv_unref(bs_old_backing);
-        }
         blk_unref(blk_old_backing);
-        if (bs_new_backing != NULL) {
-            bdrv_unref(bs_new_backing);
-        }
         blk_unref(blk_new_backing);
     }
 
-    bdrv_unref(bs);
     blk_unref(blk);
     if (ret) {
         return 1;
@@ -2785,9 +2758,6 @@ static int img_resize(int argc, char **argv)
         break;
     }
 out:
-    if (bs) {
-        bdrv_unref(bs);
-    }
     blk_unref(blk);
     if (ret) {
         return 1;
@@ -2899,9 +2869,6 @@ static int img_amend(int argc, char **argv)
     }
 
 out:
-    if (bs) {
-        bdrv_unref(bs);
-    }
     blk_unref(blk);
     qemu_opts_del(opts);
     qemu_opts_free(create_opts);
diff --git a/qemu-io.c b/qemu-io.c
index ef1d3ea..45e8167 100644
--- a/qemu-io.c
+++ b/qemu-io.c
@@ -38,7 +38,6 @@ static ReadLineState *readline_state;
 
 static int close_f(BlockDriverState *bs, int argc, char **argv)
 {
-    bdrv_unref(bs);
     blk_unref(qemuio_blk);
     qemuio_bs = NULL;
     qemuio_blk = NULL;
@@ -74,7 +73,6 @@ static int openfile(char *name, int flags, int growable, QDict *opts)
                 name ? " device " : "", name ?: "",
                 error_get_pretty(local_err));
         error_free(local_err);
-        bdrv_unref(qemuio_bs);
         blk_unref(qemuio_blk);
         qemuio_bs = NULL;
         qemuio_blk = NULL;
@@ -483,9 +481,6 @@ int main(int argc, char **argv)
      */
     bdrv_drain_all();
 
-    if (qemuio_bs) {
-        bdrv_unref(qemuio_bs);
-    }
     blk_unref(qemuio_blk);
     g_free(readline_state);
     return 0;
diff --git a/qemu-nbd.c b/qemu-nbd.c
index fa8a7d0..0c496af 100644
--- a/qemu-nbd.c
+++ b/qemu-nbd.c
@@ -771,7 +771,6 @@ int main(int argc, char **argv)
         }
     } while (state != TERMINATED);
 
-    bdrv_unref(bs);
     blk_unref(blk);
     if (sockpath) {
         unlink(sockpath);
-- 
1.9.3

^ permalink raw reply related	[flat|nested] 56+ messages in thread

* [Qemu-devel] [PATCH v2 07/23] block: Eliminate bdrv_iterate(), use bdrv_next()
  2014-09-13 15:00 [Qemu-devel] [PATCH v2 00/23] Split BlockBackend off BDS with an axe Markus Armbruster
                   ` (5 preceding siblings ...)
  2014-09-13 15:00 ` [Qemu-devel] [PATCH v2 06/23] block: Make BlockBackend own its BlockDriverState Markus Armbruster
@ 2014-09-13 15:00 ` Markus Armbruster
  2014-09-16 13:04   ` Benoît Canet
  2014-09-13 15:00 ` [Qemu-devel] [PATCH v2 08/23] block: Eliminate BlockDriverState member device_name[] Markus Armbruster
                   ` (16 subsequent siblings)
  23 siblings, 1 reply; 56+ messages in thread
From: Markus Armbruster @ 2014-09-13 15:00 UTC (permalink / raw)
  To: qemu-devel; +Cc: kwolf, benoit.canet, stefanha

Signed-off-by: Markus Armbruster <armbru@redhat.com>
---
 block-migration.c     | 30 +++++++++++++++---------------
 block.c               |  9 ---------
 blockdev.c            | 31 +++++++++++++------------------
 include/block/block.h |  2 --
 monitor.c             | 32 +++++++++-----------------------
 5 files changed, 37 insertions(+), 67 deletions(-)

diff --git a/block-migration.c b/block-migration.c
index 3ad31a2..cb3e16c 100644
--- a/block-migration.c
+++ b/block-migration.c
@@ -343,12 +343,25 @@ static void unset_dirty_tracking(void)
     }
 }
 
-static void init_blk_migration_it(void *opaque, BlockDriverState *bs)
+static void init_blk_migration(QEMUFile *f)
 {
+    BlockDriverState *bs;
     BlkMigDevState *bmds;
     int64_t sectors;
 
-    if (!bdrv_is_read_only(bs)) {
+    block_mig_state.submitted = 0;
+    block_mig_state.read_done = 0;
+    block_mig_state.transferred = 0;
+    block_mig_state.total_sector_sum = 0;
+    block_mig_state.prev_progress = -1;
+    block_mig_state.bulk_completed = 0;
+    block_mig_state.zero_blocks = migrate_zero_blocks();
+
+    for (bs = bdrv_next(NULL); bs; bs = bdrv_next(bs)) {
+        if (bdrv_is_read_only(bs)) {
+            continue;
+        }
+
         sectors = bdrv_nb_sectors(bs);
         if (sectors <= 0) {
             return;
@@ -378,19 +391,6 @@ static void init_blk_migration_it(void *opaque, BlockDriverState *bs)
     }
 }
 
-static void init_blk_migration(QEMUFile *f)
-{
-    block_mig_state.submitted = 0;
-    block_mig_state.read_done = 0;
-    block_mig_state.transferred = 0;
-    block_mig_state.total_sector_sum = 0;
-    block_mig_state.prev_progress = -1;
-    block_mig_state.bulk_completed = 0;
-    block_mig_state.zero_blocks = migrate_zero_blocks();
-
-    bdrv_iterate(init_blk_migration_it, NULL);
-}
-
 /* Called with no lock taken.  */
 
 static int blk_mig_save_bulked_block(QEMUFile *f)
diff --git a/block.c b/block.c
index 5708c7c..2fd689a 100644
--- a/block.c
+++ b/block.c
@@ -3893,15 +3893,6 @@ BlockDriverState *bdrv_next(BlockDriverState *bs)
     return QTAILQ_NEXT(bs, device_list);
 }
 
-void bdrv_iterate(void (*it)(void *opaque, BlockDriverState *bs), void *opaque)
-{
-    BlockDriverState *bs;
-
-    QTAILQ_FOREACH(bs, &bdrv_states, device_list) {
-        it(opaque, bs);
-    }
-}
-
 const char *bdrv_get_device_name(BlockDriverState *bs)
 {
     return bs->device_name;
diff --git a/blockdev.c b/blockdev.c
index 3a6fd46..85f574b 100644
--- a/blockdev.c
+++ b/blockdev.c
@@ -2527,26 +2527,21 @@ fail:
     qmp_output_visitor_cleanup(ov);
 }
 
-static void do_qmp_query_block_jobs_one(void *opaque, BlockDriverState *bs)
-{
-    BlockJobInfoList **prev = opaque;
-    BlockJob *job = bs->job;
-
-    if (job) {
-        BlockJobInfoList *elem = g_new0(BlockJobInfoList, 1);
-        elem->value = block_job_query(bs->job);
-        (*prev)->next = elem;
-        *prev = elem;
-    }
-}
-
 BlockJobInfoList *qmp_query_block_jobs(Error **errp)
 {
-    /* Dummy is a fake list element for holding the head pointer */
-    BlockJobInfoList dummy = {};
-    BlockJobInfoList *prev = &dummy;
-    bdrv_iterate(do_qmp_query_block_jobs_one, &prev);
-    return dummy.next;
+    BlockJobInfoList *head = NULL, **p_next = &head;
+    BlockDriverState *bs;
+
+    for (bs = bdrv_next(NULL); bs; bs = bdrv_next(bs)) {
+        if (bs->job) {
+            BlockJobInfoList *elem = g_new0(BlockJobInfoList, 1);
+            elem->value = block_job_query(bs->job);
+            *p_next = elem;
+            p_next = &elem->next;
+        }
+    }
+
+    return head;
 }
 
 QemuOptsList qemu_common_drive_opts = {
diff --git a/include/block/block.h b/include/block/block.h
index 6cabc98..c092eab 100644
--- a/include/block/block.h
+++ b/include/block/block.h
@@ -409,8 +409,6 @@ BlockDriverState *bdrv_lookup_bs(const char *device,
                                  Error **errp);
 bool bdrv_chain_contains(BlockDriverState *top, BlockDriverState *base);
 BlockDriverState *bdrv_next(BlockDriverState *bs);
-void bdrv_iterate(void (*it)(void *opaque, BlockDriverState *bs),
-                  void *opaque);
 int bdrv_is_encrypted(BlockDriverState *bs);
 int bdrv_key_required(BlockDriverState *bs);
 int bdrv_set_key(BlockDriverState *bs, const char *key);
diff --git a/monitor.c b/monitor.c
index 34cee74..565d60e 100644
--- a/monitor.c
+++ b/monitor.c
@@ -4208,24 +4208,6 @@ static void file_completion(Monitor *mon, const char *input)
     closedir(ffs);
 }
 
-typedef struct MonitorBlockComplete {
-    Monitor *mon;
-    const char *input;
-} MonitorBlockComplete;
-
-static void block_completion_it(void *opaque, BlockDriverState *bs)
-{
-    const char *name = bdrv_get_device_name(bs);
-    MonitorBlockComplete *mbc = opaque;
-    Monitor *mon = mbc->mon;
-    const char *input = mbc->input;
-
-    if (input[0] == '\0' ||
-        !strncmp(name, (char *)input, strlen(input))) {
-        readline_add_completion(mon->rs, name);
-    }
-}
-
 static const char *next_arg_type(const char *typestr)
 {
     const char *p = strchr(typestr, ':');
@@ -4663,9 +4645,9 @@ static void monitor_find_completion_by_table(Monitor *mon,
 {
     const char *cmdname;
     int i;
-    const char *ptype, *str;
+    const char *ptype, *str, *name;
     const mon_cmd_t *cmd;
-    MonitorBlockComplete mbs;
+    BlockDriverState *bs;
 
     if (nb_args <= 1) {
         /* command completion */
@@ -4717,10 +4699,14 @@ static void monitor_find_completion_by_table(Monitor *mon,
             break;
         case 'B':
             /* block device name completion */
-            mbs.mon = mon;
-            mbs.input = str;
             readline_set_completion_index(mon->rs, strlen(str));
-            bdrv_iterate(block_completion_it, &mbs);
+            for (bs = bdrv_next(NULL); bs; bs = bdrv_next(bs)) {
+                name = bdrv_get_device_name(bs);
+                if (str[0] == '\0' ||
+                    !strncmp(name, str, strlen(str))) {
+                    readline_add_completion(mon->rs, name);
+                }
+            }
             break;
         case 's':
         case 'S':
-- 
1.9.3

^ permalink raw reply related	[flat|nested] 56+ messages in thread

* [Qemu-devel] [PATCH v2 08/23] block: Eliminate BlockDriverState member device_name[]
  2014-09-13 15:00 [Qemu-devel] [PATCH v2 00/23] Split BlockBackend off BDS with an axe Markus Armbruster
                   ` (6 preceding siblings ...)
  2014-09-13 15:00 ` [Qemu-devel] [PATCH v2 07/23] block: Eliminate bdrv_iterate(), use bdrv_next() Markus Armbruster
@ 2014-09-13 15:00 ` Markus Armbruster
  2014-09-16 13:18   ` Benoît Canet
  2014-09-13 15:00 ` [Qemu-devel] [PATCH v2 09/23] block: Merge BlockBackend and BlockDriverState name spaces Markus Armbruster
                   ` (15 subsequent siblings)
  23 siblings, 1 reply; 56+ messages in thread
From: Markus Armbruster @ 2014-09-13 15:00 UTC (permalink / raw)
  To: qemu-devel; +Cc: kwolf, benoit.canet, stefanha

device_name[] can become non-empty only in bdrv_new_root() and
bdrv_move_feature_fields().  The latter is used only to undo damage
done by bdrv_swap().  The former is called only by blk_new_with_bs().
Therefore, when a BlockDriverState's device_name[] is non-empty, then
it's been created with a BlockBackend, and vice versa.  Furthermore,
blk_new_with_bs() keeps the two names equal.

Therefore, device_name[] is redundant.  Eliminate it.

Signed-off-by: Markus Armbruster <armbru@redhat.com>
---
 block-migration.c         | 12 +++++----
 block.c                   | 63 +++++++++++++++++------------------------------
 block/block-backend.c     | 14 ++++++-----
 block/cow.c               |  2 +-
 block/mirror.c            |  3 ++-
 block/qapi.c              |  6 ++---
 block/qcow.c              |  4 +--
 block/qcow2.c             |  4 +--
 block/qed.c               |  2 +-
 block/quorum.c            |  4 +--
 block/vdi.c               |  2 +-
 block/vhdx.c              |  2 +-
 block/vmdk.c              |  4 +--
 block/vpc.c               |  2 +-
 block/vvfat.c             |  2 +-
 blockjob.c                |  3 ++-
 include/block/block.h     |  4 +--
 include/block/block_int.h |  2 --
 18 files changed, 60 insertions(+), 75 deletions(-)

diff --git a/block-migration.c b/block-migration.c
index cb3e16c..da30e93 100644
--- a/block-migration.c
+++ b/block-migration.c
@@ -14,7 +14,9 @@
  */
 
 #include "qemu-common.h"
-#include "block/block_int.h"
+#include "block/block.h"
+#include "qemu/error-report.h"
+#include "qemu/main-loop.h"
 #include "hw/hw.h"
 #include "qemu/queue.h"
 #include "qemu/timer.h"
@@ -130,9 +132,9 @@ static void blk_send(QEMUFile *f, BlkMigBlock * blk)
                      | flags);
 
     /* device name */
-    len = strlen(blk->bmds->bs->device_name);
+    len = strlen(bdrv_get_device_name(blk->bmds->bs));
     qemu_put_byte(f, len);
-    qemu_put_buffer(f, (uint8_t *)blk->bmds->bs->device_name, len);
+    qemu_put_buffer(f, (uint8_t *)bdrv_get_device_name(blk->bmds->bs), len);
 
     /* if a block is zero we need to flush here since the network
      * bandwidth is now a lot higher than the storage device bandwidth.
@@ -382,9 +384,9 @@ static void init_blk_migration(QEMUFile *f)
 
         if (bmds->shared_base) {
             DPRINTF("Start migration for %s with shared base image\n",
-                    bs->device_name);
+                    bdrv_get_device_name(bs));
         } else {
-            DPRINTF("Start full migration for %s\n", bs->device_name);
+            DPRINTF("Start full migration for %s\n", bdrv_get_device_name(bs));
         }
 
         QSIMPLEQ_INSERT_TAIL(&block_mig_state.bmds_list, bmds, entry);
diff --git a/block.c b/block.c
index 2fd689a..b39e368 100644
--- a/block.c
+++ b/block.c
@@ -28,6 +28,7 @@
 #include "block/blockjob.h"
 #include "qemu/module.h"
 #include "qapi/qmp/qjson.h"
+#include "sysemu/block-backend.h"
 #include "sysemu/sysemu.h"
 #include "qemu/notify.h"
 #include "block/coroutine.h"
@@ -334,30 +335,11 @@ void bdrv_register(BlockDriver *bdrv)
     QLIST_INSERT_HEAD(&bdrv_drivers, bdrv, list);
 }
 
-/* create a new block device (by default it is empty) */
-BlockDriverState *bdrv_new_root(const char *device_name, Error **errp)
+BlockDriverState *bdrv_new_root(void)
 {
-    BlockDriverState *bs;
+    BlockDriverState *bs = bdrv_new();
 
-    assert(*device_name);
-
-    if (bdrv_find(device_name)) {
-        error_setg(errp, "Device with id '%s' already exists",
-                   device_name);
-        return NULL;
-    }
-    if (bdrv_find_node(device_name)) {
-        error_setg(errp,
-                   "Device name '%s' conflicts with an existing node name",
-                   device_name);
-        return NULL;
-    }
-
-    bs = bdrv_new();
-
-    pstrcpy(bs->device_name, sizeof(bs->device_name), device_name);
     QTAILQ_INSERT_TAIL(&bdrv_states, bs, device_list);
-
     return bs;
 }
 
@@ -1163,7 +1145,7 @@ void bdrv_set_backing_hd(BlockDriverState *bs, BlockDriverState *backing_hd)
     } else if (backing_hd) {
         error_setg(&bs->backing_blocker,
                    "device is used as backing hd of '%s'",
-                   bs->device_name);
+                   bdrv_get_device_name(bs));
     }
 
     bs->backing_hd = backing_hd;
@@ -1537,7 +1519,7 @@ int bdrv_open(BlockDriverState **pbs, const char *filename,
         } else {
             error_setg(errp, "Block format '%s' used by device '%s' doesn't "
                        "support the option '%s'", drv->format_name,
-                       bs->device_name, entry->key);
+                       bdrv_get_device_name(bs), entry->key);
         }
 
         ret = -EINVAL;
@@ -1744,7 +1726,7 @@ int bdrv_reopen_prepare(BDRVReopenState *reopen_state, BlockReopenQueue *queue,
     if (!(reopen_state->bs->open_flags & BDRV_O_ALLOW_RDWR) &&
         reopen_state->flags & BDRV_O_RDWR) {
         error_set(errp, QERR_DEVICE_IS_READ_ONLY,
-                  reopen_state->bs->device_name);
+                  bdrv_get_device_name(reopen_state->bs));
         goto error;
     }
 
@@ -1771,7 +1753,7 @@ int bdrv_reopen_prepare(BDRVReopenState *reopen_state, BlockReopenQueue *queue,
         /* It is currently mandatory to have a bdrv_reopen_prepare()
          * handler for each supported drv. */
         error_set(errp, QERR_BLOCK_FORMAT_FEATURE_NOT_SUPPORTED,
-                  drv->format_name, reopen_state->bs->device_name,
+                  drv->format_name, bdrv_get_device_name(reopen_state->bs),
                  "reopening of file");
         ret = -1;
         goto error;
@@ -1959,10 +1941,10 @@ void bdrv_drain_all(void)
    Also, NULL terminate the device_name to prevent double remove */
 void bdrv_make_anon(BlockDriverState *bs)
 {
-    if (bs->device_name[0] != '\0') {
+    if (bs->device_list.tqe_prev) {
         QTAILQ_REMOVE(&bdrv_states, bs, device_list);
+        bs->device_list.tqe_prev = NULL;
     }
-    bs->device_name[0] = '\0';
     if (bs->node_name[0] != '\0') {
         QTAILQ_REMOVE(&graph_bdrv_states, bs, node_list);
     }
@@ -2016,8 +1998,6 @@ static void bdrv_move_feature_fields(BlockDriverState *bs_dest,
     bs_dest->job                = bs_src->job;
 
     /* keep the same entry in bdrv_states */
-    pstrcpy(bs_dest->device_name, sizeof(bs_dest->device_name),
-            bs_src->device_name);
     bs_dest->device_list = bs_src->device_list;
     memcpy(bs_dest->op_blockers, bs_src->op_blockers,
            sizeof(bs_dest->op_blockers));
@@ -2031,7 +2011,7 @@ static void bdrv_move_feature_fields(BlockDriverState *bs_dest,
  * This will modify the BlockDriverState fields, and swap contents
  * between bs_new and bs_old. Both bs_new and bs_old are modified.
  *
- * bs_new must be nameless and not attached to a BlockBackend.
+ * bs_new must not be attached to a BlockBackend.
  *
  * This function does not create any image files.
  */
@@ -2050,8 +2030,7 @@ void bdrv_swap(BlockDriverState *bs_new, BlockDriverState *bs_old)
         QTAILQ_REMOVE(&graph_bdrv_states, bs_old, node_list);
     }
 
-    /* bs_new must be nameless and shouldn't have anything fancy enabled */
-    assert(bs_new->device_name[0] == '\0');
+    /* bs_new must be unattached and shouldn't have anything fancy enabled */
     assert(!bs_new->blk);
     assert(QLIST_EMPTY(&bs_new->dirty_bitmaps));
     assert(bs_new->job == NULL);
@@ -2068,8 +2047,7 @@ void bdrv_swap(BlockDriverState *bs_new, BlockDriverState *bs_old)
     bdrv_move_feature_fields(bs_old, bs_new);
     bdrv_move_feature_fields(bs_new, &tmp);
 
-    /* bs_new must remain nameless and unattached */
-    assert(bs_new->device_name[0] == '\0');
+    /* bs_new must remain unattached */
     assert(!bs_new->blk);
 
     /* Check a few fields that should remain attached to the device */
@@ -2097,7 +2075,7 @@ void bdrv_swap(BlockDriverState *bs_new, BlockDriverState *bs_old)
  * This will modify the BlockDriverState fields, and swap contents
  * between bs_new and bs_top. Both bs_new and bs_top are modified.
  *
- * bs_new must be nameless and not attached to a BlockBackend.
+ * bs_new must not be attached to a BlockBackend.
  *
  * This function does not create any image files.
  */
@@ -3807,7 +3785,7 @@ BlockDriverState *bdrv_find(const char *name)
     BlockDriverState *bs;
 
     QTAILQ_FOREACH(bs, &bdrv_states, device_list) {
-        if (!strcmp(name, bs->device_name)) {
+        if (!strcmp(name, bdrv_get_device_name(bs))) {
             return bs;
         }
     }
@@ -3893,9 +3871,9 @@ BlockDriverState *bdrv_next(BlockDriverState *bs)
     return QTAILQ_NEXT(bs, device_list);
 }
 
-const char *bdrv_get_device_name(BlockDriverState *bs)
+const char *bdrv_get_device_name(const BlockDriverState *bs)
 {
-    return bs->device_name;
+    return bs->blk ? blk_name(bs->blk) : "";
 }
 
 int bdrv_get_flags(BlockDriverState *bs)
@@ -5257,13 +5235,15 @@ int bdrv_media_changed(BlockDriverState *bs)
 void bdrv_eject(BlockDriverState *bs, bool eject_flag)
 {
     BlockDriver *drv = bs->drv;
+    const char *device_name;
 
     if (drv && drv->bdrv_eject) {
         drv->bdrv_eject(bs, eject_flag);
     }
 
-    if (bs->device_name[0] != '\0') {
-        qapi_event_send_device_tray_moved(bdrv_get_device_name(bs),
+    device_name = bdrv_get_device_name(bs);
+    if (device_name[0] != '\0') {
+        qapi_event_send_device_tray_moved(device_name,
                                           eject_flag, &error_abort);
     }
 }
@@ -5473,7 +5453,8 @@ bool bdrv_op_is_blocked(BlockDriverState *bs, BlockOpType op, Error **errp)
         blocker = QLIST_FIRST(&bs->op_blockers[op]);
         if (errp) {
             error_setg(errp, "Device '%s' is busy: %s",
-                       bs->device_name, error_get_pretty(blocker->reason));
+                       bdrv_get_device_name(bs),
+                       error_get_pretty(blocker->reason));
         }
         return true;
     }
diff --git a/block/block-backend.c b/block/block-backend.c
index dfe2654..af23d71 100644
--- a/block/block-backend.c
+++ b/block/block-backend.c
@@ -61,17 +61,19 @@ BlockBackend *blk_new_with_bs(const char *name, Error **errp)
     BlockBackend *blk;
     BlockDriverState *bs;
 
+    if (bdrv_find_node(name)) {
+        error_setg(errp,
+                   "Device name '%s' conflicts with an existing node name",
+                   name);
+        return NULL;
+    }
+
     blk = blk_new(name, errp);
     if (!blk) {
         return NULL;
     }
 
-    bs = bdrv_new_root(name, errp);
-    if (!bs) {
-        blk_unref(blk);
-        return NULL;
-    }
-
+    bs = bdrv_new_root();
     blk->bs = bs;
     bs->blk = blk;
     return blk;
diff --git a/block/cow.c b/block/cow.c
index 6ee4833..dda1e17 100644
--- a/block/cow.c
+++ b/block/cow.c
@@ -84,7 +84,7 @@ static int cow_open(BlockDriverState *bs, QDict *options, int flags,
         snprintf(version, sizeof(version),
                "COW version %" PRIu32, cow_header.version);
         error_set(errp, QERR_UNKNOWN_BLOCK_FORMAT_FEATURE,
-            bs->device_name, "cow", version);
+            bdrv_get_device_name(bs), "cow", version);
         ret = -ENOTSUP;
         goto fail;
     }
diff --git a/block/mirror.c b/block/mirror.c
index 18b18e0..829be2f 100644
--- a/block/mirror.c
+++ b/block/mirror.c
@@ -567,7 +567,8 @@ static void mirror_complete(BlockJob *job, Error **errp)
         return;
     }
     if (!s->synced) {
-        error_set(errp, QERR_BLOCK_JOB_NOT_READY, job->bs->device_name);
+        error_set(errp, QERR_BLOCK_JOB_NOT_READY,
+                  bdrv_get_device_name(job->bs));
         return;
     }
 
diff --git a/block/qapi.c b/block/qapi.c
index 79d1e6a..cc8f711 100644
--- a/block/qapi.c
+++ b/block/qapi.c
@@ -272,7 +272,7 @@ void bdrv_query_info(BlockDriverState *bs,
     BlockDriverState *bs0;
     ImageInfo **p_image_info;
     Error *local_err = NULL;
-    info->device = g_strdup(bs->device_name);
+    info->device = g_strdup(bdrv_get_device_name(bs));
     info->type = g_strdup("unknown");
     info->locked = bdrv_dev_is_medium_locked(bs);
     info->removable = bdrv_dev_has_removable_media(bs);
@@ -327,9 +327,9 @@ static BlockStats *bdrv_query_stats(const BlockDriverState *bs)
 
     s = g_malloc0(sizeof(*s));
 
-    if (bs->device_name[0]) {
+    if (bdrv_get_device_name(bs)[0]) {
         s->has_device = true;
-        s->device = g_strdup(bs->device_name);
+        s->device = g_strdup(bdrv_get_device_name(bs));
     }
 
     s->stats = g_malloc0(sizeof(*s->stats));
diff --git a/block/qcow.c b/block/qcow.c
index 67c237f..2d803ac 100644
--- a/block/qcow.c
+++ b/block/qcow.c
@@ -124,7 +124,7 @@ static int qcow_open(BlockDriverState *bs, QDict *options, int flags,
         snprintf(version, sizeof(version), "QCOW version %" PRIu32,
                  header.version);
         error_set(errp, QERR_UNKNOWN_BLOCK_FORMAT_FEATURE,
-                  bs->device_name, "qcow", version);
+                  bdrv_get_device_name(bs), "qcow", version);
         ret = -ENOTSUP;
         goto fail;
     }
@@ -231,7 +231,7 @@ static int qcow_open(BlockDriverState *bs, QDict *options, int flags,
     /* Disable migration when qcow images are used */
     error_set(&s->migration_blocker,
               QERR_BLOCK_FORMAT_FEATURE_NOT_SUPPORTED,
-              "qcow", bs->device_name, "live migration");
+              "qcow", bdrv_get_device_name(bs), "live migration");
     migrate_add_blocker(s->migration_blocker);
 
     qemu_co_mutex_init(&s->lock);
diff --git a/block/qcow2.c b/block/qcow2.c
index f9e045f..0ab455e 100644
--- a/block/qcow2.c
+++ b/block/qcow2.c
@@ -203,8 +203,8 @@ static void GCC_FMT_ATTR(3, 4) report_unsupported(BlockDriverState *bs,
     vsnprintf(msg, sizeof(msg), fmt, ap);
     va_end(ap);
 
-    error_set(errp, QERR_UNKNOWN_BLOCK_FORMAT_FEATURE, bs->device_name, "qcow2",
-              msg);
+    error_set(errp, QERR_UNKNOWN_BLOCK_FORMAT_FEATURE,
+              bdrv_get_device_name(bs), "qcow2", msg);
 }
 
 static void report_unsupported_feature(BlockDriverState *bs,
diff --git a/block/qed.c b/block/qed.c
index ba395af..f20ffb3 100644
--- a/block/qed.c
+++ b/block/qed.c
@@ -422,7 +422,7 @@ static int bdrv_qed_open(BlockDriverState *bs, QDict *options, int flags,
         snprintf(buf, sizeof(buf), "%" PRIx64,
             s->header.features & ~QED_FEATURE_MASK);
         error_set(errp, QERR_UNKNOWN_BLOCK_FORMAT_FEATURE,
-            bs->device_name, "QED", buf);
+            bdrv_get_device_name(bs), "QED", buf);
         return -ENOTSUP;
     }
     if (!qed_is_cluster_size_valid(s->header.cluster_size)) {
diff --git a/block/quorum.c b/block/quorum.c
index 093382e..f958269 100644
--- a/block/quorum.c
+++ b/block/quorum.c
@@ -227,8 +227,8 @@ static void quorum_report_bad(QuorumAIOCB *acb, char *node_name, int ret)
 
 static void quorum_report_failure(QuorumAIOCB *acb)
 {
-    const char *reference = acb->common.bs->device_name[0] ?
-                            acb->common.bs->device_name :
+    const char *reference = bdrv_get_device_name(acb->common.bs)[0] ?
+                            bdrv_get_device_name(acb->common.bs) :
                             acb->common.bs->node_name;
 
     qapi_event_send_quorum_failure(reference, acb->sector_num,
diff --git a/block/vdi.c b/block/vdi.c
index 4b10aac..2e6f31c 100644
--- a/block/vdi.c
+++ b/block/vdi.c
@@ -490,7 +490,7 @@ static int vdi_open(BlockDriverState *bs, QDict *options, int flags,
     /* Disable migration when vdi images are used */
     error_set(&s->migration_blocker,
               QERR_BLOCK_FORMAT_FEATURE_NOT_SUPPORTED,
-              "vdi", bs->device_name, "live migration");
+              "vdi", bdrv_get_device_name(bs), "live migration");
     migrate_add_blocker(s->migration_blocker);
 
     return 0;
diff --git a/block/vhdx.c b/block/vhdx.c
index 87c99fc..8bf1af1 100644
--- a/block/vhdx.c
+++ b/block/vhdx.c
@@ -1003,7 +1003,7 @@ static int vhdx_open(BlockDriverState *bs, QDict *options, int flags,
     /* Disable migration when VHDX images are used */
     error_set(&s->migration_blocker,
             QERR_BLOCK_FORMAT_FEATURE_NOT_SUPPORTED,
-            "vhdx", bs->device_name, "live migration");
+            "vhdx", bdrv_get_device_name(bs), "live migration");
     migrate_add_blocker(s->migration_blocker);
 
     return 0;
diff --git a/block/vmdk.c b/block/vmdk.c
index a1cb911..7bc1474 100644
--- a/block/vmdk.c
+++ b/block/vmdk.c
@@ -657,7 +657,7 @@ static int vmdk_open_vmdk4(BlockDriverState *bs,
         snprintf(buf, sizeof(buf), "VMDK version %" PRId32,
                  le32_to_cpu(header.version));
         error_set(errp, QERR_UNKNOWN_BLOCK_FORMAT_FEATURE,
-                  bs->device_name, "vmdk", buf);
+                  bdrv_get_device_name(bs), "vmdk", buf);
         return -ENOTSUP;
     } else if (le32_to_cpu(header.version) == 3 && (flags & BDRV_O_RDWR)) {
         /* VMware KB 2064959 explains that version 3 added support for
@@ -939,7 +939,7 @@ static int vmdk_open(BlockDriverState *bs, QDict *options, int flags,
     /* Disable migration when VMDK images are used */
     error_set(&s->migration_blocker,
               QERR_BLOCK_FORMAT_FEATURE_NOT_SUPPORTED,
-              "vmdk", bs->device_name, "live migration");
+              "vmdk", bdrv_get_device_name(bs), "live migration");
     migrate_add_blocker(s->migration_blocker);
     g_free(buf);
     return 0;
diff --git a/block/vpc.c b/block/vpc.c
index 055efc4..7bb90d5 100644
--- a/block/vpc.c
+++ b/block/vpc.c
@@ -320,7 +320,7 @@ static int vpc_open(BlockDriverState *bs, QDict *options, int flags,
     /* Disable migration when VHD images are used */
     error_set(&s->migration_blocker,
               QERR_BLOCK_FORMAT_FEATURE_NOT_SUPPORTED,
-              "vpc", bs->device_name, "live migration");
+              "vpc", bdrv_get_device_name(bs), "live migration");
     migrate_add_blocker(s->migration_blocker);
 
     return 0;
diff --git a/block/vvfat.c b/block/vvfat.c
index 6c9fde0..cefe3a4 100644
--- a/block/vvfat.c
+++ b/block/vvfat.c
@@ -1182,7 +1182,7 @@ static int vvfat_open(BlockDriverState *bs, QDict *options, int flags,
     if (s->qcow) {
         error_set(&s->migration_blocker,
                   QERR_BLOCK_FORMAT_FEATURE_NOT_SUPPORTED,
-                  "vvfat (rw)", bs->device_name, "live migration");
+                  "vvfat (rw)", bdrv_get_device_name(bs), "live migration");
         migrate_add_blocker(s->migration_blocker);
     }
 
diff --git a/blockjob.c b/blockjob.c
index 0689fdd..3af0f6c 100644
--- a/blockjob.c
+++ b/blockjob.c
@@ -107,7 +107,8 @@ void block_job_set_speed(BlockJob *job, int64_t speed, Error **errp)
 void block_job_complete(BlockJob *job, Error **errp)
 {
     if (job->paused || job->cancelled || !job->driver->complete) {
-        error_set(errp, QERR_BLOCK_JOB_NOT_READY, job->bs->device_name);
+        error_set(errp, QERR_BLOCK_JOB_NOT_READY,
+                  bdrv_get_device_name(job->bs));
         return;
     }
 
diff --git a/include/block/block.h b/include/block/block.h
index c092eab..c8f33c0 100644
--- a/include/block/block.h
+++ b/include/block/block.h
@@ -203,7 +203,7 @@ BlockDriver *bdrv_find_whitelisted_format(const char *format_name,
 int bdrv_create(BlockDriver *drv, const char* filename,
                 QemuOpts *opts, Error **errp);
 int bdrv_create_file(const char *filename, QemuOpts *opts, Error **errp);
-BlockDriverState *bdrv_new_root(const char *device_name, Error **errp);
+BlockDriverState *bdrv_new_root(void);
 BlockDriverState *bdrv_new(void);
 void bdrv_make_anon(BlockDriverState *bs);
 void bdrv_swap(BlockDriverState *bs_new, BlockDriverState *bs_old);
@@ -415,7 +415,7 @@ int bdrv_set_key(BlockDriverState *bs, const char *key);
 int bdrv_query_missing_keys(void);
 void bdrv_iterate_format(void (*it)(void *opaque, const char *name),
                          void *opaque);
-const char *bdrv_get_device_name(BlockDriverState *bs);
+const char *bdrv_get_device_name(const BlockDriverState *bs);
 int bdrv_get_flags(BlockDriverState *bs);
 int bdrv_write_compressed(BlockDriverState *bs, int64_t sector_num,
                           const uint8_t *buf, int nb_sectors);
diff --git a/include/block/block_int.h b/include/block/block_int.h
index a04c852..000abfa 100644
--- a/include/block/block_int.h
+++ b/include/block/block_int.h
@@ -394,8 +394,6 @@ struct BlockDriverState {
     char node_name[32];
     /* element of the list of named nodes building the graph */
     QTAILQ_ENTRY(BlockDriverState) node_list;
-    /* Device name is the name associated with the "drive" the guest sees */
-    char device_name[32];
     /* element of the list of "drives" the guest sees */
     QTAILQ_ENTRY(BlockDriverState) device_list;
     QLIST_HEAD(, BdrvDirtyBitmap) dirty_bitmaps;
-- 
1.9.3

^ permalink raw reply related	[flat|nested] 56+ messages in thread

* [Qemu-devel] [PATCH v2 09/23] block: Merge BlockBackend and BlockDriverState name spaces
  2014-09-13 15:00 [Qemu-devel] [PATCH v2 00/23] Split BlockBackend off BDS with an axe Markus Armbruster
                   ` (7 preceding siblings ...)
  2014-09-13 15:00 ` [Qemu-devel] [PATCH v2 08/23] block: Eliminate BlockDriverState member device_name[] Markus Armbruster
@ 2014-09-13 15:00 ` Markus Armbruster
  2014-09-16 13:25   ` Benoît Canet
  2014-09-13 15:00 ` [Qemu-devel] [PATCH v2 10/23] block: Eliminate DriveInfo member bdrv, use blk_by_legacy_dinfo() Markus Armbruster
                   ` (14 subsequent siblings)
  23 siblings, 1 reply; 56+ messages in thread
From: Markus Armbruster @ 2014-09-13 15:00 UTC (permalink / raw)
  To: qemu-devel; +Cc: kwolf, benoit.canet, stefanha

BlockBackend's name space is separate only to keep the initial patches
simple.  Time to merge the two.

Signed-off-by: Markus Armbruster <armbru@redhat.com>
---
 block.c               | 11 +++--------
 block/block-backend.c | 13 ++++++-------
 2 files changed, 9 insertions(+), 15 deletions(-)

diff --git a/block.c b/block.c
index b39e368..f59dade 100644
--- a/block.c
+++ b/block.c
@@ -861,7 +861,7 @@ static void bdrv_assign_node_name(BlockDriverState *bs,
     }
 
     /* takes care of avoiding namespaces collisions */
-    if (bdrv_find(node_name)) {
+    if (blk_by_name(node_name)) {
         error_setg(errp, "node-name=%s is conflicting with a device id",
                    node_name);
         return;
@@ -3782,14 +3782,9 @@ void bdrv_iterate_format(void (*it)(void *opaque, const char *name),
 /* This function is to find block backend bs */
 BlockDriverState *bdrv_find(const char *name)
 {
-    BlockDriverState *bs;
+    BlockBackend *blk = blk_by_name(name);
 
-    QTAILQ_FOREACH(bs, &bdrv_states, device_list) {
-        if (!strcmp(name, bdrv_get_device_name(bs))) {
-            return bs;
-        }
-    }
-    return NULL;
+    return blk ? blk_bs(blk) : NULL;
 }
 
 /* This function is to find a node in the bs graph */
diff --git a/block/block-backend.c b/block/block-backend.c
index af23d71..17f05a3 100644
--- a/block/block-backend.c
+++ b/block/block-backend.c
@@ -44,6 +44,12 @@ BlockBackend *blk_new(const char *name, Error **errp)
         error_setg(errp, "Device with id '%s' already exists", name);
         return NULL;
     }
+    if (bdrv_find_node(name)) {
+        error_setg(errp,
+                   "Device name '%s' conflicts with an existing node name",
+                   name);
+        return NULL;
+    }
 
     blk = g_new0(BlockBackend, 1);
     blk->name = g_strdup(name);
@@ -61,13 +67,6 @@ BlockBackend *blk_new_with_bs(const char *name, Error **errp)
     BlockBackend *blk;
     BlockDriverState *bs;
 
-    if (bdrv_find_node(name)) {
-        error_setg(errp,
-                   "Device name '%s' conflicts with an existing node name",
-                   name);
-        return NULL;
-    }
-
     blk = blk_new(name, errp);
     if (!blk) {
         return NULL;
-- 
1.9.3

^ permalink raw reply related	[flat|nested] 56+ messages in thread

* [Qemu-devel] [PATCH v2 10/23] block: Eliminate DriveInfo member bdrv, use blk_by_legacy_dinfo()
  2014-09-13 15:00 [Qemu-devel] [PATCH v2 00/23] Split BlockBackend off BDS with an axe Markus Armbruster
                   ` (8 preceding siblings ...)
  2014-09-13 15:00 ` [Qemu-devel] [PATCH v2 09/23] block: Merge BlockBackend and BlockDriverState name spaces Markus Armbruster
@ 2014-09-13 15:00 ` Markus Armbruster
  2014-09-15  6:58   ` Fam Zheng
  2014-09-13 15:00 ` [Qemu-devel] [PATCH v2 11/23] block: Rename BlockDriverAIOCB* to BlockAIOCB* Markus Armbruster
                   ` (13 subsequent siblings)
  23 siblings, 1 reply; 56+ messages in thread
From: Markus Armbruster @ 2014-09-13 15:00 UTC (permalink / raw)
  To: qemu-devel; +Cc: kwolf, benoit.canet, stefanha

The patch is big, but all it really does is replacing

    dinfo->bdrv

by

    blk_bs(blk_legacy_dinfo(dinfo))

The replacement is repetitive, but the conversion of device models to
BlockBackend is imminent, and will shorten it to just
blk_legacy_dinfo(dinfo).

Line wrapping muddies the waters a bit.  I also omit tests whether
dinfo->bdrv is null, because it never is.

Signed-off-by: Markus Armbruster <armbru@redhat.com>
---
 blockdev.c                               |  3 +--
 hw/arm/collie.c                          |  9 +++++----
 hw/arm/gumstix.c                         |  5 +++--
 hw/arm/mainstone.c                       |  8 ++++----
 hw/arm/musicpal.c                        | 11 ++++++-----
 hw/arm/nseries.c                         |  6 ++++--
 hw/arm/omap1.c                           |  4 +++-
 hw/arm/omap2.c                           |  4 +++-
 hw/arm/omap_sx1.c                        |  9 +++++----
 hw/arm/pxa2xx.c                          |  7 +++++--
 hw/arm/spitz.c                           |  4 +++-
 hw/arm/versatilepb.c                     |  4 +++-
 hw/arm/vexpress.c                        |  4 +++-
 hw/arm/xilinx_zynq.c                     |  4 +++-
 hw/arm/z2.c                              |  7 ++++---
 hw/block/fdc.c                           | 16 +++++++++++-----
 hw/block/m25p80.c                        |  5 +++--
 hw/block/xen_disk.c                      |  2 +-
 hw/cris/axis_dev88.c                     |  3 ++-
 hw/display/tc6393xb.c                    |  4 +++-
 hw/i386/pc_sysfw.c                       |  3 ++-
 hw/ide/piix.c                            |  6 ++++--
 hw/ide/qdev.c                            |  4 +++-
 hw/isa/pc87312.c                         |  7 +++++--
 hw/lm32/lm32_boards.c                    | 13 +++++++------
 hw/lm32/milkymist.c                      |  7 ++++---
 hw/microblaze/petalogix_ml605_mmu.c      |  5 +++--
 hw/microblaze/petalogix_s3adsp1800_mmu.c |  5 +++--
 hw/mips/mips_malta.c                     |  4 +++-
 hw/mips/mips_r4k.c                       |  5 +++--
 hw/pci/pci-hotplug-old.c                 |  9 ++++++---
 hw/ppc/ppc405_boards.c                   | 25 ++++++++++++++++---------
 hw/ppc/spapr.c                           |  4 +++-
 hw/ppc/virtex_ml507.c                    |  5 +++--
 hw/scsi/scsi-bus.c                       |  5 +++--
 hw/sd/milkymist-memcard.c                |  7 +++++--
 hw/sd/pl181.c                            |  3 ++-
 hw/sd/sdhci.c                            |  3 ++-
 hw/sd/ssi-sd.c                           |  3 ++-
 hw/sh4/r2d.c                             |  5 +++--
 hw/usb/dev-storage.c                     |  4 +++-
 hw/xtensa/xtfpga.c                       |  4 +++-
 include/sysemu/blockdev.h                |  1 -
 43 files changed, 163 insertions(+), 93 deletions(-)

diff --git a/blockdev.c b/blockdev.c
index 85f574b..49496b6 100644
--- a/blockdev.c
+++ b/blockdev.c
@@ -472,7 +472,6 @@ static BlockBackend *blockdev_init(const char *file, QDict *bs_opts,
 
     dinfo = g_malloc0(sizeof(*dinfo));
     dinfo->id = g_strdup(qemu_opts_id(opts));
-    dinfo->bdrv = bs;
     blk_set_legacy_dinfo(blk, dinfo);
 
     if (!file || !*file) {
@@ -502,7 +501,7 @@ static BlockBackend *blockdev_init(const char *file, QDict *bs_opts,
 
     QINCREF(bs_opts);
     ret = bdrv_open(&bs, file, NULL, bs_opts, bdrv_flags, drv, &error);
-    assert(bs == dinfo->bdrv);
+    assert(bs == blk_bs(blk));
 
     if (ret < 0) {
         error_setg(errp, "could not open disk image %s: %s",
diff --git a/hw/arm/collie.c b/hw/arm/collie.c
index ed7851f..0247290 100644
--- a/hw/arm/collie.c
+++ b/hw/arm/collie.c
@@ -15,6 +15,7 @@
 #include "strongarm.h"
 #include "hw/arm/arm.h"
 #include "hw/block/flash.h"
+#include "sysemu/block-backend.h"
 #include "sysemu/blockdev.h"
 #include "exec/address-spaces.h"
 
@@ -41,13 +42,13 @@ static void collie_init(MachineState *machine)
 
     dinfo = drive_get(IF_PFLASH, 0, 0);
     pflash_cfi01_register(SA_CS0, NULL, "collie.fl1", 0x02000000,
-                    dinfo ? dinfo->bdrv : NULL, (64 * 1024),
-                    512, 4, 0x00, 0x00, 0x00, 0x00, 0);
+                    dinfo ? blk_bs(blk_by_legacy_dinfo(dinfo)) : NULL,
+                    (64 * 1024), 512, 4, 0x00, 0x00, 0x00, 0x00, 0);
 
     dinfo = drive_get(IF_PFLASH, 0, 1);
     pflash_cfi01_register(SA_CS1, NULL, "collie.fl2", 0x02000000,
-                    dinfo ? dinfo->bdrv : NULL, (64 * 1024),
-                    512, 4, 0x00, 0x00, 0x00, 0x00, 0);
+                    dinfo ? blk_bs(blk_by_legacy_dinfo(dinfo)) : NULL,
+                    (64 * 1024), 512, 4, 0x00, 0x00, 0x00, 0x00, 0);
 
     sysbus_create_simple("scoop", 0x40800000, NULL);
 
diff --git a/hw/arm/gumstix.c b/hw/arm/gumstix.c
index 3f8465e..49f9339 100644
--- a/hw/arm/gumstix.c
+++ b/hw/arm/gumstix.c
@@ -40,6 +40,7 @@
 #include "hw/block/flash.h"
 #include "hw/devices.h"
 #include "hw/boards.h"
+#include "sysemu/block-backend.h"
 #include "sysemu/blockdev.h"
 #include "exec/address-spaces.h"
 #include "sysemu/qtest.h"
@@ -71,7 +72,7 @@ static void connex_init(MachineState *machine)
     be = 0;
 #endif
     if (!pflash_cfi01_register(0x00000000, NULL, "connext.rom", connex_rom,
-                               dinfo ? dinfo->bdrv : NULL,
+                               dinfo ? blk_bs(blk_by_legacy_dinfo(dinfo)) : NULL,
                                sector_len, connex_rom / sector_len,
                                2, 0, 0, 0, 0, be)) {
         fprintf(stderr, "qemu: Error registering flash memory.\n");
@@ -109,7 +110,7 @@ static void verdex_init(MachineState *machine)
     be = 0;
 #endif
     if (!pflash_cfi01_register(0x00000000, NULL, "verdex.rom", verdex_rom,
-                               dinfo ? dinfo->bdrv : NULL,
+                               dinfo ? blk_bs(blk_by_legacy_dinfo(dinfo)) : NULL,
                                sector_len, verdex_rom / sector_len,
                                2, 0, 0, 0, 0, be)) {
         fprintf(stderr, "qemu: Error registering flash memory.\n");
diff --git a/hw/arm/mainstone.c b/hw/arm/mainstone.c
index 44f1873..fb17d85 100644
--- a/hw/arm/mainstone.c
+++ b/hw/arm/mainstone.c
@@ -18,7 +18,7 @@
 #include "hw/devices.h"
 #include "hw/boards.h"
 #include "hw/block/flash.h"
-#include "sysemu/blockdev.h"
+#include "sysemu/block-backend.h"
 #include "hw/sysbus.h"
 #include "exec/address-spaces.h"
 #include "sysemu/qtest.h"
@@ -148,9 +148,9 @@ static void mainstone_common_init(MemoryRegion *address_space_mem,
         if (!pflash_cfi01_register(mainstone_flash_base[i], NULL,
                                    i ? "mainstone.flash1" : "mainstone.flash0",
                                    MAINSTONE_FLASH,
-                                   dinfo->bdrv, sector_len,
-                                   MAINSTONE_FLASH / sector_len, 4, 0, 0, 0, 0,
-                                   be)) {
+                                   blk_bs(blk_by_legacy_dinfo(dinfo)),
+                                   sector_len, MAINSTONE_FLASH / sector_len,
+                                   4, 0, 0, 0, 0, be)) {
             fprintf(stderr, "qemu: Error registering flash memory.\n");
             exit(1);
         }
diff --git a/hw/arm/musicpal.c b/hw/arm/musicpal.c
index 6a134f2..6a41d9c 100644
--- a/hw/arm/musicpal.c
+++ b/hw/arm/musicpal.c
@@ -22,6 +22,7 @@
 #include "hw/block/flash.h"
 #include "ui/console.h"
 #include "hw/i2c/i2c.h"
+#include "sysemu/block-backend.h"
 #include "sysemu/blockdev.h"
 #include "exec/address-spaces.h"
 #include "ui/pixel_ops.h"
@@ -1630,7 +1631,9 @@ static void musicpal_init(MachineState *machine)
     /* Register flash */
     dinfo = drive_get(IF_PFLASH, 0, 0);
     if (dinfo) {
-        flash_size = bdrv_getlength(dinfo->bdrv);
+        BlockDriverState *bs = blk_bs(blk_by_legacy_dinfo(dinfo));
+
+        flash_size = bdrv_getlength(bs);
         if (flash_size != 8*1024*1024 && flash_size != 16*1024*1024 &&
             flash_size != 32*1024*1024) {
             fprintf(stderr, "Invalid flash image size\n");
@@ -1645,16 +1648,14 @@ static void musicpal_init(MachineState *machine)
 #ifdef TARGET_WORDS_BIGENDIAN
         pflash_cfi02_register(0x100000000ULL-MP_FLASH_SIZE_MAX, NULL,
                               "musicpal.flash", flash_size,
-                              dinfo->bdrv, 0x10000,
-                              (flash_size + 0xffff) >> 16,
+                              bs, 0x10000, (flash_size + 0xffff) >> 16,
                               MP_FLASH_SIZE_MAX / flash_size,
                               2, 0x00BF, 0x236D, 0x0000, 0x0000,
                               0x5555, 0x2AAA, 1);
 #else
         pflash_cfi02_register(0x100000000ULL-MP_FLASH_SIZE_MAX, NULL,
                               "musicpal.flash", flash_size,
-                              dinfo->bdrv, 0x10000,
-                              (flash_size + 0xffff) >> 16,
+                              bs, 0x10000, (flash_size + 0xffff) >> 16,
                               MP_FLASH_SIZE_MAX / flash_size,
                               2, 0x00BF, 0x236D, 0x0000, 0x0000,
                               0x5555, 0x2AAA, 0);
diff --git a/hw/arm/nseries.c b/hw/arm/nseries.c
index 4f092d6..2536078 100644
--- a/hw/arm/nseries.c
+++ b/hw/arm/nseries.c
@@ -31,6 +31,7 @@
 #include "hw/hw.h"
 #include "hw/bt.h"
 #include "hw/loader.h"
+#include "sysemu/block-backend.h"
 #include "sysemu/blockdev.h"
 #include "hw/sysbus.h"
 #include "exec/address-spaces.h"
@@ -172,8 +173,9 @@ static void n8x0_nand_setup(struct n800_s *s)
     qdev_prop_set_uint16(s->nand, "version_id", 0);
     qdev_prop_set_int32(s->nand, "shift", 1);
     dinfo = drive_get(IF_MTD, 0, 0);
-    if (dinfo && dinfo->bdrv) {
-        qdev_prop_set_drive_nofail(s->nand, "drive", dinfo->bdrv);
+    if (dinfo) {
+        qdev_prop_set_drive_nofail(s->nand, "drive",
+                                   blk_bs(blk_by_legacy_dinfo(dinfo)));
     }
     qdev_init_nofail(s->nand);
     sysbus_connect_irq(SYS_BUS_DEVICE(s->nand), 0,
diff --git a/hw/arm/omap1.c b/hw/arm/omap1.c
index e7cc5d7..e38e07f 100644
--- a/hw/arm/omap1.c
+++ b/hw/arm/omap1.c
@@ -21,6 +21,7 @@
 #include "hw/arm/omap.h"
 #include "sysemu/sysemu.h"
 #include "hw/arm/soc_dma.h"
+#include "sysemu/block-backend.h"
 #include "sysemu/blockdev.h"
 #include "qemu/range.h"
 #include "hw/sysbus.h"
@@ -3976,7 +3977,8 @@ struct omap_mpu_state_s *omap310_mpu_init(MemoryRegion *system_memory,
         fprintf(stderr, "qemu: missing SecureDigital device\n");
         exit(1);
     }
-    s->mmc = omap_mmc_init(0xfffb7800, system_memory, dinfo->bdrv,
+    s->mmc = omap_mmc_init(0xfffb7800, system_memory,
+                           blk_bs(blk_by_legacy_dinfo(dinfo)),
                            qdev_get_gpio_in(s->ih[1], OMAP_INT_OQN),
                            &s->drq[OMAP_DMA_MMC_TX],
                     omap_findclk(s, "mmc_ck"));
diff --git a/hw/arm/omap2.c b/hw/arm/omap2.c
index dc53a7a..e47dd63 100644
--- a/hw/arm/omap2.c
+++ b/hw/arm/omap2.c
@@ -18,6 +18,7 @@
  * with this program; if not, see <http://www.gnu.org/licenses/>.
  */
 
+#include "sysemu/block-backend.h"
 #include "sysemu/blockdev.h"
 #include "hw/hw.h"
 #include "hw/arm/arm.h"
@@ -2459,7 +2460,8 @@ struct omap_mpu_state_s *omap2420_mpu_init(MemoryRegion *sysmem,
         fprintf(stderr, "qemu: missing SecureDigital device\n");
         exit(1);
     }
-    s->mmc = omap2_mmc_init(omap_l4tao(s->l4, 9), dinfo->bdrv,
+    s->mmc = omap2_mmc_init(omap_l4tao(s->l4, 9),
+                    blk_bs(blk_by_legacy_dinfo(dinfo)),
                     qdev_get_gpio_in(s->ih[0], OMAP_INT_24XX_MMC_IRQ),
                     &s->drq[OMAP24XX_DMA_MMC1_TX],
                     omap_findclk(s, "mmc_fclk"), omap_findclk(s, "mmc_iclk"));
diff --git a/hw/arm/omap_sx1.c b/hw/arm/omap_sx1.c
index b4f6da6..f475afc 100644
--- a/hw/arm/omap_sx1.c
+++ b/hw/arm/omap_sx1.c
@@ -31,6 +31,7 @@
 #include "hw/boards.h"
 #include "hw/arm/arm.h"
 #include "hw/block/flash.h"
+#include "sysemu/block-backend.h"
 #include "sysemu/blockdev.h"
 #include "sysemu/qtest.h"
 #include "exec/address-spaces.h"
@@ -153,8 +154,8 @@ static void sx1_init(MachineState *machine, const int version)
     if ((dinfo = drive_get(IF_PFLASH, 0, fl_idx)) != NULL) {
         if (!pflash_cfi01_register(OMAP_CS0_BASE, NULL,
                                    "omap_sx1.flash0-1", flash_size,
-                                   dinfo->bdrv, sector_size,
-                                   flash_size / sector_size,
+                                   blk_bs(blk_by_legacy_dinfo(dinfo)),
+                                   sector_size, flash_size / sector_size,
                                    4, 0, 0, 0, 0, be)) {
             fprintf(stderr, "qemu: Error registering flash memory %d.\n",
                            fl_idx);
@@ -176,8 +177,8 @@ static void sx1_init(MachineState *machine, const int version)
 
         if (!pflash_cfi01_register(OMAP_CS1_BASE, NULL,
                                    "omap_sx1.flash1-1", flash1_size,
-                                   dinfo->bdrv, sector_size,
-                                   flash1_size / sector_size,
+                                   blk_bs(blk_by_legacy_dinfo(dinfo)),
+                                   sector_size, flash1_size / sector_size,
                                    4, 0, 0, 0, 0, be)) {
             fprintf(stderr, "qemu: Error registering flash memory %d.\n",
                            fl_idx);
diff --git a/hw/arm/pxa2xx.c b/hw/arm/pxa2xx.c
index 557e0f1..7ec0da8 100644
--- a/hw/arm/pxa2xx.c
+++ b/hw/arm/pxa2xx.c
@@ -14,6 +14,7 @@
 #include "hw/i2c/i2c.h"
 #include "hw/ssi.h"
 #include "sysemu/char.h"
+#include "sysemu/block-backend.h"
 #include "sysemu/blockdev.h"
 
 static struct {
@@ -2083,7 +2084,8 @@ PXA2xxState *pxa270_init(MemoryRegion *address_space,
         fprintf(stderr, "qemu: missing SecureDigital device\n");
         exit(1);
     }
-    s->mmc = pxa2xx_mmci_init(address_space, 0x41100000, dinfo->bdrv,
+    s->mmc = pxa2xx_mmci_init(address_space, 0x41100000,
+                    blk_bs(blk_by_legacy_dinfo(dinfo)),
                     qdev_get_gpio_in(s->pic, PXA2XX_PIC_MMC),
                     qdev_get_gpio_in(s->dma, PXA2XX_RX_RQ_MMCI),
                     qdev_get_gpio_in(s->dma, PXA2XX_TX_RQ_MMCI));
@@ -2214,7 +2216,8 @@ PXA2xxState *pxa255_init(MemoryRegion *address_space, unsigned int sdram_size)
         fprintf(stderr, "qemu: missing SecureDigital device\n");
         exit(1);
     }
-    s->mmc = pxa2xx_mmci_init(address_space, 0x41100000, dinfo->bdrv,
+    s->mmc = pxa2xx_mmci_init(address_space, 0x41100000,
+                    blk_bs(blk_by_legacy_dinfo(dinfo)),
                     qdev_get_gpio_in(s->pic, PXA2XX_PIC_MMC),
                     qdev_get_gpio_in(s->dma, PXA2XX_RX_RQ_MMCI),
                     qdev_get_gpio_in(s->dma, PXA2XX_TX_RQ_MMCI));
diff --git a/hw/arm/spitz.c b/hw/arm/spitz.c
index 03cc6ce..5d684a2 100644
--- a/hw/arm/spitz.c
+++ b/hw/arm/spitz.c
@@ -25,6 +25,7 @@
 #include "block/block.h"
 #include "audio/audio.h"
 #include "hw/boards.h"
+#include "sysemu/block-backend.h"
 #include "sysemu/blockdev.h"
 #include "hw/sysbus.h"
 #include "exec/address-spaces.h"
@@ -170,7 +171,8 @@ static int sl_nand_init(SysBusDevice *dev)
 
     s->ctl = 0;
     nand = drive_get(IF_MTD, 0, 0);
-    s->nand = nand_init(nand ? nand->bdrv : NULL, s->manf_id, s->chip_id);
+    s->nand = nand_init(nand ? blk_bs(blk_by_legacy_dinfo(nand)) : NULL,
+                        s->manf_id, s->chip_id);
 
     memory_region_init_io(&s->iomem, OBJECT(s), &sl_ops, s, "sl", 0x40);
     sysbus_init_mmio(dev, &s->iomem);
diff --git a/hw/arm/versatilepb.c b/hw/arm/versatilepb.c
index dea5fc7..c88be6b 100644
--- a/hw/arm/versatilepb.c
+++ b/hw/arm/versatilepb.c
@@ -15,6 +15,7 @@
 #include "hw/pci/pci.h"
 #include "hw/i2c/i2c.h"
 #include "hw/boards.h"
+#include "sysemu/block-backend.h"
 #include "sysemu/blockdev.h"
 #include "exec/address-spaces.h"
 #include "hw/block/flash.h"
@@ -337,7 +338,8 @@ static void versatile_init(MachineState *machine, int board_id)
 
     dinfo = drive_get(IF_PFLASH, 0, 0);
     if (!pflash_cfi01_register(VERSATILE_FLASH_ADDR, NULL, "versatile.flash",
-                          VERSATILE_FLASH_SIZE, dinfo ? dinfo->bdrv : NULL,
+                          VERSATILE_FLASH_SIZE,
+                          dinfo ? blk_bs(blk_by_legacy_dinfo(dinfo)) : NULL,
                           VERSATILE_FLASH_SECT_SIZE,
                           VERSATILE_FLASH_SIZE / VERSATILE_FLASH_SECT_SIZE,
                           4, 0x0089, 0x0018, 0x0000, 0x0, 0)) {
diff --git a/hw/arm/vexpress.c b/hw/arm/vexpress.c
index a88732c..a492c22 100644
--- a/hw/arm/vexpress.c
+++ b/hw/arm/vexpress.c
@@ -30,6 +30,7 @@
 #include "hw/boards.h"
 #include "hw/loader.h"
 #include "exec/address-spaces.h"
+#include "sysemu/block-backend.h"
 #include "sysemu/blockdev.h"
 #include "hw/block/flash.h"
 #include "sysemu/device_tree.h"
@@ -488,7 +489,8 @@ static pflash_t *ve_pflash_cfi01_register(hwaddr base, const char *name,
 {
     DeviceState *dev = qdev_create(NULL, "cfi.pflash01");
 
-    if (di && qdev_prop_set_drive(dev, "drive", di->bdrv)) {
+    if (di && qdev_prop_set_drive(dev, "drive",
+                                  blk_bs(blk_by_legacy_dinfo(di)))) {
         abort();
     }
 
diff --git a/hw/arm/xilinx_zynq.c b/hw/arm/xilinx_zynq.c
index ba5aa82..78e6934 100644
--- a/hw/arm/xilinx_zynq.c
+++ b/hw/arm/xilinx_zynq.c
@@ -22,6 +22,7 @@
 #include "sysemu/sysemu.h"
 #include "hw/boards.h"
 #include "hw/block/flash.h"
+#include "sysemu/block-backend.h"
 #include "sysemu/blockdev.h"
 #include "hw/loader.h"
 #include "hw/ssi.h"
@@ -162,7 +163,8 @@ static void zynq_init(MachineState *machine)
 
     /* AMD */
     pflash_cfi02_register(0xe2000000, NULL, "zynq.pflash", FLASH_SIZE,
-                          dinfo ? dinfo->bdrv : NULL, FLASH_SECTOR_SIZE,
+                          dinfo ? blk_bs(blk_by_legacy_dinfo(dinfo)) : NULL,
+                          FLASH_SECTOR_SIZE,
                           FLASH_SIZE/FLASH_SECTOR_SIZE, 1,
                           1, 0x0066, 0x0022, 0x0000, 0x0000, 0x0555, 0x2aa,
                               0);
diff --git a/hw/arm/z2.c b/hw/arm/z2.c
index 36b3b50..9b38a2b 100644
--- a/hw/arm/z2.c
+++ b/hw/arm/z2.c
@@ -20,6 +20,7 @@
 #include "hw/boards.h"
 #include "sysemu/sysemu.h"
 #include "hw/block/flash.h"
+#include "sysemu/block-backend.h"
 #include "sysemu/blockdev.h"
 #include "ui/console.h"
 #include "audio/audio.h"
@@ -336,9 +337,9 @@ static void z2_init(MachineState *machine)
 
     if (!pflash_cfi01_register(Z2_FLASH_BASE,
                                NULL, "z2.flash0", Z2_FLASH_SIZE,
-                               dinfo ? dinfo->bdrv : NULL, sector_len,
-                               Z2_FLASH_SIZE / sector_len, 4, 0, 0, 0, 0,
-                               be)) {
+                               dinfo ? blk_bs(blk_by_legacy_dinfo(dinfo)) : NULL,
+                               sector_len, Z2_FLASH_SIZE / sector_len,
+                               4, 0, 0, 0, 0, be)) {
         fprintf(stderr, "qemu: Error registering flash memory.\n");
         exit(1);
     }
diff --git a/hw/block/fdc.c b/hw/block/fdc.c
index 490d127..19f215f 100644
--- a/hw/block/fdc.c
+++ b/hw/block/fdc.c
@@ -33,6 +33,7 @@
 #include "qemu/timer.h"
 #include "hw/isa/isa.h"
 #include "hw/sysbus.h"
+#include "sysemu/block-backend.h"
 #include "sysemu/blockdev.h"
 #include "sysemu/sysemu.h"
 #include "qemu/log.h"
@@ -2033,10 +2034,12 @@ ISADevice *fdctrl_init_isa(ISABus *bus, DriveInfo **fds)
     dev = DEVICE(isadev);
 
     if (fds[0]) {
-        qdev_prop_set_drive_nofail(dev, "driveA", fds[0]->bdrv);
+        qdev_prop_set_drive_nofail(dev, "driveA",
+                                   blk_bs(blk_by_legacy_dinfo(fds[0])));
     }
     if (fds[1]) {
-        qdev_prop_set_drive_nofail(dev, "driveB", fds[1]->bdrv);
+        qdev_prop_set_drive_nofail(dev, "driveB",
+                                   blk_bs(blk_by_legacy_dinfo(fds[1])));
     }
     qdev_init_nofail(dev);
 
@@ -2056,10 +2059,12 @@ void fdctrl_init_sysbus(qemu_irq irq, int dma_chann,
     fdctrl = &sys->state;
     fdctrl->dma_chann = dma_chann; /* FIXME */
     if (fds[0]) {
-        qdev_prop_set_drive_nofail(dev, "driveA", fds[0]->bdrv);
+        qdev_prop_set_drive_nofail(dev, "driveA",
+                                   blk_bs(blk_by_legacy_dinfo(fds[0])));
     }
     if (fds[1]) {
-        qdev_prop_set_drive_nofail(dev, "driveB", fds[1]->bdrv);
+        qdev_prop_set_drive_nofail(dev, "driveB",
+                                   blk_bs(blk_by_legacy_dinfo(fds[1])));
     }
     qdev_init_nofail(dev);
     sbd = SYS_BUS_DEVICE(dev);
@@ -2075,7 +2080,8 @@ void sun4m_fdctrl_init(qemu_irq irq, hwaddr io_base,
 
     dev = qdev_create(NULL, "SUNW,fdtwo");
     if (fds[0]) {
-        qdev_prop_set_drive_nofail(dev, "drive", fds[0]->bdrv);
+        qdev_prop_set_drive_nofail(dev, "drive",
+                                   blk_bs(blk_by_legacy_dinfo(fds[0])));
     }
     qdev_init_nofail(dev);
     sys = SYSBUS_FDC(dev);
diff --git a/hw/block/m25p80.c b/hw/block/m25p80.c
index 5893773..78280a8 100644
--- a/hw/block/m25p80.c
+++ b/hw/block/m25p80.c
@@ -22,6 +22,7 @@
  */
 
 #include "hw/hw.h"
+#include "sysemu/block-backend.h"
 #include "sysemu/blockdev.h"
 #include "hw/ssi.h"
 
@@ -624,9 +625,9 @@ static int m25p80_init(SSISlave *ss)
 
     dinfo = drive_get_next(IF_MTD);
 
-    if (dinfo && dinfo->bdrv) {
+    if (dinfo) {
         DB_PRINT_L(0, "Binding to IF_MTD drive\n");
-        s->bdrv = dinfo->bdrv;
+        s->bdrv = blk_bs(blk_by_legacy_dinfo(dinfo));
 
         /* FIXME: Move to late init */
         if (bdrv_read(s->bdrv, 0, s->storage, DIV_ROUND_UP(s->size,
diff --git a/hw/block/xen_disk.c b/hw/block/xen_disk.c
index 6d474b9..b571bbe 100644
--- a/hw/block/xen_disk.c
+++ b/hw/block/xen_disk.c
@@ -877,7 +877,7 @@ static int blk_connect(struct XenDevice *xendev)
     } else {
         /* setup via qemu cmdline -> already setup for us */
         xen_be_printf(&blkdev->xendev, 2, "get configured bdrv (cmdline setup)\n");
-        blkdev->bs = blkdev->dinfo->bdrv;
+        blkdev->bs = blk_bs(blk_by_legacy_dinfo(blkdev->dinfo));
         if (bdrv_is_read_only(blkdev->bs) && !readonly) {
             xen_be_printf(&blkdev->xendev, 0, "Unexpected read-only drive");
             blkdev->bs = NULL;
diff --git a/hw/cris/axis_dev88.c b/hw/cris/axis_dev88.c
index 1849338..280722d 100644
--- a/hw/cris/axis_dev88.c
+++ b/hw/cris/axis_dev88.c
@@ -30,6 +30,7 @@
 #include "hw/loader.h"
 #include "elf.h"
 #include "boot.h"
+#include "sysemu/block-backend.h"
 #include "sysemu/blockdev.h"
 #include "exec/address-spaces.h"
 #include "sysemu/qtest.h"
@@ -282,7 +283,7 @@ void axisdev88_init(MachineState *machine)
 
       /* Attach a NAND flash to CS1.  */
     nand = drive_get(IF_MTD, 0, 0);
-    nand_state.nand = nand_init(nand ? nand->bdrv : NULL,
+    nand_state.nand = nand_init(nand ? blk_bs(blk_by_legacy_dinfo(nand)) : NULL,
                                 NAND_MFR_STMICRO, 0x39);
     memory_region_init_io(&nand_state.iomem, NULL, &nand_ops, &nand_state,
                           "nand", 0x05000000);
diff --git a/hw/display/tc6393xb.c b/hw/display/tc6393xb.c
index f4011d2..62d6663 100644
--- a/hw/display/tc6393xb.c
+++ b/hw/display/tc6393xb.c
@@ -15,6 +15,7 @@
 #include "hw/block/flash.h"
 #include "ui/console.h"
 #include "ui/pixel_ops.h"
+#include "sysemu/block-backend.h"
 #include "sysemu/blockdev.h"
 
 #define IRQ_TC6393_NAND		0
@@ -576,7 +577,8 @@ TC6393xbState *tc6393xb_init(MemoryRegion *sysmem, uint32_t base, qemu_irq irq)
     s->sub_irqs = qemu_allocate_irqs(tc6393xb_sub_irq, s, TC6393XB_NR_IRQS);
 
     nand = drive_get(IF_MTD, 0, 0);
-    s->flash = nand_init(nand ? nand->bdrv : NULL, NAND_MFR_TOSHIBA, 0x76);
+    s->flash = nand_init(nand ? blk_bs(blk_by_legacy_dinfo(nand)) : NULL,
+                         NAND_MFR_TOSHIBA, 0x76);
 
     memory_region_init_io(&s->iomem, NULL, &tc6393xb_ops, s, "tc6393xb", 0x10000);
     memory_region_add_subregion(sysmem, base, &s->iomem);
diff --git a/hw/i386/pc_sysfw.c b/hw/i386/pc_sysfw.c
index 75a7ebb..6cd264a 100644
--- a/hw/i386/pc_sysfw.c
+++ b/hw/i386/pc_sysfw.c
@@ -23,6 +23,7 @@
  * THE SOFTWARE.
  */
 
+#include "sysemu/block-backend.h"
 #include "sysemu/blockdev.h"
 #include "qemu/error-report.h"
 #include "hw/sysbus.h"
@@ -118,7 +119,7 @@ static void pc_system_flash_init(MemoryRegion *rom_memory)
          (unit < FLASH_MAP_UNIT_MAX &&
           (pflash_drv = drive_get(IF_PFLASH, 0, unit)) != NULL);
          ++unit) {
-        bdrv = pflash_drv->bdrv;
+        bdrv = blk_bs(blk_by_legacy_dinfo(pflash_drv));
         size = bdrv_getlength(bdrv);
         if (size < 0) {
             fatal_errmsg = g_strdup_printf("failed to get backing file size");
diff --git a/hw/ide/piix.c b/hw/ide/piix.c
index 49e78a7..c6c256f 100644
--- a/hw/ide/piix.c
+++ b/hw/ide/piix.c
@@ -27,6 +27,7 @@
 #include <hw/i386/pc.h>
 #include <hw/pci/pci.h>
 #include <hw/isa/isa.h>
+#include "sysemu/block-backend.h"
 #include "sysemu/blockdev.h"
 #include "sysemu/sysemu.h"
 #include "sysemu/dma.h"
@@ -178,9 +179,10 @@ int pci_piix3_xen_ide_unplug(DeviceState *dev)
     for (; i < 3; i++) {
         di = drive_get_by_index(IF_IDE, i);
         if (di != NULL && !di->media_cd) {
-            DeviceState *ds = bdrv_get_attached_dev(di->bdrv);
+            BlockDriverState *bs = blk_bs(blk_by_legacy_dinfo(di));
+            DeviceState *ds = bdrv_get_attached_dev(bs);
             if (ds) {
-                bdrv_detach_dev(di->bdrv, ds);
+                bdrv_detach_dev(bs, ds);
             }
             pci_ide->bus[di->bus].ifs[di->unit].bs = NULL;
             drive_del(di);
diff --git a/hw/ide/qdev.c b/hw/ide/qdev.c
index efab95b..75e8eb3 100644
--- a/hw/ide/qdev.c
+++ b/hw/ide/qdev.c
@@ -20,6 +20,7 @@
 #include "sysemu/dma.h"
 #include "qemu/error-report.h"
 #include <hw/ide/internal.h>
+#include "sysemu/block-backend.h"
 #include "sysemu/blockdev.h"
 #include "hw/block/block.h"
 #include "sysemu/sysemu.h"
@@ -116,7 +117,8 @@ IDEDevice *ide_create_drive(IDEBus *bus, int unit, DriveInfo *drive)
 
     dev = qdev_create(&bus->qbus, drive->media_cd ? "ide-cd" : "ide-hd");
     qdev_prop_set_uint32(dev, "unit", unit);
-    qdev_prop_set_drive_nofail(dev, "drive", drive->bdrv);
+    qdev_prop_set_drive_nofail(dev, "drive",
+                               blk_bs(blk_by_legacy_dinfo(drive)));
     qdev_init_nofail(dev);
     return DO_UPCAST(IDEDevice, qdev, dev);
 }
diff --git a/hw/isa/pc87312.c b/hw/isa/pc87312.c
index 9327c53..b691a0c 100644
--- a/hw/isa/pc87312.c
+++ b/hw/isa/pc87312.c
@@ -25,6 +25,7 @@
 
 #include "hw/isa/pc87312.h"
 #include "qemu/error-report.h"
+#include "sysemu/block-backend.h"
 #include "sysemu/blockdev.h"
 #include "sysemu/sysemu.h"
 #include "sysemu/char.h"
@@ -320,11 +321,13 @@ static void pc87312_realize(DeviceState *dev, Error **errp)
         qdev_prop_set_uint32(d, "irq", 6);
         drive = drive_get(IF_FLOPPY, 0, 0);
         if (drive != NULL) {
-            qdev_prop_set_drive_nofail(d, "driveA", drive->bdrv);
+            qdev_prop_set_drive_nofail(d, "driveA",
+                                       blk_bs(blk_by_legacy_dinfo(drive)));
         }
         drive = drive_get(IF_FLOPPY, 0, 1);
         if (drive != NULL) {
-            qdev_prop_set_drive_nofail(d, "driveB", drive->bdrv);
+            qdev_prop_set_drive_nofail(d, "driveB",
+                                       blk_bs(blk_by_legacy_dinfo(drive)));
         }
         qdev_init_nofail(d);
         s->fdc.dev = isa;
diff --git a/hw/lm32/lm32_boards.c b/hw/lm32/lm32_boards.c
index 0e01340..17c5610 100644
--- a/hw/lm32/lm32_boards.c
+++ b/hw/lm32/lm32_boards.c
@@ -23,6 +23,7 @@
 #include "hw/devices.h"
 #include "hw/boards.h"
 #include "hw/loader.h"
+#include "sysemu/block-backend.h"
 #include "sysemu/blockdev.h"
 #include "elf.h"
 #include "lm32_hwsetup.h"
@@ -118,9 +119,9 @@ static void lm32_evr_init(MachineState *machine)
     dinfo = drive_get(IF_PFLASH, 0, 0);
     /* Spansion S29NS128P */
     pflash_cfi02_register(flash_base, NULL, "lm32_evr.flash", flash_size,
-                          dinfo ? dinfo->bdrv : NULL, flash_sector_size,
-                          flash_size / flash_sector_size, 1, 2,
-                          0x01, 0x7e, 0x43, 0x00, 0x555, 0x2aa, 1);
+                          dinfo ? blk_bs(blk_by_legacy_dinfo(dinfo)) : NULL,
+                          flash_sector_size, flash_size / flash_sector_size,
+                          1, 2, 0x01, 0x7e, 0x43, 0x00, 0x555, 0x2aa, 1);
 
     /* create irq lines */
     cpu_irq = qemu_allocate_irqs(cpu_irq_handler, cpu, 1);
@@ -220,9 +221,9 @@ static void lm32_uclinux_init(MachineState *machine)
     dinfo = drive_get(IF_PFLASH, 0, 0);
     /* Spansion S29NS128P */
     pflash_cfi02_register(flash_base, NULL, "lm32_uclinux.flash", flash_size,
-                          dinfo ? dinfo->bdrv : NULL, flash_sector_size,
-                          flash_size / flash_sector_size, 1, 2,
-                          0x01, 0x7e, 0x43, 0x00, 0x555, 0x2aa, 1);
+                          dinfo ? blk_bs(blk_by_legacy_dinfo(dinfo)) : NULL,
+                          flash_sector_size, flash_size / flash_sector_size,
+                          1, 2, 0x01, 0x7e, 0x43, 0x00, 0x555, 0x2aa, 1);
 
     /* create irq lines */
     cpu_irq = qemu_allocate_irqs(cpu_irq_handler, env, 1);
diff --git a/hw/lm32/milkymist.c b/hw/lm32/milkymist.c
index 81c3933..904b9c0 100644
--- a/hw/lm32/milkymist.c
+++ b/hw/lm32/milkymist.c
@@ -26,6 +26,7 @@
 #include "hw/boards.h"
 #include "hw/loader.h"
 #include "elf.h"
+#include "sysemu/block-backend.h"
 #include "sysemu/blockdev.h"
 #include "milkymist-hw.h"
 #include "lm32.h"
@@ -125,9 +126,9 @@ milkymist_init(MachineState *machine)
     dinfo = drive_get(IF_PFLASH, 0, 0);
     /* Numonyx JS28F256J3F105 */
     pflash_cfi01_register(flash_base, NULL, "milkymist.flash", flash_size,
-                          dinfo ? dinfo->bdrv : NULL, flash_sector_size,
-                          flash_size / flash_sector_size, 2,
-                          0x00, 0x89, 0x00, 0x1d, 1);
+                          dinfo ? blk_bs(blk_by_legacy_dinfo(dinfo)) : NULL,
+                          flash_sector_size, flash_size / flash_sector_size,
+                          2, 0x00, 0x89, 0x00, 0x1d, 1);
 
     /* create irq lines */
     cpu_irq = qemu_allocate_irqs(cpu_irq_handler, cpu, 1);
diff --git a/hw/microblaze/petalogix_ml605_mmu.c b/hw/microblaze/petalogix_ml605_mmu.c
index 6843abf..2974791 100644
--- a/hw/microblaze/petalogix_ml605_mmu.c
+++ b/hw/microblaze/petalogix_ml605_mmu.c
@@ -32,6 +32,7 @@
 #include "sysemu/sysemu.h"
 #include "hw/devices.h"
 #include "hw/boards.h"
+#include "sysemu/block-backend.h"
 #include "sysemu/blockdev.h"
 #include "hw/char/serial.h"
 #include "exec/address-spaces.h"
@@ -112,8 +113,8 @@ petalogix_ml605_init(MachineState *machine)
      * 10th paremeter 0 means little-endian */
     pflash_cfi01_register(FLASH_BASEADDR,
                           NULL, "petalogix_ml605.flash", FLASH_SIZE,
-                          dinfo ? dinfo->bdrv : NULL, (64 * 1024),
-                          FLASH_SIZE >> 16,
+                          dinfo ? blk_bs(blk_by_legacy_dinfo(dinfo)) : NULL,
+                          (64 * 1024), FLASH_SIZE >> 16,
                           2, 0x89, 0x18, 0x0000, 0x0, 0);
 
 
diff --git a/hw/microblaze/petalogix_s3adsp1800_mmu.c b/hw/microblaze/petalogix_s3adsp1800_mmu.c
index 49dc6d1..a69301f 100644
--- a/hw/microblaze/petalogix_s3adsp1800_mmu.c
+++ b/hw/microblaze/petalogix_s3adsp1800_mmu.c
@@ -30,6 +30,7 @@
 #include "sysemu/sysemu.h"
 #include "hw/devices.h"
 #include "hw/boards.h"
+#include "sysemu/block-backend.h"
 #include "sysemu/blockdev.h"
 #include "exec/address-spaces.h"
 
@@ -92,8 +93,8 @@ petalogix_s3adsp1800_init(MachineState *machine)
     dinfo = drive_get(IF_PFLASH, 0, 0);
     pflash_cfi01_register(FLASH_BASEADDR,
                           NULL, "petalogix_s3adsp1800.flash", FLASH_SIZE,
-                          dinfo ? dinfo->bdrv : NULL, (64 * 1024),
-                          FLASH_SIZE >> 16,
+                          dinfo ? blk_bs(blk_by_legacy_dinfo(dinfo)) : NULL,
+                          (64 * 1024), FLASH_SIZE >> 16,
                           1, 0x89, 0x18, 0x0000, 0x0, 1);
 
     dev = qdev_create(NULL, "xlnx.xps-intc");
diff --git a/hw/mips/mips_malta.c b/hw/mips/mips_malta.c
index cfb60af..9f84ad6 100644
--- a/hw/mips/mips_malta.c
+++ b/hw/mips/mips_malta.c
@@ -44,6 +44,7 @@
 #include "elf.h"
 #include "hw/timer/mc146818rtc.h"
 #include "hw/timer/i8254.h"
+#include "sysemu/block-backend.h"
 #include "sysemu/blockdev.h"
 #include "exec/address-spaces.h"
 #include "hw/sysbus.h"             /* SysBusDevice */
@@ -1035,7 +1036,8 @@ void mips_malta_init(MachineState *machine)
     }
 #endif
     fl = pflash_cfi01_register(FLASH_ADDRESS, NULL, "mips_malta.bios",
-                               BIOS_SIZE, dinfo ? dinfo->bdrv : NULL,
+                               BIOS_SIZE,
+                               dinfo ? blk_bs(blk_by_legacy_dinfo(dinfo)) : NULL,
                                65536, fl_sectors,
                                4, 0x0000, 0x0000, 0x0000, 0x0000, be);
     bios = pflash_cfi01_get_memory(fl);
diff --git a/hw/mips/mips_r4k.c b/hw/mips/mips_r4k.c
index 7120293..6fd69b9 100644
--- a/hw/mips/mips_r4k.c
+++ b/hw/mips/mips_r4k.c
@@ -24,6 +24,7 @@
 #include "elf.h"
 #include "hw/timer/mc146818rtc.h"
 #include "hw/timer/i8254.h"
+#include "sysemu/block-backend.h"
 #include "sysemu/blockdev.h"
 #include "exec/address-spaces.h"
 #include "sysemu/qtest.h"
@@ -240,8 +241,8 @@ void mips_r4k_init(MachineState *machine)
     } else if ((dinfo = drive_get(IF_PFLASH, 0, 0)) != NULL) {
         uint32_t mips_rom = 0x00400000;
         if (!pflash_cfi01_register(0x1fc00000, NULL, "mips_r4k.bios", mips_rom,
-                                   dinfo->bdrv, sector_len,
-                                   mips_rom / sector_len,
+                                   blk_bs(blk_by_legacy_dinfo(dinfo)),
+                                   sector_len, mips_rom / sector_len,
                                    4, 0, 0, 0, 0, be)) {
             fprintf(stderr, "qemu: Error registering flash memory.\n");
 	}
diff --git a/hw/pci/pci-hotplug-old.c b/hw/pci/pci-hotplug-old.c
index cf2caeb..e4d51de 100644
--- a/hw/pci/pci-hotplug-old.c
+++ b/hw/pci/pci-hotplug-old.c
@@ -33,6 +33,7 @@
 #include "hw/scsi/scsi.h"
 #include "hw/virtio/virtio-blk.h"
 #include "qemu/config-file.h"
+#include "sysemu/block-backend.h"
 #include "sysemu/blockdev.h"
 #include "qapi/error.h"
 
@@ -126,8 +127,9 @@ static int scsi_hot_add(Monitor *mon, DeviceState *adapter,
      */
     dinfo->unit = qemu_opt_get_number(dinfo->opts, "unit", -1);
     dinfo->bus = scsibus->busnr;
-    scsidev = scsi_bus_legacy_add_drive(scsibus, dinfo->bdrv, dinfo->unit,
-                                        false, -1, NULL, NULL);
+    scsidev = scsi_bus_legacy_add_drive(scsibus,
+                                        blk_bs(blk_by_legacy_dinfo(dinfo)),
+                                        dinfo->unit, false, -1, NULL, NULL);
     if (!scsidev) {
         return -1;
     }
@@ -247,7 +249,8 @@ static PCIDevice *qemu_pci_hot_add_storage(Monitor *mon,
             return NULL;
         }
         dev = pci_create(bus, devfn, "virtio-blk-pci");
-        if (qdev_prop_set_drive(&dev->qdev, "drive", dinfo->bdrv) < 0) {
+        if (qdev_prop_set_drive(&dev->qdev, "drive",
+                                blk_bs(blk_by_legacy_dinfo(dinfo))) < 0) {
             object_unparent(OBJECT(dev));
             dev = NULL;
             break;
diff --git a/hw/ppc/ppc405_boards.c b/hw/ppc/ppc405_boards.c
index 11d3379..7ff5ee5 100644
--- a/hw/ppc/ppc405_boards.c
+++ b/hw/ppc/ppc405_boards.c
@@ -33,6 +33,7 @@
 #include "qemu/log.h"
 #include "qemu/error-report.h"
 #include "hw/loader.h"
+#include "sysemu/block-backend.h"
 #include "sysemu/blockdev.h"
 #include "exec/address-spaces.h"
 
@@ -225,17 +226,19 @@ static void ref405ep_init(MachineState *machine)
 #ifdef USE_FLASH_BIOS
     dinfo = drive_get(IF_PFLASH, 0, fl_idx);
     if (dinfo) {
-        bios_size = bdrv_getlength(dinfo->bdrv);
+        BlockDriverState *bs = blk_bs(blk_by_legacy_dinfo(dinfo));
+
+        bios_size = bdrv_getlength(bs);
         fl_sectors = (bios_size + 65535) >> 16;
 #ifdef DEBUG_BOARD_INIT
         printf("Register parallel flash %d size %lx"
                " at addr %lx '%s' %d\n",
                fl_idx, bios_size, -bios_size,
-               bdrv_get_device_name(dinfo->bdrv), fl_sectors);
+               bdrv_get_device_name(bs), fl_sectors);
 #endif
         pflash_cfi02_register((uint32_t)(-bios_size),
                               NULL, "ef405ep.bios", bios_size,
-                              dinfo->bdrv, 65536, fl_sectors, 1,
+                              bs, 65536, fl_sectors, 1,
                               2, 0x0001, 0x22DA, 0x0000, 0x0000, 0x555, 0x2AA,
                               1);
         fl_idx++;
@@ -547,7 +550,9 @@ static void taihu_405ep_init(MachineState *machine)
 #if defined(USE_FLASH_BIOS)
     dinfo = drive_get(IF_PFLASH, 0, fl_idx);
     if (dinfo) {
-        bios_size = bdrv_getlength(dinfo->bdrv);
+        BlockDriverState *bs = blk_bs(blk_by_legacy_dinfo(dinfo));
+
+        bios_size = bdrv_getlength(bs);
         /* XXX: should check that size is 2MB */
         //        bios_size = 2 * 1024 * 1024;
         fl_sectors = (bios_size + 65535) >> 16;
@@ -555,11 +560,11 @@ static void taihu_405ep_init(MachineState *machine)
         printf("Register parallel flash %d size %lx"
                " at addr %lx '%s' %d\n",
                fl_idx, bios_size, -bios_size,
-               bdrv_get_device_name(dinfo->bdrv), fl_sectors);
+               bdrv_get_device_name(bs), fl_sectors);
 #endif
         pflash_cfi02_register((uint32_t)(-bios_size),
                               NULL, "taihu_405ep.bios", bios_size,
-                              dinfo->bdrv, 65536, fl_sectors, 1,
+                              bs, 65536, fl_sectors, 1,
                               4, 0x0001, 0x22DA, 0x0000, 0x0000, 0x555, 0x2AA,
                               1);
         fl_idx++;
@@ -593,7 +598,9 @@ static void taihu_405ep_init(MachineState *machine)
     /* Register Linux flash */
     dinfo = drive_get(IF_PFLASH, 0, fl_idx);
     if (dinfo) {
-        bios_size = bdrv_getlength(dinfo->bdrv);
+        BlockDriverState *bs = blk_bs(blk_by_legacy_dinfo(dinfo));
+
+        bios_size = bdrv_getlength(bs);
         /* XXX: should check that size is 32MB */
         bios_size = 32 * 1024 * 1024;
         fl_sectors = (bios_size + 65535) >> 16;
@@ -601,10 +608,10 @@ static void taihu_405ep_init(MachineState *machine)
         printf("Register parallel flash %d size %lx"
                " at addr " TARGET_FMT_lx " '%s'\n",
                fl_idx, bios_size, (target_ulong)0xfc000000,
-               bdrv_get_device_name(dinfo->bdrv));
+               bdrv_get_device_name(bs));
 #endif
         pflash_cfi02_register(0xfc000000, NULL, "taihu_405ep.flash", bios_size,
-                              dinfo->bdrv, 65536, fl_sectors, 1,
+                              bs, 65536, fl_sectors, 1,
                               4, 0x0001, 0x22DA, 0x0000, 0x0000, 0x555, 0x2AA,
                               1);
         fl_idx++;
diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
index 2ab4460..a577812 100644
--- a/hw/ppc/spapr.c
+++ b/hw/ppc/spapr.c
@@ -29,6 +29,7 @@
 #include "hw/fw-path-provider.h"
 #include "elf.h"
 #include "net/net.h"
+#include "sysemu/block-backend.h"
 #include "sysemu/blockdev.h"
 #include "sysemu/cpus.h"
 #include "sysemu/kvm.h"
@@ -925,7 +926,8 @@ static void spapr_create_nvram(sPAPREnvironment *spapr)
     DriveInfo *dinfo = drive_get(IF_PFLASH, 0, 0);
 
     if (dinfo) {
-        qdev_prop_set_drive_nofail(dev, "drive", dinfo->bdrv);
+        qdev_prop_set_drive_nofail(dev, "drive",
+                                   blk_bs(blk_by_legacy_dinfo(dinfo)));
     }
 
     qdev_init_nofail(dev);
diff --git a/hw/ppc/virtex_ml507.c b/hw/ppc/virtex_ml507.c
index 0de5148..a0ce447 100644
--- a/hw/ppc/virtex_ml507.c
+++ b/hw/ppc/virtex_ml507.c
@@ -39,6 +39,7 @@
 #include "hw/ppc/ppc4xx.h"
 #include "ppc405.h"
 
+#include "sysemu/block-backend.h"
 #include "sysemu/blockdev.h"
 #include "qapi/qmp/qerror.h"
 
@@ -227,8 +228,8 @@ static void virtex_init(MachineState *machine)
 
     dinfo = drive_get(IF_PFLASH, 0, 0);
     pflash_cfi01_register(PFLASH_BASEADDR, NULL, "virtex.flash", FLASH_SIZE,
-                          dinfo ? dinfo->bdrv : NULL, (64 * 1024),
-                          FLASH_SIZE >> 16,
+                          dinfo ? blk_bs(blk_by_legacy_dinfo(dinfo)) : NULL,
+                          (64 * 1024), FLASH_SIZE >> 16,
                           1, 0x89, 0x18, 0x0000, 0x0, 1);
 
     cpu_irq = (qemu_irq *) &env->irq_inputs[PPC40x_INPUT_INT];
diff --git a/hw/scsi/scsi-bus.c b/hw/scsi/scsi-bus.c
index 954c607..f5156ae 100644
--- a/hw/scsi/scsi-bus.c
+++ b/hw/scsi/scsi-bus.c
@@ -3,6 +3,7 @@
 #include "hw/scsi/scsi.h"
 #include "block/scsi.h"
 #include "hw/qdev.h"
+#include "sysemu/block-backend.h"
 #include "sysemu/blockdev.h"
 #include "trace.h"
 #include "sysemu/dma.h"
@@ -267,8 +268,8 @@ void scsi_bus_legacy_handle_cmdline(SCSIBus *bus, Error **errp)
             continue;
         }
         qemu_opts_loc_restore(dinfo->opts);
-        scsi_bus_legacy_add_drive(bus, dinfo->bdrv, unit, false, -1, NULL,
-                                  &err);
+        scsi_bus_legacy_add_drive(bus, blk_bs(blk_by_legacy_dinfo(dinfo)),
+                                  unit, false, -1, NULL, &err);
         if (err != NULL) {
             error_report("%s", error_get_pretty(err));
             error_propagate(errp, err);
diff --git a/hw/sd/milkymist-memcard.c b/hw/sd/milkymist-memcard.c
index 2a40f92..501aa3a 100644
--- a/hw/sd/milkymist-memcard.c
+++ b/hw/sd/milkymist-memcard.c
@@ -26,6 +26,7 @@
 #include "sysemu/sysemu.h"
 #include "trace.h"
 #include "qemu/error-report.h"
+#include "sysemu/block-backend.h"
 #include "sysemu/blockdev.h"
 #include "hw/sd.h"
 
@@ -252,14 +253,16 @@ static int milkymist_memcard_init(SysBusDevice *dev)
 {
     MilkymistMemcardState *s = MILKYMIST_MEMCARD(dev);
     DriveInfo *dinfo;
+    BlockDriverState *bs;
 
     dinfo = drive_get_next(IF_SD);
-    s->card = sd_init(dinfo ? dinfo->bdrv : NULL, false);
+    bs = dinfo ? blk_bs(blk_by_legacy_dinfo(dinfo)) : NULL;
+    s->card = sd_init(bs, false);
     if (s->card == NULL) {
         return -1;
     }
 
-    s->enabled = dinfo ? bdrv_is_inserted(dinfo->bdrv) : 0;
+    s->enabled = bs && bdrv_is_inserted(bs);
 
     memory_region_init_io(&s->regs_region, OBJECT(s), &memcard_mmio_ops, s,
             "milkymist-memcard", R_MAX * 4);
diff --git a/hw/sd/pl181.c b/hw/sd/pl181.c
index 462558b..0501d40 100644
--- a/hw/sd/pl181.c
+++ b/hw/sd/pl181.c
@@ -7,6 +7,7 @@
  * This code is licensed under the GPL.
  */
 
+#include "sysemu/block-backend.h"
 #include "sysemu/blockdev.h"
 #include "hw/sysbus.h"
 #include "hw/sd.h"
@@ -490,7 +491,7 @@ static int pl181_init(SysBusDevice *sbd)
     sysbus_init_irq(sbd, &s->irq[1]);
     qdev_init_gpio_out(dev, s->cardstatus, 2);
     dinfo = drive_get_next(IF_SD);
-    s->card = sd_init(dinfo ? dinfo->bdrv : NULL, false);
+    s->card = sd_init(dinfo ? blk_bs(blk_by_legacy_dinfo(dinfo)) : NULL, false);
     if (s->card == NULL) {
         return -1;
     }
diff --git a/hw/sd/sdhci.c b/hw/sd/sdhci.c
index f9fe700..0b7d754 100644
--- a/hw/sd/sdhci.c
+++ b/hw/sd/sdhci.c
@@ -23,6 +23,7 @@
  */
 
 #include "hw/hw.h"
+#include "sysemu/block-backend.h"
 #include "sysemu/blockdev.h"
 #include "sysemu/dma.h"
 #include "qemu/timer.h"
@@ -1165,7 +1166,7 @@ static void sdhci_initfn(Object *obj)
     DriveInfo *di;
 
     di = drive_get_next(IF_SD);
-    s->card = sd_init(di ? di->bdrv : NULL, false);
+    s->card = sd_init(di ? blk_bs(blk_by_legacy_dinfo(di)) : NULL, false);
     if (s->card == NULL) {
         exit(1);
     }
diff --git a/hw/sd/ssi-sd.c b/hw/sd/ssi-sd.c
index b012e57..6ae99e4 100644
--- a/hw/sd/ssi-sd.c
+++ b/hw/sd/ssi-sd.c
@@ -10,6 +10,7 @@
  * GNU GPL, version 2 or (at your option) any later version.
  */
 
+#include "sysemu/block-backend.h"
 #include "sysemu/blockdev.h"
 #include "hw/ssi.h"
 #include "hw/sd.h"
@@ -255,7 +256,7 @@ static int ssi_sd_init(SSISlave *d)
 
     s->mode = SSI_SD_CMD;
     dinfo = drive_get_next(IF_SD);
-    s->sd = sd_init(dinfo ? dinfo->bdrv : NULL, true);
+    s->sd = sd_init(dinfo ? blk_bs(blk_by_legacy_dinfo(dinfo)) : NULL, true);
     if (s->sd == NULL) {
         return -1;
     }
diff --git a/hw/sh4/r2d.c b/hw/sh4/r2d.c
index 95c0246..d652619 100644
--- a/hw/sh4/r2d.c
+++ b/hw/sh4/r2d.c
@@ -36,6 +36,7 @@
 #include "hw/loader.h"
 #include "hw/usb.h"
 #include "hw/block/flash.h"
+#include "sysemu/block-backend.h"
 #include "sysemu/blockdev.h"
 #include "exec/address-spaces.h"
 
@@ -290,8 +291,8 @@ static void r2d_init(MachineState *machine)
     /* onboard flash memory */
     dinfo = drive_get(IF_PFLASH, 0, 0);
     pflash_cfi02_register(0x0, NULL, "r2d.flash", FLASH_SIZE,
-                          dinfo ? dinfo->bdrv : NULL, (16 * 1024),
-                          FLASH_SIZE >> 16,
+                          dinfo ? blk_bs(blk_by_legacy_dinfo(dinfo)) : NULL,
+                          (16 * 1024), FLASH_SIZE >> 16,
                           1, 4, 0x0000, 0x0000, 0x0000, 0x0000,
                           0x555, 0x2aa, 0);
 
diff --git a/hw/usb/dev-storage.c b/hw/usb/dev-storage.c
index eb75f6a..0d6e7c6 100644
--- a/hw/usb/dev-storage.c
+++ b/hw/usb/dev-storage.c
@@ -16,6 +16,7 @@
 #include "ui/console.h"
 #include "monitor/monitor.h"
 #include "sysemu/sysemu.h"
+#include "sysemu/block-backend.h"
 #include "sysemu/blockdev.h"
 
 //#define DEBUG_MSD
@@ -704,7 +705,8 @@ static USBDevice *usb_msd_init(USBBus *bus, const char *filename)
     if (!dev) {
         return NULL;
     }
-    if (qdev_prop_set_drive(&dev->qdev, "drive", dinfo->bdrv) < 0) {
+    if (qdev_prop_set_drive(&dev->qdev, "drive",
+                            blk_bs(blk_by_legacy_dinfo(dinfo))) < 0) {
         object_unparent(OBJECT(dev));
         return NULL;
     }
diff --git a/hw/xtensa/xtfpga.c b/hw/xtensa/xtfpga.c
index a2dff5a..7c4719e 100644
--- a/hw/xtensa/xtfpga.c
+++ b/hw/xtensa/xtfpga.c
@@ -35,6 +35,7 @@
 #include "net/net.h"
 #include "hw/sysbus.h"
 #include "hw/block/flash.h"
+#include "sysemu/block-backend.h"
 #include "sysemu/blockdev.h"
 #include "sysemu/char.h"
 #include "sysemu/device_tree.h"
@@ -229,7 +230,8 @@ static void lx_init(const LxBoardDesc *board, MachineState *machine)
     if (dinfo) {
         flash = pflash_cfi01_register(board->flash_base,
                 NULL, "lx60.io.flash", board->flash_size,
-                dinfo->bdrv, board->flash_sector_size,
+                blk_bs(blk_by_legacy_dinfo(dinfo)),
+                board->flash_sector_size,
                 board->flash_size / board->flash_sector_size,
                 4, 0x0000, 0x0000, 0x0000, 0x0000, be);
         if (flash == NULL) {
diff --git a/include/sysemu/blockdev.h b/include/sysemu/blockdev.h
index 2ed297b..75f6ac6 100644
--- a/include/sysemu/blockdev.h
+++ b/include/sysemu/blockdev.h
@@ -30,7 +30,6 @@ typedef enum {
 } BlockInterfaceType;
 
 struct DriveInfo {
-    BlockDriverState *bdrv;
     char *id;
     const char *devaddr;
     BlockInterfaceType type;
-- 
1.9.3

^ permalink raw reply related	[flat|nested] 56+ messages in thread

* [Qemu-devel] [PATCH v2 11/23] block: Rename BlockDriverAIOCB* to BlockAIOCB*
  2014-09-13 15:00 [Qemu-devel] [PATCH v2 00/23] Split BlockBackend off BDS with an axe Markus Armbruster
                   ` (9 preceding siblings ...)
  2014-09-13 15:00 ` [Qemu-devel] [PATCH v2 10/23] block: Eliminate DriveInfo member bdrv, use blk_by_legacy_dinfo() Markus Armbruster
@ 2014-09-13 15:00 ` Markus Armbruster
  2014-09-13 15:00 ` [Qemu-devel] [PATCH v2 12/23] virtio-blk: Drop redundant VirtIOBlock member conf Markus Armbruster
                   ` (12 subsequent siblings)
  23 siblings, 0 replies; 56+ messages in thread
From: Markus Armbruster @ 2014-09-13 15:00 UTC (permalink / raw)
  To: qemu-devel; +Cc: kwolf, benoit.canet, stefanha

I'll use BlockDriverAIOCB with block backends shortly, and the name is
going to fit badly there.  It's a block layer thing anyway, not just a
block driver thing.

Signed-off-by: Markus Armbruster <armbru@redhat.com>
---
 block-migration.c           |   2 +-
 block.c                     | 151 ++++++++++++++++++++++----------------------
 block/archipelago.c         |  30 ++++-----
 block/backup.c              |   2 +-
 block/blkdebug.c            |  22 +++----
 block/blkverify.c           |  20 +++---
 block/commit.c              |   2 +-
 block/curl.c                |   8 +--
 block/iscsi.c               |   8 +--
 block/linux-aio.c           |   8 +--
 block/mirror.c              |   6 +-
 block/qed-gencb.c           |   4 +-
 block/qed-table.c           |  10 +--
 block/qed.c                 |  46 +++++++-------
 block/qed.h                 |  12 ++--
 block/quorum.c              |  38 +++++------
 block/raw-aio.h             |   8 +--
 block/raw-posix.c           |  32 +++++-----
 block/raw-win32.c           |  16 ++---
 block/raw_bsd.c             |   8 +--
 block/rbd.c                 |  58 ++++++++---------
 block/sheepdog.c            |   4 +-
 block/stream.c              |   2 +-
 block/win32-aio.c           |   8 +--
 blockjob.c                  |   4 +-
 dma-helpers.c               |  24 +++----
 hw/block/nvme.h             |   2 +-
 hw/ide/ahci.c               |   2 +-
 hw/ide/ahci.h               |   2 +-
 hw/ide/core.c               |  12 ++--
 hw/ide/internal.h           |  12 ++--
 hw/ide/macio.c              |   2 +-
 hw/ide/pci.c                |   2 +-
 hw/ide/pci.h                |   2 +-
 hw/ppc/mac.h                |   2 +-
 hw/scsi/scsi-generic.c      |   2 +-
 include/block/aio.h         |  12 ++--
 include/block/block.h       |  36 +++++------
 include/block/block_int.h   |  30 ++++-----
 include/block/blockjob.h    |   4 +-
 include/block/thread-pool.h |   4 +-
 include/hw/scsi/scsi.h      |   2 +-
 include/monitor/monitor.h   |   4 +-
 include/sysemu/dma.h        |  26 ++++----
 monitor.c                   |   6 +-
 tests/test-thread-pool.c    |   2 +-
 thread-pool.c               |   8 +--
 47 files changed, 353 insertions(+), 354 deletions(-)

diff --git a/block-migration.c b/block-migration.c
index da30e93..08db01a 100644
--- a/block-migration.c
+++ b/block-migration.c
@@ -72,7 +72,7 @@ typedef struct BlkMigBlock {
     int nr_sectors;
     struct iovec iov;
     QEMUIOVector qiov;
-    BlockDriverAIOCB *aiocb;
+    BlockAIOCB *aiocb;
 
     /* Protected by block migration lock.  */
     int ret;
diff --git a/block.c b/block.c
index f59dade..9c6d467 100644
--- a/block.c
+++ b/block.c
@@ -61,12 +61,12 @@ struct BdrvDirtyBitmap {
 #define COROUTINE_POOL_RESERVATION 64 /* number of coroutines to reserve */
 
 static void bdrv_dev_change_media_cb(BlockDriverState *bs, bool load);
-static BlockDriverAIOCB *bdrv_aio_readv_em(BlockDriverState *bs,
+static BlockAIOCB *bdrv_aio_readv_em(BlockDriverState *bs,
         int64_t sector_num, QEMUIOVector *qiov, int nb_sectors,
-        BlockDriverCompletionFunc *cb, void *opaque);
-static BlockDriverAIOCB *bdrv_aio_writev_em(BlockDriverState *bs,
+        BlockCompletionFunc *cb, void *opaque);
+static BlockAIOCB *bdrv_aio_writev_em(BlockDriverState *bs,
         int64_t sector_num, QEMUIOVector *qiov, int nb_sectors,
-        BlockDriverCompletionFunc *cb, void *opaque);
+        BlockCompletionFunc *cb, void *opaque);
 static int coroutine_fn bdrv_co_readv_em(BlockDriverState *bs,
                                          int64_t sector_num, int nb_sectors,
                                          QEMUIOVector *iov);
@@ -79,14 +79,14 @@ static int coroutine_fn bdrv_co_do_preadv(BlockDriverState *bs,
 static int coroutine_fn bdrv_co_do_pwritev(BlockDriverState *bs,
     int64_t offset, unsigned int bytes, QEMUIOVector *qiov,
     BdrvRequestFlags flags);
-static BlockDriverAIOCB *bdrv_co_aio_rw_vector(BlockDriverState *bs,
-                                               int64_t sector_num,
-                                               QEMUIOVector *qiov,
-                                               int nb_sectors,
-                                               BdrvRequestFlags flags,
-                                               BlockDriverCompletionFunc *cb,
-                                               void *opaque,
-                                               bool is_write);
+static BlockAIOCB *bdrv_co_aio_rw_vector(BlockDriverState *bs,
+                                         int64_t sector_num,
+                                         QEMUIOVector *qiov,
+                                         int nb_sectors,
+                                         BdrvRequestFlags flags,
+                                         BlockCompletionFunc *cb,
+                                         void *opaque,
+                                         bool is_write);
 static void coroutine_fn bdrv_co_do_rw(void *opaque);
 static int coroutine_fn bdrv_co_do_write_zeroes(BlockDriverState *bs,
     int64_t sector_num, int nb_sectors, BdrvRequestFlags flags);
@@ -4395,9 +4395,9 @@ int bdrv_get_backing_file_depth(BlockDriverState *bs)
 /**************************************************************/
 /* async I/Os */
 
-BlockDriverAIOCB *bdrv_aio_readv(BlockDriverState *bs, int64_t sector_num,
-                                 QEMUIOVector *qiov, int nb_sectors,
-                                 BlockDriverCompletionFunc *cb, void *opaque)
+BlockAIOCB *bdrv_aio_readv(BlockDriverState *bs, int64_t sector_num,
+                           QEMUIOVector *qiov, int nb_sectors,
+                           BlockCompletionFunc *cb, void *opaque)
 {
     trace_bdrv_aio_readv(bs, sector_num, nb_sectors, opaque);
 
@@ -4405,9 +4405,9 @@ BlockDriverAIOCB *bdrv_aio_readv(BlockDriverState *bs, int64_t sector_num,
                                  cb, opaque, false);
 }
 
-BlockDriverAIOCB *bdrv_aio_writev(BlockDriverState *bs, int64_t sector_num,
-                                  QEMUIOVector *qiov, int nb_sectors,
-                                  BlockDriverCompletionFunc *cb, void *opaque)
+BlockAIOCB *bdrv_aio_writev(BlockDriverState *bs, int64_t sector_num,
+                            QEMUIOVector *qiov, int nb_sectors,
+                            BlockCompletionFunc *cb, void *opaque)
 {
     trace_bdrv_aio_writev(bs, sector_num, nb_sectors, opaque);
 
@@ -4415,9 +4415,9 @@ BlockDriverAIOCB *bdrv_aio_writev(BlockDriverState *bs, int64_t sector_num,
                                  cb, opaque, true);
 }
 
-BlockDriverAIOCB *bdrv_aio_write_zeroes(BlockDriverState *bs,
+BlockAIOCB *bdrv_aio_write_zeroes(BlockDriverState *bs,
         int64_t sector_num, int nb_sectors, BdrvRequestFlags flags,
-        BlockDriverCompletionFunc *cb, void *opaque)
+        BlockCompletionFunc *cb, void *opaque)
 {
     trace_bdrv_aio_write_zeroes(bs, sector_num, nb_sectors, flags, opaque);
 
@@ -4432,7 +4432,7 @@ typedef struct MultiwriteCB {
     int num_requests;
     int num_callbacks;
     struct {
-        BlockDriverCompletionFunc *cb;
+        BlockCompletionFunc *cb;
         void *opaque;
         QEMUIOVector *free_qiov;
     } callbacks[];
@@ -4609,7 +4609,7 @@ int bdrv_aio_multiwrite(BlockDriverState *bs, BlockRequest *reqs, int num_reqs)
     return 0;
 }
 
-void bdrv_aio_cancel(BlockDriverAIOCB *acb)
+void bdrv_aio_cancel(BlockAIOCB *acb)
 {
     acb->aiocb_info->cancel(acb);
 }
@@ -4617,33 +4617,32 @@ void bdrv_aio_cancel(BlockDriverAIOCB *acb)
 /**************************************************************/
 /* async block device emulation */
 
-typedef struct BlockDriverAIOCBSync {
-    BlockDriverAIOCB common;
+typedef struct BlockAIOCBSync {
+    BlockAIOCB common;
     QEMUBH *bh;
     int ret;
     /* vector translation state */
     QEMUIOVector *qiov;
     uint8_t *bounce;
     int is_write;
-} BlockDriverAIOCBSync;
+} BlockAIOCBSync;
 
-static void bdrv_aio_cancel_em(BlockDriverAIOCB *blockacb)
+static void bdrv_aio_cancel_em(BlockAIOCB *blockacb)
 {
-    BlockDriverAIOCBSync *acb =
-        container_of(blockacb, BlockDriverAIOCBSync, common);
+    BlockAIOCBSync *acb = container_of(blockacb, BlockAIOCBSync, common);
     qemu_bh_delete(acb->bh);
     acb->bh = NULL;
     qemu_aio_release(acb);
 }
 
 static const AIOCBInfo bdrv_em_aiocb_info = {
-    .aiocb_size         = sizeof(BlockDriverAIOCBSync),
+    .aiocb_size         = sizeof(BlockAIOCBSync),
     .cancel             = bdrv_aio_cancel_em,
 };
 
 static void bdrv_aio_bh_cb(void *opaque)
 {
-    BlockDriverAIOCBSync *acb = opaque;
+    BlockAIOCBSync *acb = opaque;
 
     if (!acb->is_write && acb->ret >= 0) {
         qemu_iovec_from_buf(acb->qiov, 0, acb->bounce, acb->qiov->size);
@@ -4655,16 +4654,16 @@ static void bdrv_aio_bh_cb(void *opaque)
     qemu_aio_release(acb);
 }
 
-static BlockDriverAIOCB *bdrv_aio_rw_vector(BlockDriverState *bs,
-                                            int64_t sector_num,
-                                            QEMUIOVector *qiov,
-                                            int nb_sectors,
-                                            BlockDriverCompletionFunc *cb,
-                                            void *opaque,
-                                            int is_write)
+static BlockAIOCB *bdrv_aio_rw_vector(BlockDriverState *bs,
+                                      int64_t sector_num,
+                                      QEMUIOVector *qiov,
+                                      int nb_sectors,
+                                      BlockCompletionFunc *cb,
+                                      void *opaque,
+                                      int is_write)
 
 {
-    BlockDriverAIOCBSync *acb;
+    BlockAIOCBSync *acb;
 
     acb = qemu_aio_get(&bdrv_em_aiocb_info, bs, cb, opaque);
     acb->is_write = is_write;
@@ -4686,34 +4685,34 @@ static BlockDriverAIOCB *bdrv_aio_rw_vector(BlockDriverState *bs,
     return &acb->common;
 }
 
-static BlockDriverAIOCB *bdrv_aio_readv_em(BlockDriverState *bs,
+static BlockAIOCB *bdrv_aio_readv_em(BlockDriverState *bs,
         int64_t sector_num, QEMUIOVector *qiov, int nb_sectors,
-        BlockDriverCompletionFunc *cb, void *opaque)
+        BlockCompletionFunc *cb, void *opaque)
 {
     return bdrv_aio_rw_vector(bs, sector_num, qiov, nb_sectors, cb, opaque, 0);
 }
 
-static BlockDriverAIOCB *bdrv_aio_writev_em(BlockDriverState *bs,
+static BlockAIOCB *bdrv_aio_writev_em(BlockDriverState *bs,
         int64_t sector_num, QEMUIOVector *qiov, int nb_sectors,
-        BlockDriverCompletionFunc *cb, void *opaque)
+        BlockCompletionFunc *cb, void *opaque)
 {
     return bdrv_aio_rw_vector(bs, sector_num, qiov, nb_sectors, cb, opaque, 1);
 }
 
 
-typedef struct BlockDriverAIOCBCoroutine {
-    BlockDriverAIOCB common;
+typedef struct BlockAIOCBCoroutine {
+    BlockAIOCB common;
     BlockRequest req;
     bool is_write;
     bool *done;
     QEMUBH* bh;
-} BlockDriverAIOCBCoroutine;
+} BlockAIOCBCoroutine;
 
-static void bdrv_aio_co_cancel_em(BlockDriverAIOCB *blockacb)
+static void bdrv_aio_co_cancel_em(BlockAIOCB *blockacb)
 {
     AioContext *aio_context = bdrv_get_aio_context(blockacb->bs);
-    BlockDriverAIOCBCoroutine *acb =
-        container_of(blockacb, BlockDriverAIOCBCoroutine, common);
+    BlockAIOCBCoroutine *acb =
+        container_of(blockacb, BlockAIOCBCoroutine, common);
     bool done = false;
 
     acb->done = &done;
@@ -4723,13 +4722,13 @@ static void bdrv_aio_co_cancel_em(BlockDriverAIOCB *blockacb)
 }
 
 static const AIOCBInfo bdrv_em_co_aiocb_info = {
-    .aiocb_size         = sizeof(BlockDriverAIOCBCoroutine),
+    .aiocb_size         = sizeof(BlockAIOCBCoroutine),
     .cancel             = bdrv_aio_co_cancel_em,
 };
 
 static void bdrv_co_em_bh(void *opaque)
 {
-    BlockDriverAIOCBCoroutine *acb = opaque;
+    BlockAIOCBCoroutine *acb = opaque;
 
     acb->common.cb(acb->common.opaque, acb->req.error);
 
@@ -4744,7 +4743,7 @@ static void bdrv_co_em_bh(void *opaque)
 /* Invoke bdrv_co_do_readv/bdrv_co_do_writev */
 static void coroutine_fn bdrv_co_do_rw(void *opaque)
 {
-    BlockDriverAIOCBCoroutine *acb = opaque;
+    BlockAIOCBCoroutine *acb = opaque;
     BlockDriverState *bs = acb->common.bs;
 
     if (!acb->is_write) {
@@ -4759,17 +4758,17 @@ static void coroutine_fn bdrv_co_do_rw(void *opaque)
     qemu_bh_schedule(acb->bh);
 }
 
-static BlockDriverAIOCB *bdrv_co_aio_rw_vector(BlockDriverState *bs,
-                                               int64_t sector_num,
-                                               QEMUIOVector *qiov,
-                                               int nb_sectors,
-                                               BdrvRequestFlags flags,
-                                               BlockDriverCompletionFunc *cb,
-                                               void *opaque,
-                                               bool is_write)
+static BlockAIOCB *bdrv_co_aio_rw_vector(BlockDriverState *bs,
+                                         int64_t sector_num,
+                                         QEMUIOVector *qiov,
+                                         int nb_sectors,
+                                         BdrvRequestFlags flags,
+                                         BlockCompletionFunc *cb,
+                                         void *opaque,
+                                         bool is_write)
 {
     Coroutine *co;
-    BlockDriverAIOCBCoroutine *acb;
+    BlockAIOCBCoroutine *acb;
 
     acb = qemu_aio_get(&bdrv_em_co_aiocb_info, bs, cb, opaque);
     acb->req.sector = sector_num;
@@ -4787,7 +4786,7 @@ static BlockDriverAIOCB *bdrv_co_aio_rw_vector(BlockDriverState *bs,
 
 static void coroutine_fn bdrv_aio_flush_co_entry(void *opaque)
 {
-    BlockDriverAIOCBCoroutine *acb = opaque;
+    BlockAIOCBCoroutine *acb = opaque;
     BlockDriverState *bs = acb->common.bs;
 
     acb->req.error = bdrv_co_flush(bs);
@@ -4795,13 +4794,13 @@ static void coroutine_fn bdrv_aio_flush_co_entry(void *opaque)
     qemu_bh_schedule(acb->bh);
 }
 
-BlockDriverAIOCB *bdrv_aio_flush(BlockDriverState *bs,
-        BlockDriverCompletionFunc *cb, void *opaque)
+BlockAIOCB *bdrv_aio_flush(BlockDriverState *bs,
+        BlockCompletionFunc *cb, void *opaque)
 {
     trace_bdrv_aio_flush(bs, opaque);
 
     Coroutine *co;
-    BlockDriverAIOCBCoroutine *acb;
+    BlockAIOCBCoroutine *acb;
 
     acb = qemu_aio_get(&bdrv_em_co_aiocb_info, bs, cb, opaque);
     acb->done = NULL;
@@ -4814,7 +4813,7 @@ BlockDriverAIOCB *bdrv_aio_flush(BlockDriverState *bs,
 
 static void coroutine_fn bdrv_aio_discard_co_entry(void *opaque)
 {
-    BlockDriverAIOCBCoroutine *acb = opaque;
+    BlockAIOCBCoroutine *acb = opaque;
     BlockDriverState *bs = acb->common.bs;
 
     acb->req.error = bdrv_co_discard(bs, acb->req.sector, acb->req.nb_sectors);
@@ -4822,12 +4821,12 @@ static void coroutine_fn bdrv_aio_discard_co_entry(void *opaque)
     qemu_bh_schedule(acb->bh);
 }
 
-BlockDriverAIOCB *bdrv_aio_discard(BlockDriverState *bs,
+BlockAIOCB *bdrv_aio_discard(BlockDriverState *bs,
         int64_t sector_num, int nb_sectors,
-        BlockDriverCompletionFunc *cb, void *opaque)
+        BlockCompletionFunc *cb, void *opaque)
 {
     Coroutine *co;
-    BlockDriverAIOCBCoroutine *acb;
+    BlockAIOCBCoroutine *acb;
 
     trace_bdrv_aio_discard(bs, sector_num, nb_sectors, opaque);
 
@@ -4853,9 +4852,9 @@ void bdrv_init_with_whitelist(void)
 }
 
 void *qemu_aio_get(const AIOCBInfo *aiocb_info, BlockDriverState *bs,
-                   BlockDriverCompletionFunc *cb, void *opaque)
+                   BlockCompletionFunc *cb, void *opaque)
 {
-    BlockDriverAIOCB *acb;
+    BlockAIOCB *acb;
 
     acb = g_slice_alloc(aiocb_info->aiocb_size);
     acb->aiocb_info = aiocb_info;
@@ -4867,7 +4866,7 @@ void *qemu_aio_get(const AIOCBInfo *aiocb_info, BlockDriverState *bs,
 
 void qemu_aio_release(void *p)
 {
-    BlockDriverAIOCB *acb = p;
+    BlockAIOCB *acb = p;
     g_slice_free1(acb->aiocb_info->aiocb_size, acb);
 }
 
@@ -4894,7 +4893,7 @@ static int coroutine_fn bdrv_co_io_em(BlockDriverState *bs, int64_t sector_num,
     CoroutineIOCompletion co = {
         .coroutine = qemu_coroutine_self(),
     };
-    BlockDriverAIOCB *acb;
+    BlockAIOCB *acb;
 
     if (is_write) {
         acb = bs->drv->bdrv_aio_writev(bs, sector_num, iov, nb_sectors,
@@ -4960,7 +4959,7 @@ int coroutine_fn bdrv_co_flush(BlockDriverState *bs)
     if (bs->drv->bdrv_co_flush_to_disk) {
         ret = bs->drv->bdrv_co_flush_to_disk(bs);
     } else if (bs->drv->bdrv_aio_flush) {
-        BlockDriverAIOCB *acb;
+        BlockAIOCB *acb;
         CoroutineIOCompletion co = {
             .coroutine = qemu_coroutine_self(),
         };
@@ -5143,7 +5142,7 @@ int coroutine_fn bdrv_co_discard(BlockDriverState *bs, int64_t sector_num,
         if (bs->drv->bdrv_co_discard) {
             ret = bs->drv->bdrv_co_discard(bs, sector_num, num);
         } else {
-            BlockDriverAIOCB *acb;
+            BlockAIOCB *acb;
             CoroutineIOCompletion co = {
                 .coroutine = qemu_coroutine_self(),
             };
@@ -5269,9 +5268,9 @@ int bdrv_ioctl(BlockDriverState *bs, unsigned long int req, void *buf)
     return -ENOTSUP;
 }
 
-BlockDriverAIOCB *bdrv_aio_ioctl(BlockDriverState *bs,
+BlockAIOCB *bdrv_aio_ioctl(BlockDriverState *bs,
         unsigned long int req, void *buf,
-        BlockDriverCompletionFunc *cb, void *opaque)
+        BlockCompletionFunc *cb, void *opaque)
 {
     BlockDriver *drv = bs->drv;
 
diff --git a/block/archipelago.c b/block/archipelago.c
index 22a7daa..9bbae4e 100644
--- a/block/archipelago.c
+++ b/block/archipelago.c
@@ -87,7 +87,7 @@ typedef enum {
 } ARCHIPCmd;
 
 typedef struct ArchipelagoAIOCB {
-    BlockDriverAIOCB common;
+    BlockAIOCB common;
     QEMUBH *bh;
     struct BDRVArchipelagoState *s;
     QEMUIOVector *qiov;
@@ -724,7 +724,7 @@ static int qemu_archipelago_create(const char *filename,
     return ret;
 }
 
-static void qemu_archipelago_aio_cancel(BlockDriverAIOCB *blockacb)
+static void qemu_archipelago_aio_cancel(BlockAIOCB *blockacb)
 {
     ArchipelagoAIOCB *aio_cb = (ArchipelagoAIOCB *) blockacb;
     aio_cb->cancelled = true;
@@ -869,13 +869,13 @@ err_exit:
     return ret;
 }
 
-static BlockDriverAIOCB *qemu_archipelago_aio_rw(BlockDriverState *bs,
-                                                 int64_t sector_num,
-                                                 QEMUIOVector *qiov,
-                                                 int nb_sectors,
-                                                 BlockDriverCompletionFunc *cb,
-                                                 void *opaque,
-                                                 int op)
+static BlockAIOCB *qemu_archipelago_aio_rw(BlockDriverState *bs,
+                                           int64_t sector_num,
+                                           QEMUIOVector *qiov,
+                                           int nb_sectors,
+                                           BlockCompletionFunc *cb,
+                                           void *opaque,
+                                           int op)
 {
     ArchipelagoAIOCB *aio_cb;
     BDRVArchipelagoState *s = bs->opaque;
@@ -908,17 +908,17 @@ err_exit:
     return NULL;
 }
 
-static BlockDriverAIOCB *qemu_archipelago_aio_readv(BlockDriverState *bs,
+static BlockAIOCB *qemu_archipelago_aio_readv(BlockDriverState *bs,
         int64_t sector_num, QEMUIOVector *qiov, int nb_sectors,
-        BlockDriverCompletionFunc *cb, void *opaque)
+        BlockCompletionFunc *cb, void *opaque)
 {
     return qemu_archipelago_aio_rw(bs, sector_num, qiov, nb_sectors, cb,
                                    opaque, ARCHIP_OP_READ);
 }
 
-static BlockDriverAIOCB *qemu_archipelago_aio_writev(BlockDriverState *bs,
+static BlockAIOCB *qemu_archipelago_aio_writev(BlockDriverState *bs,
         int64_t sector_num, QEMUIOVector *qiov, int nb_sectors,
-        BlockDriverCompletionFunc *cb, void *opaque)
+        BlockCompletionFunc *cb, void *opaque)
 {
     return qemu_archipelago_aio_rw(bs, sector_num, qiov, nb_sectors, cb,
                                    opaque, ARCHIP_OP_WRITE);
@@ -1008,8 +1008,8 @@ static QemuOptsList qemu_archipelago_create_opts = {
     }
 };
 
-static BlockDriverAIOCB *qemu_archipelago_aio_flush(BlockDriverState *bs,
-        BlockDriverCompletionFunc *cb, void *opaque)
+static BlockAIOCB *qemu_archipelago_aio_flush(BlockDriverState *bs,
+        BlockCompletionFunc *cb, void *opaque)
 {
     return qemu_archipelago_aio_rw(bs, 0, NULL, 0, cb, opaque,
                                    ARCHIP_OP_FLUSH);
diff --git a/block/backup.c b/block/backup.c
index d0b0225..e334740 100644
--- a/block/backup.c
+++ b/block/backup.c
@@ -353,7 +353,7 @@ void backup_start(BlockDriverState *bs, BlockDriverState *target,
                   int64_t speed, MirrorSyncMode sync_mode,
                   BlockdevOnError on_source_error,
                   BlockdevOnError on_target_error,
-                  BlockDriverCompletionFunc *cb, void *opaque,
+                  BlockCompletionFunc *cb, void *opaque,
                   Error **errp)
 {
     int64_t len;
diff --git a/block/blkdebug.c b/block/blkdebug.c
index 69b330e..008d3e3 100644
--- a/block/blkdebug.c
+++ b/block/blkdebug.c
@@ -41,7 +41,7 @@ typedef struct BDRVBlkdebugState {
 } BDRVBlkdebugState;
 
 typedef struct BlkdebugAIOCB {
-    BlockDriverAIOCB common;
+    BlockAIOCB common;
     QEMUBH *bh;
     int ret;
 } BlkdebugAIOCB;
@@ -52,7 +52,7 @@ typedef struct BlkdebugSuspendedReq {
     QLIST_ENTRY(BlkdebugSuspendedReq) next;
 } BlkdebugSuspendedReq;
 
-static void blkdebug_aio_cancel(BlockDriverAIOCB *blockacb);
+static void blkdebug_aio_cancel(BlockAIOCB *blockacb);
 
 static const AIOCBInfo blkdebug_aiocb_info = {
     .aiocb_size = sizeof(BlkdebugAIOCB),
@@ -450,7 +450,7 @@ static void error_callback_bh(void *opaque)
     qemu_aio_release(acb);
 }
 
-static void blkdebug_aio_cancel(BlockDriverAIOCB *blockacb)
+static void blkdebug_aio_cancel(BlockAIOCB *blockacb)
 {
     BlkdebugAIOCB *acb = container_of(blockacb, BlkdebugAIOCB, common);
     if (acb->bh) {
@@ -460,8 +460,8 @@ static void blkdebug_aio_cancel(BlockDriverAIOCB *blockacb)
     qemu_aio_release(acb);
 }
 
-static BlockDriverAIOCB *inject_error(BlockDriverState *bs,
-    BlockDriverCompletionFunc *cb, void *opaque, BlkdebugRule *rule)
+static BlockAIOCB *inject_error(BlockDriverState *bs,
+    BlockCompletionFunc *cb, void *opaque, BlkdebugRule *rule)
 {
     BDRVBlkdebugState *s = bs->opaque;
     int error = rule->options.inject.error;
@@ -486,9 +486,9 @@ static BlockDriverAIOCB *inject_error(BlockDriverState *bs,
     return &acb->common;
 }
 
-static BlockDriverAIOCB *blkdebug_aio_readv(BlockDriverState *bs,
+static BlockAIOCB *blkdebug_aio_readv(BlockDriverState *bs,
     int64_t sector_num, QEMUIOVector *qiov, int nb_sectors,
-    BlockDriverCompletionFunc *cb, void *opaque)
+    BlockCompletionFunc *cb, void *opaque)
 {
     BDRVBlkdebugState *s = bs->opaque;
     BlkdebugRule *rule = NULL;
@@ -508,9 +508,9 @@ static BlockDriverAIOCB *blkdebug_aio_readv(BlockDriverState *bs,
     return bdrv_aio_readv(bs->file, sector_num, qiov, nb_sectors, cb, opaque);
 }
 
-static BlockDriverAIOCB *blkdebug_aio_writev(BlockDriverState *bs,
+static BlockAIOCB *blkdebug_aio_writev(BlockDriverState *bs,
     int64_t sector_num, QEMUIOVector *qiov, int nb_sectors,
-    BlockDriverCompletionFunc *cb, void *opaque)
+    BlockCompletionFunc *cb, void *opaque)
 {
     BDRVBlkdebugState *s = bs->opaque;
     BlkdebugRule *rule = NULL;
@@ -530,8 +530,8 @@ static BlockDriverAIOCB *blkdebug_aio_writev(BlockDriverState *bs,
     return bdrv_aio_writev(bs->file, sector_num, qiov, nb_sectors, cb, opaque);
 }
 
-static BlockDriverAIOCB *blkdebug_aio_flush(BlockDriverState *bs,
-    BlockDriverCompletionFunc *cb, void *opaque)
+static BlockAIOCB *blkdebug_aio_flush(BlockDriverState *bs,
+    BlockCompletionFunc *cb, void *opaque)
 {
     BDRVBlkdebugState *s = bs->opaque;
     BlkdebugRule *rule = NULL;
diff --git a/block/blkverify.c b/block/blkverify.c
index 163064c..d4553cc 100644
--- a/block/blkverify.c
+++ b/block/blkverify.c
@@ -19,7 +19,7 @@ typedef struct {
 
 typedef struct BlkverifyAIOCB BlkverifyAIOCB;
 struct BlkverifyAIOCB {
-    BlockDriverAIOCB common;
+    BlockAIOCB common;
     QEMUBH *bh;
 
     /* Request metadata */
@@ -38,7 +38,7 @@ struct BlkverifyAIOCB {
     void (*verify)(BlkverifyAIOCB *acb);
 };
 
-static void blkverify_aio_cancel(BlockDriverAIOCB *blockacb)
+static void blkverify_aio_cancel(BlockAIOCB *blockacb)
 {
     BlkverifyAIOCB *acb = (BlkverifyAIOCB *)blockacb;
     AioContext *aio_context = bdrv_get_aio_context(blockacb->bs);
@@ -180,7 +180,7 @@ static int64_t blkverify_getlength(BlockDriverState *bs)
 static BlkverifyAIOCB *blkverify_aio_get(BlockDriverState *bs, bool is_write,
                                          int64_t sector_num, QEMUIOVector *qiov,
                                          int nb_sectors,
-                                         BlockDriverCompletionFunc *cb,
+                                         BlockCompletionFunc *cb,
                                          void *opaque)
 {
     BlkverifyAIOCB *acb = qemu_aio_get(&blkverify_aiocb_info, bs, cb, opaque);
@@ -248,9 +248,9 @@ static void blkverify_verify_readv(BlkverifyAIOCB *acb)
     }
 }
 
-static BlockDriverAIOCB *blkverify_aio_readv(BlockDriverState *bs,
+static BlockAIOCB *blkverify_aio_readv(BlockDriverState *bs,
         int64_t sector_num, QEMUIOVector *qiov, int nb_sectors,
-        BlockDriverCompletionFunc *cb, void *opaque)
+        BlockCompletionFunc *cb, void *opaque)
 {
     BDRVBlkverifyState *s = bs->opaque;
     BlkverifyAIOCB *acb = blkverify_aio_get(bs, false, sector_num, qiov,
@@ -268,9 +268,9 @@ static BlockDriverAIOCB *blkverify_aio_readv(BlockDriverState *bs,
     return &acb->common;
 }
 
-static BlockDriverAIOCB *blkverify_aio_writev(BlockDriverState *bs,
+static BlockAIOCB *blkverify_aio_writev(BlockDriverState *bs,
         int64_t sector_num, QEMUIOVector *qiov, int nb_sectors,
-        BlockDriverCompletionFunc *cb, void *opaque)
+        BlockCompletionFunc *cb, void *opaque)
 {
     BDRVBlkverifyState *s = bs->opaque;
     BlkverifyAIOCB *acb = blkverify_aio_get(bs, true, sector_num, qiov,
@@ -283,9 +283,9 @@ static BlockDriverAIOCB *blkverify_aio_writev(BlockDriverState *bs,
     return &acb->common;
 }
 
-static BlockDriverAIOCB *blkverify_aio_flush(BlockDriverState *bs,
-                                             BlockDriverCompletionFunc *cb,
-                                             void *opaque)
+static BlockAIOCB *blkverify_aio_flush(BlockDriverState *bs,
+                                       BlockCompletionFunc *cb,
+                                       void *opaque)
 {
     BDRVBlkverifyState *s = bs->opaque;
 
diff --git a/block/commit.c b/block/commit.c
index 91517d3..60a2acc 100644
--- a/block/commit.c
+++ b/block/commit.c
@@ -182,7 +182,7 @@ static const BlockJobDriver commit_job_driver = {
 
 void commit_start(BlockDriverState *bs, BlockDriverState *base,
                   BlockDriverState *top, int64_t speed,
-                  BlockdevOnError on_error, BlockDriverCompletionFunc *cb,
+                  BlockdevOnError on_error, BlockCompletionFunc *cb,
                   void *opaque, const char *backing_file_str, Error **errp)
 {
     CommitBlockJob *s;
diff --git a/block/curl.c b/block/curl.c
index 938f9d9..5e96b05 100644
--- a/block/curl.c
+++ b/block/curl.c
@@ -78,7 +78,7 @@ static CURLMcode __curl_multi_socket_action(CURLM *multi_handle,
 struct BDRVCURLState;
 
 typedef struct CURLAIOCB {
-    BlockDriverAIOCB common;
+    BlockAIOCB common;
     QEMUBH *bh;
     QEMUIOVector *qiov;
 
@@ -613,7 +613,7 @@ out_noclean:
     return -EINVAL;
 }
 
-static void curl_aio_cancel(BlockDriverAIOCB *blockacb)
+static void curl_aio_cancel(BlockAIOCB *blockacb)
 {
     // Do we have to implement canceling? Seems to work without...
 }
@@ -686,9 +686,9 @@ static void curl_readv_bh_cb(void *p)
     curl_multi_socket_action(s->multi, CURL_SOCKET_TIMEOUT, 0, &running);
 }
 
-static BlockDriverAIOCB *curl_aio_readv(BlockDriverState *bs,
+static BlockAIOCB *curl_aio_readv(BlockDriverState *bs,
         int64_t sector_num, QEMUIOVector *qiov, int nb_sectors,
-        BlockDriverCompletionFunc *cb, void *opaque)
+        BlockCompletionFunc *cb, void *opaque)
 {
     CURLAIOCB *acb;
 
diff --git a/block/iscsi.c b/block/iscsi.c
index af3d0f6..1a1a389 100644
--- a/block/iscsi.c
+++ b/block/iscsi.c
@@ -81,7 +81,7 @@ typedef struct IscsiTask {
 } IscsiTask;
 
 typedef struct IscsiAIOCB {
-    BlockDriverAIOCB common;
+    BlockAIOCB common;
     QEMUIOVector *qiov;
     QEMUBH *bh;
     IscsiLun *iscsilun;
@@ -231,7 +231,7 @@ iscsi_abort_task_cb(struct iscsi_context *iscsi, int status, void *command_data,
 }
 
 static void
-iscsi_aio_cancel(BlockDriverAIOCB *blockacb)
+iscsi_aio_cancel(BlockAIOCB *blockacb)
 {
     IscsiAIOCB *acb = (IscsiAIOCB *)blockacb;
     IscsiLun *iscsilun = acb->iscsilun;
@@ -669,9 +669,9 @@ iscsi_aio_ioctl_cb(struct iscsi_context *iscsi, int status,
     iscsi_schedule_bh(acb);
 }
 
-static BlockDriverAIOCB *iscsi_aio_ioctl(BlockDriverState *bs,
+static BlockAIOCB *iscsi_aio_ioctl(BlockDriverState *bs,
         unsigned long int req, void *buf,
-        BlockDriverCompletionFunc *cb, void *opaque)
+        BlockCompletionFunc *cb, void *opaque)
 {
     IscsiLun *iscsilun = bs->opaque;
     struct iscsi_context *iscsi = iscsilun->iscsi;
diff --git a/block/linux-aio.c b/block/linux-aio.c
index 9aca758..2436140 100644
--- a/block/linux-aio.c
+++ b/block/linux-aio.c
@@ -28,7 +28,7 @@
 #define MAX_QUEUED_IO  128
 
 struct qemu_laiocb {
-    BlockDriverAIOCB common;
+    BlockAIOCB common;
     struct qemu_laio_state *ctx;
     struct iocb iocb;
     ssize_t ret;
@@ -147,7 +147,7 @@ static void qemu_laio_completion_cb(EventNotifier *e)
     }
 }
 
-static void laio_cancel(BlockDriverAIOCB *blockacb)
+static void laio_cancel(BlockAIOCB *blockacb)
 {
     struct qemu_laiocb *laiocb = (struct qemu_laiocb *)blockacb;
     struct io_event event;
@@ -257,9 +257,9 @@ int laio_io_unplug(BlockDriverState *bs, void *aio_ctx, bool unplug)
     return ret;
 }
 
-BlockDriverAIOCB *laio_submit(BlockDriverState *bs, void *aio_ctx, int fd,
+BlockAIOCB *laio_submit(BlockDriverState *bs, void *aio_ctx, int fd,
         int64_t sector_num, QEMUIOVector *qiov, int nb_sectors,
-        BlockDriverCompletionFunc *cb, void *opaque, int type)
+        BlockCompletionFunc *cb, void *opaque, int type)
 {
     struct qemu_laio_state *s = aio_ctx;
     struct qemu_laiocb *laiocb;
diff --git a/block/mirror.c b/block/mirror.c
index 829be2f..e8a43eb 100644
--- a/block/mirror.c
+++ b/block/mirror.c
@@ -613,7 +613,7 @@ static void mirror_start_job(BlockDriverState *bs, BlockDriverState *target,
                              int64_t buf_size,
                              BlockdevOnError on_source_error,
                              BlockdevOnError on_target_error,
-                             BlockDriverCompletionFunc *cb,
+                             BlockCompletionFunc *cb,
                              void *opaque, Error **errp,
                              const BlockJobDriver *driver,
                              bool is_none_mode, BlockDriverState *base)
@@ -673,7 +673,7 @@ void mirror_start(BlockDriverState *bs, BlockDriverState *target,
                   int64_t speed, int64_t granularity, int64_t buf_size,
                   MirrorSyncMode mode, BlockdevOnError on_source_error,
                   BlockdevOnError on_target_error,
-                  BlockDriverCompletionFunc *cb,
+                  BlockCompletionFunc *cb,
                   void *opaque, Error **errp)
 {
     bool is_none_mode;
@@ -690,7 +690,7 @@ void mirror_start(BlockDriverState *bs, BlockDriverState *target,
 void commit_active_start(BlockDriverState *bs, BlockDriverState *base,
                          int64_t speed,
                          BlockdevOnError on_error,
-                         BlockDriverCompletionFunc *cb,
+                         BlockCompletionFunc *cb,
                          void *opaque, Error **errp)
 {
     int64_t length, base_length;
diff --git a/block/qed-gencb.c b/block/qed-gencb.c
index 7d7ac1f..b817a8b 100644
--- a/block/qed-gencb.c
+++ b/block/qed-gencb.c
@@ -13,7 +13,7 @@
 
 #include "qed.h"
 
-void *gencb_alloc(size_t len, BlockDriverCompletionFunc *cb, void *opaque)
+void *gencb_alloc(size_t len, BlockCompletionFunc *cb, void *opaque)
 {
     GenericCB *gencb = g_malloc(len);
     gencb->cb = cb;
@@ -24,7 +24,7 @@ void *gencb_alloc(size_t len, BlockDriverCompletionFunc *cb, void *opaque)
 void gencb_complete(void *opaque, int ret)
 {
     GenericCB *gencb = opaque;
-    BlockDriverCompletionFunc *cb = gencb->cb;
+    BlockCompletionFunc *cb = gencb->cb;
     void *user_opaque = gencb->opaque;
 
     g_free(gencb);
diff --git a/block/qed-table.c b/block/qed-table.c
index f61107a..513aa87 100644
--- a/block/qed-table.c
+++ b/block/qed-table.c
@@ -49,7 +49,7 @@ out:
 }
 
 static void qed_read_table(BDRVQEDState *s, uint64_t offset, QEDTable *table,
-                           BlockDriverCompletionFunc *cb, void *opaque)
+                           BlockCompletionFunc *cb, void *opaque)
 {
     QEDReadTableCB *read_table_cb = gencb_alloc(sizeof(*read_table_cb),
                                                 cb, opaque);
@@ -119,7 +119,7 @@ out:
  */
 static void qed_write_table(BDRVQEDState *s, uint64_t offset, QEDTable *table,
                             unsigned int index, unsigned int n, bool flush,
-                            BlockDriverCompletionFunc *cb, void *opaque)
+                            BlockCompletionFunc *cb, void *opaque)
 {
     QEDWriteTableCB *write_table_cb;
     unsigned int sector_mask = BDRV_SECTOR_SIZE / sizeof(uint64_t) - 1;
@@ -180,7 +180,7 @@ int qed_read_l1_table_sync(BDRVQEDState *s)
 }
 
 void qed_write_l1_table(BDRVQEDState *s, unsigned int index, unsigned int n,
-                        BlockDriverCompletionFunc *cb, void *opaque)
+                        BlockCompletionFunc *cb, void *opaque)
 {
     BLKDBG_EVENT(s->bs->file, BLKDBG_L1_UPDATE);
     qed_write_table(s, s->header.l1_table_offset,
@@ -235,7 +235,7 @@ static void qed_read_l2_table_cb(void *opaque, int ret)
 }
 
 void qed_read_l2_table(BDRVQEDState *s, QEDRequest *request, uint64_t offset,
-                       BlockDriverCompletionFunc *cb, void *opaque)
+                       BlockCompletionFunc *cb, void *opaque)
 {
     QEDReadL2TableCB *read_l2_table_cb;
 
@@ -275,7 +275,7 @@ int qed_read_l2_table_sync(BDRVQEDState *s, QEDRequest *request, uint64_t offset
 
 void qed_write_l2_table(BDRVQEDState *s, QEDRequest *request,
                         unsigned int index, unsigned int n, bool flush,
-                        BlockDriverCompletionFunc *cb, void *opaque)
+                        BlockCompletionFunc *cb, void *opaque)
 {
     BLKDBG_EVENT(s->bs->file, BLKDBG_L2_UPDATE);
     qed_write_table(s, request->l2_table->offset,
diff --git a/block/qed.c b/block/qed.c
index f20ffb3..a0eafa9 100644
--- a/block/qed.c
+++ b/block/qed.c
@@ -18,7 +18,7 @@
 #include "qapi/qmp/qerror.h"
 #include "migration/migration.h"
 
-static void qed_aio_cancel(BlockDriverAIOCB *blockacb)
+static void qed_aio_cancel(BlockAIOCB *blockacb)
 {
     QEDAIOCB *acb = (QEDAIOCB *)blockacb;
     AioContext *aio_context = bdrv_get_aio_context(blockacb->bs);
@@ -144,7 +144,7 @@ static void qed_write_header_read_cb(void *opaque, int ret)
  * This function only updates known header fields in-place and does not affect
  * extra data after the QED header.
  */
-static void qed_write_header(BDRVQEDState *s, BlockDriverCompletionFunc cb,
+static void qed_write_header(BDRVQEDState *s, BlockCompletionFunc cb,
                              void *opaque)
 {
     /* We must write full sectors for O_DIRECT but cannot necessarily generate
@@ -772,7 +772,7 @@ static BDRVQEDState *acb_to_s(QEDAIOCB *acb)
 static void qed_read_backing_file(BDRVQEDState *s, uint64_t pos,
                                   QEMUIOVector *qiov,
                                   QEMUIOVector **backing_qiov,
-                                  BlockDriverCompletionFunc *cb, void *opaque)
+                                  BlockCompletionFunc *cb, void *opaque)
 {
     uint64_t backing_length = 0;
     size_t size;
@@ -864,7 +864,7 @@ static void qed_copy_from_backing_file_write(void *opaque, int ret)
  */
 static void qed_copy_from_backing_file(BDRVQEDState *s, uint64_t pos,
                                        uint64_t len, uint64_t offset,
-                                       BlockDriverCompletionFunc *cb,
+                                       BlockCompletionFunc *cb,
                                        void *opaque)
 {
     CopyFromBackingFileCB *copy_cb;
@@ -915,7 +915,7 @@ static void qed_update_l2_table(BDRVQEDState *s, QEDTable *table, int index,
 static void qed_aio_complete_bh(void *opaque)
 {
     QEDAIOCB *acb = opaque;
-    BlockDriverCompletionFunc *cb = acb->common.cb;
+    BlockCompletionFunc *cb = acb->common.cb;
     void *user_opaque = acb->common.opaque;
     int ret = acb->bh_ret;
     bool *finished = acb->finished;
@@ -1083,7 +1083,7 @@ static void qed_aio_write_main(void *opaque, int ret)
     BDRVQEDState *s = acb_to_s(acb);
     uint64_t offset = acb->cur_cluster +
                       qed_offset_into_cluster(s, acb->cur_pos);
-    BlockDriverCompletionFunc *next_fn;
+    BlockCompletionFunc *next_fn;
 
     trace_qed_aio_write_main(s, acb, ret, offset, acb->cur_qiov.size);
 
@@ -1183,7 +1183,7 @@ static void qed_aio_write_zero_cluster(void *opaque, int ret)
 static void qed_aio_write_alloc(QEDAIOCB *acb, size_t len)
 {
     BDRVQEDState *s = acb_to_s(acb);
-    BlockDriverCompletionFunc *cb;
+    BlockCompletionFunc *cb;
 
     /* Cancel timer when the first allocating request comes in */
     if (QSIMPLEQ_EMPTY(&s->allocating_write_reqs)) {
@@ -1384,11 +1384,11 @@ static void qed_aio_next_io(void *opaque, int ret)
                       io_fn, acb);
 }
 
-static BlockDriverAIOCB *qed_aio_setup(BlockDriverState *bs,
-                                       int64_t sector_num,
-                                       QEMUIOVector *qiov, int nb_sectors,
-                                       BlockDriverCompletionFunc *cb,
-                                       void *opaque, int flags)
+static BlockAIOCB *qed_aio_setup(BlockDriverState *bs,
+                                 int64_t sector_num,
+                                 QEMUIOVector *qiov, int nb_sectors,
+                                 BlockCompletionFunc *cb,
+                                 void *opaque, int flags)
 {
     QEDAIOCB *acb = qemu_aio_get(&qed_aiocb_info, bs, cb, opaque);
 
@@ -1410,20 +1410,20 @@ static BlockDriverAIOCB *qed_aio_setup(BlockDriverState *bs,
     return &acb->common;
 }
 
-static BlockDriverAIOCB *bdrv_qed_aio_readv(BlockDriverState *bs,
-                                            int64_t sector_num,
-                                            QEMUIOVector *qiov, int nb_sectors,
-                                            BlockDriverCompletionFunc *cb,
-                                            void *opaque)
+static BlockAIOCB *bdrv_qed_aio_readv(BlockDriverState *bs,
+                                      int64_t sector_num,
+                                      QEMUIOVector *qiov, int nb_sectors,
+                                      BlockCompletionFunc *cb,
+                                      void *opaque)
 {
     return qed_aio_setup(bs, sector_num, qiov, nb_sectors, cb, opaque, 0);
 }
 
-static BlockDriverAIOCB *bdrv_qed_aio_writev(BlockDriverState *bs,
-                                             int64_t sector_num,
-                                             QEMUIOVector *qiov, int nb_sectors,
-                                             BlockDriverCompletionFunc *cb,
-                                             void *opaque)
+static BlockAIOCB *bdrv_qed_aio_writev(BlockDriverState *bs,
+                                       int64_t sector_num,
+                                       QEMUIOVector *qiov, int nb_sectors,
+                                       BlockCompletionFunc *cb,
+                                       void *opaque)
 {
     return qed_aio_setup(bs, sector_num, qiov, nb_sectors, cb,
                          opaque, QED_AIOCB_WRITE);
@@ -1451,7 +1451,7 @@ static int coroutine_fn bdrv_qed_co_write_zeroes(BlockDriverState *bs,
                                                  int nb_sectors,
                                                  BdrvRequestFlags flags)
 {
-    BlockDriverAIOCB *blockacb;
+    BlockAIOCB *blockacb;
     BDRVQEDState *s = bs->opaque;
     QEDWriteZeroesCB cb = { .done = false };
     QEMUIOVector qiov;
diff --git a/block/qed.h b/block/qed.h
index 2b0e724..d3934a0 100644
--- a/block/qed.h
+++ b/block/qed.h
@@ -128,7 +128,7 @@ enum {
 };
 
 typedef struct QEDAIOCB {
-    BlockDriverAIOCB common;
+    BlockAIOCB common;
     QEMUBH *bh;
     int bh_ret;                     /* final return status for completion bh */
     QSIMPLEQ_ENTRY(QEDAIOCB) next;  /* next request */
@@ -203,11 +203,11 @@ typedef void QEDFindClusterFunc(void *opaque, int ret, uint64_t offset, size_t l
  * Generic callback for chaining async callbacks
  */
 typedef struct {
-    BlockDriverCompletionFunc *cb;
+    BlockCompletionFunc *cb;
     void *opaque;
 } GenericCB;
 
-void *gencb_alloc(size_t len, BlockDriverCompletionFunc *cb, void *opaque);
+void *gencb_alloc(size_t len, BlockCompletionFunc *cb, void *opaque);
 void gencb_complete(void *opaque, int ret);
 
 /**
@@ -230,16 +230,16 @@ void qed_commit_l2_cache_entry(L2TableCache *l2_cache, CachedL2Table *l2_table);
  */
 int qed_read_l1_table_sync(BDRVQEDState *s);
 void qed_write_l1_table(BDRVQEDState *s, unsigned int index, unsigned int n,
-                        BlockDriverCompletionFunc *cb, void *opaque);
+                        BlockCompletionFunc *cb, void *opaque);
 int qed_write_l1_table_sync(BDRVQEDState *s, unsigned int index,
                             unsigned int n);
 int qed_read_l2_table_sync(BDRVQEDState *s, QEDRequest *request,
                            uint64_t offset);
 void qed_read_l2_table(BDRVQEDState *s, QEDRequest *request, uint64_t offset,
-                       BlockDriverCompletionFunc *cb, void *opaque);
+                       BlockCompletionFunc *cb, void *opaque);
 void qed_write_l2_table(BDRVQEDState *s, QEDRequest *request,
                         unsigned int index, unsigned int n, bool flush,
-                        BlockDriverCompletionFunc *cb, void *opaque);
+                        BlockCompletionFunc *cb, void *opaque);
 int qed_write_l2_table_sync(BDRVQEDState *s, QEDRequest *request,
                             unsigned int index, unsigned int n, bool flush);
 
diff --git a/block/quorum.c b/block/quorum.c
index f958269..26f8dfa 100644
--- a/block/quorum.c
+++ b/block/quorum.c
@@ -92,7 +92,7 @@ typedef struct QuorumAIOCB QuorumAIOCB;
  * $children_count QuorumChildRequest.
  */
 typedef struct QuorumChildRequest {
-    BlockDriverAIOCB *aiocb;
+    BlockAIOCB *aiocb;
     QEMUIOVector qiov;
     uint8_t *buf;
     int ret;
@@ -105,7 +105,7 @@ typedef struct QuorumChildRequest {
  * used to do operations on each children and track overall progress.
  */
 struct QuorumAIOCB {
-    BlockDriverAIOCB common;
+    BlockAIOCB common;
 
     /* Request metadata */
     uint64_t sector_num;
@@ -130,7 +130,7 @@ struct QuorumAIOCB {
 
 static bool quorum_vote(QuorumAIOCB *acb);
 
-static void quorum_aio_cancel(BlockDriverAIOCB *blockacb)
+static void quorum_aio_cancel(BlockAIOCB *blockacb)
 {
     QuorumAIOCB *acb = container_of(blockacb, QuorumAIOCB, common);
     BDRVQuorumState *s = acb->common.bs->opaque;
@@ -187,7 +187,7 @@ static QuorumAIOCB *quorum_aio_get(BDRVQuorumState *s,
                                    QEMUIOVector *qiov,
                                    uint64_t sector_num,
                                    int nb_sectors,
-                                   BlockDriverCompletionFunc *cb,
+                                   BlockCompletionFunc *cb,
                                    void *opaque)
 {
     QuorumAIOCB *acb = qemu_aio_get(&quorum_aiocb_info, bs, cb, opaque);
@@ -265,7 +265,7 @@ static void quorum_rewrite_aio_cb(void *opaque, int ret)
     quorum_aio_finalize(acb);
 }
 
-static BlockDriverAIOCB *read_fifo_child(QuorumAIOCB *acb);
+static BlockAIOCB *read_fifo_child(QuorumAIOCB *acb);
 
 static void quorum_copy_qiov(QEMUIOVector *dest, QEMUIOVector *source)
 {
@@ -641,7 +641,7 @@ free_exit:
     return rewrite;
 }
 
-static BlockDriverAIOCB *read_quorum_children(QuorumAIOCB *acb)
+static BlockAIOCB *read_quorum_children(QuorumAIOCB *acb)
 {
     BDRVQuorumState *s = acb->common.bs->opaque;
     int i;
@@ -660,7 +660,7 @@ static BlockDriverAIOCB *read_quorum_children(QuorumAIOCB *acb)
     return &acb->common;
 }
 
-static BlockDriverAIOCB *read_fifo_child(QuorumAIOCB *acb)
+static BlockAIOCB *read_fifo_child(QuorumAIOCB *acb)
 {
     BDRVQuorumState *s = acb->common.bs->opaque;
 
@@ -676,12 +676,12 @@ static BlockDriverAIOCB *read_fifo_child(QuorumAIOCB *acb)
     return &acb->common;
 }
 
-static BlockDriverAIOCB *quorum_aio_readv(BlockDriverState *bs,
-                                          int64_t sector_num,
-                                          QEMUIOVector *qiov,
-                                          int nb_sectors,
-                                          BlockDriverCompletionFunc *cb,
-                                          void *opaque)
+static BlockAIOCB *quorum_aio_readv(BlockDriverState *bs,
+                                    int64_t sector_num,
+                                    QEMUIOVector *qiov,
+                                    int nb_sectors,
+                                    BlockCompletionFunc *cb,
+                                    void *opaque)
 {
     BDRVQuorumState *s = bs->opaque;
     QuorumAIOCB *acb = quorum_aio_get(s, bs, qiov, sector_num,
@@ -697,12 +697,12 @@ static BlockDriverAIOCB *quorum_aio_readv(BlockDriverState *bs,
     return read_fifo_child(acb);
 }
 
-static BlockDriverAIOCB *quorum_aio_writev(BlockDriverState *bs,
-                                          int64_t sector_num,
-                                          QEMUIOVector *qiov,
-                                          int nb_sectors,
-                                          BlockDriverCompletionFunc *cb,
-                                          void *opaque)
+static BlockAIOCB *quorum_aio_writev(BlockDriverState *bs,
+                                     int64_t sector_num,
+                                     QEMUIOVector *qiov,
+                                     int nb_sectors,
+                                     BlockCompletionFunc *cb,
+                                     void *opaque)
 {
     BDRVQuorumState *s = bs->opaque;
     QuorumAIOCB *acb = quorum_aio_get(s, bs, qiov, sector_num, nb_sectors,
diff --git a/block/raw-aio.h b/block/raw-aio.h
index e18c975..80681ce 100644
--- a/block/raw-aio.h
+++ b/block/raw-aio.h
@@ -35,9 +35,9 @@
 #ifdef CONFIG_LINUX_AIO
 void *laio_init(void);
 void laio_cleanup(void *s);
-BlockDriverAIOCB *laio_submit(BlockDriverState *bs, void *aio_ctx, int fd,
+BlockAIOCB *laio_submit(BlockDriverState *bs, void *aio_ctx, int fd,
         int64_t sector_num, QEMUIOVector *qiov, int nb_sectors,
-        BlockDriverCompletionFunc *cb, void *opaque, int type);
+        BlockCompletionFunc *cb, void *opaque, int type);
 void laio_detach_aio_context(void *s, AioContext *old_context);
 void laio_attach_aio_context(void *s, AioContext *new_context);
 void laio_io_plug(BlockDriverState *bs, void *aio_ctx);
@@ -49,10 +49,10 @@ typedef struct QEMUWin32AIOState QEMUWin32AIOState;
 QEMUWin32AIOState *win32_aio_init(void);
 void win32_aio_cleanup(QEMUWin32AIOState *aio);
 int win32_aio_attach(QEMUWin32AIOState *aio, HANDLE hfile);
-BlockDriverAIOCB *win32_aio_submit(BlockDriverState *bs,
+BlockAIOCB *win32_aio_submit(BlockDriverState *bs,
         QEMUWin32AIOState *aio, HANDLE hfile,
         int64_t sector_num, QEMUIOVector *qiov, int nb_sectors,
-        BlockDriverCompletionFunc *cb, void *opaque, int type);
+        BlockCompletionFunc *cb, void *opaque, int type);
 void win32_aio_detach_aio_context(QEMUWin32AIOState *aio,
                                   AioContext *old_context);
 void win32_aio_attach_aio_context(QEMUWin32AIOState *aio,
diff --git a/block/raw-posix.c b/block/raw-posix.c
index d737f3a..2efbfeb 100644
--- a/block/raw-posix.c
+++ b/block/raw-posix.c
@@ -1040,9 +1040,9 @@ static int paio_submit_co(BlockDriverState *bs, int fd,
     return thread_pool_submit_co(pool, aio_worker, acb);
 }
 
-static BlockDriverAIOCB *paio_submit(BlockDriverState *bs, int fd,
+static BlockAIOCB *paio_submit(BlockDriverState *bs, int fd,
         int64_t sector_num, QEMUIOVector *qiov, int nb_sectors,
-        BlockDriverCompletionFunc *cb, void *opaque, int type)
+        BlockCompletionFunc *cb, void *opaque, int type)
 {
     RawPosixAIOData *acb = g_slice_new(RawPosixAIOData);
     ThreadPool *pool;
@@ -1065,9 +1065,9 @@ static BlockDriverAIOCB *paio_submit(BlockDriverState *bs, int fd,
     return thread_pool_submit_aio(pool, aio_worker, acb, cb, opaque);
 }
 
-static BlockDriverAIOCB *raw_aio_submit(BlockDriverState *bs,
+static BlockAIOCB *raw_aio_submit(BlockDriverState *bs,
         int64_t sector_num, QEMUIOVector *qiov, int nb_sectors,
-        BlockDriverCompletionFunc *cb, void *opaque, int type)
+        BlockCompletionFunc *cb, void *opaque, int type)
 {
     BDRVRawState *s = bs->opaque;
 
@@ -1124,24 +1124,24 @@ static void raw_aio_flush_io_queue(BlockDriverState *bs)
 #endif
 }
 
-static BlockDriverAIOCB *raw_aio_readv(BlockDriverState *bs,
+static BlockAIOCB *raw_aio_readv(BlockDriverState *bs,
         int64_t sector_num, QEMUIOVector *qiov, int nb_sectors,
-        BlockDriverCompletionFunc *cb, void *opaque)
+        BlockCompletionFunc *cb, void *opaque)
 {
     return raw_aio_submit(bs, sector_num, qiov, nb_sectors,
                           cb, opaque, QEMU_AIO_READ);
 }
 
-static BlockDriverAIOCB *raw_aio_writev(BlockDriverState *bs,
+static BlockAIOCB *raw_aio_writev(BlockDriverState *bs,
         int64_t sector_num, QEMUIOVector *qiov, int nb_sectors,
-        BlockDriverCompletionFunc *cb, void *opaque)
+        BlockCompletionFunc *cb, void *opaque)
 {
     return raw_aio_submit(bs, sector_num, qiov, nb_sectors,
                           cb, opaque, QEMU_AIO_WRITE);
 }
 
-static BlockDriverAIOCB *raw_aio_flush(BlockDriverState *bs,
-        BlockDriverCompletionFunc *cb, void *opaque)
+static BlockAIOCB *raw_aio_flush(BlockDriverState *bs,
+        BlockCompletionFunc *cb, void *opaque)
 {
     BDRVRawState *s = bs->opaque;
 
@@ -1536,9 +1536,9 @@ static int64_t coroutine_fn raw_co_get_block_status(BlockDriverState *bs,
     return ret;
 }
 
-static coroutine_fn BlockDriverAIOCB *raw_aio_discard(BlockDriverState *bs,
+static coroutine_fn BlockAIOCB *raw_aio_discard(BlockDriverState *bs,
     int64_t sector_num, int nb_sectors,
-    BlockDriverCompletionFunc *cb, void *opaque)
+    BlockCompletionFunc *cb, void *opaque)
 {
     BDRVRawState *s = bs->opaque;
 
@@ -1871,9 +1871,9 @@ static int hdev_ioctl(BlockDriverState *bs, unsigned long int req, void *buf)
     return ioctl(s->fd, req, buf);
 }
 
-static BlockDriverAIOCB *hdev_aio_ioctl(BlockDriverState *bs,
+static BlockAIOCB *hdev_aio_ioctl(BlockDriverState *bs,
         unsigned long int req, void *buf,
-        BlockDriverCompletionFunc *cb, void *opaque)
+        BlockCompletionFunc *cb, void *opaque)
 {
     BDRVRawState *s = bs->opaque;
     RawPosixAIOData *acb;
@@ -1912,9 +1912,9 @@ static int fd_open(BlockDriverState *bs)
 
 #endif /* !linux && !FreeBSD */
 
-static coroutine_fn BlockDriverAIOCB *hdev_aio_discard(BlockDriverState *bs,
+static coroutine_fn BlockAIOCB *hdev_aio_discard(BlockDriverState *bs,
     int64_t sector_num, int nb_sectors,
-    BlockDriverCompletionFunc *cb, void *opaque)
+    BlockCompletionFunc *cb, void *opaque)
 {
     BDRVRawState *s = bs->opaque;
 
diff --git a/block/raw-win32.c b/block/raw-win32.c
index 902eab6..88a2a33 100644
--- a/block/raw-win32.c
+++ b/block/raw-win32.c
@@ -138,9 +138,9 @@ static int aio_worker(void *arg)
     return ret;
 }
 
-static BlockDriverAIOCB *paio_submit(BlockDriverState *bs, HANDLE hfile,
+static BlockAIOCB *paio_submit(BlockDriverState *bs, HANDLE hfile,
         int64_t sector_num, QEMUIOVector *qiov, int nb_sectors,
-        BlockDriverCompletionFunc *cb, void *opaque, int type)
+        BlockCompletionFunc *cb, void *opaque, int type)
 {
     RawWin32AIOData *acb = g_slice_new(RawWin32AIOData);
     ThreadPool *pool;
@@ -369,9 +369,9 @@ fail:
     return ret;
 }
 
-static BlockDriverAIOCB *raw_aio_readv(BlockDriverState *bs,
+static BlockAIOCB *raw_aio_readv(BlockDriverState *bs,
                          int64_t sector_num, QEMUIOVector *qiov, int nb_sectors,
-                         BlockDriverCompletionFunc *cb, void *opaque)
+                         BlockCompletionFunc *cb, void *opaque)
 {
     BDRVRawState *s = bs->opaque;
     if (s->aio) {
@@ -383,9 +383,9 @@ static BlockDriverAIOCB *raw_aio_readv(BlockDriverState *bs,
     }
 }
 
-static BlockDriverAIOCB *raw_aio_writev(BlockDriverState *bs,
+static BlockAIOCB *raw_aio_writev(BlockDriverState *bs,
                           int64_t sector_num, QEMUIOVector *qiov, int nb_sectors,
-                          BlockDriverCompletionFunc *cb, void *opaque)
+                          BlockCompletionFunc *cb, void *opaque)
 {
     BDRVRawState *s = bs->opaque;
     if (s->aio) {
@@ -397,8 +397,8 @@ static BlockDriverAIOCB *raw_aio_writev(BlockDriverState *bs,
     }
 }
 
-static BlockDriverAIOCB *raw_aio_flush(BlockDriverState *bs,
-                         BlockDriverCompletionFunc *cb, void *opaque)
+static BlockAIOCB *raw_aio_flush(BlockDriverState *bs,
+                         BlockCompletionFunc *cb, void *opaque)
 {
     BDRVRawState *s = bs->opaque;
     return paio_submit(bs, s->hfile, 0, NULL, 0, cb, opaque, QEMU_AIO_FLUSH);
diff --git a/block/raw_bsd.c b/block/raw_bsd.c
index f82f4c2..401b967 100644
--- a/block/raw_bsd.c
+++ b/block/raw_bsd.c
@@ -129,10 +129,10 @@ static int raw_ioctl(BlockDriverState *bs, unsigned long int req, void *buf)
     return bdrv_ioctl(bs->file, req, buf);
 }
 
-static BlockDriverAIOCB *raw_aio_ioctl(BlockDriverState *bs,
-                                       unsigned long int req, void *buf,
-                                       BlockDriverCompletionFunc *cb,
-                                       void *opaque)
+static BlockAIOCB *raw_aio_ioctl(BlockDriverState *bs,
+                                 unsigned long int req, void *buf,
+                                 BlockCompletionFunc *cb,
+                                 void *opaque)
 {
     return bdrv_aio_ioctl(bs->file, req, buf, cb, opaque);
 }
diff --git a/block/rbd.c b/block/rbd.c
index ea969e7..ceddc11 100644
--- a/block/rbd.c
+++ b/block/rbd.c
@@ -68,7 +68,7 @@ typedef enum {
 } RBDAIOCmd;
 
 typedef struct RBDAIOCB {
-    BlockDriverAIOCB common;
+    BlockAIOCB common;
     QEMUBH *bh;
     int64_t ret;
     QEMUIOVector *qiov;
@@ -542,7 +542,7 @@ static void qemu_rbd_close(BlockDriverState *bs)
  * Cancel aio. Since we don't reference acb in a non qemu threads,
  * it is safe to access it here.
  */
-static void qemu_rbd_aio_cancel(BlockDriverAIOCB *blockacb)
+static void qemu_rbd_aio_cancel(BlockAIOCB *blockacb)
 {
     RBDAIOCB *acb = (RBDAIOCB *) blockacb;
     acb->cancelled = 1;
@@ -608,13 +608,13 @@ static int rbd_aio_flush_wrapper(rbd_image_t image,
 #endif
 }
 
-static BlockDriverAIOCB *rbd_start_aio(BlockDriverState *bs,
-                                       int64_t sector_num,
-                                       QEMUIOVector *qiov,
-                                       int nb_sectors,
-                                       BlockDriverCompletionFunc *cb,
-                                       void *opaque,
-                                       RBDAIOCmd cmd)
+static BlockAIOCB *rbd_start_aio(BlockDriverState *bs,
+                                 int64_t sector_num,
+                                 QEMUIOVector *qiov,
+                                 int nb_sectors,
+                                 BlockCompletionFunc *cb,
+                                 void *opaque,
+                                 RBDAIOCmd cmd)
 {
     RBDAIOCB *acb;
     RADOSCB *rcb = NULL;
@@ -695,32 +695,32 @@ failed:
     return NULL;
 }
 
-static BlockDriverAIOCB *qemu_rbd_aio_readv(BlockDriverState *bs,
-                                            int64_t sector_num,
-                                            QEMUIOVector *qiov,
-                                            int nb_sectors,
-                                            BlockDriverCompletionFunc *cb,
-                                            void *opaque)
+static BlockAIOCB *qemu_rbd_aio_readv(BlockDriverState *bs,
+                                      int64_t sector_num,
+                                      QEMUIOVector *qiov,
+                                      int nb_sectors,
+                                      BlockCompletionFunc *cb,
+                                      void *opaque)
 {
     return rbd_start_aio(bs, sector_num, qiov, nb_sectors, cb, opaque,
                          RBD_AIO_READ);
 }
 
-static BlockDriverAIOCB *qemu_rbd_aio_writev(BlockDriverState *bs,
-                                             int64_t sector_num,
-                                             QEMUIOVector *qiov,
-                                             int nb_sectors,
-                                             BlockDriverCompletionFunc *cb,
-                                             void *opaque)
+static BlockAIOCB *qemu_rbd_aio_writev(BlockDriverState *bs,
+                                       int64_t sector_num,
+                                       QEMUIOVector *qiov,
+                                       int nb_sectors,
+                                       BlockCompletionFunc *cb,
+                                       void *opaque)
 {
     return rbd_start_aio(bs, sector_num, qiov, nb_sectors, cb, opaque,
                          RBD_AIO_WRITE);
 }
 
 #ifdef LIBRBD_SUPPORTS_AIO_FLUSH
-static BlockDriverAIOCB *qemu_rbd_aio_flush(BlockDriverState *bs,
-                                            BlockDriverCompletionFunc *cb,
-                                            void *opaque)
+static BlockAIOCB *qemu_rbd_aio_flush(BlockDriverState *bs,
+                                      BlockCompletionFunc *cb,
+                                      void *opaque)
 {
     return rbd_start_aio(bs, 0, NULL, 0, cb, opaque, RBD_AIO_FLUSH);
 }
@@ -896,11 +896,11 @@ static int qemu_rbd_snap_list(BlockDriverState *bs,
 }
 
 #ifdef LIBRBD_SUPPORTS_DISCARD
-static BlockDriverAIOCB* qemu_rbd_aio_discard(BlockDriverState *bs,
-                                              int64_t sector_num,
-                                              int nb_sectors,
-                                              BlockDriverCompletionFunc *cb,
-                                              void *opaque)
+static BlockAIOCB *qemu_rbd_aio_discard(BlockDriverState *bs,
+                                        int64_t sector_num,
+                                        int nb_sectors,
+                                        BlockCompletionFunc *cb,
+                                        void *opaque)
 {
     return rbd_start_aio(bs, sector_num, NULL, nb_sectors, cb, opaque,
                          RBD_AIO_DISCARD);
diff --git a/block/sheepdog.c b/block/sheepdog.c
index f91afc3..86085d3 100644
--- a/block/sheepdog.c
+++ b/block/sheepdog.c
@@ -301,7 +301,7 @@ enum AIOCBState {
 };
 
 struct SheepdogAIOCB {
-    BlockDriverAIOCB common;
+    BlockAIOCB common;
 
     QEMUIOVector *qiov;
 
@@ -477,7 +477,7 @@ static bool sd_acb_cancelable(const SheepdogAIOCB *acb)
     return true;
 }
 
-static void sd_aio_cancel(BlockDriverAIOCB *blockacb)
+static void sd_aio_cancel(BlockAIOCB *blockacb)
 {
     SheepdogAIOCB *acb = (SheepdogAIOCB *)blockacb;
     BDRVSheepdogState *s = acb->common.bs->opaque;
diff --git a/block/stream.c b/block/stream.c
index cdea3e8..a1dc8da 100644
--- a/block/stream.c
+++ b/block/stream.c
@@ -220,7 +220,7 @@ static const BlockJobDriver stream_job_driver = {
 void stream_start(BlockDriverState *bs, BlockDriverState *base,
                   const char *backing_file_str, int64_t speed,
                   BlockdevOnError on_error,
-                  BlockDriverCompletionFunc *cb,
+                  BlockCompletionFunc *cb,
                   void *opaque, Error **errp)
 {
     StreamBlockJob *s;
diff --git a/block/win32-aio.c b/block/win32-aio.c
index 5030e32..de273b8 100644
--- a/block/win32-aio.c
+++ b/block/win32-aio.c
@@ -44,7 +44,7 @@ struct QEMUWin32AIOState {
 };
 
 typedef struct QEMUWin32AIOCB {
-    BlockDriverAIOCB common;
+    BlockAIOCB common;
     struct QEMUWin32AIOState *ctx;
     int nbytes;
     OVERLAPPED ov;
@@ -106,7 +106,7 @@ static void win32_aio_completion_cb(EventNotifier *e)
     }
 }
 
-static void win32_aio_cancel(BlockDriverAIOCB *blockacb)
+static void win32_aio_cancel(BlockAIOCB *blockacb)
 {
     QEMUWin32AIOCB *waiocb = (QEMUWin32AIOCB *)blockacb;
 
@@ -124,10 +124,10 @@ static const AIOCBInfo win32_aiocb_info = {
     .cancel             = win32_aio_cancel,
 };
 
-BlockDriverAIOCB *win32_aio_submit(BlockDriverState *bs,
+BlockAIOCB *win32_aio_submit(BlockDriverState *bs,
         QEMUWin32AIOState *aio, HANDLE hfile,
         int64_t sector_num, QEMUIOVector *qiov, int nb_sectors,
-        BlockDriverCompletionFunc *cb, void *opaque, int type)
+        BlockCompletionFunc *cb, void *opaque, int type)
 {
     struct QEMUWin32AIOCB *waiocb;
     uint64_t offset = sector_num * 512;
diff --git a/blockjob.c b/blockjob.c
index 3af0f6c..ff0908a 100644
--- a/blockjob.c
+++ b/blockjob.c
@@ -36,7 +36,7 @@
 #include "qapi-event.h"
 
 void *block_job_create(const BlockJobDriver *driver, BlockDriverState *bs,
-                       int64_t speed, BlockDriverCompletionFunc *cb,
+                       int64_t speed, BlockCompletionFunc *cb,
                        void *opaque, Error **errp)
 {
     BlockJob *job;
@@ -155,7 +155,7 @@ void block_job_iostatus_reset(BlockJob *job)
 
 struct BlockCancelData {
     BlockJob *job;
-    BlockDriverCompletionFunc *cb;
+    BlockCompletionFunc *cb;
     void *opaque;
     bool cancelled;
     int ret;
diff --git a/dma-helpers.c b/dma-helpers.c
index 499b52b..e7bea06 100644
--- a/dma-helpers.c
+++ b/dma-helpers.c
@@ -67,9 +67,9 @@ void qemu_sglist_destroy(QEMUSGList *qsg)
 }
 
 typedef struct {
-    BlockDriverAIOCB common;
+    BlockAIOCB common;
     BlockDriverState *bs;
-    BlockDriverAIOCB *acb;
+    BlockAIOCB *acb;
     QEMUSGList *sg;
     uint64_t sector_num;
     DMADirection dir;
@@ -179,14 +179,14 @@ static void dma_bdrv_cb(void *opaque, int ret)
     assert(dbs->acb);
 }
 
-static void dma_aio_cancel(BlockDriverAIOCB *acb)
+static void dma_aio_cancel(BlockAIOCB *acb)
 {
     DMAAIOCB *dbs = container_of(acb, DMAAIOCB, common);
 
     trace_dma_aio_cancel(dbs);
 
     if (dbs->acb) {
-        BlockDriverAIOCB *acb = dbs->acb;
+        BlockAIOCB *acb = dbs->acb;
         dbs->acb = NULL;
         dbs->in_cancel = true;
         bdrv_aio_cancel(acb);
@@ -201,9 +201,9 @@ static const AIOCBInfo dma_aiocb_info = {
     .cancel             = dma_aio_cancel,
 };
 
-BlockDriverAIOCB *dma_bdrv_io(
+BlockAIOCB *dma_bdrv_io(
     BlockDriverState *bs, QEMUSGList *sg, uint64_t sector_num,
-    DMAIOFunc *io_func, BlockDriverCompletionFunc *cb,
+    DMAIOFunc *io_func, BlockCompletionFunc *cb,
     void *opaque, DMADirection dir)
 {
     DMAAIOCB *dbs = qemu_aio_get(&dma_aiocb_info, bs, cb, opaque);
@@ -226,17 +226,17 @@ BlockDriverAIOCB *dma_bdrv_io(
 }
 
 
-BlockDriverAIOCB *dma_bdrv_read(BlockDriverState *bs,
-                                QEMUSGList *sg, uint64_t sector,
-                                void (*cb)(void *opaque, int ret), void *opaque)
+BlockAIOCB *dma_bdrv_read(BlockDriverState *bs,
+                          QEMUSGList *sg, uint64_t sector,
+                          void (*cb)(void *opaque, int ret), void *opaque)
 {
     return dma_bdrv_io(bs, sg, sector, bdrv_aio_readv, cb, opaque,
                        DMA_DIRECTION_FROM_DEVICE);
 }
 
-BlockDriverAIOCB *dma_bdrv_write(BlockDriverState *bs,
-                                 QEMUSGList *sg, uint64_t sector,
-                                 void (*cb)(void *opaque, int ret), void *opaque)
+BlockAIOCB *dma_bdrv_write(BlockDriverState *bs,
+                           QEMUSGList *sg, uint64_t sector,
+                           void (*cb)(void *opaque, int ret), void *opaque)
 {
     return dma_bdrv_io(bs, sg, sector, bdrv_aio_writev, cb, opaque,
                        DMA_DIRECTION_TO_DEVICE);
diff --git a/hw/block/nvme.h b/hw/block/nvme.h
index bd8fc3e..993c511 100644
--- a/hw/block/nvme.h
+++ b/hw/block/nvme.h
@@ -636,7 +636,7 @@ typedef struct NvmeAsyncEvent {
 
 typedef struct NvmeRequest {
     struct NvmeSQueue       *sq;
-    BlockDriverAIOCB        *aiocb;
+    BlockAIOCB              *aiocb;
     uint16_t                status;
     NvmeCqe                 cqe;
     BlockAcctCookie         acct;
diff --git a/hw/ide/ahci.c b/hw/ide/ahci.c
index 0ee713b..97c997c 100644
--- a/hw/ide/ahci.c
+++ b/hw/ide/ahci.c
@@ -1104,7 +1104,7 @@ out:
 }
 
 static void ahci_start_dma(IDEDMA *dma, IDEState *s,
-                           BlockDriverCompletionFunc *dma_cb)
+                           BlockCompletionFunc *dma_cb)
 {
 #ifdef DEBUG_AHCI
     AHCIDevice *ad = DO_UPCAST(AHCIDevice, dma, dma);
diff --git a/hw/ide/ahci.h b/hw/ide/ahci.h
index 1543df7..fe32eab 100644
--- a/hw/ide/ahci.h
+++ b/hw/ide/ahci.h
@@ -241,7 +241,7 @@ typedef struct AHCIDevice AHCIDevice;
 
 typedef struct NCQTransferState {
     AHCIDevice *drive;
-    BlockDriverAIOCB *aiocb;
+    BlockAIOCB *aiocb;
     QEMUSGList sglist;
     BlockAcctCookie acct;
     uint16_t sector_count;
diff --git a/hw/ide/core.c b/hw/ide/core.c
index 191f893..36df217 100644
--- a/hw/ide/core.c
+++ b/hw/ide/core.c
@@ -360,15 +360,15 @@ static void ide_set_signature(IDEState *s)
 }
 
 typedef struct TrimAIOCB {
-    BlockDriverAIOCB common;
+    BlockAIOCB common;
     QEMUBH *bh;
     int ret;
     QEMUIOVector *qiov;
-    BlockDriverAIOCB *aiocb;
+    BlockAIOCB *aiocb;
     int i, j;
 } TrimAIOCB;
 
-static void trim_aio_cancel(BlockDriverAIOCB *acb)
+static void trim_aio_cancel(BlockAIOCB *acb)
 {
     TrimAIOCB *iocb = container_of(acb, TrimAIOCB, common);
 
@@ -440,9 +440,9 @@ static void ide_issue_trim_cb(void *opaque, int ret)
     }
 }
 
-BlockDriverAIOCB *ide_issue_trim(BlockDriverState *bs,
+BlockAIOCB *ide_issue_trim(BlockDriverState *bs,
         int64_t sector_num, QEMUIOVector *qiov, int nb_sectors,
-        BlockDriverCompletionFunc *cb, void *opaque)
+        BlockCompletionFunc *cb, void *opaque)
 {
     TrimAIOCB *iocb;
 
@@ -784,7 +784,7 @@ static void ide_sector_start_dma(IDEState *s, enum ide_dma_cmd dma_cmd)
     ide_start_dma(s, ide_dma_cb);
 }
 
-void ide_start_dma(IDEState *s, BlockDriverCompletionFunc *cb)
+void ide_start_dma(IDEState *s, BlockCompletionFunc *cb)
 {
     if (s->bus->dma->ops->start_dma) {
         s->bus->dma->ops->start_dma(s->bus->dma, s, cb);
diff --git a/hw/ide/internal.h b/hw/ide/internal.h
index 5c19f79..9314c80 100644
--- a/hw/ide/internal.h
+++ b/hw/ide/internal.h
@@ -319,7 +319,7 @@ typedef enum { IDE_HD, IDE_CD, IDE_CFATA } IDEDriveKind;
 
 typedef void EndTransferFunc(IDEState *);
 
-typedef void DMAStartFunc(IDEDMA *, IDEState *, BlockDriverCompletionFunc *);
+typedef void DMAStartFunc(IDEDMA *, IDEState *, BlockCompletionFunc *);
 typedef void DMAVoidFunc(IDEDMA *);
 typedef int DMAIntFunc(IDEDMA *, int);
 typedef void DMAStopFunc(IDEDMA *, bool);
@@ -389,7 +389,7 @@ struct IDEState {
     int cd_sector_size;
     int atapi_dma; /* true if dma is requested for the packet cmd */
     BlockAcctCookie acct;
-    BlockDriverAIOCB *pio_aiocb;
+    BlockAIOCB *pio_aiocb;
     struct iovec iov;
     QEMUIOVector qiov;
     /* ATA DMA state */
@@ -442,7 +442,7 @@ struct IDEDMA {
     const struct IDEDMAOps *ops;
     struct iovec iov;
     QEMUIOVector qiov;
-    BlockDriverAIOCB *aiocb;
+    BlockAIOCB *aiocb;
 };
 
 struct IDEBus {
@@ -521,7 +521,7 @@ void ide_bus_reset(IDEBus *bus);
 int64_t ide_get_sector(IDEState *s);
 void ide_set_sector(IDEState *s, int64_t sector_num);
 
-void ide_start_dma(IDEState *s, BlockDriverCompletionFunc *cb);
+void ide_start_dma(IDEState *s, BlockCompletionFunc *cb);
 void ide_dma_error(IDEState *s);
 
 void ide_atapi_cmd_ok(IDEState *s);
@@ -555,9 +555,9 @@ void ide_transfer_start(IDEState *s, uint8_t *buf, int size,
                         EndTransferFunc *end_transfer_func);
 void ide_transfer_stop(IDEState *s);
 void ide_set_inactive(IDEState *s, bool more);
-BlockDriverAIOCB *ide_issue_trim(BlockDriverState *bs,
+BlockAIOCB *ide_issue_trim(BlockDriverState *bs,
         int64_t sector_num, QEMUIOVector *qiov, int nb_sectors,
-        BlockDriverCompletionFunc *cb, void *opaque);
+        BlockCompletionFunc *cb, void *opaque);
 
 /* hw/ide/atapi.c */
 void ide_atapi_cmd(IDEState *s);
diff --git a/hw/ide/macio.c b/hw/ide/macio.c
index b0c0d40..371e172 100644
--- a/hw/ide/macio.c
+++ b/hw/ide/macio.c
@@ -555,7 +555,7 @@ static void ide_nop_restart(void *opaque, int x, RunState y)
 }
 
 static void ide_dbdma_start(IDEDMA *dma, IDEState *s,
-                            BlockDriverCompletionFunc *cb)
+                            BlockCompletionFunc *cb)
 {
     MACIOIDEState *m = container_of(dma, MACIOIDEState, dma);
 
diff --git a/hw/ide/pci.c b/hw/ide/pci.c
index 2397f35..6ff1c58 100644
--- a/hw/ide/pci.c
+++ b/hw/ide/pci.c
@@ -38,7 +38,7 @@
         IDE_RETRY_READ | IDE_RETRY_FLUSH)
 
 static void bmdma_start_dma(IDEDMA *dma, IDEState *s,
-                            BlockDriverCompletionFunc *dma_cb)
+                            BlockCompletionFunc *dma_cb)
 {
     BMDMAState *bm = DO_UPCAST(BMDMAState, dma, dma);
 
diff --git a/hw/ide/pci.h b/hw/ide/pci.h
index 517711f..2e9314a 100644
--- a/hw/ide/pci.h
+++ b/hw/ide/pci.h
@@ -23,7 +23,7 @@ typedef struct BMDMAState {
     uint32_t cur_prd_addr;
     uint32_t cur_prd_len;
     uint8_t unit;
-    BlockDriverCompletionFunc *dma_cb;
+    BlockCompletionFunc *dma_cb;
     int64_t sector_num;
     uint32_t nsector;
     MemoryRegion addr_ioport;
diff --git a/hw/ppc/mac.h b/hw/ppc/mac.h
index aff2b9a..8bdba30 100644
--- a/hw/ppc/mac.h
+++ b/hw/ppc/mac.h
@@ -131,7 +131,7 @@ typedef struct MACIOIDEState {
 
     MemoryRegion mem;
     IDEBus bus;
-    BlockDriverAIOCB *aiocb;
+    BlockAIOCB *aiocb;
     IDEDMA dma;
     void *dbdma;
     bool dma_active;
diff --git a/hw/scsi/scsi-generic.c b/hw/scsi/scsi-generic.c
index 20587b4..5301886 100644
--- a/hw/scsi/scsi-generic.c
+++ b/hw/scsi/scsi-generic.c
@@ -157,7 +157,7 @@ static void scsi_cancel_io(SCSIRequest *req)
 
 static int execute_command(BlockDriverState *bdrv,
                            SCSIGenericReq *r, int direction,
-			   BlockDriverCompletionFunc *complete)
+                           BlockCompletionFunc *complete)
 {
     r->io_header.interface_id = 'S';
     r->io_header.dxfer_direction = direction;
diff --git a/include/block/aio.h b/include/block/aio.h
index 4603c0f..57619ab 100644
--- a/include/block/aio.h
+++ b/include/block/aio.h
@@ -22,23 +22,23 @@
 #include "qemu/rfifolock.h"
 #include "qemu/timer.h"
 
-typedef struct BlockDriverAIOCB BlockDriverAIOCB;
-typedef void BlockDriverCompletionFunc(void *opaque, int ret);
+typedef struct BlockAIOCB BlockAIOCB;
+typedef void BlockCompletionFunc(void *opaque, int ret);
 
 typedef struct AIOCBInfo {
-    void (*cancel)(BlockDriverAIOCB *acb);
+    void (*cancel)(BlockAIOCB *acb);
     size_t aiocb_size;
 } AIOCBInfo;
 
-struct BlockDriverAIOCB {
+struct BlockAIOCB {
     const AIOCBInfo *aiocb_info;
     BlockDriverState *bs;
-    BlockDriverCompletionFunc *cb;
+    BlockCompletionFunc *cb;
     void *opaque;
 };
 
 void *qemu_aio_get(const AIOCBInfo *aiocb_info, BlockDriverState *bs,
-                   BlockDriverCompletionFunc *cb, void *opaque);
+                   BlockCompletionFunc *cb, void *opaque);
 void qemu_aio_release(void *p);
 
 typedef struct AioHandler AioHandler;
diff --git a/include/block/block.h b/include/block/block.h
index c8f33c0..0d8e5f7 100644
--- a/include/block/block.h
+++ b/include/block/block.h
@@ -247,9 +247,9 @@ int bdrv_write(BlockDriverState *bs, int64_t sector_num,
                const uint8_t *buf, int nb_sectors);
 int bdrv_write_zeroes(BlockDriverState *bs, int64_t sector_num,
                int nb_sectors, BdrvRequestFlags flags);
-BlockDriverAIOCB *bdrv_aio_write_zeroes(BlockDriverState *bs, int64_t sector_num,
-                                        int nb_sectors, BdrvRequestFlags flags,
-                                        BlockDriverCompletionFunc *cb, void *opaque);
+BlockAIOCB *bdrv_aio_write_zeroes(BlockDriverState *bs, int64_t sector_num,
+                                  int nb_sectors, BdrvRequestFlags flags,
+                                  BlockCompletionFunc *cb, void *opaque);
 int bdrv_make_zero(BlockDriverState *bs, BdrvRequestFlags flags);
 int bdrv_pread(BlockDriverState *bs, int64_t offset,
                void *buf, int count);
@@ -325,18 +325,18 @@ BlockDriverState *check_to_replace_node(const char *node_name, Error **errp);
 /* async block I/O */
 typedef void BlockDriverDirtyHandler(BlockDriverState *bs, int64_t sector,
                                      int sector_num);
-BlockDriverAIOCB *bdrv_aio_readv(BlockDriverState *bs, int64_t sector_num,
-                                 QEMUIOVector *iov, int nb_sectors,
-                                 BlockDriverCompletionFunc *cb, void *opaque);
-BlockDriverAIOCB *bdrv_aio_writev(BlockDriverState *bs, int64_t sector_num,
-                                  QEMUIOVector *iov, int nb_sectors,
-                                  BlockDriverCompletionFunc *cb, void *opaque);
-BlockDriverAIOCB *bdrv_aio_flush(BlockDriverState *bs,
-                                 BlockDriverCompletionFunc *cb, void *opaque);
-BlockDriverAIOCB *bdrv_aio_discard(BlockDriverState *bs,
-                                   int64_t sector_num, int nb_sectors,
-                                   BlockDriverCompletionFunc *cb, void *opaque);
-void bdrv_aio_cancel(BlockDriverAIOCB *acb);
+BlockAIOCB *bdrv_aio_readv(BlockDriverState *bs, int64_t sector_num,
+                           QEMUIOVector *iov, int nb_sectors,
+                           BlockCompletionFunc *cb, void *opaque);
+BlockAIOCB *bdrv_aio_writev(BlockDriverState *bs, int64_t sector_num,
+                            QEMUIOVector *iov, int nb_sectors,
+                            BlockCompletionFunc *cb, void *opaque);
+BlockAIOCB *bdrv_aio_flush(BlockDriverState *bs,
+                           BlockCompletionFunc *cb, void *opaque);
+BlockAIOCB *bdrv_aio_discard(BlockDriverState *bs,
+                             int64_t sector_num, int nb_sectors,
+                             BlockCompletionFunc *cb, void *opaque);
+void bdrv_aio_cancel(BlockAIOCB *acb);
 
 typedef struct BlockRequest {
     /* Fields to be filled by multiwrite caller */
@@ -344,7 +344,7 @@ typedef struct BlockRequest {
     int nb_sectors;
     int flags;
     QEMUIOVector *qiov;
-    BlockDriverCompletionFunc *cb;
+    BlockCompletionFunc *cb;
     void *opaque;
 
     /* Filled by multiwrite implementation */
@@ -356,9 +356,9 @@ int bdrv_aio_multiwrite(BlockDriverState *bs, BlockRequest *reqs,
 
 /* sg packet commands */
 int bdrv_ioctl(BlockDriverState *bs, unsigned long int req, void *buf);
-BlockDriverAIOCB *bdrv_aio_ioctl(BlockDriverState *bs,
+BlockAIOCB *bdrv_aio_ioctl(BlockDriverState *bs,
         unsigned long int req, void *buf,
-        BlockDriverCompletionFunc *cb, void *opaque);
+        BlockCompletionFunc *cb, void *opaque);
 
 /* Invalidate any cached metadata used by image formats */
 void bdrv_invalidate_cache(BlockDriverState *bs, Error **errp);
diff --git a/include/block/block_int.h b/include/block/block_int.h
index 000abfa..4d6a802 100644
--- a/include/block/block_int.h
+++ b/include/block/block_int.h
@@ -127,17 +127,17 @@ struct BlockDriver {
     void (*bdrv_refresh_filename)(BlockDriverState *bs);
 
     /* aio */
-    BlockDriverAIOCB *(*bdrv_aio_readv)(BlockDriverState *bs,
+    BlockAIOCB *(*bdrv_aio_readv)(BlockDriverState *bs,
         int64_t sector_num, QEMUIOVector *qiov, int nb_sectors,
-        BlockDriverCompletionFunc *cb, void *opaque);
-    BlockDriverAIOCB *(*bdrv_aio_writev)(BlockDriverState *bs,
+        BlockCompletionFunc *cb, void *opaque);
+    BlockAIOCB *(*bdrv_aio_writev)(BlockDriverState *bs,
         int64_t sector_num, QEMUIOVector *qiov, int nb_sectors,
-        BlockDriverCompletionFunc *cb, void *opaque);
-    BlockDriverAIOCB *(*bdrv_aio_flush)(BlockDriverState *bs,
-        BlockDriverCompletionFunc *cb, void *opaque);
-    BlockDriverAIOCB *(*bdrv_aio_discard)(BlockDriverState *bs,
+        BlockCompletionFunc *cb, void *opaque);
+    BlockAIOCB *(*bdrv_aio_flush)(BlockDriverState *bs,
+        BlockCompletionFunc *cb, void *opaque);
+    BlockAIOCB *(*bdrv_aio_discard)(BlockDriverState *bs,
         int64_t sector_num, int nb_sectors,
-        BlockDriverCompletionFunc *cb, void *opaque);
+        BlockCompletionFunc *cb, void *opaque);
 
     int coroutine_fn (*bdrv_co_readv)(BlockDriverState *bs,
         int64_t sector_num, int nb_sectors, QEMUIOVector *qiov);
@@ -217,9 +217,9 @@ struct BlockDriver {
 
     /* to control generic scsi devices */
     int (*bdrv_ioctl)(BlockDriverState *bs, unsigned long int req, void *buf);
-    BlockDriverAIOCB *(*bdrv_aio_ioctl)(BlockDriverState *bs,
+    BlockAIOCB *(*bdrv_aio_ioctl)(BlockDriverState *bs,
         unsigned long int req, void *buf,
-        BlockDriverCompletionFunc *cb, void *opaque);
+        BlockCompletionFunc *cb, void *opaque);
 
     /* List of options for creating images, terminated by name == NULL */
     QemuOptsList *create_opts;
@@ -503,7 +503,7 @@ int is_windows_drive(const char *filename);
  */
 void stream_start(BlockDriverState *bs, BlockDriverState *base,
                   const char *base_id, int64_t speed, BlockdevOnError on_error,
-                  BlockDriverCompletionFunc *cb,
+                  BlockCompletionFunc *cb,
                   void *opaque, Error **errp);
 
 /**
@@ -521,7 +521,7 @@ void stream_start(BlockDriverState *bs, BlockDriverState *base,
  */
 void commit_start(BlockDriverState *bs, BlockDriverState *base,
                  BlockDriverState *top, int64_t speed,
-                 BlockdevOnError on_error, BlockDriverCompletionFunc *cb,
+                 BlockdevOnError on_error, BlockCompletionFunc *cb,
                  void *opaque, const char *backing_file_str, Error **errp);
 /**
  * commit_active_start:
@@ -537,7 +537,7 @@ void commit_start(BlockDriverState *bs, BlockDriverState *base,
 void commit_active_start(BlockDriverState *bs, BlockDriverState *base,
                          int64_t speed,
                          BlockdevOnError on_error,
-                         BlockDriverCompletionFunc *cb,
+                         BlockCompletionFunc *cb,
                          void *opaque, Error **errp);
 /*
  * mirror_start:
@@ -565,7 +565,7 @@ void mirror_start(BlockDriverState *bs, BlockDriverState *target,
                   int64_t speed, int64_t granularity, int64_t buf_size,
                   MirrorSyncMode mode, BlockdevOnError on_source_error,
                   BlockdevOnError on_target_error,
-                  BlockDriverCompletionFunc *cb,
+                  BlockCompletionFunc *cb,
                   void *opaque, Error **errp);
 
 /*
@@ -586,7 +586,7 @@ void backup_start(BlockDriverState *bs, BlockDriverState *target,
                   int64_t speed, MirrorSyncMode sync_mode,
                   BlockdevOnError on_source_error,
                   BlockdevOnError on_target_error,
-                  BlockDriverCompletionFunc *cb, void *opaque,
+                  BlockCompletionFunc *cb, void *opaque,
                   Error **errp);
 
 #endif /* BLOCK_INT_H */
diff --git a/include/block/blockjob.h b/include/block/blockjob.h
index 60aa835..acb399f 100644
--- a/include/block/blockjob.h
+++ b/include/block/blockjob.h
@@ -104,7 +104,7 @@ struct BlockJob {
     int64_t speed;
 
     /** The completion function that will be called when the job completes.  */
-    BlockDriverCompletionFunc *cb;
+    BlockCompletionFunc *cb;
 
     /** Block other operations when block job is running */
     Error *blocker;
@@ -132,7 +132,7 @@ struct BlockJob {
  * called from a wrapper that is specific to the job type.
  */
 void *block_job_create(const BlockJobDriver *driver, BlockDriverState *bs,
-                       int64_t speed, BlockDriverCompletionFunc *cb,
+                       int64_t speed, BlockCompletionFunc *cb,
                        void *opaque, Error **errp);
 
 /**
diff --git a/include/block/thread-pool.h b/include/block/thread-pool.h
index 4723752..42eb5e8 100644
--- a/include/block/thread-pool.h
+++ b/include/block/thread-pool.h
@@ -27,9 +27,9 @@ typedef struct ThreadPool ThreadPool;
 ThreadPool *thread_pool_new(struct AioContext *ctx);
 void thread_pool_free(ThreadPool *pool);
 
-BlockDriverAIOCB *thread_pool_submit_aio(ThreadPool *pool,
+BlockAIOCB *thread_pool_submit_aio(ThreadPool *pool,
         ThreadPoolFunc *func, void *arg,
-        BlockDriverCompletionFunc *cb, void *opaque);
+        BlockCompletionFunc *cb, void *opaque);
 int coroutine_fn thread_pool_submit_co(ThreadPool *pool,
         ThreadPoolFunc *func, void *arg);
 void thread_pool_submit(ThreadPool *pool, ThreadPoolFunc *func, void *arg);
diff --git a/include/hw/scsi/scsi.h b/include/hw/scsi/scsi.h
index 2e3a8f9..e3e27cb 100644
--- a/include/hw/scsi/scsi.h
+++ b/include/hw/scsi/scsi.h
@@ -52,7 +52,7 @@ struct SCSIRequest {
     uint32_t          status;
     size_t            resid;
     SCSICommand       cmd;
-    BlockDriverAIOCB  *aiocb;
+    BlockAIOCB        *aiocb;
     QEMUSGList        *sg;
     bool              dma_started;
     uint8_t sense[SCSI_SENSE_BUF_SIZE];
diff --git a/include/monitor/monitor.h b/include/monitor/monitor.h
index 78a5fc8..47606d0 100644
--- a/include/monitor/monitor.h
+++ b/include/monitor/monitor.h
@@ -27,10 +27,10 @@ int monitor_suspend(Monitor *mon);
 void monitor_resume(Monitor *mon);
 
 int monitor_read_bdrv_key_start(Monitor *mon, BlockDriverState *bs,
-                                BlockDriverCompletionFunc *completion_cb,
+                                BlockCompletionFunc *completion_cb,
                                 void *opaque);
 int monitor_read_block_device_key(Monitor *mon, const char *device,
-                                  BlockDriverCompletionFunc *completion_cb,
+                                  BlockCompletionFunc *completion_cb,
                                   void *opaque);
 
 int monitor_get_fd(Monitor *mon, const char *fdname, Error **errp);
diff --git a/include/sysemu/dma.h b/include/sysemu/dma.h
index 00f21f3..464f9f7 100644
--- a/include/sysemu/dma.h
+++ b/include/sysemu/dma.h
@@ -196,20 +196,20 @@ void qemu_sglist_add(QEMUSGList *qsg, dma_addr_t base, dma_addr_t len);
 void qemu_sglist_destroy(QEMUSGList *qsg);
 #endif
 
-typedef BlockDriverAIOCB *DMAIOFunc(BlockDriverState *bs, int64_t sector_num,
-                                 QEMUIOVector *iov, int nb_sectors,
-                                 BlockDriverCompletionFunc *cb, void *opaque);
+typedef BlockAIOCB *DMAIOFunc(BlockDriverState *bs, int64_t sector_num,
+                              QEMUIOVector *iov, int nb_sectors,
+                              BlockCompletionFunc *cb, void *opaque);
 
-BlockDriverAIOCB *dma_bdrv_io(BlockDriverState *bs,
-                              QEMUSGList *sg, uint64_t sector_num,
-                              DMAIOFunc *io_func, BlockDriverCompletionFunc *cb,
-                              void *opaque, DMADirection dir);
-BlockDriverAIOCB *dma_bdrv_read(BlockDriverState *bs,
-                                QEMUSGList *sg, uint64_t sector,
-                                BlockDriverCompletionFunc *cb, void *opaque);
-BlockDriverAIOCB *dma_bdrv_write(BlockDriverState *bs,
-                                 QEMUSGList *sg, uint64_t sector,
-                                 BlockDriverCompletionFunc *cb, void *opaque);
+BlockAIOCB *dma_bdrv_io(BlockDriverState *bs,
+                        QEMUSGList *sg, uint64_t sector_num,
+                        DMAIOFunc *io_func, BlockCompletionFunc *cb,
+                        void *opaque, DMADirection dir);
+BlockAIOCB *dma_bdrv_read(BlockDriverState *bs,
+                          QEMUSGList *sg, uint64_t sector,
+                          BlockCompletionFunc *cb, void *opaque);
+BlockAIOCB *dma_bdrv_write(BlockDriverState *bs,
+                           QEMUSGList *sg, uint64_t sector,
+                           BlockCompletionFunc *cb, void *opaque);
 uint64_t dma_buf_read(uint8_t *ptr, int32_t len, QEMUSGList *sg);
 uint64_t dma_buf_write(uint8_t *ptr, int32_t len, QEMUSGList *sg);
 
diff --git a/monitor.c b/monitor.c
index 565d60e..a11dc58 100644
--- a/monitor.c
+++ b/monitor.c
@@ -206,7 +206,7 @@ struct Monitor {
     ReadLineState *rs;
     MonitorControl *mc;
     CPUState *mon_cpu;
-    BlockDriverCompletionFunc *password_completion_cb;
+    BlockCompletionFunc *password_completion_cb;
     void *password_opaque;
     mon_cmd_t *cmd_table;
     QError *error;
@@ -5362,7 +5362,7 @@ ReadLineState *monitor_get_rs(Monitor *mon)
 }
 
 int monitor_read_bdrv_key_start(Monitor *mon, BlockDriverState *bs,
-                                BlockDriverCompletionFunc *completion_cb,
+                                BlockCompletionFunc *completion_cb,
                                 void *opaque)
 {
     int err;
@@ -5394,7 +5394,7 @@ int monitor_read_bdrv_key_start(Monitor *mon, BlockDriverState *bs,
 }
 
 int monitor_read_block_device_key(Monitor *mon, const char *device,
-                                  BlockDriverCompletionFunc *completion_cb,
+                                  BlockCompletionFunc *completion_cb,
                                   void *opaque)
 {
     BlockDriverState *bs;
diff --git a/tests/test-thread-pool.c b/tests/test-thread-pool.c
index f40b7fc..acc911b 100644
--- a/tests/test-thread-pool.c
+++ b/tests/test-thread-pool.c
@@ -10,7 +10,7 @@ static ThreadPool *pool;
 static int active;
 
 typedef struct {
-    BlockDriverAIOCB *aiocb;
+    BlockAIOCB *aiocb;
     int n;
     int ret;
 } WorkerTestData;
diff --git a/thread-pool.c b/thread-pool.c
index bc07d7a..f9e9901 100644
--- a/thread-pool.c
+++ b/thread-pool.c
@@ -35,7 +35,7 @@ enum ThreadState {
 };
 
 struct ThreadPoolElement {
-    BlockDriverAIOCB common;
+    BlockAIOCB common;
     ThreadPool *pool;
     ThreadPoolFunc *func;
     void *arg;
@@ -201,7 +201,7 @@ restart:
     }
 }
 
-static void thread_pool_cancel(BlockDriverAIOCB *acb)
+static void thread_pool_cancel(BlockAIOCB *acb)
 {
     ThreadPoolElement *elem = (ThreadPoolElement *)acb;
     ThreadPool *pool = elem->pool;
@@ -235,9 +235,9 @@ static const AIOCBInfo thread_pool_aiocb_info = {
     .cancel             = thread_pool_cancel,
 };
 
-BlockDriverAIOCB *thread_pool_submit_aio(ThreadPool *pool,
+BlockAIOCB *thread_pool_submit_aio(ThreadPool *pool,
         ThreadPoolFunc *func, void *arg,
-        BlockDriverCompletionFunc *cb, void *opaque)
+        BlockCompletionFunc *cb, void *opaque)
 {
     ThreadPoolElement *req;
 
-- 
1.9.3

^ permalink raw reply related	[flat|nested] 56+ messages in thread

* [Qemu-devel] [PATCH v2 12/23] virtio-blk: Drop redundant VirtIOBlock member conf
  2014-09-13 15:00 [Qemu-devel] [PATCH v2 00/23] Split BlockBackend off BDS with an axe Markus Armbruster
                   ` (10 preceding siblings ...)
  2014-09-13 15:00 ` [Qemu-devel] [PATCH v2 11/23] block: Rename BlockDriverAIOCB* to BlockAIOCB* Markus Armbruster
@ 2014-09-13 15:00 ` Markus Armbruster
  2014-09-13 15:00 ` [Qemu-devel] [PATCH v2 13/23] virtio-blk: Rename VirtIOBlkConf variables to conf Markus Armbruster
                   ` (11 subsequent siblings)
  23 siblings, 0 replies; 56+ messages in thread
From: Markus Armbruster @ 2014-09-13 15:00 UTC (permalink / raw)
  To: qemu-devel; +Cc: kwolf, benoit.canet, stefanha

Commit 12c5674 turned it into a pointer to member blk.conf.

Signed-off-by: Markus Armbruster <armbru@redhat.com>
---
 hw/block/virtio-blk.c          | 28 ++++++++++++++--------------
 include/hw/virtio/virtio-blk.h |  1 -
 2 files changed, 14 insertions(+), 15 deletions(-)

diff --git a/hw/block/virtio-blk.c b/hw/block/virtio-blk.c
index a7f2827..0be7203 100644
--- a/hw/block/virtio-blk.c
+++ b/hw/block/virtio-blk.c
@@ -297,7 +297,7 @@ static bool virtio_blk_sect_range_ok(VirtIOBlock *dev,
     if (sector & dev->sector_mask) {
         return false;
     }
-    if (size % dev->conf->logical_block_size) {
+    if (size % dev->blk.conf.logical_block_size) {
         return false;
     }
     bdrv_get_geometry(dev->bs, &total_sectors);
@@ -516,19 +516,20 @@ static void virtio_blk_reset(VirtIODevice *vdev)
 static void virtio_blk_update_config(VirtIODevice *vdev, uint8_t *config)
 {
     VirtIOBlock *s = VIRTIO_BLK(vdev);
+    BlockConf *conf = &s->blk.conf;
     struct virtio_blk_config blkcfg;
     uint64_t capacity;
-    int blk_size = s->conf->logical_block_size;
+    int blk_size = conf->logical_block_size;
 
     bdrv_get_geometry(s->bs, &capacity);
     memset(&blkcfg, 0, sizeof(blkcfg));
     virtio_stq_p(vdev, &blkcfg.capacity, capacity);
     virtio_stl_p(vdev, &blkcfg.seg_max, 128 - 2);
-    virtio_stw_p(vdev, &blkcfg.cylinders, s->conf->cyls);
+    virtio_stw_p(vdev, &blkcfg.cylinders, conf->cyls);
     virtio_stl_p(vdev, &blkcfg.blk_size, blk_size);
-    virtio_stw_p(vdev, &blkcfg.min_io_size, s->conf->min_io_size / blk_size);
-    virtio_stw_p(vdev, &blkcfg.opt_io_size, s->conf->opt_io_size / blk_size);
-    blkcfg.heads = s->conf->heads;
+    virtio_stw_p(vdev, &blkcfg.min_io_size, conf->min_io_size / blk_size);
+    virtio_stw_p(vdev, &blkcfg.opt_io_size, conf->opt_io_size / blk_size);
+    blkcfg.heads = conf->heads;
     /*
      * We must ensure that the block device capacity is a multiple of
      * the logical block size. If that is not the case, let's use
@@ -540,13 +541,13 @@ static void virtio_blk_update_config(VirtIODevice *vdev, uint8_t *config)
      * divided by 512 - instead it is the amount of blk_size blocks
      * per track (cylinder).
      */
-    if (bdrv_getlength(s->bs) /  s->conf->heads / s->conf->secs % blk_size) {
-        blkcfg.sectors = s->conf->secs & ~s->sector_mask;
+    if (bdrv_getlength(s->bs) /  conf->heads / conf->secs % blk_size) {
+        blkcfg.sectors = conf->secs & ~s->sector_mask;
     } else {
-        blkcfg.sectors = s->conf->secs;
+        blkcfg.sectors = conf->secs;
     }
     blkcfg.size_max = 0;
-    blkcfg.physical_block_exp = get_physical_block_exp(s->conf);
+    blkcfg.physical_block_exp = get_physical_block_exp(&s->blk.conf);
     blkcfg.alignment_offset = 0;
     blkcfg.wce = bdrv_enable_write_cache(s->bs);
     memcpy(config, &blkcfg, sizeof(struct virtio_blk_config));
@@ -753,9 +754,8 @@ static void virtio_blk_device_realize(DeviceState *dev, Error **errp)
                 sizeof(struct virtio_blk_config));
 
     s->bs = blk->conf.bs;
-    s->conf = &blk->conf;
     s->rq = NULL;
-    s->sector_mask = (s->conf->logical_block_size / BDRV_SECTOR_SIZE) - 1;
+    s->sector_mask = (s->blk.conf.logical_block_size / BDRV_SECTOR_SIZE) - 1;
 
     s->vq = virtio_add_queue(vdev, 128, virtio_blk_handle_output);
     s->complete_request = virtio_blk_complete_request;
@@ -774,11 +774,11 @@ static void virtio_blk_device_realize(DeviceState *dev, Error **errp)
     register_savevm(dev, "virtio-blk", virtio_blk_id++, 2,
                     virtio_blk_save, virtio_blk_load, s);
     bdrv_set_dev_ops(s->bs, &virtio_block_ops, s);
-    bdrv_set_guest_block_size(s->bs, s->conf->logical_block_size);
+    bdrv_set_guest_block_size(s->bs, s->blk.conf.logical_block_size);
 
     bdrv_iostatus_enable(s->bs);
 
-    add_boot_device_path(s->conf->bootindex, dev, "/disk@0,0");
+    add_boot_device_path(s->blk.conf.bootindex, dev, "/disk@0,0");
 }
 
 static void virtio_blk_device_unrealize(DeviceState *dev, Error **errp)
diff --git a/include/hw/virtio/virtio-blk.h b/include/hw/virtio/virtio-blk.h
index afb7b8d..1329482 100644
--- a/include/hw/virtio/virtio-blk.h
+++ b/include/hw/virtio/virtio-blk.h
@@ -124,7 +124,6 @@ typedef struct VirtIOBlock {
     VirtQueue *vq;
     void *rq;
     QEMUBH *bh;
-    BlockConf *conf;
     VirtIOBlkConf blk;
     unsigned short sector_mask;
     bool original_wce;
-- 
1.9.3

^ permalink raw reply related	[flat|nested] 56+ messages in thread

* [Qemu-devel] [PATCH v2 13/23] virtio-blk: Rename VirtIOBlkConf variables to conf
  2014-09-13 15:00 [Qemu-devel] [PATCH v2 00/23] Split BlockBackend off BDS with an axe Markus Armbruster
                   ` (11 preceding siblings ...)
  2014-09-13 15:00 ` [Qemu-devel] [PATCH v2 12/23] virtio-blk: Drop redundant VirtIOBlock member conf Markus Armbruster
@ 2014-09-13 15:00 ` Markus Armbruster
  2014-09-13 15:00 ` [Qemu-devel] [PATCH v2 14/23] hw: Convert from BlockDriverState to BlockBackend, mostly Markus Armbruster
                   ` (10 subsequent siblings)
  23 siblings, 0 replies; 56+ messages in thread
From: Markus Armbruster @ 2014-09-13 15:00 UTC (permalink / raw)
  To: qemu-devel; +Cc: kwolf, benoit.canet, stefanha

This is consistent with how VirtIOFOOConf variables are named
elsewhere, and makes blk available for BlockBackend variables.

Signed-off-by: Markus Armbruster <armbru@redhat.com>
---
 hw/block/dataplane/virtio-blk.c | 33 +++++++++++++-------------
 hw/block/dataplane/virtio-blk.h |  2 +-
 hw/block/virtio-blk.c           | 52 ++++++++++++++++++++---------------------
 include/hw/virtio/virtio-blk.h  |  2 +-
 4 files changed, 45 insertions(+), 44 deletions(-)

diff --git a/hw/block/dataplane/virtio-blk.c b/hw/block/dataplane/virtio-blk.c
index b55188c..af67dc3 100644
--- a/hw/block/dataplane/virtio-blk.c
+++ b/hw/block/dataplane/virtio-blk.c
@@ -30,7 +30,7 @@ struct VirtIOBlockDataPlane {
     bool stopping;
     bool disabled;
 
-    VirtIOBlkConf *blk;
+    VirtIOBlkConf *conf;
 
     VirtIODevice *vdev;
     Vring vring;                    /* virtqueue vring */
@@ -94,7 +94,7 @@ static void handle_notify(EventNotifier *e)
     VirtIOBlock *vblk = VIRTIO_BLK(s->vdev);
 
     event_notifier_test_and_clear(&s->host_notifier);
-    bdrv_io_plug(s->blk->conf.bs);
+    bdrv_io_plug(s->conf->conf.bs);
     for (;;) {
         MultiReqBuffer mrb = {
             .num_writes = 0,
@@ -120,7 +120,7 @@ static void handle_notify(EventNotifier *e)
             virtio_blk_handle_request(req, &mrb);
         }
 
-        virtio_submit_multiwrite(s->blk->conf.bs, &mrb);
+        virtio_submit_multiwrite(s->conf->conf.bs, &mrb);
 
         if (likely(ret == -EAGAIN)) { /* vring emptied */
             /* Re-enable guest->host notifies and stop processing the vring.
@@ -133,11 +133,11 @@ static void handle_notify(EventNotifier *e)
             break;
         }
     }
-    bdrv_io_unplug(s->blk->conf.bs);
+    bdrv_io_unplug(s->conf->conf.bs);
 }
 
 /* Context: QEMU global mutex held */
-void virtio_blk_data_plane_create(VirtIODevice *vdev, VirtIOBlkConf *blk,
+void virtio_blk_data_plane_create(VirtIODevice *vdev, VirtIOBlkConf *conf,
                                   VirtIOBlockDataPlane **dataplane,
                                   Error **errp)
 {
@@ -148,7 +148,7 @@ void virtio_blk_data_plane_create(VirtIODevice *vdev, VirtIOBlkConf *blk,
 
     *dataplane = NULL;
 
-    if (!blk->data_plane && !blk->iothread) {
+    if (!conf->data_plane && !conf->iothread) {
         return;
     }
 
@@ -163,7 +163,8 @@ void virtio_blk_data_plane_create(VirtIODevice *vdev, VirtIOBlkConf *blk,
     /* If dataplane is (re-)enabled while the guest is running there could be
      * block jobs that can conflict.
      */
-    if (bdrv_op_is_blocked(blk->conf.bs, BLOCK_OP_TYPE_DATAPLANE, &local_err)) {
+    if (bdrv_op_is_blocked(conf->conf.bs, BLOCK_OP_TYPE_DATAPLANE,
+                           &local_err)) {
         error_report("cannot start dataplane thread: %s",
                       error_get_pretty(local_err));
         error_free(local_err);
@@ -172,10 +173,10 @@ void virtio_blk_data_plane_create(VirtIODevice *vdev, VirtIOBlkConf *blk,
 
     s = g_new0(VirtIOBlockDataPlane, 1);
     s->vdev = vdev;
-    s->blk = blk;
+    s->conf = conf;
 
-    if (blk->iothread) {
-        s->iothread = blk->iothread;
+    if (conf->iothread) {
+        s->iothread = conf->iothread;
         object_ref(OBJECT(s->iothread));
     } else {
         /* Create per-device IOThread if none specified.  This is for
@@ -192,9 +193,9 @@ void virtio_blk_data_plane_create(VirtIODevice *vdev, VirtIOBlkConf *blk,
     s->bh = aio_bh_new(s->ctx, notify_guest_bh, s);
 
     error_setg(&s->blocker, "block device is in use by data plane");
-    bdrv_op_block_all(blk->conf.bs, s->blocker);
-    bdrv_op_unblock(blk->conf.bs, BLOCK_OP_TYPE_RESIZE, s->blocker);
-    bdrv_op_unblock(blk->conf.bs, BLOCK_OP_TYPE_DRIVE_DEL, s->blocker);
+    bdrv_op_block_all(conf->conf.bs, s->blocker);
+    bdrv_op_unblock(conf->conf.bs, BLOCK_OP_TYPE_RESIZE, s->blocker);
+    bdrv_op_unblock(conf->conf.bs, BLOCK_OP_TYPE_DRIVE_DEL, s->blocker);
 
     *dataplane = s;
 }
@@ -207,7 +208,7 @@ void virtio_blk_data_plane_destroy(VirtIOBlockDataPlane *s)
     }
 
     virtio_blk_data_plane_stop(s);
-    bdrv_op_unblock_all(s->blk->conf.bs, s->blocker);
+    bdrv_op_unblock_all(s->conf->conf.bs, s->blocker);
     error_free(s->blocker);
     object_unref(OBJECT(s->iothread));
     qemu_bh_delete(s->bh);
@@ -262,7 +263,7 @@ void virtio_blk_data_plane_start(VirtIOBlockDataPlane *s)
     s->started = true;
     trace_virtio_blk_data_plane_start(s);
 
-    bdrv_set_aio_context(s->blk->conf.bs, s->ctx);
+    bdrv_set_aio_context(s->conf->conf.bs, s->ctx);
 
     /* Kick right away to begin processing requests already in vring */
     event_notifier_set(virtio_queue_get_host_notifier(vq));
@@ -308,7 +309,7 @@ void virtio_blk_data_plane_stop(VirtIOBlockDataPlane *s)
     aio_set_event_notifier(s->ctx, &s->host_notifier, NULL);
 
     /* Drain and switch bs back to the QEMU main loop */
-    bdrv_set_aio_context(s->blk->conf.bs, qemu_get_aio_context());
+    bdrv_set_aio_context(s->conf->conf.bs, qemu_get_aio_context());
 
     aio_context_release(s->ctx);
 
diff --git a/hw/block/dataplane/virtio-blk.h b/hw/block/dataplane/virtio-blk.h
index 1750c99..c88d40e 100644
--- a/hw/block/dataplane/virtio-blk.h
+++ b/hw/block/dataplane/virtio-blk.h
@@ -19,7 +19,7 @@
 
 typedef struct VirtIOBlockDataPlane VirtIOBlockDataPlane;
 
-void virtio_blk_data_plane_create(VirtIODevice *vdev, VirtIOBlkConf *blk,
+void virtio_blk_data_plane_create(VirtIODevice *vdev, VirtIOBlkConf *conf,
                                   VirtIOBlockDataPlane **dataplane,
                                   Error **errp);
 void virtio_blk_data_plane_destroy(VirtIOBlockDataPlane *s);
diff --git a/hw/block/virtio-blk.c b/hw/block/virtio-blk.c
index 0be7203..347f372 100644
--- a/hw/block/virtio-blk.c
+++ b/hw/block/virtio-blk.c
@@ -157,7 +157,7 @@ int virtio_blk_handle_scsi_req(VirtIOBlock *blk,
      */
     scsi = (void *)elem->in_sg[elem->in_num - 2].iov_base;
 
-    if (!blk->blk.scsi) {
+    if (!blk->conf.scsi) {
         status = VIRTIO_BLK_S_UNSUPP;
         goto fail;
     }
@@ -297,7 +297,7 @@ static bool virtio_blk_sect_range_ok(VirtIOBlock *dev,
     if (sector & dev->sector_mask) {
         return false;
     }
-    if (size % dev->blk.conf.logical_block_size) {
+    if (size % dev->conf.conf.logical_block_size) {
         return false;
     }
     bdrv_get_geometry(dev->bs, &total_sectors);
@@ -404,7 +404,7 @@ void virtio_blk_handle_request(VirtIOBlockReq *req, MultiReqBuffer *mrb)
          * NB: per existing s/n string convention the string is
          * terminated by '\0' only when shorter than buffer.
          */
-        const char *serial = s->blk.serial ? s->blk.serial : "";
+        const char *serial = s->conf.serial ? s->conf.serial : "";
         size_t size = MIN(strlen(serial) + 1,
                           MIN(iov_size(in_iov, in_num),
                               VIRTIO_BLK_ID_BYTES));
@@ -487,7 +487,7 @@ static void virtio_blk_dma_restart_cb(void *opaque, int running,
     }
 
     if (!s->bh) {
-        s->bh = aio_bh_new(bdrv_get_aio_context(s->blk.conf.bs),
+        s->bh = aio_bh_new(bdrv_get_aio_context(s->conf.conf.bs),
                            virtio_blk_dma_restart_bh, s);
         qemu_bh_schedule(s->bh);
     }
@@ -516,7 +516,7 @@ static void virtio_blk_reset(VirtIODevice *vdev)
 static void virtio_blk_update_config(VirtIODevice *vdev, uint8_t *config)
 {
     VirtIOBlock *s = VIRTIO_BLK(vdev);
-    BlockConf *conf = &s->blk.conf;
+    BlockConf *conf = &s->conf.conf;
     struct virtio_blk_config blkcfg;
     uint64_t capacity;
     int blk_size = conf->logical_block_size;
@@ -547,7 +547,7 @@ static void virtio_blk_update_config(VirtIODevice *vdev, uint8_t *config)
         blkcfg.sectors = conf->secs;
     }
     blkcfg.size_max = 0;
-    blkcfg.physical_block_exp = get_physical_block_exp(&s->blk.conf);
+    blkcfg.physical_block_exp = get_physical_block_exp(&s->conf.conf);
     blkcfg.alignment_offset = 0;
     blkcfg.wce = bdrv_enable_write_cache(s->bs);
     memcpy(config, &blkcfg, sizeof(struct virtio_blk_config));
@@ -575,7 +575,7 @@ static uint32_t virtio_blk_get_features(VirtIODevice *vdev, uint32_t features)
     features |= (1 << VIRTIO_BLK_F_BLK_SIZE);
     features |= (1 << VIRTIO_BLK_F_SCSI);
 
-    if (s->blk.config_wce) {
+    if (s->conf.config_wce) {
         features |= (1 << VIRTIO_BLK_F_CONFIG_WCE);
     }
     if (bdrv_enable_write_cache(s->bs))
@@ -715,7 +715,7 @@ static void virtio_blk_migration_state_changed(Notifier *notifier, void *data)
             return;
         }
         bdrv_drain_all(); /* complete in-flight non-dataplane requests */
-        virtio_blk_data_plane_create(VIRTIO_DEVICE(s), &s->blk,
+        virtio_blk_data_plane_create(VIRTIO_DEVICE(s), &s->conf,
                                      &s->dataplane, &err);
         if (err != NULL) {
             error_report("%s", error_get_pretty(err));
@@ -729,22 +729,22 @@ static void virtio_blk_device_realize(DeviceState *dev, Error **errp)
 {
     VirtIODevice *vdev = VIRTIO_DEVICE(dev);
     VirtIOBlock *s = VIRTIO_BLK(dev);
-    VirtIOBlkConf *blk = &(s->blk);
+    VirtIOBlkConf *conf = &s->conf;
     Error *err = NULL;
     static int virtio_blk_id;
 
-    if (!blk->conf.bs) {
+    if (!conf->conf.bs) {
         error_setg(errp, "drive property not set");
         return;
     }
-    if (!bdrv_is_inserted(blk->conf.bs)) {
+    if (!bdrv_is_inserted(conf->conf.bs)) {
         error_setg(errp, "Device needs media, but drive is empty");
         return;
     }
 
-    blkconf_serial(&blk->conf, &blk->serial);
-    s->original_wce = bdrv_enable_write_cache(blk->conf.bs);
-    blkconf_geometry(&blk->conf, NULL, 65535, 255, 255, &err);
+    blkconf_serial(&conf->conf, &conf->serial);
+    s->original_wce = bdrv_enable_write_cache(conf->conf.bs);
+    blkconf_geometry(&conf->conf, NULL, 65535, 255, 255, &err);
     if (err) {
         error_propagate(errp, err);
         return;
@@ -753,14 +753,14 @@ static void virtio_blk_device_realize(DeviceState *dev, Error **errp)
     virtio_init(vdev, "virtio-blk", VIRTIO_ID_BLOCK,
                 sizeof(struct virtio_blk_config));
 
-    s->bs = blk->conf.bs;
+    s->bs = conf->conf.bs;
     s->rq = NULL;
-    s->sector_mask = (s->blk.conf.logical_block_size / BDRV_SECTOR_SIZE) - 1;
+    s->sector_mask = (s->conf.conf.logical_block_size / BDRV_SECTOR_SIZE) - 1;
 
     s->vq = virtio_add_queue(vdev, 128, virtio_blk_handle_output);
     s->complete_request = virtio_blk_complete_request;
 #ifdef CONFIG_VIRTIO_BLK_DATA_PLANE
-    virtio_blk_data_plane_create(vdev, blk, &s->dataplane, &err);
+    virtio_blk_data_plane_create(vdev, conf, &s->dataplane, &err);
     if (err != NULL) {
         error_propagate(errp, err);
         virtio_cleanup(vdev);
@@ -774,11 +774,11 @@ static void virtio_blk_device_realize(DeviceState *dev, Error **errp)
     register_savevm(dev, "virtio-blk", virtio_blk_id++, 2,
                     virtio_blk_save, virtio_blk_load, s);
     bdrv_set_dev_ops(s->bs, &virtio_block_ops, s);
-    bdrv_set_guest_block_size(s->bs, s->blk.conf.logical_block_size);
+    bdrv_set_guest_block_size(s->bs, s->conf.conf.logical_block_size);
 
     bdrv_iostatus_enable(s->bs);
 
-    add_boot_device_path(s->blk.conf.bootindex, dev, "/disk@0,0");
+    add_boot_device_path(s->conf.conf.bootindex, dev, "/disk@0,0");
 }
 
 static void virtio_blk_device_unrealize(DeviceState *dev, Error **errp)
@@ -802,21 +802,21 @@ static void virtio_blk_instance_init(Object *obj)
     VirtIOBlock *s = VIRTIO_BLK(obj);
 
     object_property_add_link(obj, "iothread", TYPE_IOTHREAD,
-                             (Object **)&s->blk.iothread,
+                             (Object **)&s->conf.iothread,
                              qdev_prop_allow_set_link_before_realize,
                              OBJ_PROP_LINK_UNREF_ON_RELEASE, NULL);
 }
 
 static Property virtio_blk_properties[] = {
-    DEFINE_BLOCK_PROPERTIES(VirtIOBlock, blk.conf),
-    DEFINE_BLOCK_CHS_PROPERTIES(VirtIOBlock, blk.conf),
-    DEFINE_PROP_STRING("serial", VirtIOBlock, blk.serial),
-    DEFINE_PROP_BIT("config-wce", VirtIOBlock, blk.config_wce, 0, true),
+    DEFINE_BLOCK_PROPERTIES(VirtIOBlock, conf.conf),
+    DEFINE_BLOCK_CHS_PROPERTIES(VirtIOBlock, conf.conf),
+    DEFINE_PROP_STRING("serial", VirtIOBlock, conf.serial),
+    DEFINE_PROP_BIT("config-wce", VirtIOBlock, conf.config_wce, 0, true),
 #ifdef __linux__
-    DEFINE_PROP_BIT("scsi", VirtIOBlock, blk.scsi, 0, true),
+    DEFINE_PROP_BIT("scsi", VirtIOBlock, conf.scsi, 0, true),
 #endif
 #ifdef CONFIG_VIRTIO_BLK_DATA_PLANE
-    DEFINE_PROP_BIT("x-data-plane", VirtIOBlock, blk.data_plane, 0, false),
+    DEFINE_PROP_BIT("x-data-plane", VirtIOBlock, conf.data_plane, 0, false),
 #endif
     DEFINE_PROP_END_OF_LIST(),
 };
diff --git a/include/hw/virtio/virtio-blk.h b/include/hw/virtio/virtio-blk.h
index 1329482..b30237f 100644
--- a/include/hw/virtio/virtio-blk.h
+++ b/include/hw/virtio/virtio-blk.h
@@ -124,7 +124,7 @@ typedef struct VirtIOBlock {
     VirtQueue *vq;
     void *rq;
     QEMUBH *bh;
-    VirtIOBlkConf blk;
+    VirtIOBlkConf conf;
     unsigned short sector_mask;
     bool original_wce;
     VMChangeStateEntry *change;
-- 
1.9.3

^ permalink raw reply related	[flat|nested] 56+ messages in thread

* [Qemu-devel] [PATCH v2 14/23] hw: Convert from BlockDriverState to BlockBackend, mostly
  2014-09-13 15:00 [Qemu-devel] [PATCH v2 00/23] Split BlockBackend off BDS with an axe Markus Armbruster
                   ` (12 preceding siblings ...)
  2014-09-13 15:00 ` [Qemu-devel] [PATCH v2 13/23] virtio-blk: Rename VirtIOBlkConf variables to conf Markus Armbruster
@ 2014-09-13 15:00 ` Markus Armbruster
  2014-09-13 15:00 ` [Qemu-devel] [PATCH v2 15/23] ide: Complete conversion from BlockDriverState to BlockBackend Markus Armbruster
                   ` (9 subsequent siblings)
  23 siblings, 0 replies; 56+ messages in thread
From: Markus Armbruster @ 2014-09-13 15:00 UTC (permalink / raw)
  To: qemu-devel; +Cc: kwolf, benoit.canet, stefanha

Just four uses of BlockDriverState are left:

* The Xen paravirtual block device backend (xen_disk.c) opens images
  itself when set up via xenbus, bypassing blockdev.c.  I figure it
  should go through qmp_blockdev_add() instead.

* Device model "usb-storage" prompts for keys.  No other device model
  does, and this one probably shouldn't do it, either.

* ide_issue_trim_cb() uses bdrv_aio_discard() instead of
  blk_aio_discard() because it fishes its backend out of a BlockAIOCB,
  which has only the BlockDriverState.

* PC87312State has an unused BlockDriverState[] member.

The next two commits take care of the latter two.

Signed-off-by: Markus Armbruster <armbru@redhat.com>
---
 block/block-backend.c                    | 263 +++++++++++++++++++++++++++++++
 blockdev.c                               |  19 +--
 dma-helpers.c                            |  61 +++----
 hw/arm/collie.c                          |   5 +-
 hw/arm/gumstix.c                         |   5 +-
 hw/arm/highbank.c                        |   2 +-
 hw/arm/mainstone.c                       |   2 +-
 hw/arm/musicpal.c                        |  10 +-
 hw/arm/nseries.c                         |   3 +-
 hw/arm/omap1.c                           |   2 +-
 hw/arm/omap2.c                           |   2 +-
 hw/arm/omap_sx1.c                        |   5 +-
 hw/arm/pxa2xx.c                          |   4 +-
 hw/arm/realview.c                        |   2 +-
 hw/arm/spitz.c                           |   4 +-
 hw/arm/tosa.c                            |   3 +-
 hw/arm/versatilepb.c                     |   3 +-
 hw/arm/vexpress.c                        |   3 +-
 hw/arm/xilinx_zynq.c                     |   3 +-
 hw/arm/z2.c                              |   3 +-
 hw/block/block.c                         |   7 +-
 hw/block/dataplane/virtio-blk.c          |  24 +--
 hw/block/fdc.c                           |  78 +++++----
 hw/block/hd-geometry.c                   |  24 +--
 hw/block/m25p80.c                        |  28 ++--
 hw/block/nand.c                          |  50 +++---
 hw/block/nvme.c                          |  17 +-
 hw/block/onenand.c                       |  67 ++++----
 hw/block/pflash_cfi01.c                  |  24 +--
 hw/block/pflash_cfi02.c                  |  24 +--
 hw/block/virtio-blk.c                    |  95 +++++------
 hw/block/xen_disk.c                      |  83 +++++-----
 hw/core/qdev-properties-system.c         |  26 +--
 hw/core/qdev-properties.c                |   2 +-
 hw/cris/axis_dev88.c                     |   3 +-
 hw/display/tc6393xb.c                    |   2 +-
 hw/i386/pc.c                             |   2 +-
 hw/i386/pc_piix.c                        |   2 +-
 hw/i386/pc_sysfw.c                       |   9 +-
 hw/i386/xen/xen_platform.c               |   5 +-
 hw/ide/ahci.c                            |  31 ++--
 hw/ide/atapi.c                           |  33 ++--
 hw/ide/cmd646.c                          |   2 +-
 hw/ide/core.c                            | 190 +++++++++++-----------
 hw/ide/ich.c                             |   2 +-
 hw/ide/internal.h                        |   6 +-
 hw/ide/isa.c                             |   2 +-
 hw/ide/macio.c                           |  52 +++---
 hw/ide/microdrive.c                      |   4 +-
 hw/ide/mmio.c                            |   2 +-
 hw/ide/pci.c                             |   4 +-
 hw/ide/piix.c                            |   9 +-
 hw/ide/qdev.c                            |  11 +-
 hw/ide/via.c                             |   2 +-
 hw/isa/pc87312.c                         |   4 +-
 hw/lm32/lm32_boards.c                    |   5 +-
 hw/lm32/milkymist.c                      |   3 +-
 hw/microblaze/petalogix_ml605_mmu.c      |   3 +-
 hw/microblaze/petalogix_s3adsp1800_mmu.c |   3 +-
 hw/mips/mips_fulong2e.c                  |   2 +-
 hw/mips/mips_jazz.c                      |   2 +-
 hw/mips/mips_malta.c                     |   6 +-
 hw/mips/mips_r4k.c                       |   3 +-
 hw/nvram/spapr_nvram.c                   |  17 +-
 hw/pci/pci-hotplug-old.c                 |   5 +-
 hw/ppc/mac_newworld.c                    |   2 +-
 hw/ppc/mac_oldworld.c                    |   2 +-
 hw/ppc/ppc405_boards.c                   |  26 +--
 hw/ppc/prep.c                            |   2 +-
 hw/ppc/spapr.c                           |   4 +-
 hw/ppc/virtex_ml507.c                    |   3 +-
 hw/s390x/s390-virtio-bus.c               |   2 +-
 hw/s390x/s390-virtio.c                   |   2 +-
 hw/s390x/virtio-ccw.c                    |   2 +-
 hw/scsi/megasas.c                        |  15 +-
 hw/scsi/scsi-bus.c                       |   8 +-
 hw/scsi/scsi-disk.c                      | 192 +++++++++++-----------
 hw/scsi/scsi-generic.c                   |  39 ++---
 hw/sd/milkymist-memcard.c                |   8 +-
 hw/sd/omap_mmc.c                         |   8 +-
 hw/sd/pl181.c                            |   2 +-
 hw/sd/pxa2xx_mmci.c                      |   4 +-
 hw/sd/sd.c                               |  60 +++----
 hw/sd/sdhci.c                            |   2 +-
 hw/sd/ssi-sd.c                           |   2 +-
 hw/sh4/r2d.c                             |   3 +-
 hw/sparc/sun4m.c                         |   2 +-
 hw/sparc64/sun4u.c                       |   2 +-
 hw/tpm/tpm_tis.c                         |   2 +-
 hw/tricore/tricore_testboard.c           |   2 +-
 hw/usb/dev-storage.c                     |  17 +-
 hw/virtio/virtio-pci.c                   |   2 +-
 hw/xen/xen_devconfig.c                   |   1 +
 hw/xenpv/xen_machine_pv.c                |   2 +-
 hw/xtensa/xtfpga.c                       |   3 +-
 include/hw/arm/omap.h                    |   4 +-
 include/hw/arm/pxa.h                     |   2 +-
 include/hw/block/block.h                 |   6 +-
 include/hw/block/flash.h                 |   6 +-
 include/hw/qdev-properties.h             |   8 +-
 include/hw/scsi/scsi.h                   |   4 +-
 include/hw/sd.h                          |   2 +-
 include/hw/virtio/virtio-blk.h           |   6 +-
 include/qemu/typedefs.h                  |   1 +
 include/sysemu/block-backend.h           |  77 +++++++++
 include/sysemu/blockdev.h                |   5 +-
 include/sysemu/dma.h                     |  24 +--
 trace-events                             |   8 +-
 108 files changed, 1142 insertions(+), 811 deletions(-)

diff --git a/block/block-backend.c b/block/block-backend.c
index 17f05a3..472b545 100644
--- a/block/block-backend.c
+++ b/block/block-backend.c
@@ -233,3 +233,266 @@ void blk_hide_on_behalf_of_do_drive_del(BlockBackend *blk)
         bdrv_make_anon(blk->bs);
     }
 }
+
+void blk_iostatus_enable(BlockBackend *blk)
+{
+    bdrv_iostatus_enable(blk->bs);
+}
+
+int blk_attach_dev(BlockBackend *blk, void *dev)
+{
+    return bdrv_attach_dev(blk->bs, dev);
+}
+
+void blk_attach_dev_nofail(BlockBackend *blk, void *dev)
+{
+    bdrv_attach_dev_nofail(blk->bs, dev);
+}
+
+void blk_detach_dev(BlockBackend *blk, void *dev)
+{
+    bdrv_detach_dev(blk->bs, dev);
+}
+
+void *blk_get_attached_dev(BlockBackend *blk)
+{
+    return bdrv_get_attached_dev(blk->bs);
+}
+
+void blk_set_dev_ops(BlockBackend *blk, const BlockDevOps *ops, void *opaque)
+{
+    bdrv_set_dev_ops(blk->bs, ops, opaque);
+}
+
+int blk_read(BlockBackend *blk, int64_t sector_num, uint8_t *buf,
+             int nb_sectors)
+{
+    return bdrv_read(blk->bs, sector_num, buf, nb_sectors);
+}
+
+int blk_read_unthrottled(BlockBackend *blk, int64_t sector_num, uint8_t *buf,
+                         int nb_sectors)
+{
+    return bdrv_read_unthrottled(blk->bs, sector_num, buf, nb_sectors);
+}
+
+int blk_write(BlockBackend *blk, int64_t sector_num, const uint8_t *buf,
+              int nb_sectors)
+{
+    return bdrv_write(blk->bs, sector_num, buf, nb_sectors);
+}
+
+BlockAIOCB *blk_aio_write_zeroes(BlockBackend *blk, int64_t sector_num,
+                                 int nb_sectors, BdrvRequestFlags flags,
+                                 BlockCompletionFunc *cb, void *opaque)
+{
+    return bdrv_aio_write_zeroes(blk->bs, sector_num, nb_sectors, flags,
+                                 cb, opaque);
+}
+
+int blk_pread(BlockBackend *blk, int64_t offset, void *buf, int count)
+{
+    return bdrv_pread(blk->bs, offset, buf, count);
+}
+
+int blk_pwrite(BlockBackend *blk, int64_t offset, const void *buf, int count)
+{
+    return bdrv_pwrite(blk->bs, offset, buf, count);
+}
+
+int64_t blk_getlength(BlockBackend *blk)
+{
+    return bdrv_getlength(blk->bs);
+}
+
+void blk_get_geometry(BlockBackend *blk, uint64_t *nb_sectors_ptr)
+{
+    bdrv_get_geometry(blk->bs, nb_sectors_ptr);
+}
+
+BlockAIOCB *blk_aio_readv(BlockBackend *blk, int64_t sector_num,
+                          QEMUIOVector *iov, int nb_sectors,
+                          BlockCompletionFunc *cb, void *opaque)
+{
+    return bdrv_aio_readv(blk->bs, sector_num, iov, nb_sectors, cb, opaque);
+}
+
+BlockAIOCB *blk_aio_writev(BlockBackend *blk, int64_t sector_num,
+                           QEMUIOVector *iov, int nb_sectors,
+                           BlockCompletionFunc *cb, void *opaque)
+{
+    return bdrv_aio_writev(blk->bs, sector_num, iov, nb_sectors, cb, opaque);
+}
+
+BlockAIOCB *blk_aio_flush(BlockBackend *blk,
+                          BlockCompletionFunc *cb, void *opaque)
+{
+    return bdrv_aio_flush(blk->bs, cb, opaque);
+}
+
+BlockAIOCB *blk_aio_discard(BlockBackend *blk,
+                            int64_t sector_num, int nb_sectors,
+                            BlockCompletionFunc *cb, void *opaque)
+{
+    return bdrv_aio_discard(blk->bs, sector_num, nb_sectors, cb, opaque);
+}
+
+void blk_aio_cancel(BlockAIOCB *acb)
+{
+    bdrv_aio_cancel(acb);
+}
+
+int blk_aio_multiwrite(BlockBackend *blk, BlockRequest *reqs, int num_reqs)
+{
+    return bdrv_aio_multiwrite(blk->bs, reqs, num_reqs);
+}
+
+int blk_ioctl(BlockBackend *blk, unsigned long int req, void *buf)
+{
+    return bdrv_ioctl(blk->bs, req, buf);
+}
+
+BlockAIOCB *blk_aio_ioctl(BlockBackend *blk, unsigned long int req, void *buf,
+                          BlockCompletionFunc *cb, void *opaque)
+{
+    return bdrv_aio_ioctl(blk->bs, req, buf, cb, opaque);
+}
+
+int blk_flush(BlockBackend *blk)
+{
+    return bdrv_flush(blk->bs);
+}
+
+int blk_flush_all(void)
+{
+    return bdrv_flush_all();
+}
+
+void blk_drain_all(void)
+{
+    bdrv_drain_all();
+}
+
+BlockdevOnError blk_get_on_error(BlockBackend *blk, bool is_read)
+{
+    return bdrv_get_on_error(blk->bs, is_read);
+}
+
+BlockErrorAction blk_get_error_action(BlockBackend *blk, bool is_read,
+                                      int error)
+{
+    return bdrv_get_error_action(blk->bs, is_read, error);
+}
+
+void blk_error_action(BlockBackend *blk, BlockErrorAction action,
+                      bool is_read, int error)
+{
+    bdrv_error_action(blk->bs, action, is_read, error);
+}
+
+int blk_is_read_only(BlockBackend *blk)
+{
+    return bdrv_is_read_only(blk->bs);
+}
+
+int blk_is_sg(BlockBackend *blk)
+{
+    return bdrv_is_sg(blk->bs);
+}
+
+int blk_enable_write_cache(BlockBackend *blk)
+{
+    return bdrv_enable_write_cache(blk->bs);
+}
+
+void blk_set_enable_write_cache(BlockBackend *blk, bool wce)
+{
+    bdrv_set_enable_write_cache(blk->bs, wce);
+}
+
+int blk_is_inserted(BlockBackend *blk)
+{
+    return bdrv_is_inserted(blk->bs);
+}
+
+void blk_lock_medium(BlockBackend *blk, bool locked)
+{
+    bdrv_lock_medium(blk->bs, locked);
+}
+
+void blk_eject(BlockBackend *blk, bool eject_flag)
+{
+    bdrv_eject(blk->bs, eject_flag);
+}
+
+int blk_get_flags(BlockBackend *blk)
+{
+    return bdrv_get_flags(blk->bs);
+}
+
+void blk_set_guest_block_size(BlockBackend *blk, int align)
+{
+    bdrv_set_guest_block_size(blk->bs, align);
+}
+
+void *blk_blockalign(BlockBackend *blk, size_t size)
+{
+    return qemu_blockalign(blk ? blk->bs : NULL, size);
+}
+
+bool blk_op_is_blocked(BlockBackend *blk, BlockOpType op, Error **errp)
+{
+    return bdrv_op_is_blocked(blk->bs, op, errp);
+}
+
+void blk_op_unblock(BlockBackend *blk, BlockOpType op, Error *reason)
+{
+    bdrv_op_unblock(blk->bs, op, reason);
+}
+
+void blk_op_block_all(BlockBackend *blk, Error *reason)
+{
+    bdrv_op_block_all(blk->bs, reason);
+}
+
+void blk_op_unblock_all(BlockBackend *blk, Error *reason)
+{
+    bdrv_op_unblock_all(blk->bs, reason);
+}
+
+void blk_acct_start(BlockBackend *blk, BlockAcctCookie *cookie,
+                    int64_t bytes, enum BlockAcctType type)
+{
+    bdrv_acct_start(blk->bs, cookie, bytes, type);
+}
+
+void blk_acct_done(BlockBackend *blk, BlockAcctCookie *cookie)
+{
+    bdrv_acct_done(blk->bs, cookie);
+}
+
+AioContext *blk_get_aio_context(BlockBackend *blk)
+{
+    return bdrv_get_aio_context(blk->bs);
+}
+
+void blk_set_aio_context(BlockBackend *blk, AioContext *new_context)
+{
+    bdrv_set_aio_context(blk->bs, new_context);
+}
+
+void blk_io_plug(BlockBackend *blk)
+{
+    bdrv_io_plug(blk->bs);
+}
+
+void blk_io_unplug(BlockBackend *blk)
+{
+    bdrv_io_unplug(blk->bs);
+}
+
+void *blk_aio_get(const AIOCBInfo *aiocb_info, BlockBackend *blk,
+                  BlockCompletionFunc *cb, void *opaque)
+{
+    return qemu_aio_get(aiocb_info, blk_bs(blk), cb, opaque);
+}
diff --git a/blockdev.c b/blockdev.c
index 49496b6..e87bf4b 100644
--- a/blockdev.c
+++ b/blockdev.c
@@ -85,10 +85,10 @@ static const int if_max_devs[IF_COUNT] = {
  * automatic deletion, and generic qdev code calls blockdev_auto_del()
  * when deletion is actually safe.
  */
-void blockdev_mark_auto_del(BlockDriverState *bs)
+void blockdev_mark_auto_del(BlockBackend *blk)
 {
-    BlockBackend *blk = bs->blk;
     DriveInfo *dinfo = blk_legacy_dinfo(blk);
+    BlockDriverState *bs = blk_bs(blk);
 
     if (dinfo && !dinfo->enable_auto_del) {
         return;
@@ -102,9 +102,8 @@ void blockdev_mark_auto_del(BlockDriverState *bs)
     }
 }
 
-void blockdev_auto_del(BlockDriverState *bs)
+void blockdev_auto_del(BlockBackend *blk)
 {
-    BlockBackend *blk = bs->blk;
     DriveInfo *dinfo = blk_legacy_dinfo(blk);
 
     if (dinfo && dinfo->auto_del) {
@@ -200,18 +199,6 @@ DriveInfo *drive_get_next(BlockInterfaceType type)
     return drive_get(type, 0, next_block_unit[type]++);
 }
 
-DriveInfo *drive_get_by_blockdev(BlockDriverState *bs)
-{
-    BlockBackend *blk;
-
-    for (blk = blk_next(NULL); blk; blk = blk_next(blk)) {
-        if (blk_bs(blk) == bs) {
-            return blk_legacy_dinfo(blk);
-        }
-    }
-    return NULL;
-}
-
 static void bdrv_format_print(void *opaque, const char *name)
 {
     error_printf(" %s", name);
diff --git a/dma-helpers.c b/dma-helpers.c
index e7bea06..76d2597 100644
--- a/dma-helpers.c
+++ b/dma-helpers.c
@@ -7,6 +7,7 @@
  * (GNU GPL), version 2 or later.
  */
 
+#include "sysemu/block-backend.h"
 #include "sysemu/dma.h"
 #include "trace.h"
 #include "qemu/range.h"
@@ -68,7 +69,7 @@ void qemu_sglist_destroy(QEMUSGList *qsg)
 
 typedef struct {
     BlockAIOCB common;
-    BlockDriverState *bs;
+    BlockBackend *blk;
     BlockAIOCB *acb;
     QEMUSGList *sg;
     uint64_t sector_num;
@@ -81,7 +82,7 @@ typedef struct {
     DMAIOFunc *io_func;
 } DMAAIOCB;
 
-static void dma_bdrv_cb(void *opaque, int ret);
+static void dma_blk_cb(void *opaque, int ret);
 
 static void reschedule_dma(void *opaque)
 {
@@ -89,7 +90,7 @@ static void reschedule_dma(void *opaque)
 
     qemu_bh_delete(dbs->bh);
     dbs->bh = NULL;
-    dma_bdrv_cb(dbs, 0);
+    dma_blk_cb(dbs, 0);
 }
 
 static void continue_after_map_failure(void *opaque)
@@ -100,7 +101,7 @@ static void continue_after_map_failure(void *opaque)
     qemu_bh_schedule(dbs->bh);
 }
 
-static void dma_bdrv_unmap(DMAAIOCB *dbs)
+static void dma_blk_unmap(DMAAIOCB *dbs)
 {
     int i;
 
@@ -116,7 +117,7 @@ static void dma_complete(DMAAIOCB *dbs, int ret)
 {
     trace_dma_complete(dbs, ret, dbs->common.cb);
 
-    dma_bdrv_unmap(dbs);
+    dma_blk_unmap(dbs);
     if (dbs->common.cb) {
         dbs->common.cb(dbs->common.opaque, ret);
     }
@@ -133,13 +134,13 @@ static void dma_complete(DMAAIOCB *dbs, int ret)
     }
 }
 
-static void dma_bdrv_cb(void *opaque, int ret)
+static void dma_blk_cb(void *opaque, int ret)
 {
     DMAAIOCB *dbs = (DMAAIOCB *)opaque;
     dma_addr_t cur_addr, cur_len;
     void *mem;
 
-    trace_dma_bdrv_cb(dbs, ret);
+    trace_dma_blk_cb(dbs, ret);
 
     dbs->acb = NULL;
     dbs->sector_num += dbs->iov.size / 512;
@@ -148,7 +149,7 @@ static void dma_bdrv_cb(void *opaque, int ret)
         dma_complete(dbs, ret);
         return;
     }
-    dma_bdrv_unmap(dbs);
+    dma_blk_unmap(dbs);
 
     while (dbs->sg_cur_index < dbs->sg->nsg) {
         cur_addr = dbs->sg->sg[dbs->sg_cur_index].base + dbs->sg_cur_byte;
@@ -174,8 +175,8 @@ static void dma_bdrv_cb(void *opaque, int ret)
         qemu_iovec_discard_back(&dbs->iov, dbs->iov.size & ~BDRV_SECTOR_MASK);
     }
 
-    dbs->acb = dbs->io_func(dbs->bs, dbs->sector_num, &dbs->iov,
-                            dbs->iov.size / 512, dma_bdrv_cb, dbs);
+    dbs->acb = dbs->io_func(dbs->blk, dbs->sector_num, &dbs->iov,
+                            dbs->iov.size / 512, dma_blk_cb, dbs);
     assert(dbs->acb);
 }
 
@@ -189,7 +190,7 @@ static void dma_aio_cancel(BlockAIOCB *acb)
         BlockAIOCB *acb = dbs->acb;
         dbs->acb = NULL;
         dbs->in_cancel = true;
-        bdrv_aio_cancel(acb);
+        blk_aio_cancel(acb);
         dbs->in_cancel = false;
     }
     dbs->common.cb = NULL;
@@ -201,17 +202,17 @@ static const AIOCBInfo dma_aiocb_info = {
     .cancel             = dma_aio_cancel,
 };
 
-BlockAIOCB *dma_bdrv_io(
-    BlockDriverState *bs, QEMUSGList *sg, uint64_t sector_num,
+BlockAIOCB *dma_blk_io(
+    BlockBackend *blk, QEMUSGList *sg, uint64_t sector_num,
     DMAIOFunc *io_func, BlockCompletionFunc *cb,
     void *opaque, DMADirection dir)
 {
-    DMAAIOCB *dbs = qemu_aio_get(&dma_aiocb_info, bs, cb, opaque);
+    DMAAIOCB *dbs = blk_aio_get(&dma_aiocb_info, blk, cb, opaque);
 
-    trace_dma_bdrv_io(dbs, bs, sector_num, (dir == DMA_DIRECTION_TO_DEVICE));
+    trace_dma_blk_io(dbs, blk, sector_num, (dir == DMA_DIRECTION_TO_DEVICE));
 
     dbs->acb = NULL;
-    dbs->bs = bs;
+    dbs->blk = blk;
     dbs->sg = sg;
     dbs->sector_num = sector_num;
     dbs->sg_cur_index = 0;
@@ -221,25 +222,25 @@ BlockAIOCB *dma_bdrv_io(
     dbs->io_func = io_func;
     dbs->bh = NULL;
     qemu_iovec_init(&dbs->iov, sg->nsg);
-    dma_bdrv_cb(dbs, 0);
+    dma_blk_cb(dbs, 0);
     return &dbs->common;
 }
 
 
-BlockAIOCB *dma_bdrv_read(BlockDriverState *bs,
+BlockAIOCB *dma_blk_read(BlockBackend *blk,
+                         QEMUSGList *sg, uint64_t sector,
+                         void (*cb)(void *opaque, int ret), void *opaque)
+{
+    return dma_blk_io(blk, sg, sector, blk_aio_readv, cb, opaque,
+                      DMA_DIRECTION_FROM_DEVICE);
+}
+
+BlockAIOCB *dma_blk_write(BlockBackend *blk,
                           QEMUSGList *sg, uint64_t sector,
                           void (*cb)(void *opaque, int ret), void *opaque)
 {
-    return dma_bdrv_io(bs, sg, sector, bdrv_aio_readv, cb, opaque,
-                       DMA_DIRECTION_FROM_DEVICE);
-}
-
-BlockAIOCB *dma_bdrv_write(BlockDriverState *bs,
-                           QEMUSGList *sg, uint64_t sector,
-                           void (*cb)(void *opaque, int ret), void *opaque)
-{
-    return dma_bdrv_io(bs, sg, sector, bdrv_aio_writev, cb, opaque,
-                       DMA_DIRECTION_TO_DEVICE);
+    return dma_blk_io(blk, sg, sector, blk_aio_writev, cb, opaque,
+                      DMA_DIRECTION_TO_DEVICE);
 }
 
 
@@ -274,8 +275,8 @@ uint64_t dma_buf_write(uint8_t *ptr, int32_t len, QEMUSGList *sg)
     return dma_buf_rw(ptr, len, sg, DMA_DIRECTION_TO_DEVICE);
 }
 
-void dma_acct_start(BlockDriverState *bs, BlockAcctCookie *cookie,
+void dma_acct_start(BlockBackend *blk, BlockAcctCookie *cookie,
                     QEMUSGList *sg, enum BlockAcctType type)
 {
-    bdrv_acct_start(bs, cookie, sg->size, type);
+    blk_acct_start(blk, cookie, sg->size, type);
 }
diff --git a/hw/arm/collie.c b/hw/arm/collie.c
index 0247290..6c9b82f 100644
--- a/hw/arm/collie.c
+++ b/hw/arm/collie.c
@@ -16,7 +16,6 @@
 #include "hw/arm/arm.h"
 #include "hw/block/flash.h"
 #include "sysemu/block-backend.h"
-#include "sysemu/blockdev.h"
 #include "exec/address-spaces.h"
 
 static struct arm_boot_info collie_binfo = {
@@ -42,12 +41,12 @@ static void collie_init(MachineState *machine)
 
     dinfo = drive_get(IF_PFLASH, 0, 0);
     pflash_cfi01_register(SA_CS0, NULL, "collie.fl1", 0x02000000,
-                    dinfo ? blk_bs(blk_by_legacy_dinfo(dinfo)) : NULL,
+                    dinfo ? blk_by_legacy_dinfo(dinfo) : NULL,
                     (64 * 1024), 512, 4, 0x00, 0x00, 0x00, 0x00, 0);
 
     dinfo = drive_get(IF_PFLASH, 0, 1);
     pflash_cfi01_register(SA_CS1, NULL, "collie.fl2", 0x02000000,
-                    dinfo ? blk_bs(blk_by_legacy_dinfo(dinfo)) : NULL,
+                    dinfo ? blk_by_legacy_dinfo(dinfo) : NULL,
                     (64 * 1024), 512, 4, 0x00, 0x00, 0x00, 0x00, 0);
 
     sysbus_create_simple("scoop", 0x40800000, NULL);
diff --git a/hw/arm/gumstix.c b/hw/arm/gumstix.c
index 49f9339..8103278 100644
--- a/hw/arm/gumstix.c
+++ b/hw/arm/gumstix.c
@@ -41,7 +41,6 @@
 #include "hw/devices.h"
 #include "hw/boards.h"
 #include "sysemu/block-backend.h"
-#include "sysemu/blockdev.h"
 #include "exec/address-spaces.h"
 #include "sysemu/qtest.h"
 
@@ -72,7 +71,7 @@ static void connex_init(MachineState *machine)
     be = 0;
 #endif
     if (!pflash_cfi01_register(0x00000000, NULL, "connext.rom", connex_rom,
-                               dinfo ? blk_bs(blk_by_legacy_dinfo(dinfo)) : NULL,
+                               dinfo ? blk_by_legacy_dinfo(dinfo) : NULL,
                                sector_len, connex_rom / sector_len,
                                2, 0, 0, 0, 0, be)) {
         fprintf(stderr, "qemu: Error registering flash memory.\n");
@@ -110,7 +109,7 @@ static void verdex_init(MachineState *machine)
     be = 0;
 #endif
     if (!pflash_cfi01_register(0x00000000, NULL, "verdex.rom", verdex_rom,
-                               dinfo ? blk_bs(blk_by_legacy_dinfo(dinfo)) : NULL,
+                               dinfo ? blk_by_legacy_dinfo(dinfo) : NULL,
                                sector_len, verdex_rom / sector_len,
                                2, 0, 0, 0, 0, be)) {
         fprintf(stderr, "qemu: Error registering flash memory.\n");
diff --git a/hw/arm/highbank.c b/hw/arm/highbank.c
index 8340434..2c2eb6b 100644
--- a/hw/arm/highbank.c
+++ b/hw/arm/highbank.c
@@ -24,7 +24,7 @@
 #include "net/net.h"
 #include "sysemu/sysemu.h"
 #include "hw/boards.h"
-#include "sysemu/blockdev.h"
+#include "sysemu/block-backend.h"
 #include "exec/address-spaces.h"
 #include "qemu/error-report.h"
 
diff --git a/hw/arm/mainstone.c b/hw/arm/mainstone.c
index fb17d85..6ec7892 100644
--- a/hw/arm/mainstone.c
+++ b/hw/arm/mainstone.c
@@ -148,7 +148,7 @@ static void mainstone_common_init(MemoryRegion *address_space_mem,
         if (!pflash_cfi01_register(mainstone_flash_base[i], NULL,
                                    i ? "mainstone.flash1" : "mainstone.flash0",
                                    MAINSTONE_FLASH,
-                                   blk_bs(blk_by_legacy_dinfo(dinfo)),
+                                   blk_by_legacy_dinfo(dinfo),
                                    sector_len, MAINSTONE_FLASH / sector_len,
                                    4, 0, 0, 0, 0, be)) {
             fprintf(stderr, "qemu: Error registering flash memory.\n");
diff --git a/hw/arm/musicpal.c b/hw/arm/musicpal.c
index 6a41d9c..92a634a 100644
--- a/hw/arm/musicpal.c
+++ b/hw/arm/musicpal.c
@@ -18,12 +18,10 @@
 #include "hw/char/serial.h"
 #include "qemu/timer.h"
 #include "hw/ptimer.h"
-#include "block/block.h"
 #include "hw/block/flash.h"
 #include "ui/console.h"
 #include "hw/i2c/i2c.h"
 #include "sysemu/block-backend.h"
-#include "sysemu/blockdev.h"
 #include "exec/address-spaces.h"
 #include "ui/pixel_ops.h"
 
@@ -1631,9 +1629,9 @@ static void musicpal_init(MachineState *machine)
     /* Register flash */
     dinfo = drive_get(IF_PFLASH, 0, 0);
     if (dinfo) {
-        BlockDriverState *bs = blk_bs(blk_by_legacy_dinfo(dinfo));
+        BlockBackend *blk = blk_by_legacy_dinfo(dinfo);
 
-        flash_size = bdrv_getlength(bs);
+        flash_size = blk_getlength(blk);
         if (flash_size != 8*1024*1024 && flash_size != 16*1024*1024 &&
             flash_size != 32*1024*1024) {
             fprintf(stderr, "Invalid flash image size\n");
@@ -1648,14 +1646,14 @@ static void musicpal_init(MachineState *machine)
 #ifdef TARGET_WORDS_BIGENDIAN
         pflash_cfi02_register(0x100000000ULL-MP_FLASH_SIZE_MAX, NULL,
                               "musicpal.flash", flash_size,
-                              bs, 0x10000, (flash_size + 0xffff) >> 16,
+                              blk, 0x10000, (flash_size + 0xffff) >> 16,
                               MP_FLASH_SIZE_MAX / flash_size,
                               2, 0x00BF, 0x236D, 0x0000, 0x0000,
                               0x5555, 0x2AAA, 1);
 #else
         pflash_cfi02_register(0x100000000ULL-MP_FLASH_SIZE_MAX, NULL,
                               "musicpal.flash", flash_size,
-                              bs, 0x10000, (flash_size + 0xffff) >> 16,
+                              blk, 0x10000, (flash_size + 0xffff) >> 16,
                               MP_FLASH_SIZE_MAX / flash_size,
                               2, 0x00BF, 0x236D, 0x0000, 0x0000,
                               0x5555, 0x2AAA, 0);
diff --git a/hw/arm/nseries.c b/hw/arm/nseries.c
index 2536078..c7ebaa6 100644
--- a/hw/arm/nseries.c
+++ b/hw/arm/nseries.c
@@ -32,7 +32,6 @@
 #include "hw/bt.h"
 #include "hw/loader.h"
 #include "sysemu/block-backend.h"
-#include "sysemu/blockdev.h"
 #include "hw/sysbus.h"
 #include "exec/address-spaces.h"
 
@@ -175,7 +174,7 @@ static void n8x0_nand_setup(struct n800_s *s)
     dinfo = drive_get(IF_MTD, 0, 0);
     if (dinfo) {
         qdev_prop_set_drive_nofail(s->nand, "drive",
-                                   blk_bs(blk_by_legacy_dinfo(dinfo)));
+                                   blk_by_legacy_dinfo(dinfo));
     }
     qdev_init_nofail(s->nand);
     sysbus_connect_irq(SYS_BUS_DEVICE(s->nand), 0,
diff --git a/hw/arm/omap1.c b/hw/arm/omap1.c
index e38e07f..786b571 100644
--- a/hw/arm/omap1.c
+++ b/hw/arm/omap1.c
@@ -3978,7 +3978,7 @@ struct omap_mpu_state_s *omap310_mpu_init(MemoryRegion *system_memory,
         exit(1);
     }
     s->mmc = omap_mmc_init(0xfffb7800, system_memory,
-                           blk_bs(blk_by_legacy_dinfo(dinfo)),
+                           blk_by_legacy_dinfo(dinfo),
                            qdev_get_gpio_in(s->ih[1], OMAP_INT_OQN),
                            &s->drq[OMAP_DMA_MMC_TX],
                     omap_findclk(s, "mmc_ck"));
diff --git a/hw/arm/omap2.c b/hw/arm/omap2.c
index e47dd63..e2accbf 100644
--- a/hw/arm/omap2.c
+++ b/hw/arm/omap2.c
@@ -2461,7 +2461,7 @@ struct omap_mpu_state_s *omap2420_mpu_init(MemoryRegion *sysmem,
         exit(1);
     }
     s->mmc = omap2_mmc_init(omap_l4tao(s->l4, 9),
-                    blk_bs(blk_by_legacy_dinfo(dinfo)),
+                    blk_by_legacy_dinfo(dinfo),
                     qdev_get_gpio_in(s->ih[0], OMAP_INT_24XX_MMC_IRQ),
                     &s->drq[OMAP24XX_DMA_MMC1_TX],
                     omap_findclk(s, "mmc_fclk"), omap_findclk(s, "mmc_iclk"));
diff --git a/hw/arm/omap_sx1.c b/hw/arm/omap_sx1.c
index f475afc..5ee0d4e 100644
--- a/hw/arm/omap_sx1.c
+++ b/hw/arm/omap_sx1.c
@@ -32,7 +32,6 @@
 #include "hw/arm/arm.h"
 #include "hw/block/flash.h"
 #include "sysemu/block-backend.h"
-#include "sysemu/blockdev.h"
 #include "sysemu/qtest.h"
 #include "exec/address-spaces.h"
 
@@ -154,7 +153,7 @@ static void sx1_init(MachineState *machine, const int version)
     if ((dinfo = drive_get(IF_PFLASH, 0, fl_idx)) != NULL) {
         if (!pflash_cfi01_register(OMAP_CS0_BASE, NULL,
                                    "omap_sx1.flash0-1", flash_size,
-                                   blk_bs(blk_by_legacy_dinfo(dinfo)),
+                                   blk_by_legacy_dinfo(dinfo),
                                    sector_size, flash_size / sector_size,
                                    4, 0, 0, 0, 0, be)) {
             fprintf(stderr, "qemu: Error registering flash memory %d.\n",
@@ -177,7 +176,7 @@ static void sx1_init(MachineState *machine, const int version)
 
         if (!pflash_cfi01_register(OMAP_CS1_BASE, NULL,
                                    "omap_sx1.flash1-1", flash1_size,
-                                   blk_bs(blk_by_legacy_dinfo(dinfo)),
+                                   blk_by_legacy_dinfo(dinfo),
                                    sector_size, flash1_size / sector_size,
                                    4, 0, 0, 0, 0, be)) {
             fprintf(stderr, "qemu: Error registering flash memory %d.\n",
diff --git a/hw/arm/pxa2xx.c b/hw/arm/pxa2xx.c
index 7ec0da8..2b72e25 100644
--- a/hw/arm/pxa2xx.c
+++ b/hw/arm/pxa2xx.c
@@ -2085,7 +2085,7 @@ PXA2xxState *pxa270_init(MemoryRegion *address_space,
         exit(1);
     }
     s->mmc = pxa2xx_mmci_init(address_space, 0x41100000,
-                    blk_bs(blk_by_legacy_dinfo(dinfo)),
+                    blk_by_legacy_dinfo(dinfo),
                     qdev_get_gpio_in(s->pic, PXA2XX_PIC_MMC),
                     qdev_get_gpio_in(s->dma, PXA2XX_RX_RQ_MMCI),
                     qdev_get_gpio_in(s->dma, PXA2XX_TX_RQ_MMCI));
@@ -2217,7 +2217,7 @@ PXA2xxState *pxa255_init(MemoryRegion *address_space, unsigned int sdram_size)
         exit(1);
     }
     s->mmc = pxa2xx_mmci_init(address_space, 0x41100000,
-                    blk_bs(blk_by_legacy_dinfo(dinfo)),
+                    blk_by_legacy_dinfo(dinfo),
                     qdev_get_gpio_in(s->pic, PXA2XX_PIC_MMC),
                     qdev_get_gpio_in(s->dma, PXA2XX_RX_RQ_MMCI),
                     qdev_get_gpio_in(s->dma, PXA2XX_TX_RQ_MMCI));
diff --git a/hw/arm/realview.c b/hw/arm/realview.c
index 64b9251..820c17a 100644
--- a/hw/arm/realview.c
+++ b/hw/arm/realview.c
@@ -16,7 +16,7 @@
 #include "sysemu/sysemu.h"
 #include "hw/boards.h"
 #include "hw/i2c/i2c.h"
-#include "sysemu/blockdev.h"
+#include "sysemu/block-backend.h"
 #include "exec/address-spaces.h"
 #include "qemu/error-report.h"
 
diff --git a/hw/arm/spitz.c b/hw/arm/spitz.c
index 5d684a2..cd3d6ca 100644
--- a/hw/arm/spitz.c
+++ b/hw/arm/spitz.c
@@ -22,11 +22,9 @@
 #include "hw/devices.h"
 #include "hw/arm/sharpsl.h"
 #include "ui/console.h"
-#include "block/block.h"
 #include "audio/audio.h"
 #include "hw/boards.h"
 #include "sysemu/block-backend.h"
-#include "sysemu/blockdev.h"
 #include "hw/sysbus.h"
 #include "exec/address-spaces.h"
 
@@ -171,7 +169,7 @@ static int sl_nand_init(SysBusDevice *dev)
 
     s->ctl = 0;
     nand = drive_get(IF_MTD, 0, 0);
-    s->nand = nand_init(nand ? blk_bs(blk_by_legacy_dinfo(nand)) : NULL,
+    s->nand = nand_init(nand ? blk_by_legacy_dinfo(nand) : NULL,
                         s->manf_id, s->chip_id);
 
     memory_region_init_io(&s->iomem, OBJECT(s), &sl_ops, s, "sl", 0x40);
diff --git a/hw/arm/tosa.c b/hw/arm/tosa.c
index abc0f2a..3c59f82 100644
--- a/hw/arm/tosa.c
+++ b/hw/arm/tosa.c
@@ -17,11 +17,10 @@
 #include "hw/devices.h"
 #include "hw/arm/sharpsl.h"
 #include "hw/pcmcia.h"
-#include "block/block.h"
 #include "hw/boards.h"
 #include "hw/i2c/i2c.h"
 #include "hw/ssi.h"
-#include "sysemu/blockdev.h"
+#include "sysemu/block-backend.h"
 #include "hw/sysbus.h"
 #include "exec/address-spaces.h"
 
diff --git a/hw/arm/versatilepb.c b/hw/arm/versatilepb.c
index c88be6b..3e43c2d 100644
--- a/hw/arm/versatilepb.c
+++ b/hw/arm/versatilepb.c
@@ -16,7 +16,6 @@
 #include "hw/i2c/i2c.h"
 #include "hw/boards.h"
 #include "sysemu/block-backend.h"
-#include "sysemu/blockdev.h"
 #include "exec/address-spaces.h"
 #include "hw/block/flash.h"
 
@@ -339,7 +338,7 @@ static void versatile_init(MachineState *machine, int board_id)
     dinfo = drive_get(IF_PFLASH, 0, 0);
     if (!pflash_cfi01_register(VERSATILE_FLASH_ADDR, NULL, "versatile.flash",
                           VERSATILE_FLASH_SIZE,
-                          dinfo ? blk_bs(blk_by_legacy_dinfo(dinfo)) : NULL,
+                          dinfo ? blk_by_legacy_dinfo(dinfo) : NULL,
                           VERSATILE_FLASH_SECT_SIZE,
                           VERSATILE_FLASH_SIZE / VERSATILE_FLASH_SECT_SIZE,
                           4, 0x0089, 0x0018, 0x0000, 0x0, 0)) {
diff --git a/hw/arm/vexpress.c b/hw/arm/vexpress.c
index a492c22..ad43753 100644
--- a/hw/arm/vexpress.c
+++ b/hw/arm/vexpress.c
@@ -31,7 +31,6 @@
 #include "hw/loader.h"
 #include "exec/address-spaces.h"
 #include "sysemu/block-backend.h"
-#include "sysemu/blockdev.h"
 #include "hw/block/flash.h"
 #include "sysemu/device_tree.h"
 #include "qemu/error-report.h"
@@ -490,7 +489,7 @@ static pflash_t *ve_pflash_cfi01_register(hwaddr base, const char *name,
     DeviceState *dev = qdev_create(NULL, "cfi.pflash01");
 
     if (di && qdev_prop_set_drive(dev, "drive",
-                                  blk_bs(blk_by_legacy_dinfo(di)))) {
+                                  blk_by_legacy_dinfo(di))) {
         abort();
     }
 
diff --git a/hw/arm/xilinx_zynq.c b/hw/arm/xilinx_zynq.c
index 78e6934..601ff39 100644
--- a/hw/arm/xilinx_zynq.c
+++ b/hw/arm/xilinx_zynq.c
@@ -23,7 +23,6 @@
 #include "hw/boards.h"
 #include "hw/block/flash.h"
 #include "sysemu/block-backend.h"
-#include "sysemu/blockdev.h"
 #include "hw/loader.h"
 #include "hw/ssi.h"
 #include "qemu/error-report.h"
@@ -163,7 +162,7 @@ static void zynq_init(MachineState *machine)
 
     /* AMD */
     pflash_cfi02_register(0xe2000000, NULL, "zynq.pflash", FLASH_SIZE,
-                          dinfo ? blk_bs(blk_by_legacy_dinfo(dinfo)) : NULL,
+                          dinfo ? blk_by_legacy_dinfo(dinfo) : NULL,
                           FLASH_SECTOR_SIZE,
                           FLASH_SIZE/FLASH_SECTOR_SIZE, 1,
                           1, 0x0066, 0x0022, 0x0000, 0x0000, 0x0555, 0x2aa,
diff --git a/hw/arm/z2.c b/hw/arm/z2.c
index 9b38a2b..1735547 100644
--- a/hw/arm/z2.c
+++ b/hw/arm/z2.c
@@ -21,7 +21,6 @@
 #include "sysemu/sysemu.h"
 #include "hw/block/flash.h"
 #include "sysemu/block-backend.h"
-#include "sysemu/blockdev.h"
 #include "ui/console.h"
 #include "audio/audio.h"
 #include "exec/address-spaces.h"
@@ -337,7 +336,7 @@ static void z2_init(MachineState *machine)
 
     if (!pflash_cfi01_register(Z2_FLASH_BASE,
                                NULL, "z2.flash0", Z2_FLASH_SIZE,
-                               dinfo ? blk_bs(blk_by_legacy_dinfo(dinfo)) : NULL,
+                               dinfo ? blk_by_legacy_dinfo(dinfo) : NULL,
                                sector_len, Z2_FLASH_SIZE / sector_len,
                                4, 0, 0, 0, 0, be)) {
         fprintf(stderr, "qemu: Error registering flash memory.\n");
diff --git a/hw/block/block.c b/hw/block/block.c
index b6a6dc6..0666dd3 100644
--- a/hw/block/block.c
+++ b/hw/block/block.c
@@ -8,6 +8,7 @@
  */
 
 #include "sysemu/blockdev.h"
+#include "sysemu/block-backend.h"
 #include "hw/block/block.h"
 #include "qemu/error-report.h"
 
@@ -17,7 +18,7 @@ void blkconf_serial(BlockConf *conf, char **serial)
 
     if (!*serial) {
         /* try to fall back to value set with legacy -drive serial=... */
-        dinfo = drive_get_by_blockdev(conf->bs);
+        dinfo = blk_legacy_dinfo(conf->blk);
         *serial = g_strdup(dinfo->serial);
     }
 }
@@ -30,7 +31,7 @@ void blkconf_geometry(BlockConf *conf, int *ptrans,
 
     if (!conf->cyls && !conf->heads && !conf->secs) {
         /* try to fall back to value set with legacy -drive cyls=... */
-        dinfo = drive_get_by_blockdev(conf->bs);
+        dinfo = blk_legacy_dinfo(conf->blk);
         conf->cyls  = dinfo->cyls;
         conf->heads = dinfo->heads;
         conf->secs  = dinfo->secs;
@@ -39,7 +40,7 @@ void blkconf_geometry(BlockConf *conf, int *ptrans,
         }
     }
     if (!conf->cyls && !conf->heads && !conf->secs) {
-        hd_geometry_guess(conf->bs,
+        hd_geometry_guess(conf->blk,
                           &conf->cyls, &conf->heads, &conf->secs,
                           ptrans);
     } else if (ptrans && *ptrans == BIOS_ATA_TRANSLATION_AUTO) {
diff --git a/hw/block/dataplane/virtio-blk.c b/hw/block/dataplane/virtio-blk.c
index af67dc3..ab5df12 100644
--- a/hw/block/dataplane/virtio-blk.c
+++ b/hw/block/dataplane/virtio-blk.c
@@ -17,7 +17,7 @@
 #include "qemu/thread.h"
 #include "qemu/error-report.h"
 #include "hw/virtio/dataplane/vring.h"
-#include "block/block.h"
+#include "sysemu/block-backend.h"
 #include "hw/virtio/virtio-blk.h"
 #include "virtio-blk.h"
 #include "block/aio.h"
@@ -94,7 +94,7 @@ static void handle_notify(EventNotifier *e)
     VirtIOBlock *vblk = VIRTIO_BLK(s->vdev);
 
     event_notifier_test_and_clear(&s->host_notifier);
-    bdrv_io_plug(s->conf->conf.bs);
+    blk_io_plug(s->conf->conf.blk);
     for (;;) {
         MultiReqBuffer mrb = {
             .num_writes = 0,
@@ -120,7 +120,7 @@ static void handle_notify(EventNotifier *e)
             virtio_blk_handle_request(req, &mrb);
         }
 
-        virtio_submit_multiwrite(s->conf->conf.bs, &mrb);
+        virtio_submit_multiwrite(s->conf->conf.blk, &mrb);
 
         if (likely(ret == -EAGAIN)) { /* vring emptied */
             /* Re-enable guest->host notifies and stop processing the vring.
@@ -133,7 +133,7 @@ static void handle_notify(EventNotifier *e)
             break;
         }
     }
-    bdrv_io_unplug(s->conf->conf.bs);
+    blk_io_unplug(s->conf->conf.blk);
 }
 
 /* Context: QEMU global mutex held */
@@ -163,8 +163,8 @@ void virtio_blk_data_plane_create(VirtIODevice *vdev, VirtIOBlkConf *conf,
     /* If dataplane is (re-)enabled while the guest is running there could be
      * block jobs that can conflict.
      */
-    if (bdrv_op_is_blocked(conf->conf.bs, BLOCK_OP_TYPE_DATAPLANE,
-                           &local_err)) {
+    if (blk_op_is_blocked(conf->conf.blk, BLOCK_OP_TYPE_DATAPLANE,
+                          &local_err)) {
         error_report("cannot start dataplane thread: %s",
                       error_get_pretty(local_err));
         error_free(local_err);
@@ -193,9 +193,9 @@ void virtio_blk_data_plane_create(VirtIODevice *vdev, VirtIOBlkConf *conf,
     s->bh = aio_bh_new(s->ctx, notify_guest_bh, s);
 
     error_setg(&s->blocker, "block device is in use by data plane");
-    bdrv_op_block_all(conf->conf.bs, s->blocker);
-    bdrv_op_unblock(conf->conf.bs, BLOCK_OP_TYPE_RESIZE, s->blocker);
-    bdrv_op_unblock(conf->conf.bs, BLOCK_OP_TYPE_DRIVE_DEL, s->blocker);
+    blk_op_block_all(conf->conf.blk, s->blocker);
+    blk_op_unblock(conf->conf.blk, BLOCK_OP_TYPE_RESIZE, s->blocker);
+    blk_op_unblock(conf->conf.blk, BLOCK_OP_TYPE_DRIVE_DEL, s->blocker);
 
     *dataplane = s;
 }
@@ -208,7 +208,7 @@ void virtio_blk_data_plane_destroy(VirtIOBlockDataPlane *s)
     }
 
     virtio_blk_data_plane_stop(s);
-    bdrv_op_unblock_all(s->conf->conf.bs, s->blocker);
+    blk_op_unblock_all(s->conf->conf.blk, s->blocker);
     error_free(s->blocker);
     object_unref(OBJECT(s->iothread));
     qemu_bh_delete(s->bh);
@@ -263,7 +263,7 @@ void virtio_blk_data_plane_start(VirtIOBlockDataPlane *s)
     s->started = true;
     trace_virtio_blk_data_plane_start(s);
 
-    bdrv_set_aio_context(s->conf->conf.bs, s->ctx);
+    blk_set_aio_context(s->conf->conf.blk, s->ctx);
 
     /* Kick right away to begin processing requests already in vring */
     event_notifier_set(virtio_queue_get_host_notifier(vq));
@@ -309,7 +309,7 @@ void virtio_blk_data_plane_stop(VirtIOBlockDataPlane *s)
     aio_set_event_notifier(s->ctx, &s->host_notifier, NULL);
 
     /* Drain and switch bs back to the QEMU main loop */
-    bdrv_set_aio_context(s->conf->conf.bs, qemu_get_aio_context());
+    blk_set_aio_context(s->conf->conf.blk, qemu_get_aio_context());
 
     aio_context_release(s->ctx);
 
diff --git a/hw/block/fdc.c b/hw/block/fdc.c
index 19f215f..4b20339 100644
--- a/hw/block/fdc.c
+++ b/hw/block/fdc.c
@@ -114,7 +114,7 @@ static const FDFormat fd_formats[] = {
     { FDRIVE_DRV_NONE, -1, -1, 0, 0, },
 };
 
-static void pick_geometry(BlockDriverState *bs, int *nb_heads,
+static void pick_geometry(BlockBackend *blk, int *nb_heads,
                           int *max_track, int *last_sect,
                           FDriveType drive_in, FDriveType *drive,
                           FDriveRate *rate)
@@ -123,7 +123,7 @@ static void pick_geometry(BlockDriverState *bs, int *nb_heads,
     uint64_t nb_sectors, size;
     int i, first_match, match;
 
-    bdrv_get_geometry(bs, &nb_sectors);
+    blk_get_geometry(blk, &nb_sectors);
     match = -1;
     first_match = -1;
     for (i = 0; ; i++) {
@@ -176,7 +176,7 @@ typedef enum FDiskFlags {
 
 typedef struct FDrive {
     FDCtrl *fdctrl;
-    BlockDriverState *bs;
+    BlockBackend *blk;
     /* Drive status */
     FDriveType drive;
     uint8_t perpendicular;    /* 2.88 MB access mode    */
@@ -261,7 +261,7 @@ static int fd_seek(FDrive *drv, uint8_t head, uint8_t track, uint8_t sect,
 #endif
         drv->head = head;
         if (drv->track != track) {
-            if (drv->bs != NULL && bdrv_is_inserted(drv->bs)) {
+            if (drv->blk != NULL && blk_is_inserted(drv->blk)) {
                 drv->media_changed = 0;
             }
             ret = 1;
@@ -270,7 +270,7 @@ static int fd_seek(FDrive *drv, uint8_t head, uint8_t track, uint8_t sect,
         drv->sect = sect;
     }
 
-    if (drv->bs == NULL || !bdrv_is_inserted(drv->bs)) {
+    if (drv->blk == NULL || !blk_is_inserted(drv->blk)) {
         ret = 2;
     }
 
@@ -292,11 +292,11 @@ static void fd_revalidate(FDrive *drv)
     FDriveRate rate;
 
     FLOPPY_DPRINTF("revalidate\n");
-    if (drv->bs != NULL) {
-        ro = bdrv_is_read_only(drv->bs);
-        pick_geometry(drv->bs, &nb_heads, &max_track,
+    if (drv->blk != NULL) {
+        ro = blk_is_read_only(drv->blk);
+        pick_geometry(drv->blk, &nb_heads, &max_track,
                       &last_sect, drv->drive, &drive, &rate);
-        if (!bdrv_is_inserted(drv->bs)) {
+        if (!blk_is_inserted(drv->blk)) {
             FLOPPY_DPRINTF("No disk in drive\n");
         } else {
             FLOPPY_DPRINTF("Floppy disk (%d h %d t %d s) %s\n", nb_heads,
@@ -666,7 +666,7 @@ static bool fdrive_media_changed_needed(void *opaque)
 {
     FDrive *drive = opaque;
 
-    return (drive->bs != NULL && drive->media_changed != 1);
+    return (drive->blk != NULL && drive->media_changed != 1);
 }
 
 static const VMStateDescription vmstate_fdrive_media_changed = {
@@ -839,8 +839,9 @@ static void fdctrl_reset(FDCtrl *fdctrl, int do_irq)
     /* Initialise controller */
     fdctrl->sra = 0;
     fdctrl->srb = 0xc0;
-    if (!fdctrl->drives[1].bs)
+    if (!fdctrl->drives[1].blk) {
         fdctrl->sra |= FD_SRA_nDRV2;
+    }
     fdctrl->cur_drv = 0;
     fdctrl->dor = FD_DOR_nRESET;
     fdctrl->dor |= (fdctrl->dma_chann != -1) ? FD_DOR_DMAEN : 0;
@@ -1330,7 +1331,7 @@ static int fdctrl_transfer_handler (void *opaque, int nchan,
         status2 = FD_SR2_SNS;
     if (dma_len > fdctrl->data_len)
         dma_len = fdctrl->data_len;
-    if (cur_drv->bs == NULL) {
+    if (cur_drv->blk == NULL) {
         if (fdctrl->data_dir == FD_DIR_WRITE)
             fdctrl_stop_transfer(fdctrl, FD_SR0_ABNTERM | FD_SR0_SEEK, 0x00, 0x00);
         else
@@ -1351,8 +1352,8 @@ static int fdctrl_transfer_handler (void *opaque, int nchan,
         if (fdctrl->data_dir != FD_DIR_WRITE ||
             len < FD_SECTOR_LEN || rel_pos != 0) {
             /* READ & SCAN commands and realign to a sector for WRITE */
-            if (bdrv_read(cur_drv->bs, fd_sector(cur_drv),
-                          fdctrl->fifo, 1) < 0) {
+            if (blk_read(cur_drv->blk, fd_sector(cur_drv),
+                         fdctrl->fifo, 1) < 0) {
                 FLOPPY_DPRINTF("Floppy: error getting sector %d\n",
                                fd_sector(cur_drv));
                 /* Sure, image size is too small... */
@@ -1379,8 +1380,8 @@ static int fdctrl_transfer_handler (void *opaque, int nchan,
 
             DMA_read_memory (nchan, fdctrl->fifo + rel_pos,
                              fdctrl->data_pos, len);
-            if (bdrv_write(cur_drv->bs, fd_sector(cur_drv),
-                           fdctrl->fifo, 1) < 0) {
+            if (blk_write(cur_drv->blk, fd_sector(cur_drv),
+                          fdctrl->fifo, 1) < 0) {
                 FLOPPY_DPRINTF("error writing sector %d\n",
                                fd_sector(cur_drv));
                 fdctrl_stop_transfer(fdctrl, FD_SR0_ABNTERM | FD_SR0_SEEK, 0x00, 0x00);
@@ -1455,7 +1456,8 @@ static uint32_t fdctrl_read_data(FDCtrl *fdctrl)
                                    fd_sector(cur_drv));
                     return 0;
                 }
-            if (bdrv_read(cur_drv->bs, fd_sector(cur_drv), fdctrl->fifo, 1) < 0) {
+            if (blk_read(cur_drv->blk, fd_sector(cur_drv), fdctrl->fifo, 1)
+                < 0) {
                 FLOPPY_DPRINTF("error getting sector %d\n",
                                fd_sector(cur_drv));
                 /* Sure, image size is too small... */
@@ -1524,8 +1526,8 @@ static void fdctrl_format_sector(FDCtrl *fdctrl)
         break;
     }
     memset(fdctrl->fifo, 0, FD_SECTOR_LEN);
-    if (cur_drv->bs == NULL ||
-        bdrv_write(cur_drv->bs, fd_sector(cur_drv), fdctrl->fifo, 1) < 0) {
+    if (cur_drv->blk == NULL ||
+        blk_write(cur_drv->blk, fd_sector(cur_drv), fdctrl->fifo, 1) < 0) {
         FLOPPY_DPRINTF("error formatting sector %d\n", fd_sector(cur_drv));
         fdctrl_stop_transfer(fdctrl, FD_SR0_ABNTERM | FD_SR0_SEEK, 0x00, 0x00);
     } else {
@@ -1915,7 +1917,8 @@ static void fdctrl_write_data(FDCtrl *fdctrl, uint32_t value)
         if (pos == FD_SECTOR_LEN - 1 ||
             fdctrl->data_pos == fdctrl->data_len) {
             cur_drv = get_cur_drv(fdctrl);
-            if (bdrv_write(cur_drv->bs, fd_sector(cur_drv), fdctrl->fifo, 1) < 0) {
+            if (blk_write(cur_drv->blk, fd_sector(cur_drv), fdctrl->fifo, 1)
+                < 0) {
                 FLOPPY_DPRINTF("error writing sector %d\n",
                                fd_sector(cur_drv));
                 return;
@@ -2003,12 +2006,12 @@ static void fdctrl_connect_drives(FDCtrl *fdctrl, Error **errp)
         drive = &fdctrl->drives[i];
         drive->fdctrl = fdctrl;
 
-        if (drive->bs) {
-            if (bdrv_get_on_error(drive->bs, 0) != BLOCKDEV_ON_ERROR_ENOSPC) {
+        if (drive->blk) {
+            if (blk_get_on_error(drive->blk, 0) != BLOCKDEV_ON_ERROR_ENOSPC) {
                 error_setg(errp, "fdc doesn't support drive option werror");
                 return;
             }
-            if (bdrv_get_on_error(drive->bs, 1) != BLOCKDEV_ON_ERROR_REPORT) {
+            if (blk_get_on_error(drive->blk, 1) != BLOCKDEV_ON_ERROR_REPORT) {
                 error_setg(errp, "fdc doesn't support drive option rerror");
                 return;
             }
@@ -2016,8 +2019,8 @@ static void fdctrl_connect_drives(FDCtrl *fdctrl, Error **errp)
 
         fd_init(drive);
         fdctrl_change_cb(drive, 0);
-        if (drive->bs) {
-            bdrv_set_dev_ops(drive->bs, &fdctrl_block_ops, drive);
+        if (drive->blk) {
+            blk_set_dev_ops(drive->blk, &fdctrl_block_ops, drive);
         }
     }
 }
@@ -2034,12 +2037,10 @@ ISADevice *fdctrl_init_isa(ISABus *bus, DriveInfo **fds)
     dev = DEVICE(isadev);
 
     if (fds[0]) {
-        qdev_prop_set_drive_nofail(dev, "driveA",
-                                   blk_bs(blk_by_legacy_dinfo(fds[0])));
+        qdev_prop_set_drive_nofail(dev, "driveA", blk_by_legacy_dinfo(fds[0]));
     }
     if (fds[1]) {
-        qdev_prop_set_drive_nofail(dev, "driveB",
-                                   blk_bs(blk_by_legacy_dinfo(fds[1])));
+        qdev_prop_set_drive_nofail(dev, "driveB", blk_by_legacy_dinfo(fds[1]));
     }
     qdev_init_nofail(dev);
 
@@ -2059,12 +2060,10 @@ void fdctrl_init_sysbus(qemu_irq irq, int dma_chann,
     fdctrl = &sys->state;
     fdctrl->dma_chann = dma_chann; /* FIXME */
     if (fds[0]) {
-        qdev_prop_set_drive_nofail(dev, "driveA",
-                                   blk_bs(blk_by_legacy_dinfo(fds[0])));
+        qdev_prop_set_drive_nofail(dev, "driveA", blk_by_legacy_dinfo(fds[0]));
     }
     if (fds[1]) {
-        qdev_prop_set_drive_nofail(dev, "driveB",
-                                   blk_bs(blk_by_legacy_dinfo(fds[1])));
+        qdev_prop_set_drive_nofail(dev, "driveB", blk_by_legacy_dinfo(fds[1]));
     }
     qdev_init_nofail(dev);
     sbd = SYS_BUS_DEVICE(dev);
@@ -2080,8 +2079,7 @@ void sun4m_fdctrl_init(qemu_irq irq, hwaddr io_base,
 
     dev = qdev_create(NULL, "SUNW,fdtwo");
     if (fds[0]) {
-        qdev_prop_set_drive_nofail(dev, "drive",
-                                   blk_bs(blk_by_legacy_dinfo(fds[0])));
+        qdev_prop_set_drive_nofail(dev, "drive", blk_by_legacy_dinfo(fds[0]));
     }
     qdev_init_nofail(dev);
     sys = SYSBUS_FDC(dev);
@@ -2221,8 +2219,8 @@ static Property isa_fdc_properties[] = {
     DEFINE_PROP_UINT32("iobase", FDCtrlISABus, iobase, 0x3f0),
     DEFINE_PROP_UINT32("irq", FDCtrlISABus, irq, 6),
     DEFINE_PROP_UINT32("dma", FDCtrlISABus, dma, 2),
-    DEFINE_PROP_DRIVE("driveA", FDCtrlISABus, state.drives[0].bs),
-    DEFINE_PROP_DRIVE("driveB", FDCtrlISABus, state.drives[1].bs),
+    DEFINE_PROP_DRIVE("driveA", FDCtrlISABus, state.drives[0].blk),
+    DEFINE_PROP_DRIVE("driveB", FDCtrlISABus, state.drives[1].blk),
     DEFINE_PROP_INT32("bootindexA", FDCtrlISABus, bootindexA, -1),
     DEFINE_PROP_INT32("bootindexB", FDCtrlISABus, bootindexB, -1),
     DEFINE_PROP_BIT("check_media_rate", FDCtrlISABus, state.check_media_rate,
@@ -2260,8 +2258,8 @@ static const VMStateDescription vmstate_sysbus_fdc ={
 };
 
 static Property sysbus_fdc_properties[] = {
-    DEFINE_PROP_DRIVE("driveA", FDCtrlSysBus, state.drives[0].bs),
-    DEFINE_PROP_DRIVE("driveB", FDCtrlSysBus, state.drives[1].bs),
+    DEFINE_PROP_DRIVE("driveA", FDCtrlSysBus, state.drives[0].blk),
+    DEFINE_PROP_DRIVE("driveB", FDCtrlSysBus, state.drives[1].blk),
     DEFINE_PROP_END_OF_LIST(),
 };
 
@@ -2281,7 +2279,7 @@ static const TypeInfo sysbus_fdc_info = {
 };
 
 static Property sun4m_fdc_properties[] = {
-    DEFINE_PROP_DRIVE("drive", FDCtrlSysBus, state.drives[0].bs),
+    DEFINE_PROP_DRIVE("drive", FDCtrlSysBus, state.drives[0].blk),
     DEFINE_PROP_END_OF_LIST(),
 };
 
diff --git a/hw/block/hd-geometry.c b/hw/block/hd-geometry.c
index 6feb4f8..6fcf74d 100644
--- a/hw/block/hd-geometry.c
+++ b/hw/block/hd-geometry.c
@@ -30,7 +30,7 @@
  * THE SOFTWARE.
  */
 
-#include "block/block.h"
+#include "sysemu/block-backend.h"
 #include "hw/block/block.h"
 #include "trace.h"
 
@@ -49,7 +49,7 @@ struct partition {
 
 /* try to guess the disk logical geometry from the MSDOS partition table.
    Return 0 if OK, -1 if could not guess */
-static int guess_disk_lchs(BlockDriverState *bs,
+static int guess_disk_lchs(BlockBackend *blk,
                            int *pcylinders, int *pheads, int *psectors)
 {
     uint8_t buf[BDRV_SECTOR_SIZE];
@@ -58,14 +58,14 @@ static int guess_disk_lchs(BlockDriverState *bs,
     uint32_t nr_sects;
     uint64_t nb_sectors;
 
-    bdrv_get_geometry(bs, &nb_sectors);
+    blk_get_geometry(blk, &nb_sectors);
 
     /**
      * The function will be invoked during startup not only in sync I/O mode,
      * but also in async I/O mode. So the I/O throttling function has to
      * be disabled temporarily here, not permanently.
      */
-    if (bdrv_read_unthrottled(bs, 0, buf, 1) < 0) {
+    if (blk_read_unthrottled(blk, 0, buf, 1) < 0) {
         return -1;
     }
     /* test msdos magic */
@@ -90,20 +90,20 @@ static int guess_disk_lchs(BlockDriverState *bs,
             *pheads = heads;
             *psectors = sectors;
             *pcylinders = cylinders;
-            trace_hd_geometry_lchs_guess(bs, cylinders, heads, sectors);
+            trace_hd_geometry_lchs_guess(blk, cylinders, heads, sectors);
             return 0;
         }
     }
     return -1;
 }
 
-static void guess_chs_for_size(BlockDriverState *bs,
+static void guess_chs_for_size(BlockBackend *blk,
                 uint32_t *pcyls, uint32_t *pheads, uint32_t *psecs)
 {
     uint64_t nb_sectors;
     int cylinders;
 
-    bdrv_get_geometry(bs, &nb_sectors);
+    blk_get_geometry(blk, &nb_sectors);
 
     cylinders = nb_sectors / (16 * 63);
     if (cylinders > 16383) {
@@ -116,21 +116,21 @@ static void guess_chs_for_size(BlockDriverState *bs,
     *psecs = 63;
 }
 
-void hd_geometry_guess(BlockDriverState *bs,
+void hd_geometry_guess(BlockBackend *blk,
                        uint32_t *pcyls, uint32_t *pheads, uint32_t *psecs,
                        int *ptrans)
 {
     int cylinders, heads, secs, translation;
 
-    if (guess_disk_lchs(bs, &cylinders, &heads, &secs) < 0) {
+    if (guess_disk_lchs(blk, &cylinders, &heads, &secs) < 0) {
         /* no LCHS guess: use a standard physical disk geometry  */
-        guess_chs_for_size(bs, pcyls, pheads, psecs);
+        guess_chs_for_size(blk, pcyls, pheads, psecs);
         translation = hd_bios_chs_auto_trans(*pcyls, *pheads, *psecs);
     } else if (heads > 16) {
         /* LCHS guess with heads > 16 means that a BIOS LBA
            translation was active, so a standard physical disk
            geometry is OK */
-        guess_chs_for_size(bs, pcyls, pheads, psecs);
+        guess_chs_for_size(blk, pcyls, pheads, psecs);
         translation = *pcyls * *pheads <= 131072
             ? BIOS_ATA_TRANSLATION_LARGE
             : BIOS_ATA_TRANSLATION_LBA;
@@ -146,7 +146,7 @@ void hd_geometry_guess(BlockDriverState *bs,
     if (ptrans) {
         *ptrans = translation;
     }
-    trace_hd_geometry_guess(bs, *pcyls, *pheads, *psecs, translation);
+    trace_hd_geometry_guess(blk, *pcyls, *pheads, *psecs, translation);
 }
 
 int hd_bios_chs_auto_trans(uint32_t cyls, uint32_t heads, uint32_t secs)
diff --git a/hw/block/m25p80.c b/hw/block/m25p80.c
index 78280a8..ff1106b 100644
--- a/hw/block/m25p80.c
+++ b/hw/block/m25p80.c
@@ -246,7 +246,7 @@ typedef struct Flash {
 
     uint32_t r;
 
-    BlockDriverState *bdrv;
+    BlockBackend *blk;
 
     uint8_t *storage;
     uint32_t size;
@@ -280,7 +280,7 @@ typedef struct M25P80Class {
 #define M25P80_GET_CLASS(obj) \
      OBJECT_GET_CLASS(M25P80Class, (obj), TYPE_M25P80)
 
-static void bdrv_sync_complete(void *opaque, int ret)
+static void blk_sync_complete(void *opaque, int ret)
 {
     /* do nothing. Masters do not directly interact with the backing store,
      * only the working copy so no mutexing required.
@@ -289,20 +289,20 @@ static void bdrv_sync_complete(void *opaque, int ret)
 
 static void flash_sync_page(Flash *s, int page)
 {
-    int bdrv_sector, nb_sectors;
+    int blk_sector, nb_sectors;
     QEMUIOVector iov;
 
-    if (!s->bdrv || bdrv_is_read_only(s->bdrv)) {
+    if (!s->blk || blk_is_read_only(s->blk)) {
         return;
     }
 
-    bdrv_sector = (page * s->pi->page_size) / BDRV_SECTOR_SIZE;
+    blk_sector = (page * s->pi->page_size) / BDRV_SECTOR_SIZE;
     nb_sectors = DIV_ROUND_UP(s->pi->page_size, BDRV_SECTOR_SIZE);
     qemu_iovec_init(&iov, 1);
-    qemu_iovec_add(&iov, s->storage + bdrv_sector * BDRV_SECTOR_SIZE,
+    qemu_iovec_add(&iov, s->storage + blk_sector * BDRV_SECTOR_SIZE,
                    nb_sectors * BDRV_SECTOR_SIZE);
-    bdrv_aio_writev(s->bdrv, bdrv_sector, &iov, nb_sectors, bdrv_sync_complete,
-                    NULL);
+    blk_aio_writev(s->blk, blk_sector, &iov, nb_sectors, blk_sync_complete,
+                   NULL);
 }
 
 static inline void flash_sync_area(Flash *s, int64_t off, int64_t len)
@@ -310,7 +310,7 @@ static inline void flash_sync_area(Flash *s, int64_t off, int64_t len)
     int64_t start, end, nb_sectors;
     QEMUIOVector iov;
 
-    if (!s->bdrv || bdrv_is_read_only(s->bdrv)) {
+    if (!s->blk || blk_is_read_only(s->blk)) {
         return;
     }
 
@@ -321,7 +321,7 @@ static inline void flash_sync_area(Flash *s, int64_t off, int64_t len)
     qemu_iovec_init(&iov, 1);
     qemu_iovec_add(&iov, s->storage + (start * BDRV_SECTOR_SIZE),
                                         nb_sectors * BDRV_SECTOR_SIZE);
-    bdrv_aio_writev(s->bdrv, start, &iov, nb_sectors, bdrv_sync_complete, NULL);
+    blk_aio_writev(s->blk, start, &iov, nb_sectors, blk_sync_complete, NULL);
 }
 
 static void flash_erase(Flash *s, int offset, FlashCMD cmd)
@@ -621,17 +621,17 @@ static int m25p80_init(SSISlave *ss)
 
     s->size = s->pi->sector_size * s->pi->n_sectors;
     s->dirty_page = -1;
-    s->storage = qemu_blockalign(s->bdrv, s->size);
+    s->storage = blk_blockalign(s->blk, s->size);
 
     dinfo = drive_get_next(IF_MTD);
 
     if (dinfo) {
         DB_PRINT_L(0, "Binding to IF_MTD drive\n");
-        s->bdrv = blk_bs(blk_by_legacy_dinfo(dinfo));
+        s->blk = blk_by_legacy_dinfo(dinfo);
 
         /* FIXME: Move to late init */
-        if (bdrv_read(s->bdrv, 0, s->storage, DIV_ROUND_UP(s->size,
-                                                    BDRV_SECTOR_SIZE))) {
+        if (blk_read(s->blk, 0, s->storage,
+                     DIV_ROUND_UP(s->size, BDRV_SECTOR_SIZE))) {
             fprintf(stderr, "Failed to initialize SPI flash!\n");
             return 1;
         }
diff --git a/hw/block/nand.c b/hw/block/nand.c
index 38eefd4..1882a0c 100644
--- a/hw/block/nand.c
+++ b/hw/block/nand.c
@@ -20,7 +20,7 @@
 
 # include "hw/hw.h"
 # include "hw/block/flash.h"
-# include "sysemu/blockdev.h"
+#include "sysemu/block-backend.h"
 #include "hw/qdev.h"
 #include "qemu/error-report.h"
 
@@ -61,7 +61,7 @@ struct NANDFlashState {
     int size, pages;
     int page_shift, oob_shift, erase_shift, addr_shift;
     uint8_t *storage;
-    BlockDriverState *bdrv;
+    BlockBackend *blk;
     int mem_oob;
 
     uint8_t cle, ale, ce, wp, gnd;
@@ -400,12 +400,12 @@ static void nand_realize(DeviceState *dev, Error **errp)
 
     pagesize = 1 << s->oob_shift;
     s->mem_oob = 1;
-    if (s->bdrv) {
-        if (bdrv_is_read_only(s->bdrv)) {
+    if (s->blk) {
+        if (blk_is_read_only(s->blk)) {
             error_setg(errp, "Can't use a read-only drive");
             return;
         }
-        if (bdrv_getlength(s->bdrv) >=
+        if (blk_getlength(s->blk) >=
                 (s->pages << s->page_shift) + (s->pages << s->oob_shift)) {
             pagesize = 0;
             s->mem_oob = 0;
@@ -424,7 +424,7 @@ static void nand_realize(DeviceState *dev, Error **errp)
 static Property nand_properties[] = {
     DEFINE_PROP_UINT8("manufacturer_id", NANDFlashState, manf_id, 0),
     DEFINE_PROP_UINT8("chip_id", NANDFlashState, chip_id, 0),
-    DEFINE_PROP_DRIVE("drive", NANDFlashState, bdrv),
+    DEFINE_PROP_DRIVE("drive", NANDFlashState, blk),
     DEFINE_PROP_END_OF_LIST(),
 };
 
@@ -624,7 +624,7 @@ uint32_t nand_getbuswidth(DeviceState *dev)
     return s->buswidth << 3;
 }
 
-DeviceState *nand_init(BlockDriverState *bdrv, int manf_id, int chip_id)
+DeviceState *nand_init(BlockBackend *blk, int manf_id, int chip_id)
 {
     DeviceState *dev;
 
@@ -634,8 +634,8 @@ DeviceState *nand_init(BlockDriverState *bdrv, int manf_id, int chip_id)
     dev = DEVICE(object_new(TYPE_NAND));
     qdev_prop_set_uint8(dev, "manufacturer_id", manf_id);
     qdev_prop_set_uint8(dev, "chip_id", chip_id);
-    if (bdrv) {
-        qdev_prop_set_drive_nofail(dev, "drive", bdrv);
+    if (blk) {
+        qdev_prop_set_drive_nofail(dev, "drive", blk);
     }
 
     qdev_init_nofail(dev);
@@ -654,14 +654,14 @@ static void glue(nand_blk_write_, PAGE_SIZE)(NANDFlashState *s)
     if (PAGE(s->addr) >= s->pages)
         return;
 
-    if (!s->bdrv) {
+    if (!s->blk) {
         mem_and(s->storage + PAGE_START(s->addr) + (s->addr & PAGE_MASK) +
                         s->offset, s->io, s->iolen);
     } else if (s->mem_oob) {
         sector = SECTOR(s->addr);
         off = (s->addr & PAGE_MASK) + s->offset;
         soff = SECTOR_OFFSET(s->addr);
-        if (bdrv_read(s->bdrv, sector, iobuf, PAGE_SECTORS) < 0) {
+        if (blk_read(s->blk, sector, iobuf, PAGE_SECTORS) < 0) {
             printf("%s: read error in sector %" PRIu64 "\n", __func__, sector);
             return;
         }
@@ -673,21 +673,21 @@ static void glue(nand_blk_write_, PAGE_SIZE)(NANDFlashState *s)
                             MIN(OOB_SIZE, off + s->iolen - PAGE_SIZE));
         }
 
-        if (bdrv_write(s->bdrv, sector, iobuf, PAGE_SECTORS) < 0) {
+        if (blk_write(s->blk, sector, iobuf, PAGE_SECTORS) < 0) {
             printf("%s: write error in sector %" PRIu64 "\n", __func__, sector);
         }
     } else {
         off = PAGE_START(s->addr) + (s->addr & PAGE_MASK) + s->offset;
         sector = off >> 9;
         soff = off & 0x1ff;
-        if (bdrv_read(s->bdrv, sector, iobuf, PAGE_SECTORS + 2) < 0) {
+        if (blk_read(s->blk, sector, iobuf, PAGE_SECTORS + 2) < 0) {
             printf("%s: read error in sector %" PRIu64 "\n", __func__, sector);
             return;
         }
 
         mem_and(iobuf + soff, s->io, s->iolen);
 
-        if (bdrv_write(s->bdrv, sector, iobuf, PAGE_SECTORS + 2) < 0) {
+        if (blk_write(s->blk, sector, iobuf, PAGE_SECTORS + 2) < 0) {
             printf("%s: write error in sector %" PRIu64 "\n", __func__, sector);
         }
     }
@@ -705,7 +705,7 @@ static void glue(nand_blk_erase_, PAGE_SIZE)(NANDFlashState *s)
         return;
     }
 
-    if (!s->bdrv) {
+    if (!s->blk) {
         memset(s->storage + PAGE_START(addr),
                         0xff, (PAGE_SIZE + OOB_SIZE) << s->erase_shift);
     } else if (s->mem_oob) {
@@ -714,17 +714,17 @@ static void glue(nand_blk_erase_, PAGE_SIZE)(NANDFlashState *s)
         i = SECTOR(addr);
         page = SECTOR(addr + (ADDR_SHIFT + s->erase_shift));
         for (; i < page; i ++)
-            if (bdrv_write(s->bdrv, i, iobuf, 1) < 0) {
+            if (blk_write(s->blk, i, iobuf, 1) < 0) {
                 printf("%s: write error in sector %" PRIu64 "\n", __func__, i);
             }
     } else {
         addr = PAGE_START(addr);
         page = addr >> 9;
-        if (bdrv_read(s->bdrv, page, iobuf, 1) < 0) {
+        if (blk_read(s->blk, page, iobuf, 1) < 0) {
             printf("%s: read error in sector %" PRIu64 "\n", __func__, page);
         }
         memset(iobuf + (addr & 0x1ff), 0xff, (~addr & 0x1ff) + 1);
-        if (bdrv_write(s->bdrv, page, iobuf, 1) < 0) {
+        if (blk_write(s->blk, page, iobuf, 1) < 0) {
             printf("%s: write error in sector %" PRIu64 "\n", __func__, page);
         }
 
@@ -732,18 +732,18 @@ static void glue(nand_blk_erase_, PAGE_SIZE)(NANDFlashState *s)
         i = (addr & ~0x1ff) + 0x200;
         for (addr += ((PAGE_SIZE + OOB_SIZE) << s->erase_shift) - 0x200;
                         i < addr; i += 0x200) {
-            if (bdrv_write(s->bdrv, i >> 9, iobuf, 1) < 0) {
+            if (blk_write(s->blk, i >> 9, iobuf, 1) < 0) {
                 printf("%s: write error in sector %" PRIu64 "\n",
                        __func__, i >> 9);
             }
         }
 
         page = i >> 9;
-        if (bdrv_read(s->bdrv, page, iobuf, 1) < 0) {
+        if (blk_read(s->blk, page, iobuf, 1) < 0) {
             printf("%s: read error in sector %" PRIu64 "\n", __func__, page);
         }
         memset(iobuf, 0xff, ((addr - 1) & 0x1ff) + 1);
-        if (bdrv_write(s->bdrv, page, iobuf, 1) < 0) {
+        if (blk_write(s->blk, page, iobuf, 1) < 0) {
             printf("%s: write error in sector %" PRIu64 "\n", __func__, page);
         }
     }
@@ -756,9 +756,9 @@ static void glue(nand_blk_load_, PAGE_SIZE)(NANDFlashState *s,
         return;
     }
 
-    if (s->bdrv) {
+    if (s->blk) {
         if (s->mem_oob) {
-            if (bdrv_read(s->bdrv, SECTOR(addr), s->io, PAGE_SECTORS) < 0) {
+            if (blk_read(s->blk, SECTOR(addr), s->io, PAGE_SECTORS) < 0) {
                 printf("%s: read error in sector %" PRIu64 "\n",
                                 __func__, SECTOR(addr));
             }
@@ -767,8 +767,8 @@ static void glue(nand_blk_load_, PAGE_SIZE)(NANDFlashState *s,
                             OOB_SIZE);
             s->ioaddr = s->io + SECTOR_OFFSET(s->addr) + offset;
         } else {
-            if (bdrv_read(s->bdrv, PAGE_START(addr) >> 9,
-                                    s->io, (PAGE_SECTORS + 2)) < 0) {
+            if (blk_read(s->blk, PAGE_START(addr) >> 9,
+                         s->io, (PAGE_SECTORS + 2)) < 0) {
                 printf("%s: read error in sector %" PRIu64 "\n",
                                 __func__, PAGE_START(addr) >> 9);
             }
diff --git a/hw/block/nvme.c b/hw/block/nvme.c
index 04459e5..3ffd69c 100644
--- a/hw/block/nvme.c
+++ b/hw/block/nvme.c
@@ -24,6 +24,7 @@
 #include <hw/hw.h>
 #include <hw/pci/msix.h>
 #include <hw/pci/pci.h>
+#include "sysemu/block-backend.h"
 
 #include "nvme.h"
 
@@ -197,7 +198,7 @@ static void nvme_rw_cb(void *opaque, int ret)
     NvmeCtrl *n = sq->ctrl;
     NvmeCQueue *cq = n->cq[sq->cqid];
 
-    bdrv_acct_done(n->conf.bs, &req->acct);
+    blk_acct_done(n->conf.blk, &req->acct);
     if (!ret) {
         req->status = NVME_SUCCESS;
     } else {
@@ -231,11 +232,11 @@ static uint16_t nvme_rw(NvmeCtrl *n, NvmeNamespace *ns, NvmeCmd *cmd,
     }
     assert((nlb << data_shift) == req->qsg.size);
 
-    dma_acct_start(n->conf.bs, &req->acct, &req->qsg, is_write ?
+    dma_acct_start(n->conf.blk, &req->acct, &req->qsg, is_write ?
         BDRV_ACCT_WRITE : BDRV_ACCT_READ);
     req->aiocb = is_write ?
-        dma_bdrv_write(n->conf.bs, &req->qsg, aio_slba, nvme_rw_cb, req) :
-        dma_bdrv_read(n->conf.bs, &req->qsg, aio_slba, nvme_rw_cb, req);
+        dma_blk_write(n->conf.blk, &req->qsg, aio_slba, nvme_rw_cb, req) :
+        dma_blk_read(n->conf.blk, &req->qsg, aio_slba, nvme_rw_cb, req);
 
     return NVME_NO_COMPLETE;
 }
@@ -288,7 +289,7 @@ static uint16_t nvme_del_sq(NvmeCtrl *n, NvmeCmd *cmd)
     while (!QTAILQ_EMPTY(&sq->out_req_list)) {
         req = QTAILQ_FIRST(&sq->out_req_list);
         assert(req->aiocb);
-        bdrv_aio_cancel(req->aiocb);
+        blk_aio_cancel(req->aiocb);
     }
     if (!nvme_check_cqid(n, sq->cqid)) {
         cq = n->cq[sq->cqid];
@@ -563,7 +564,7 @@ static void nvme_clear_ctrl(NvmeCtrl *n)
         }
     }
 
-    bdrv_flush(n->conf.bs);
+    blk_flush(n->conf.blk);
     n->bar.cc = 0;
 }
 
@@ -748,11 +749,11 @@ static int nvme_init(PCIDevice *pci_dev)
     int64_t bs_size;
     uint8_t *pci_conf;
 
-    if (!(n->conf.bs)) {
+    if (!n->conf.blk) {
         return -1;
     }
 
-    bs_size = bdrv_getlength(n->conf.bs);
+    bs_size = blk_getlength(n->conf.blk);
     if (bs_size < 0) {
         return -1;
     }
diff --git a/hw/block/onenand.c b/hw/block/onenand.c
index 5388122..a85861e 100644
--- a/hw/block/onenand.c
+++ b/hw/block/onenand.c
@@ -22,6 +22,7 @@
 #include "hw/hw.h"
 #include "hw/block/flash.h"
 #include "hw/irq.h"
+#include "sysemu/block-backend.h"
 #include "sysemu/blockdev.h"
 #include "exec/memory.h"
 #include "exec/address-spaces.h"
@@ -49,8 +50,8 @@ typedef struct OneNANDState {
     hwaddr base;
     qemu_irq intr;
     qemu_irq rdy;
-    BlockDriverState *bdrv;
-    BlockDriverState *bdrv_cur;
+    BlockBackend *blk;
+    BlockBackend *blk_cur;
     uint8_t *image;
     uint8_t *otp;
     uint8_t *current;
@@ -213,7 +214,7 @@ static void onenand_reset(OneNANDState *s, int cold)
     s->wpstatus = 0x0002;
     s->cycle = 0;
     s->otpmode = 0;
-    s->bdrv_cur = s->bdrv;
+    s->blk_cur = s->blk;
     s->current = s->image;
     s->secs_cur = s->secs;
 
@@ -221,7 +222,7 @@ static void onenand_reset(OneNANDState *s, int cold)
         /* Lock the whole flash */
         memset(s->blockwp, ONEN_LOCK_LOCKED, s->blocks);
 
-        if (s->bdrv_cur && bdrv_read(s->bdrv_cur, 0, s->boot[0], 8) < 0) {
+        if (s->blk_cur && blk_read(s->blk_cur, 0, s->boot[0], 8) < 0) {
             hw_error("%s: Loading the BootRAM failed.\n", __func__);
         }
     }
@@ -237,10 +238,11 @@ static void onenand_system_reset(DeviceState *dev)
 static inline int onenand_load_main(OneNANDState *s, int sec, int secn,
                 void *dest)
 {
-    if (s->bdrv_cur)
-        return bdrv_read(s->bdrv_cur, sec, dest, secn) < 0;
-    else if (sec + secn > s->secs_cur)
+    if (s->blk_cur) {
+        return blk_read(s->blk_cur, sec, dest, secn) < 0;
+    } else if (sec + secn > s->secs_cur) {
         return 1;
+    }
 
     memcpy(dest, s->current + (sec << 9), secn << 9);
 
@@ -256,9 +258,9 @@ static inline int onenand_prog_main(OneNANDState *s, int sec, int secn,
         uint32_t size = (uint32_t)secn * 512;
         const uint8_t *sp = (const uint8_t *)src;
         uint8_t *dp = 0;
-        if (s->bdrv_cur) {
+        if (s->blk_cur) {
             dp = g_malloc(size);
-            if (!dp || bdrv_read(s->bdrv_cur, sec, dp, secn) < 0) {
+            if (!dp || blk_read(s->blk_cur, sec, dp, secn) < 0) {
                 result = 1;
             }
         } else {
@@ -273,11 +275,11 @@ static inline int onenand_prog_main(OneNANDState *s, int sec, int secn,
             for (i = 0; i < size; i++) {
                 dp[i] &= sp[i];
             }
-            if (s->bdrv_cur) {
-                result = bdrv_write(s->bdrv_cur, sec, dp, secn) < 0;
+            if (s->blk_cur) {
+                result = blk_write(s->blk_cur, sec, dp, secn) < 0;
             }
         }
-        if (dp && s->bdrv_cur) {
+        if (dp && s->blk_cur) {
             g_free(dp);
         }
     }
@@ -290,14 +292,16 @@ static inline int onenand_load_spare(OneNANDState *s, int sec, int secn,
 {
     uint8_t buf[512];
 
-    if (s->bdrv_cur) {
-        if (bdrv_read(s->bdrv_cur, s->secs_cur + (sec >> 5), buf, 1) < 0)
+    if (s->blk_cur) {
+        if (blk_read(s->blk_cur, s->secs_cur + (sec >> 5), buf, 1) < 0) {
             return 1;
+        }
         memcpy(dest, buf + ((sec & 31) << 4), secn << 4);
-    } else if (sec + secn > s->secs_cur)
+    } else if (sec + secn > s->secs_cur) {
         return 1;
-    else
+    } else {
         memcpy(dest, s->current + (s->secs_cur << 9) + (sec << 4), secn << 4);
+    }
  
     return 0;
 }
@@ -309,11 +313,10 @@ static inline int onenand_prog_spare(OneNANDState *s, int sec, int secn,
     if (secn > 0) {
         const uint8_t *sp = (const uint8_t *)src;
         uint8_t *dp = 0, *dpp = 0;
-        if (s->bdrv_cur) {
+        if (s->blk_cur) {
             dp = g_malloc(512);
-            if (!dp || bdrv_read(s->bdrv_cur,
-                                 s->secs_cur + (sec >> 5),
-                                 dp, 1) < 0) {
+            if (!dp
+                || blk_read(s->blk_cur, s->secs_cur + (sec >> 5), dp, 1) < 0) {
                 result = 1;
             } else {
                 dpp = dp + ((sec & 31) << 4);
@@ -330,9 +333,9 @@ static inline int onenand_prog_spare(OneNANDState *s, int sec, int secn,
             for (i = 0; i < (secn << 4); i++) {
                 dpp[i] &= sp[i];
             }
-            if (s->bdrv_cur) {
-                result = bdrv_write(s->bdrv_cur, s->secs_cur + (sec >> 5),
-                                    dp, 1) < 0;
+            if (s->blk_cur) {
+                result = blk_write(s->blk_cur, s->secs_cur + (sec >> 5),
+                                   dp, 1) < 0;
             }
         }
         g_free(dp);
@@ -354,16 +357,16 @@ static inline int onenand_erase(OneNANDState *s, int sec, int num)
     }
     memset(blankbuf, 0xff, 512);
     for (; num > 0; num--, sec++) {
-        if (s->bdrv_cur) {
+        if (s->blk_cur) {
             int erasesec = s->secs_cur + (sec >> 5);
-            if (bdrv_write(s->bdrv_cur, sec, blankbuf, 1) < 0) {
+            if (blk_write(s->blk_cur, sec, blankbuf, 1) < 0) {
                 goto fail;
             }
-            if (bdrv_read(s->bdrv_cur, erasesec, tmpbuf, 1) < 0) {
+            if (blk_read(s->blk_cur, erasesec, tmpbuf, 1) < 0) {
                 goto fail;
             }
             memcpy(tmpbuf + ((sec & 31) << 4), blankbuf, 1 << 4);
-            if (bdrv_write(s->bdrv_cur, erasesec, tmpbuf, 1) < 0) {
+            if (blk_write(s->blk_cur, erasesec, tmpbuf, 1) < 0) {
                 goto fail;
             }
         } else {
@@ -576,7 +579,7 @@ static void onenand_command(OneNANDState *s)
 
     case 0x65:	/* OTP Access */
         s->intstatus |= ONEN_INT;
-        s->bdrv_cur = NULL;
+        s->blk_cur = NULL;
         s->current = s->otp;
         s->secs_cur = 1 << (BLOCK_SHIFT - 9);
         s->addr[ONEN_BUF_BLOCK] = 0;
@@ -776,15 +779,15 @@ static int onenand_initfn(SysBusDevice *sbd)
         ? (1 << (6 + ((s->id.dev >> 4) & 7))) : 0;
     memory_region_init_io(&s->iomem, OBJECT(s), &onenand_ops, s, "onenand",
                           0x10000 << s->shift);
-    if (!s->bdrv) {
+    if (!s->blk) {
         s->image = memset(g_malloc(size + (size >> 5)),
                           0xff, size + (size >> 5));
     } else {
-        if (bdrv_is_read_only(s->bdrv)) {
+        if (blk_is_read_only(s->blk)) {
             error_report("Can't use a read-only drive");
             return -1;
         }
-        s->bdrv_cur = s->bdrv;
+        s->blk_cur = s->blk;
     }
     s->otp = memset(g_malloc((64 + 2) << PAGE_SHIFT),
                     0xff, (64 + 2) << PAGE_SHIFT);
@@ -815,7 +818,7 @@ static Property onenand_properties[] = {
     DEFINE_PROP_UINT16("device_id", OneNANDState, id.dev, 0),
     DEFINE_PROP_UINT16("version_id", OneNANDState, id.ver, 0),
     DEFINE_PROP_INT32("shift", OneNANDState, shift, 0),
-    DEFINE_PROP_DRIVE("drive", OneNANDState, bdrv),
+    DEFINE_PROP_DRIVE("drive", OneNANDState, blk),
     DEFINE_PROP_END_OF_LIST(),
 };
 
diff --git a/hw/block/pflash_cfi01.c b/hw/block/pflash_cfi01.c
index 593fbc5..ab9fef9 100644
--- a/hw/block/pflash_cfi01.c
+++ b/hw/block/pflash_cfi01.c
@@ -38,7 +38,7 @@
 
 #include "hw/hw.h"
 #include "hw/block/flash.h"
-#include "block/block.h"
+#include "sysemu/block-backend.h"
 #include "qemu/timer.h"
 #include "qemu/bitops.h"
 #include "exec/address-spaces.h"
@@ -69,7 +69,7 @@ struct pflash_t {
     SysBusDevice parent_obj;
     /*< public >*/
 
-    BlockDriverState *bs;
+    BlockBackend *blk;
     uint32_t nb_blocs;
     uint64_t sector_len;
     uint8_t bank_width;
@@ -395,13 +395,13 @@ static void pflash_update(pflash_t *pfl, int offset,
                           int size)
 {
     int offset_end;
-    if (pfl->bs) {
+    if (pfl->blk) {
         offset_end = offset + size;
         /* round to sectors */
         offset = offset >> 9;
         offset_end = (offset_end + 511) >> 9;
-        bdrv_write(pfl->bs, offset, pfl->storage + (offset << 9),
-                   offset_end - offset);
+        blk_write(pfl->blk, offset, pfl->storage + (offset << 9),
+                  offset_end - offset);
     }
 }
 
@@ -778,9 +778,9 @@ static void pflash_cfi01_realize(DeviceState *dev, Error **errp)
     pfl->storage = memory_region_get_ram_ptr(&pfl->mem);
     sysbus_init_mmio(SYS_BUS_DEVICE(dev), &pfl->mem);
 
-    if (pfl->bs) {
+    if (pfl->blk) {
         /* read the initial flash content */
-        ret = bdrv_read(pfl->bs, 0, pfl->storage, total_len >> 9);
+        ret = blk_read(pfl->blk, 0, pfl->storage, total_len >> 9);
 
         if (ret < 0) {
             vmstate_unregister_ram(&pfl->mem, DEVICE(pfl));
@@ -789,8 +789,8 @@ static void pflash_cfi01_realize(DeviceState *dev, Error **errp)
         }
     }
 
-    if (pfl->bs) {
-        pfl->ro = bdrv_is_read_only(pfl->bs);
+    if (pfl->blk) {
+        pfl->ro = blk_is_read_only(pfl->blk);
     } else {
         pfl->ro = 0;
     }
@@ -892,7 +892,7 @@ static void pflash_cfi01_realize(DeviceState *dev, Error **errp)
 }
 
 static Property pflash_cfi01_properties[] = {
-    DEFINE_PROP_DRIVE("drive", struct pflash_t, bs),
+    DEFINE_PROP_DRIVE("drive", struct pflash_t, blk),
     /* num-blocks is the number of blocks actually visible to the guest,
      * ie the total size of the device divided by the sector length.
      * If we're emulating flash devices wired in parallel the actual
@@ -956,14 +956,14 @@ type_init(pflash_cfi01_register_types)
 pflash_t *pflash_cfi01_register(hwaddr base,
                                 DeviceState *qdev, const char *name,
                                 hwaddr size,
-                                BlockDriverState *bs,
+                                BlockBackend *blk,
                                 uint32_t sector_len, int nb_blocs,
                                 int bank_width, uint16_t id0, uint16_t id1,
                                 uint16_t id2, uint16_t id3, int be)
 {
     DeviceState *dev = qdev_create(NULL, TYPE_CFI_PFLASH01);
 
-    if (bs && qdev_prop_set_drive(dev, "drive", bs)) {
+    if (blk && qdev_prop_set_drive(dev, "drive", blk)) {
         abort();
     }
     qdev_prop_set_uint32(dev, "num-blocks", nb_blocs);
diff --git a/hw/block/pflash_cfi02.c b/hw/block/pflash_cfi02.c
index e196f4d..d372c31 100644
--- a/hw/block/pflash_cfi02.c
+++ b/hw/block/pflash_cfi02.c
@@ -38,7 +38,7 @@
 #include "hw/hw.h"
 #include "hw/block/flash.h"
 #include "qemu/timer.h"
-#include "block/block.h"
+#include "sysemu/block-backend.h"
 #include "exec/address-spaces.h"
 #include "qemu/host-utils.h"
 #include "hw/sysbus.h"
@@ -63,7 +63,7 @@ struct pflash_t {
     SysBusDevice parent_obj;
     /*< public >*/
 
-    BlockDriverState *bs;
+    BlockBackend *blk;
     uint32_t sector_len;
     uint32_t nb_blocs;
     uint32_t chip_len;
@@ -249,13 +249,13 @@ static void pflash_update(pflash_t *pfl, int offset,
                           int size)
 {
     int offset_end;
-    if (pfl->bs) {
+    if (pfl->blk) {
         offset_end = offset + size;
         /* round to sectors */
         offset = offset >> 9;
         offset_end = (offset_end + 511) >> 9;
-        bdrv_write(pfl->bs, offset, pfl->storage + (offset << 9),
-                   offset_end - offset);
+        blk_write(pfl->blk, offset, pfl->storage + (offset << 9),
+                  offset_end - offset);
     }
 }
 
@@ -612,9 +612,9 @@ static void pflash_cfi02_realize(DeviceState *dev, Error **errp)
     vmstate_register_ram(&pfl->orig_mem, DEVICE(pfl));
     pfl->storage = memory_region_get_ram_ptr(&pfl->orig_mem);
     pfl->chip_len = chip_len;
-    if (pfl->bs) {
+    if (pfl->blk) {
         /* read the initial flash content */
-        ret = bdrv_read(pfl->bs, 0, pfl->storage, chip_len >> 9);
+        ret = blk_read(pfl->blk, 0, pfl->storage, chip_len >> 9);
         if (ret < 0) {
             vmstate_unregister_ram(&pfl->orig_mem, DEVICE(pfl));
             error_setg(errp, "failed to read the initial flash content");
@@ -626,8 +626,8 @@ static void pflash_cfi02_realize(DeviceState *dev, Error **errp)
     pfl->rom_mode = 1;
     sysbus_init_mmio(SYS_BUS_DEVICE(dev), &pfl->mem);
 
-    if (pfl->bs) {
-        pfl->ro = bdrv_is_read_only(pfl->bs);
+    if (pfl->blk) {
+        pfl->ro = blk_is_read_only(pfl->blk);
     } else {
         pfl->ro = 0;
     }
@@ -716,7 +716,7 @@ static void pflash_cfi02_realize(DeviceState *dev, Error **errp)
 }
 
 static Property pflash_cfi02_properties[] = {
-    DEFINE_PROP_DRIVE("drive", struct pflash_t, bs),
+    DEFINE_PROP_DRIVE("drive", struct pflash_t, blk),
     DEFINE_PROP_UINT32("num-blocks", struct pflash_t, nb_blocs, 0),
     DEFINE_PROP_UINT32("sector-length", struct pflash_t, sector_len, 0),
     DEFINE_PROP_UINT8("width", struct pflash_t, width, 0),
@@ -757,7 +757,7 @@ type_init(pflash_cfi02_register_types)
 pflash_t *pflash_cfi02_register(hwaddr base,
                                 DeviceState *qdev, const char *name,
                                 hwaddr size,
-                                BlockDriverState *bs, uint32_t sector_len,
+                                BlockBackend *blk, uint32_t sector_len,
                                 int nb_blocs, int nb_mappings, int width,
                                 uint16_t id0, uint16_t id1,
                                 uint16_t id2, uint16_t id3,
@@ -766,7 +766,7 @@ pflash_t *pflash_cfi02_register(hwaddr base,
 {
     DeviceState *dev = qdev_create(NULL, TYPE_CFI_PFLASH02);
 
-    if (bs && qdev_prop_set_drive(dev, "drive", bs)) {
+    if (blk && qdev_prop_set_drive(dev, "drive", blk)) {
         abort();
     }
     qdev_prop_set_uint32(dev, "num-blocks", nb_blocs);
diff --git a/hw/block/virtio-blk.c b/hw/block/virtio-blk.c
index 347f372..a22b3d4 100644
--- a/hw/block/virtio-blk.c
+++ b/hw/block/virtio-blk.c
@@ -16,6 +16,7 @@
 #include "qemu/error-report.h"
 #include "trace.h"
 #include "hw/block/block.h"
+#include "sysemu/block-backend.h"
 #include "sysemu/blockdev.h"
 #include "hw/virtio/virtio-blk.h"
 #ifdef CONFIG_VIRTIO_BLK_DATA_PLANE
@@ -66,7 +67,8 @@ static void virtio_blk_req_complete(VirtIOBlockReq *req, unsigned char status)
 static int virtio_blk_handle_rw_error(VirtIOBlockReq *req, int error,
     bool is_read)
 {
-    BlockErrorAction action = bdrv_get_error_action(req->dev->bs, is_read, error);
+    BlockErrorAction action = blk_get_error_action(req->dev->blk,
+                                                   is_read, error);
     VirtIOBlock *s = req->dev;
 
     if (action == BLOCK_ERROR_ACTION_STOP) {
@@ -74,11 +76,11 @@ static int virtio_blk_handle_rw_error(VirtIOBlockReq *req, int error,
         s->rq = req;
     } else if (action == BLOCK_ERROR_ACTION_REPORT) {
         virtio_blk_req_complete(req, VIRTIO_BLK_S_IOERR);
-        bdrv_acct_done(s->bs, &req->acct);
+        blk_acct_done(s->blk, &req->acct);
         virtio_blk_free_request(req);
     }
 
-    bdrv_error_action(s->bs, action, is_read, error);
+    blk_error_action(s->blk, action, is_read, error);
     return action != BLOCK_ERROR_ACTION_IGNORE;
 }
 
@@ -96,7 +98,7 @@ static void virtio_blk_rw_complete(void *opaque, int ret)
     }
 
     virtio_blk_req_complete(req, VIRTIO_BLK_S_OK);
-    bdrv_acct_done(req->dev->bs, &req->acct);
+    blk_acct_done(req->dev->blk, &req->acct);
     virtio_blk_free_request(req);
 }
 
@@ -111,7 +113,7 @@ static void virtio_blk_flush_complete(void *opaque, int ret)
     }
 
     virtio_blk_req_complete(req, VIRTIO_BLK_S_OK);
-    bdrv_acct_done(req->dev->bs, &req->acct);
+    blk_acct_done(req->dev->blk, &req->acct);
     virtio_blk_free_request(req);
 }
 
@@ -211,7 +213,7 @@ int virtio_blk_handle_scsi_req(VirtIOBlock *blk,
     hdr.sbp = elem->in_sg[elem->in_num - 3].iov_base;
     hdr.mx_sb_len = elem->in_sg[elem->in_num - 3].iov_len;
 
-    status = bdrv_ioctl(blk->bs, SG_IO, &hdr);
+    status = blk_ioctl(blk->blk, SG_IO, &hdr);
     if (status) {
         status = VIRTIO_BLK_S_UNSUPP;
         goto fail;
@@ -257,7 +259,7 @@ static void virtio_blk_handle_scsi(VirtIOBlockReq *req)
     virtio_blk_free_request(req);
 }
 
-void virtio_submit_multiwrite(BlockDriverState *bs, MultiReqBuffer *mrb)
+void virtio_submit_multiwrite(BlockBackend *blk, MultiReqBuffer *mrb)
 {
     int i, ret;
 
@@ -265,7 +267,7 @@ void virtio_submit_multiwrite(BlockDriverState *bs, MultiReqBuffer *mrb)
         return;
     }
 
-    ret = bdrv_aio_multiwrite(bs, mrb->blkreq, mrb->num_writes);
+    ret = blk_aio_multiwrite(blk, mrb->blkreq, mrb->num_writes);
     if (ret != 0) {
         for (i = 0; i < mrb->num_writes; i++) {
             if (mrb->blkreq[i].error) {
@@ -279,13 +281,13 @@ void virtio_submit_multiwrite(BlockDriverState *bs, MultiReqBuffer *mrb)
 
 static void virtio_blk_handle_flush(VirtIOBlockReq *req, MultiReqBuffer *mrb)
 {
-    bdrv_acct_start(req->dev->bs, &req->acct, 0, BDRV_ACCT_FLUSH);
+    blk_acct_start(req->dev->blk, &req->acct, 0, BDRV_ACCT_FLUSH);
 
     /*
      * Make sure all outstanding writes are posted to the backing device.
      */
-    virtio_submit_multiwrite(req->dev->bs, mrb);
-    bdrv_aio_flush(req->dev->bs, virtio_blk_flush_complete, req);
+    virtio_submit_multiwrite(req->dev->blk, mrb);
+    blk_aio_flush(req->dev->blk, virtio_blk_flush_complete, req);
 }
 
 static bool virtio_blk_sect_range_ok(VirtIOBlock *dev,
@@ -300,7 +302,7 @@ static bool virtio_blk_sect_range_ok(VirtIOBlock *dev,
     if (size % dev->conf.conf.logical_block_size) {
         return false;
     }
-    bdrv_get_geometry(dev->bs, &total_sectors);
+    blk_get_geometry(dev->blk, &total_sectors);
     if (sector > total_sectors || nb_sectors > total_sectors - sector) {
         return false;
     }
@@ -322,10 +324,10 @@ static void virtio_blk_handle_write(VirtIOBlockReq *req, MultiReqBuffer *mrb)
         return;
     }
 
-    bdrv_acct_start(req->dev->bs, &req->acct, req->qiov.size, BDRV_ACCT_WRITE);
+    blk_acct_start(req->dev->blk, &req->acct, req->qiov.size, BDRV_ACCT_WRITE);
 
     if (mrb->num_writes == 32) {
-        virtio_submit_multiwrite(req->dev->bs, mrb);
+        virtio_submit_multiwrite(req->dev->blk, mrb);
     }
 
     blkreq = &mrb->blkreq[mrb->num_writes];
@@ -353,10 +355,10 @@ static void virtio_blk_handle_read(VirtIOBlockReq *req)
         return;
     }
 
-    bdrv_acct_start(req->dev->bs, &req->acct, req->qiov.size, BDRV_ACCT_READ);
-    bdrv_aio_readv(req->dev->bs, sector, &req->qiov,
-                   req->qiov.size / BDRV_SECTOR_SIZE,
-                   virtio_blk_rw_complete, req);
+    blk_acct_start(req->dev->blk, &req->acct, req->qiov.size, BDRV_ACCT_READ);
+    blk_aio_readv(req->dev->blk, sector, &req->qiov,
+                  req->qiov.size / BDRV_SECTOR_SIZE,
+                  virtio_blk_rw_complete, req);
 }
 
 void virtio_blk_handle_request(VirtIOBlockReq *req, MultiReqBuffer *mrb)
@@ -446,7 +448,7 @@ static void virtio_blk_handle_output(VirtIODevice *vdev, VirtQueue *vq)
         virtio_blk_handle_request(req, &mrb);
     }
 
-    virtio_submit_multiwrite(s->bs, &mrb);
+    virtio_submit_multiwrite(s->blk, &mrb);
 
     /*
      * FIXME: Want to check for completions before returning to guest mode,
@@ -474,7 +476,7 @@ static void virtio_blk_dma_restart_bh(void *opaque)
         req = next;
     }
 
-    virtio_submit_multiwrite(s->bs, &mrb);
+    virtio_submit_multiwrite(s->blk, &mrb);
 }
 
 static void virtio_blk_dma_restart_cb(void *opaque, int running,
@@ -487,7 +489,7 @@ static void virtio_blk_dma_restart_cb(void *opaque, int running,
     }
 
     if (!s->bh) {
-        s->bh = aio_bh_new(bdrv_get_aio_context(s->conf.conf.bs),
+        s->bh = aio_bh_new(blk_get_aio_context(s->conf.conf.blk),
                            virtio_blk_dma_restart_bh, s);
         qemu_bh_schedule(s->bh);
     }
@@ -507,8 +509,8 @@ static void virtio_blk_reset(VirtIODevice *vdev)
      * This should cancel pending requests, but can't do nicely until there
      * are per-device request lists.
      */
-    bdrv_drain_all();
-    bdrv_set_enable_write_cache(s->bs, s->original_wce);
+    blk_drain_all();
+    blk_set_enable_write_cache(s->blk, s->original_wce);
 }
 
 /* coalesce internal state, copy to pci i/o region 0
@@ -521,7 +523,7 @@ static void virtio_blk_update_config(VirtIODevice *vdev, uint8_t *config)
     uint64_t capacity;
     int blk_size = conf->logical_block_size;
 
-    bdrv_get_geometry(s->bs, &capacity);
+    blk_get_geometry(s->blk, &capacity);
     memset(&blkcfg, 0, sizeof(blkcfg));
     virtio_stq_p(vdev, &blkcfg.capacity, capacity);
     virtio_stl_p(vdev, &blkcfg.seg_max, 128 - 2);
@@ -541,7 +543,7 @@ static void virtio_blk_update_config(VirtIODevice *vdev, uint8_t *config)
      * divided by 512 - instead it is the amount of blk_size blocks
      * per track (cylinder).
      */
-    if (bdrv_getlength(s->bs) /  conf->heads / conf->secs % blk_size) {
+    if (blk_getlength(s->blk) /  conf->heads / conf->secs % blk_size) {
         blkcfg.sectors = conf->secs & ~s->sector_mask;
     } else {
         blkcfg.sectors = conf->secs;
@@ -549,7 +551,7 @@ static void virtio_blk_update_config(VirtIODevice *vdev, uint8_t *config)
     blkcfg.size_max = 0;
     blkcfg.physical_block_exp = get_physical_block_exp(&s->conf.conf);
     blkcfg.alignment_offset = 0;
-    blkcfg.wce = bdrv_enable_write_cache(s->bs);
+    blkcfg.wce = blk_enable_write_cache(s->blk);
     memcpy(config, &blkcfg, sizeof(struct virtio_blk_config));
 }
 
@@ -560,9 +562,9 @@ static void virtio_blk_set_config(VirtIODevice *vdev, const uint8_t *config)
 
     memcpy(&blkcfg, config, sizeof(blkcfg));
 
-    aio_context_acquire(bdrv_get_aio_context(s->bs));
-    bdrv_set_enable_write_cache(s->bs, blkcfg.wce != 0);
-    aio_context_release(bdrv_get_aio_context(s->bs));
+    aio_context_acquire(blk_get_aio_context(s->blk));
+    blk_set_enable_write_cache(s->blk, blkcfg.wce != 0);
+    aio_context_release(blk_get_aio_context(s->blk));
 }
 
 static uint32_t virtio_blk_get_features(VirtIODevice *vdev, uint32_t features)
@@ -578,11 +580,12 @@ static uint32_t virtio_blk_get_features(VirtIODevice *vdev, uint32_t features)
     if (s->conf.config_wce) {
         features |= (1 << VIRTIO_BLK_F_CONFIG_WCE);
     }
-    if (bdrv_enable_write_cache(s->bs))
+    if (blk_enable_write_cache(s->blk)) {
         features |= (1 << VIRTIO_BLK_F_WCE);
-
-    if (bdrv_is_read_only(s->bs))
+    }
+    if (blk_is_read_only(s->blk)) {
         features |= 1 << VIRTIO_BLK_F_RO;
+    }
 
     return features;
 }
@@ -618,13 +621,13 @@ static void virtio_blk_set_status(VirtIODevice *vdev, uint8_t status)
      *     Guest writes 1 to the WCE configuration field (writeback mode)
      *     Guest sets DRIVER_OK bit in status field
      *
-     * s->bs would erroneously be placed in writethrough mode.
+     * s->blk would erroneously be placed in writethrough mode.
      */
     if (!(features & (1 << VIRTIO_BLK_F_CONFIG_WCE))) {
-        aio_context_acquire(bdrv_get_aio_context(s->bs));
-        bdrv_set_enable_write_cache(s->bs,
-                                    !!(features & (1 << VIRTIO_BLK_F_WCE)));
-        aio_context_release(bdrv_get_aio_context(s->bs));
+        aio_context_acquire(blk_get_aio_context(s->blk));
+        blk_set_enable_write_cache(s->blk,
+                                   !!(features & (1 << VIRTIO_BLK_F_WCE)));
+        aio_context_release(blk_get_aio_context(s->blk));
     }
 }
 
@@ -714,7 +717,7 @@ static void virtio_blk_migration_state_changed(Notifier *notifier, void *data)
         if (s->dataplane) {
             return;
         }
-        bdrv_drain_all(); /* complete in-flight non-dataplane requests */
+        blk_drain_all(); /* complete in-flight non-dataplane requests */
         virtio_blk_data_plane_create(VIRTIO_DEVICE(s), &s->conf,
                                      &s->dataplane, &err);
         if (err != NULL) {
@@ -733,17 +736,17 @@ static void virtio_blk_device_realize(DeviceState *dev, Error **errp)
     Error *err = NULL;
     static int virtio_blk_id;
 
-    if (!conf->conf.bs) {
+    if (!conf->conf.blk) {
         error_setg(errp, "drive property not set");
         return;
     }
-    if (!bdrv_is_inserted(conf->conf.bs)) {
+    if (!blk_is_inserted(conf->conf.blk)) {
         error_setg(errp, "Device needs media, but drive is empty");
         return;
     }
 
     blkconf_serial(&conf->conf, &conf->serial);
-    s->original_wce = bdrv_enable_write_cache(conf->conf.bs);
+    s->original_wce = blk_enable_write_cache(conf->conf.blk);
     blkconf_geometry(&conf->conf, NULL, 65535, 255, 255, &err);
     if (err) {
         error_propagate(errp, err);
@@ -753,7 +756,7 @@ static void virtio_blk_device_realize(DeviceState *dev, Error **errp)
     virtio_init(vdev, "virtio-blk", VIRTIO_ID_BLOCK,
                 sizeof(struct virtio_blk_config));
 
-    s->bs = conf->conf.bs;
+    s->blk = conf->conf.blk;
     s->rq = NULL;
     s->sector_mask = (s->conf.conf.logical_block_size / BDRV_SECTOR_SIZE) - 1;
 
@@ -773,10 +776,10 @@ static void virtio_blk_device_realize(DeviceState *dev, Error **errp)
     s->change = qemu_add_vm_change_state_handler(virtio_blk_dma_restart_cb, s);
     register_savevm(dev, "virtio-blk", virtio_blk_id++, 2,
                     virtio_blk_save, virtio_blk_load, s);
-    bdrv_set_dev_ops(s->bs, &virtio_block_ops, s);
-    bdrv_set_guest_block_size(s->bs, s->conf.conf.logical_block_size);
+    blk_set_dev_ops(s->blk, &virtio_block_ops, s);
+    blk_set_guest_block_size(s->blk, s->conf.conf.logical_block_size);
 
-    bdrv_iostatus_enable(s->bs);
+    blk_iostatus_enable(s->blk);
 
     add_boot_device_path(s->conf.conf.bootindex, dev, "/disk@0,0");
 }
@@ -793,7 +796,7 @@ static void virtio_blk_device_unrealize(DeviceState *dev, Error **errp)
 #endif
     qemu_del_vm_change_state_handler(s->change);
     unregister_savevm(dev, "virtio-blk", s);
-    blockdev_mark_auto_del(s->bs);
+    blockdev_mark_auto_del(s->blk);
     virtio_cleanup(vdev);
 }
 
diff --git a/hw/block/xen_disk.c b/hw/block/xen_disk.c
index b571bbe..ad9a1fc 100644
--- a/hw/block/xen_disk.c
+++ b/hw/block/xen_disk.c
@@ -123,7 +123,7 @@ struct XenBlkDev {
 
     /* qemu block driver */
     DriveInfo           *dinfo;
-    BlockDriverState    *bs;
+    BlockBackend        *blk;
     QEMUBH              *bh;
 };
 
@@ -480,7 +480,7 @@ static void qemu_aio_complete(void *opaque, int ret)
     if (ioreq->postsync) {
         ioreq->postsync = 0;
         ioreq->aio_inflight++;
-        bdrv_aio_flush(ioreq->blkdev->bs, qemu_aio_complete, ioreq);
+        blk_aio_flush(ioreq->blkdev->blk, qemu_aio_complete, ioreq);
         return;
     }
 
@@ -494,7 +494,7 @@ static void qemu_aio_complete(void *opaque, int ret)
             break;
         }
     case BLKIF_OP_READ:
-        bdrv_acct_done(ioreq->blkdev->bs, &ioreq->acct);
+        blk_acct_done(ioreq->blkdev->blk, &ioreq->acct);
         break;
     case BLKIF_OP_DISCARD:
     default:
@@ -513,35 +513,37 @@ static int ioreq_runio_qemu_aio(struct ioreq *ioreq)
 
     ioreq->aio_inflight++;
     if (ioreq->presync) {
-        bdrv_aio_flush(ioreq->blkdev->bs, qemu_aio_complete, ioreq);
+        blk_aio_flush(ioreq->blkdev->blk, qemu_aio_complete, ioreq);
         return 0;
     }
 
     switch (ioreq->req.operation) {
     case BLKIF_OP_READ:
-        bdrv_acct_start(blkdev->bs, &ioreq->acct, ioreq->v.size, BDRV_ACCT_READ);
+        blk_acct_start(blkdev->blk, &ioreq->acct, ioreq->v.size,
+                       BDRV_ACCT_READ);
         ioreq->aio_inflight++;
-        bdrv_aio_readv(blkdev->bs, ioreq->start / BLOCK_SIZE,
+        blk_aio_readv(blkdev->blk, ioreq->start / BLOCK_SIZE,
+                      &ioreq->v, ioreq->v.size / BLOCK_SIZE,
+                      qemu_aio_complete, ioreq);
+        break;
+    case BLKIF_OP_WRITE:
+    case BLKIF_OP_FLUSH_DISKCACHE:
+        if (!ioreq->req.nr_segments) {
+            break;
+        }
+
+        blk_acct_start(blkdev->blk, &ioreq->acct, ioreq->v.size,
+                       BDRV_ACCT_WRITE);
+        ioreq->aio_inflight++;
+        blk_aio_writev(blkdev->blk, ioreq->start / BLOCK_SIZE,
                        &ioreq->v, ioreq->v.size / BLOCK_SIZE,
                        qemu_aio_complete, ioreq);
         break;
-    case BLKIF_OP_WRITE:
-    case BLKIF_OP_FLUSH_DISKCACHE:
-        if (!ioreq->req.nr_segments) {
-            break;
-        }
-
-        bdrv_acct_start(blkdev->bs, &ioreq->acct, ioreq->v.size, BDRV_ACCT_WRITE);
-        ioreq->aio_inflight++;
-        bdrv_aio_writev(blkdev->bs, ioreq->start / BLOCK_SIZE,
-                        &ioreq->v, ioreq->v.size / BLOCK_SIZE,
-                        qemu_aio_complete, ioreq);
-        break;
     case BLKIF_OP_DISCARD:
     {
         struct blkif_request_discard *discard_req = (void *)&ioreq->req;
         ioreq->aio_inflight++;
-        bdrv_aio_discard(blkdev->bs,
+        blk_aio_discard(blkdev->blk,
                         discard_req->sector_number, discard_req->nr_sectors,
                         qemu_aio_complete, ioreq);
         break;
@@ -855,6 +857,7 @@ static int blk_connect(struct XenDevice *xendev)
         Error *local_err = NULL;
         BlockBackend *blk;
         BlockDriver *drv;
+        BlockDriverState *bs;
 
         /* setup via xenbus -> create new block driver instance */
         xen_be_printf(&blkdev->xendev, 2, "create new bdrv (xenbus setup)\n");
@@ -862,39 +865,39 @@ static int blk_connect(struct XenDevice *xendev)
         if (!blk) {
             return -1;
         }
-        blkdev->bs = blk_bs(blk);
+        blkdev->blk = blk;
 
+        bs = blk_bs(blk);
         drv = bdrv_find_whitelisted_format(blkdev->fileproto, readonly);
-        if (bdrv_open(&blkdev->bs, blkdev->filename, NULL, NULL, qflags,
+        if (bdrv_open(&bs, blkdev->filename, NULL, NULL, qflags,
                       drv, &local_err) != 0) {
             xen_be_printf(&blkdev->xendev, 0, "error: %s\n",
                           error_get_pretty(local_err));
             error_free(local_err);
             blk_unref(blk);
-            blkdev->bs = NULL;
+            blkdev->blk = NULL;
             return -1;
         }
+        assert(bs == blk_bs(blk));
     } else {
         /* setup via qemu cmdline -> already setup for us */
         xen_be_printf(&blkdev->xendev, 2, "get configured bdrv (cmdline setup)\n");
-        blkdev->bs = blk_bs(blk_by_legacy_dinfo(blkdev->dinfo));
-        if (bdrv_is_read_only(blkdev->bs) && !readonly) {
+        blkdev->blk = blk_by_legacy_dinfo(blkdev->dinfo);
+        if (blk_is_read_only(blkdev->blk) && !readonly) {
             xen_be_printf(&blkdev->xendev, 0, "Unexpected read-only drive");
-            blkdev->bs = NULL;
+            blkdev->blk = NULL;
             return -1;
         }
-        /* blkdev->bs is not create by us, we get a reference
-         * so we can bdrv_unref() unconditionally */
-        /* Except we don't bdrv_unref() anymore, we blk_unref().
-         * Conditionally, because we can't easily blk_ref() here.
-         * TODO Clean this up! */
+        /* blkdev->blk is not create by us, we get a reference
+         * so we can blk_unref() unconditionally */
+        blk_ref(blkdev->blk);
     }
-    bdrv_attach_dev_nofail(blkdev->bs, blkdev);
-    blkdev->file_size = bdrv_getlength(blkdev->bs);
+    blk_attach_dev_nofail(blkdev->blk, blkdev);
+    blkdev->file_size = blk_getlength(blkdev->blk);
     if (blkdev->file_size < 0) {
-        xen_be_printf(&blkdev->xendev, 1, "bdrv_getlength: %d (%s) | drv %s\n",
+        xen_be_printf(&blkdev->xendev, 1, "blk_getlength: %d (%s) | drv %s\n",
                       (int)blkdev->file_size, strerror(-blkdev->file_size),
-                      bdrv_get_format_name(blkdev->bs) ?: "-");
+                      bdrv_get_format_name(blk_bs(blkdev->blk)) ?: "-");
         blkdev->file_size = 0;
     }
 
@@ -985,12 +988,10 @@ static void blk_disconnect(struct XenDevice *xendev)
 {
     struct XenBlkDev *blkdev = container_of(xendev, struct XenBlkDev, xendev);
 
-    if (blkdev->bs) {
-        bdrv_detach_dev(blkdev->bs, blkdev);
-        if (!blkdev->dinfo) {
-            blk_unref(blk_by_name(blkdev->dev));
-        }
-        blkdev->bs = NULL;
+    if (blkdev->blk) {
+        blk_detach_dev(blkdev->blk, blkdev);
+        blk_unref(blkdev->blk);
+        blkdev->blk = NULL;
     }
     xen_be_unbind_evtchn(&blkdev->xendev);
 
@@ -1006,7 +1007,7 @@ static int blk_free(struct XenDevice *xendev)
     struct XenBlkDev *blkdev = container_of(xendev, struct XenBlkDev, xendev);
     struct ioreq *ioreq;
 
-    if (blkdev->bs || blkdev->sring) {
+    if (blkdev->blk || blkdev->sring) {
         blk_disconnect(xendev);
     }
 
diff --git a/hw/core/qdev-properties-system.c b/hw/core/qdev-properties-system.c
index ae0900f..f77b22a 100644
--- a/hw/core/qdev-properties-system.c
+++ b/hw/core/qdev-properties-system.c
@@ -13,6 +13,7 @@
 #include "net/net.h"
 #include "hw/qdev.h"
 #include "qapi/qmp/qerror.h"
+#include "sysemu/block-backend.h"
 #include "sysemu/blockdev.h"
 #include "hw/block/block.h"
 #include "net/hub.h"
@@ -68,16 +69,16 @@ static void set_pointer(Object *obj, Visitor *v, Property *prop,
 
 static int parse_drive(DeviceState *dev, const char *str, void **ptr)
 {
-    BlockDriverState *bs;
+    BlockBackend *blk;
 
-    bs = bdrv_find(str);
-    if (bs == NULL) {
+    blk = blk_by_name(str);
+    if (!blk) {
         return -ENOENT;
     }
-    if (bdrv_attach_dev(bs, dev) < 0) {
+    if (blk_attach_dev(blk, dev) < 0) {
         return -EEXIST;
     }
-    *ptr = bs;
+    *ptr = blk;
     return 0;
 }
 
@@ -85,17 +86,17 @@ static void release_drive(Object *obj, const char *name, void *opaque)
 {
     DeviceState *dev = DEVICE(obj);
     Property *prop = opaque;
-    BlockDriverState **ptr = qdev_get_prop_ptr(dev, prop);
+    BlockBackend **ptr = qdev_get_prop_ptr(dev, prop);
 
     if (*ptr) {
-        bdrv_detach_dev(*ptr, dev);
+        blk_detach_dev(*ptr, dev);
         blockdev_auto_del(*ptr);
     }
 }
 
 static char *print_drive(void *ptr)
 {
-    return g_strdup(bdrv_get_device_name(ptr));
+    return g_strdup(blk_name(ptr));
 }
 
 static void get_drive(Object *obj, Visitor *v, void *opaque,
@@ -335,12 +336,11 @@ PropertyInfo qdev_prop_vlan = {
 };
 
 int qdev_prop_set_drive(DeviceState *dev, const char *name,
-                        BlockDriverState *value)
+                        BlockBackend *value)
 {
     Error *err = NULL;
-    const char *bdrv_name = value ? bdrv_get_device_name(value) : "";
-    object_property_set_str(OBJECT(dev), bdrv_name,
-                            name, &err);
+    object_property_set_str(OBJECT(dev),
+                            value ? blk_name(value) : "", name, &err);
     if (err) {
         qerror_report_err(err);
         error_free(err);
@@ -350,7 +350,7 @@ int qdev_prop_set_drive(DeviceState *dev, const char *name,
 }
 
 void qdev_prop_set_drive_nofail(DeviceState *dev, const char *name,
-                                BlockDriverState *value)
+                                BlockBackend *value)
 {
     if (qdev_prop_set_drive(dev, name, value) < 0) {
         exit(1);
diff --git a/hw/core/qdev-properties.c b/hw/core/qdev-properties.c
index 3d12560..931a48c 100644
--- a/hw/core/qdev-properties.c
+++ b/hw/core/qdev-properties.c
@@ -1,7 +1,7 @@
 #include "net/net.h"
 #include "hw/qdev.h"
 #include "qapi/qmp/qerror.h"
-#include "sysemu/blockdev.h"
+#include "sysemu/block-backend.h"
 #include "hw/block/block.h"
 #include "net/hub.h"
 #include "qapi/visitor.h"
diff --git a/hw/cris/axis_dev88.c b/hw/cris/axis_dev88.c
index 280722d..f43de34 100644
--- a/hw/cris/axis_dev88.c
+++ b/hw/cris/axis_dev88.c
@@ -31,7 +31,6 @@
 #include "elf.h"
 #include "boot.h"
 #include "sysemu/block-backend.h"
-#include "sysemu/blockdev.h"
 #include "exec/address-spaces.h"
 #include "sysemu/qtest.h"
 
@@ -283,7 +282,7 @@ void axisdev88_init(MachineState *machine)
 
       /* Attach a NAND flash to CS1.  */
     nand = drive_get(IF_MTD, 0, 0);
-    nand_state.nand = nand_init(nand ? blk_bs(blk_by_legacy_dinfo(nand)) : NULL,
+    nand_state.nand = nand_init(nand ? blk_by_legacy_dinfo(nand) : NULL,
                                 NAND_MFR_STMICRO, 0x39);
     memory_region_init_io(&nand_state.iomem, NULL, &nand_ops, &nand_state,
                           "nand", 0x05000000);
diff --git a/hw/display/tc6393xb.c b/hw/display/tc6393xb.c
index 62d6663..b89415a 100644
--- a/hw/display/tc6393xb.c
+++ b/hw/display/tc6393xb.c
@@ -577,7 +577,7 @@ TC6393xbState *tc6393xb_init(MemoryRegion *sysmem, uint32_t base, qemu_irq irq)
     s->sub_irqs = qemu_allocate_irqs(tc6393xb_sub_irq, s, TC6393XB_NR_IRQS);
 
     nand = drive_get(IF_MTD, 0, 0);
-    s->flash = nand_init(nand ? blk_bs(blk_by_legacy_dinfo(nand)) : NULL,
+    s->flash = nand_init(nand ? blk_by_legacy_dinfo(nand) : NULL,
                          NAND_MFR_TOSHIBA, 0x76);
 
     memory_region_init_io(&s->iomem, NULL, &tc6393xb_ops, s, "tc6393xb", 0x10000);
diff --git a/hw/i386/pc.c b/hw/i386/pc.c
index b6c9b61..aadf4bc 100644
--- a/hw/i386/pc.c
+++ b/hw/i386/pc.c
@@ -44,7 +44,7 @@
 #include "sysemu/kvm.h"
 #include "kvm_i386.h"
 #include "hw/xen/xen.h"
-#include "sysemu/blockdev.h"
+#include "sysemu/block-backend.h"
 #include "hw/block/block.h"
 #include "ui/qemu-spice.h"
 #include "exec/memory.h"
diff --git a/hw/i386/pc_piix.c b/hw/i386/pc_piix.c
index 103d756..000b34a 100644
--- a/hw/i386/pc_piix.c
+++ b/hw/i386/pc_piix.c
@@ -41,7 +41,7 @@
 #include "hw/sysbus.h"
 #include "hw/cpu/icc_bus.h"
 #include "sysemu/arch_init.h"
-#include "sysemu/blockdev.h"
+#include "sysemu/block-backend.h"
 #include "hw/i2c/smbus.h"
 #include "hw/xen/xen.h"
 #include "exec/memory.h"
diff --git a/hw/i386/pc_sysfw.c b/hw/i386/pc_sysfw.c
index 6cd264a..efe256c 100644
--- a/hw/i386/pc_sysfw.c
+++ b/hw/i386/pc_sysfw.c
@@ -24,7 +24,6 @@
  */
 
 #include "sysemu/block-backend.h"
-#include "sysemu/blockdev.h"
 #include "qemu/error-report.h"
 #include "hw/sysbus.h"
 #include "hw/hw.h"
@@ -103,7 +102,7 @@ static void pc_system_flash_init(MemoryRegion *rom_memory)
 {
     int unit;
     DriveInfo *pflash_drv;
-    BlockDriverState *bdrv;
+    BlockBackend *blk;
     int64_t size;
     char *fatal_errmsg = NULL;
     hwaddr phys_addr = 0x100000000ULL;
@@ -119,8 +118,8 @@ static void pc_system_flash_init(MemoryRegion *rom_memory)
          (unit < FLASH_MAP_UNIT_MAX &&
           (pflash_drv = drive_get(IF_PFLASH, 0, unit)) != NULL);
          ++unit) {
-        bdrv = blk_bs(blk_by_legacy_dinfo(pflash_drv));
-        size = bdrv_getlength(bdrv);
+        blk = blk_by_legacy_dinfo(pflash_drv);
+        size = blk_getlength(blk);
         if (size < 0) {
             fatal_errmsg = g_strdup_printf("failed to get backing file size");
         } else if (size == 0) {
@@ -156,7 +155,7 @@ static void pc_system_flash_init(MemoryRegion *rom_memory)
         /* pflash_cfi01_register() creates a deep copy of the name */
         snprintf(name, sizeof name, "system.flash%d", unit);
         system_flash = pflash_cfi01_register(phys_addr, NULL /* qdev */, name,
-                                             size, bdrv, sector_size,
+                                             size, blk, sector_size,
                                              size >> sector_bits,
                                              1      /* width */,
                                              0x0000 /* id0 */,
diff --git a/hw/i386/xen/xen_platform.c b/hw/i386/xen/xen_platform.c
index 8bb18b4..28b324a 100644
--- a/hw/i386/xen/xen_platform.c
+++ b/hw/i386/xen/xen_platform.c
@@ -34,6 +34,7 @@
 #include "hw/xen/xen_backend.h"
 #include "trace.h"
 #include "exec/address-spaces.h"
+#include "sysemu/block-backend.h"
 
 #include <xenguest.h>
 
@@ -132,8 +133,8 @@ static void platform_fixed_ioport_writew(void *opaque, uint32_t addr, uint32_t v
            devices, and bit 2 the non-primary-master IDE devices. */
         if (val & UNPLUG_ALL_IDE_DISKS) {
             DPRINTF("unplug disks\n");
-            bdrv_drain_all();
-            bdrv_flush_all();
+            blk_drain_all();
+            blk_flush_all();
             pci_unplug_disks(pci_dev->bus);
         }
         if (val & UNPLUG_ALL_NICS) {
diff --git a/hw/ide/ahci.c b/hw/ide/ahci.c
index 97c997c..2ca8dfe 100644
--- a/hw/ide/ahci.c
+++ b/hw/ide/ahci.c
@@ -28,6 +28,7 @@
 #include <hw/sysbus.h>
 
 #include "monitor/monitor.h"
+#include "sysemu/block-backend.h"
 #include "sysemu/dma.h"
 #include "internal.h"
 #include <hw/ide/pci.h>
@@ -85,7 +86,7 @@ static uint32_t  ahci_port_read(AHCIState *s, int port, int offset)
         val = pr->sig;
         break;
     case PORT_SCR_STAT:
-        if (s->dev[port].port.ifs[0].bs) {
+        if (s->dev[port].port.ifs[0].blk) {
             val = SATA_SCR_SSTATUS_DET_DEV_PRESENT_PHY_UP |
                   SATA_SCR_SSTATUS_SPD_GEN1 | SATA_SCR_SSTATUS_IPM_ACTIVE;
         } else {
@@ -501,7 +502,7 @@ static void ahci_reset_port(AHCIState *s, int port)
     d->init_d2h_sent = false;
 
     ide_state = &s->dev[port].port.ifs[0];
-    if (!ide_state->bs) {
+    if (!ide_state->blk) {
         return;
     }
 
@@ -513,11 +514,11 @@ static void ahci_reset_port(AHCIState *s, int port)
         }
 
         if (ncq_tfs->aiocb) {
-            bdrv_aio_cancel(ncq_tfs->aiocb);
+            blk_aio_cancel(ncq_tfs->aiocb);
             ncq_tfs->aiocb = NULL;
         }
 
-        /* Maybe we just finished the request thanks to bdrv_aio_cancel() */
+        /* Maybe we just finished the request thanks to blk_aio_cancel() */
         if (!ncq_tfs->used) {
             continue;
         }
@@ -527,7 +528,7 @@ static void ahci_reset_port(AHCIState *s, int port)
     }
 
     s->dev[port].port_state = STATE_RUN;
-    if (!ide_state->bs) {
+    if (!ide_state->blk) {
         s->dev[port].port_regs.sig = 0;
         ide_state->status = SEEK_STAT | WRERR_STAT;
     } else if (ide_state->drive_kind == IDE_CD) {
@@ -809,7 +810,7 @@ static void ncq_cb(void *opaque, int ret)
     DPRINTF(ncq_tfs->drive->port_no, "NCQ transfer tag %d finished\n",
             ncq_tfs->tag);
 
-    bdrv_acct_done(ncq_tfs->drive->port.ifs[0].bs, &ncq_tfs->acct);
+    blk_acct_done(ncq_tfs->drive->port.ifs[0].blk, &ncq_tfs->acct);
     qemu_sglist_destroy(&ncq_tfs->sglist);
     ncq_tfs->used = 0;
 }
@@ -859,11 +860,11 @@ static void process_ncq_command(AHCIState *s, int port, uint8_t *cmd_fis,
             DPRINTF(port, "tag %d aio read %"PRId64"\n",
                     ncq_tfs->tag, ncq_tfs->lba);
 
-            dma_acct_start(ncq_tfs->drive->port.ifs[0].bs, &ncq_tfs->acct,
+            dma_acct_start(ncq_tfs->drive->port.ifs[0].blk, &ncq_tfs->acct,
                            &ncq_tfs->sglist, BDRV_ACCT_READ);
-            ncq_tfs->aiocb = dma_bdrv_read(ncq_tfs->drive->port.ifs[0].bs,
-                                           &ncq_tfs->sglist, ncq_tfs->lba,
-                                           ncq_cb, ncq_tfs);
+            ncq_tfs->aiocb = dma_blk_read(ncq_tfs->drive->port.ifs[0].blk,
+                                          &ncq_tfs->sglist, ncq_tfs->lba,
+                                          ncq_cb, ncq_tfs);
             break;
         case WRITE_FPDMA_QUEUED:
             DPRINTF(port, "NCQ writing %d sectors to LBA %"PRId64", tag %d\n",
@@ -872,11 +873,11 @@ static void process_ncq_command(AHCIState *s, int port, uint8_t *cmd_fis,
             DPRINTF(port, "tag %d aio write %"PRId64"\n",
                     ncq_tfs->tag, ncq_tfs->lba);
 
-            dma_acct_start(ncq_tfs->drive->port.ifs[0].bs, &ncq_tfs->acct,
+            dma_acct_start(ncq_tfs->drive->port.ifs[0].blk, &ncq_tfs->acct,
                            &ncq_tfs->sglist, BDRV_ACCT_WRITE);
-            ncq_tfs->aiocb = dma_bdrv_write(ncq_tfs->drive->port.ifs[0].bs,
-                                            &ncq_tfs->sglist, ncq_tfs->lba,
-                                            ncq_cb, ncq_tfs);
+            ncq_tfs->aiocb = dma_blk_write(ncq_tfs->drive->port.ifs[0].blk,
+                                           &ncq_tfs->sglist, ncq_tfs->lba,
+                                           ncq_cb, ncq_tfs);
             break;
         default:
             DPRINTF(port, "error: tried to process non-NCQ command as NCQ\n");
@@ -925,7 +926,7 @@ static int handle_cmd(AHCIState *s, int port, int slot)
     /* The device we are working for */
     ide_state = &s->dev[port].port.ifs[0];
 
-    if (!ide_state->bs) {
+    if (!ide_state->blk) {
         DPRINTF(port, "error: guest accessed unused port");
         goto out;
     }
diff --git a/hw/ide/atapi.c b/hw/ide/atapi.c
index 3d92b52..7364b9f 100644
--- a/hw/ide/atapi.c
+++ b/hw/ide/atapi.c
@@ -25,6 +25,7 @@
 
 #include "hw/ide/internal.h"
 #include "hw/scsi/scsi.h"
+#include "sysemu/block-backend.h"
 
 static void ide_atapi_cmd_read_dma_cb(void *opaque, int ret);
 
@@ -110,14 +111,14 @@ static int cd_read_sector(IDEState *s, int lba, uint8_t *buf, int sector_size)
 
     switch(sector_size) {
     case 2048:
-        bdrv_acct_start(s->bs, &s->acct, 4 * BDRV_SECTOR_SIZE, BDRV_ACCT_READ);
-        ret = bdrv_read(s->bs, (int64_t)lba << 2, buf, 4);
-        bdrv_acct_done(s->bs, &s->acct);
+        blk_acct_start(s->blk, &s->acct, 4 * BDRV_SECTOR_SIZE, BDRV_ACCT_READ);
+        ret = blk_read(s->blk, (int64_t)lba << 2, buf, 4);
+        blk_acct_done(s->blk, &s->acct);
         break;
     case 2352:
-        bdrv_acct_start(s->bs, &s->acct, 4 * BDRV_SECTOR_SIZE, BDRV_ACCT_READ);
-        ret = bdrv_read(s->bs, (int64_t)lba << 2, buf + 16, 4);
-        bdrv_acct_done(s->bs, &s->acct);
+        blk_acct_start(s->blk, &s->acct, 4 * BDRV_SECTOR_SIZE, BDRV_ACCT_READ);
+        ret = blk_read(s->blk, (int64_t)lba << 2, buf + 16, 4);
+        blk_acct_done(s->blk, &s->acct);
         if (ret < 0)
             return ret;
         cd_data_to_raw(buf, lba);
@@ -253,7 +254,7 @@ static void ide_atapi_cmd_reply(IDEState *s, int size, int max_size)
     s->io_buffer_index = 0;
 
     if (s->atapi_dma) {
-        bdrv_acct_start(s->bs, &s->acct, size, BDRV_ACCT_READ);
+        blk_acct_start(s->blk, &s->acct, size, BDRV_ACCT_READ);
         s->status = READY_STAT | SEEK_STAT | DRQ_STAT;
         ide_start_dma(s, ide_atapi_cmd_read_dma_cb);
     } else {
@@ -348,13 +349,13 @@ static void ide_atapi_cmd_read_dma_cb(void *opaque, int ret)
     s->bus->dma->iov.iov_len = n * 4 * 512;
     qemu_iovec_init_external(&s->bus->dma->qiov, &s->bus->dma->iov, 1);
 
-    s->bus->dma->aiocb = bdrv_aio_readv(s->bs, (int64_t)s->lba << 2,
+    s->bus->dma->aiocb = blk_aio_readv(s->blk, (int64_t)s->lba << 2,
                                        &s->bus->dma->qiov, n * 4,
                                        ide_atapi_cmd_read_dma_cb, s);
     return;
 
 eot:
-    bdrv_acct_done(s->bs, &s->acct);
+    blk_acct_done(s->blk, &s->acct);
     ide_set_inactive(s, false);
 }
 
@@ -369,7 +370,7 @@ static void ide_atapi_cmd_read_dma(IDEState *s, int lba, int nb_sectors,
     s->io_buffer_size = 0;
     s->cd_sector_size = sector_size;
 
-    bdrv_acct_start(s->bs, &s->acct, s->packet_transfer_size, BDRV_ACCT_READ);
+    blk_acct_start(s->blk, &s->acct, s->packet_transfer_size, BDRV_ACCT_READ);
 
     /* XXX: check if BUSY_STAT should be set */
     s->status = READY_STAT | SEEK_STAT | DRQ_STAT | BUSY_STAT;
@@ -501,7 +502,7 @@ static unsigned int event_status_media(IDEState *s,
     media_status = 0;
     if (s->tray_open) {
         media_status = MS_TRAY_OPEN;
-    } else if (bdrv_is_inserted(s->bs)) {
+    } else if (blk_is_inserted(s->blk)) {
         media_status = MS_MEDIA_PRESENT;
     }
 
@@ -797,7 +798,7 @@ static void cmd_test_unit_ready(IDEState *s, uint8_t *buf)
 static void cmd_prevent_allow_medium_removal(IDEState *s, uint8_t* buf)
 {
     s->tray_locked = buf[4] & 1;
-    bdrv_lock_medium(s->bs, buf[4] & 1);
+    blk_lock_medium(s->blk, buf[4] & 1);
     ide_atapi_cmd_ok(s);
 }
 
@@ -881,14 +882,14 @@ static void cmd_start_stop_unit(IDEState *s, uint8_t* buf)
 
     if (loej) {
         if (!start && !s->tray_open && s->tray_locked) {
-            sense = bdrv_is_inserted(s->bs)
+            sense = blk_is_inserted(s->blk)
                 ? NOT_READY : ILLEGAL_REQUEST;
             ide_atapi_cmd_error(s, sense, ASC_MEDIA_REMOVAL_PREVENTED);
             return;
         }
 
         if (s->tray_open != !start) {
-            bdrv_eject(s->bs, !start);
+            blk_eject(s->blk, !start);
             s->tray_open = !start;
         }
     }
@@ -1122,7 +1123,7 @@ void ide_atapi_cmd(IDEState *s)
      * states rely on this behavior.
      */
     if (!(atapi_cmd_table[s->io_buffer[0]].flags & ALLOW_UA) &&
-        !s->tray_open && bdrv_is_inserted(s->bs) && s->cdrom_changed) {
+        !s->tray_open && blk_is_inserted(s->blk) && s->cdrom_changed) {
 
         if (s->cdrom_changed == 1) {
             ide_atapi_cmd_error(s, NOT_READY, ASC_MEDIUM_NOT_PRESENT);
@@ -1137,7 +1138,7 @@ void ide_atapi_cmd(IDEState *s)
 
     /* Report a Not Ready condition if appropriate for the command */
     if ((atapi_cmd_table[s->io_buffer[0]].flags & CHECK_READY) &&
-        (!media_present(s) || !bdrv_is_inserted(s->bs)))
+        (!media_present(s) || !blk_is_inserted(s->blk)))
     {
         ide_atapi_cmd_error(s, NOT_READY, ASC_MEDIUM_NOT_PRESENT);
         return;
diff --git a/hw/ide/cmd646.c b/hw/ide/cmd646.c
index 91048f2..c8b0322 100644
--- a/hw/ide/cmd646.c
+++ b/hw/ide/cmd646.c
@@ -26,7 +26,7 @@
 #include <hw/i386/pc.h>
 #include <hw/pci/pci.h>
 #include <hw/isa/isa.h>
-#include "block/block.h"
+#include "sysemu/block-backend.h"
 #include "sysemu/sysemu.h"
 #include "sysemu/dma.h"
 
diff --git a/hw/ide/core.c b/hw/ide/core.c
index 36df217..fe12145 100644
--- a/hw/ide/core.c
+++ b/hw/ide/core.c
@@ -31,7 +31,7 @@
 #include "sysemu/sysemu.h"
 #include "sysemu/dma.h"
 #include "hw/block/block.h"
-#include "sysemu/blockdev.h"
+#include "sysemu/block-backend.h"
 
 #include <hw/ide/internal.h>
 
@@ -158,10 +158,11 @@ static void ide_identify(IDEState *s)
         put_le16(p + 84, (1 << 14) | 0);
     }
     /* 14 = NOP supported, 5=WCACHE enabled, 0=SMART feature set enabled */
-    if (bdrv_enable_write_cache(s->bs))
-         put_le16(p + 85, (1 << 14) | (1 << 5) | 1);
-    else
-         put_le16(p + 85, (1 << 14) | 1);
+    if (blk_enable_write_cache(s->blk)) {
+        put_le16(p + 85, (1 << 14) | (1 << 5) | 1);
+    } else {
+        put_le16(p + 85, (1 << 14) | 1);
+    }
     /* 13=flush_cache_ext,12=flush_cache,10=lba48 */
     put_le16(p + 86, (1 << 13) | (1 <<12) | (1 << 10));
     /* 14=set to 1, 8=has WWN, 1=SMART self test, 0=SMART error logging */
@@ -350,7 +351,7 @@ static void ide_set_signature(IDEState *s)
     if (s->drive_kind == IDE_CD) {
         s->lcyl = 0x14;
         s->hcyl = 0xeb;
-    } else if (s->bs) {
+    } else if (s->blk) {
         s->lcyl = 0;
         s->hcyl = 0;
     } else {
@@ -372,7 +373,7 @@ static void trim_aio_cancel(BlockAIOCB *acb)
 {
     TrimAIOCB *iocb = container_of(acb, TrimAIOCB, common);
 
-    /* Exit the loop in case bdrv_aio_cancel calls ide_issue_trim_cb again.  */
+    /* Exit the loop in case blk_aio_cancel calls ide_issue_trim_cb again.  */
     iocb->j = iocb->qiov->niov - 1;
     iocb->i = (iocb->qiov->iov[iocb->j].iov_len / 8) - 1;
 
@@ -381,7 +382,7 @@ static void trim_aio_cancel(BlockAIOCB *acb)
     iocb->bh = NULL;
 
     if (iocb->aiocb) {
-        bdrv_aio_cancel(iocb->aiocb);
+        blk_aio_cancel(iocb->aiocb);
     }
     qemu_aio_release(iocb);
 }
@@ -440,13 +441,13 @@ static void ide_issue_trim_cb(void *opaque, int ret)
     }
 }
 
-BlockAIOCB *ide_issue_trim(BlockDriverState *bs,
+BlockAIOCB *ide_issue_trim(BlockBackend *blk,
         int64_t sector_num, QEMUIOVector *qiov, int nb_sectors,
         BlockCompletionFunc *cb, void *opaque)
 {
     TrimAIOCB *iocb;
 
-    iocb = qemu_aio_get(&trim_aiocb_info, bs, cb, opaque);
+    iocb = blk_aio_get(&trim_aiocb_info, blk, cb, opaque);
     iocb->bh = qemu_bh_new(ide_trim_bh_cb, iocb);
     iocb->ret = 0;
     iocb->qiov = qiov;
@@ -553,7 +554,7 @@ static bool ide_sect_range_ok(IDEState *s,
 {
     uint64_t total_sectors;
 
-    bdrv_get_geometry(s->bs, &total_sectors);
+    blk_get_geometry(s->blk, &total_sectors);
     if (sector > total_sectors || nb_sectors > total_sectors - sector) {
         return false;
     }
@@ -568,7 +569,7 @@ static void ide_sector_read_cb(void *opaque, int ret)
     s->pio_aiocb = NULL;
     s->status &= ~BUSY_STAT;
 
-    bdrv_acct_done(s->bs, &s->acct);
+    blk_acct_done(s->blk, &s->acct);
     if (ret != 0) {
         if (ide_handle_rw_error(s, -ret, IDE_RETRY_PIO |
                                 IDE_RETRY_READ)) {
@@ -624,9 +625,9 @@ void ide_sector_read(IDEState *s)
     s->iov.iov_len  = n * BDRV_SECTOR_SIZE;
     qemu_iovec_init_external(&s->qiov, &s->iov, 1);
 
-    bdrv_acct_start(s->bs, &s->acct, n * BDRV_SECTOR_SIZE, BDRV_ACCT_READ);
-    s->pio_aiocb = bdrv_aio_readv(s->bs, sector_num, &s->qiov, n,
-                                  ide_sector_read_cb, s);
+    blk_acct_start(s->blk, &s->acct, n * BDRV_SECTOR_SIZE, BDRV_ACCT_READ);
+    s->pio_aiocb = blk_aio_readv(s->blk, sector_num, &s->qiov, n,
+                                 ide_sector_read_cb, s);
 }
 
 static void dma_buf_commit(IDEState *s)
@@ -653,7 +654,7 @@ void ide_dma_error(IDEState *s)
 static int ide_handle_rw_error(IDEState *s, int error, int op)
 {
     bool is_read = (op & IDE_RETRY_READ) != 0;
-    BlockErrorAction action = bdrv_get_error_action(s->bs, is_read, error);
+    BlockErrorAction action = blk_get_error_action(s->blk, is_read, error);
 
     if (action == BLOCK_ERROR_ACTION_STOP) {
         s->bus->dma->ops->set_unit(s->bus->dma, s->unit);
@@ -666,7 +667,7 @@ static int ide_handle_rw_error(IDEState *s, int error, int op)
             ide_rw_error(s);
         }
     }
-    bdrv_error_action(s->bs, action, is_read, error);
+    blk_error_action(s->blk, action, is_read, error);
     return action != BLOCK_ERROR_ACTION_IGNORE;
 }
 
@@ -739,24 +740,24 @@ void ide_dma_cb(void *opaque, int ret)
 
     switch (s->dma_cmd) {
     case IDE_DMA_READ:
-        s->bus->dma->aiocb = dma_bdrv_read(s->bs, &s->sg, sector_num,
+        s->bus->dma->aiocb = dma_blk_read(s->blk, &s->sg, sector_num,
+                                          ide_dma_cb, s);
+        break;
+    case IDE_DMA_WRITE:
+        s->bus->dma->aiocb = dma_blk_write(s->blk, &s->sg, sector_num,
                                            ide_dma_cb, s);
         break;
-    case IDE_DMA_WRITE:
-        s->bus->dma->aiocb = dma_bdrv_write(s->bs, &s->sg, sector_num,
-                                            ide_dma_cb, s);
-        break;
     case IDE_DMA_TRIM:
-        s->bus->dma->aiocb = dma_bdrv_io(s->bs, &s->sg, sector_num,
-                                         ide_issue_trim, ide_dma_cb, s,
-                                         DMA_DIRECTION_TO_DEVICE);
+        s->bus->dma->aiocb = dma_blk_io(s->blk, &s->sg, sector_num,
+                                        ide_issue_trim, ide_dma_cb, s,
+                                        DMA_DIRECTION_TO_DEVICE);
         break;
     }
     return;
 
 eot:
     if (s->dma_cmd == IDE_DMA_READ || s->dma_cmd == IDE_DMA_WRITE) {
-        bdrv_acct_done(s->bs, &s->acct);
+        blk_acct_done(s->blk, &s->acct);
     }
     ide_set_inactive(s, stay_active);
 }
@@ -770,12 +771,12 @@ static void ide_sector_start_dma(IDEState *s, enum ide_dma_cmd dma_cmd)
 
     switch (dma_cmd) {
     case IDE_DMA_READ:
-        bdrv_acct_start(s->bs, &s->acct, s->nsector * BDRV_SECTOR_SIZE,
-                        BDRV_ACCT_READ);
+        blk_acct_start(s->blk, &s->acct, s->nsector * BDRV_SECTOR_SIZE,
+                       BDRV_ACCT_READ);
         break;
     case IDE_DMA_WRITE:
-        bdrv_acct_start(s->bs, &s->acct, s->nsector * BDRV_SECTOR_SIZE,
-                        BDRV_ACCT_WRITE);
+        blk_acct_start(s->blk, &s->acct, s->nsector * BDRV_SECTOR_SIZE,
+                       BDRV_ACCT_WRITE);
         break;
     default:
         break;
@@ -802,7 +803,7 @@ static void ide_sector_write_cb(void *opaque, int ret)
     IDEState *s = opaque;
     int n;
 
-    bdrv_acct_done(s->bs, &s->acct);
+    blk_acct_done(s->blk, &s->acct);
 
     s->pio_aiocb = NULL;
     s->status &= ~BUSY_STAT;
@@ -869,9 +870,9 @@ void ide_sector_write(IDEState *s)
     s->iov.iov_len  = n * BDRV_SECTOR_SIZE;
     qemu_iovec_init_external(&s->qiov, &s->iov, 1);
 
-    bdrv_acct_start(s->bs, &s->acct, n * BDRV_SECTOR_SIZE, BDRV_ACCT_READ);
-    s->pio_aiocb = bdrv_aio_writev(s->bs, sector_num, &s->qiov, n,
-                                   ide_sector_write_cb, s);
+    blk_acct_start(s->blk, &s->acct, n * BDRV_SECTOR_SIZE, BDRV_ACCT_READ);
+    s->pio_aiocb = blk_aio_writev(s->blk, sector_num, &s->qiov, n,
+                                  ide_sector_write_cb, s);
 }
 
 static void ide_flush_cb(void *opaque, int ret)
@@ -887,8 +888,8 @@ static void ide_flush_cb(void *opaque, int ret)
         }
     }
 
-    if (s->bs) {
-        bdrv_acct_done(s->bs, &s->acct);
+    if (s->blk) {
+        blk_acct_done(s->blk, &s->acct);
     }
     s->status = READY_STAT | SEEK_STAT;
     ide_cmd_done(s);
@@ -897,14 +898,14 @@ static void ide_flush_cb(void *opaque, int ret)
 
 void ide_flush_cache(IDEState *s)
 {
-    if (s->bs == NULL) {
+    if (s->blk == NULL) {
         ide_flush_cb(s, 0);
         return;
     }
 
     s->status |= BUSY_STAT;
-    bdrv_acct_start(s->bs, &s->acct, 0, BDRV_ACCT_FLUSH);
-    s->pio_aiocb = bdrv_aio_flush(s->bs, ide_flush_cb, s);
+    blk_acct_start(s->blk, &s->acct, 0, BDRV_ACCT_FLUSH);
+    s->pio_aiocb = blk_aio_flush(s->blk, ide_flush_cb, s);
 }
 
 static void ide_cfata_metadata_inquiry(IDEState *s)
@@ -967,7 +968,7 @@ static void ide_cd_change_cb(void *opaque, bool load)
     uint64_t nb_sectors;
 
     s->tray_open = !load;
-    bdrv_get_geometry(s->bs, &nb_sectors);
+    blk_get_geometry(s->blk, &nb_sectors);
     s->nb_sectors = nb_sectors;
 
     /*
@@ -1101,7 +1102,7 @@ static bool cmd_data_set_management(IDEState *s, uint8_t cmd)
 {
     switch (s->feature) {
     case DSM_TRIM:
-        if (s->bs) {
+        if (s->blk) {
             ide_sector_start_dma(s, IDE_DMA_TRIM);
             return false;
         }
@@ -1114,7 +1115,7 @@ static bool cmd_data_set_management(IDEState *s, uint8_t cmd)
 
 static bool cmd_identify(IDEState *s, uint8_t cmd)
 {
-    if (s->bs && s->drive_kind != IDE_CD) {
+    if (s->blk && s->drive_kind != IDE_CD) {
         if (s->drive_kind != IDE_CFATA) {
             ide_identify(s);
         } else {
@@ -1164,7 +1165,7 @@ static bool cmd_read_multiple(IDEState *s, uint8_t cmd)
 {
     bool lba48 = (cmd == WIN_MULTREAD_EXT);
 
-    if (!s->bs || !s->mult_sectors) {
+    if (!s->blk || !s->mult_sectors) {
         ide_abort_command(s);
         return true;
     }
@@ -1180,7 +1181,7 @@ static bool cmd_write_multiple(IDEState *s, uint8_t cmd)
     bool lba48 = (cmd == WIN_MULTWRITE_EXT);
     int n;
 
-    if (!s->bs || !s->mult_sectors) {
+    if (!s->blk || !s->mult_sectors) {
         ide_abort_command(s);
         return true;
     }
@@ -1208,7 +1209,7 @@ static bool cmd_read_pio(IDEState *s, uint8_t cmd)
         return true;
     }
 
-    if (!s->bs) {
+    if (!s->blk) {
         ide_abort_command(s);
         return true;
     }
@@ -1224,7 +1225,7 @@ static bool cmd_write_pio(IDEState *s, uint8_t cmd)
 {
     bool lba48 = (cmd == WIN_WRITE_EXT);
 
-    if (!s->bs) {
+    if (!s->blk) {
         ide_abort_command(s);
         return true;
     }
@@ -1244,7 +1245,7 @@ static bool cmd_read_dma(IDEState *s, uint8_t cmd)
 {
     bool lba48 = (cmd == WIN_READDMA_EXT);
 
-    if (!s->bs) {
+    if (!s->blk) {
         ide_abort_command(s);
         return true;
     }
@@ -1259,7 +1260,7 @@ static bool cmd_write_dma(IDEState *s, uint8_t cmd)
 {
     bool lba48 = (cmd == WIN_WRITEDMA_EXT);
 
-    if (!s->bs) {
+    if (!s->blk) {
         ide_abort_command(s);
         return true;
     }
@@ -1310,7 +1311,7 @@ static bool cmd_set_features(IDEState *s, uint8_t cmd)
 {
     uint16_t *identify_data;
 
-    if (!s->bs) {
+    if (!s->blk) {
         ide_abort_command(s);
         return true;
     }
@@ -1318,12 +1319,12 @@ static bool cmd_set_features(IDEState *s, uint8_t cmd)
     /* XXX: valid for CDROM ? */
     switch (s->feature) {
     case 0x02: /* write cache enable */
-        bdrv_set_enable_write_cache(s->bs, true);
+        blk_set_enable_write_cache(s->blk, true);
         identify_data = (uint16_t *)s->identify_data;
         put_le16(identify_data + 85, (1 << 14) | (1 << 5) | 1);
         return true;
     case 0x82: /* write cache disable */
-        bdrv_set_enable_write_cache(s->bs, false);
+        blk_set_enable_write_cache(s->blk, false);
         identify_data = (uint16_t *)s->identify_data;
         put_le16(identify_data + 85, (1 << 14) | 1);
         ide_flush_cache(s);
@@ -1790,8 +1791,9 @@ void ide_exec_cmd(IDEBus *bus, uint32_t val)
 #endif
     s = idebus_active_if(bus);
     /* ignore commands to non existent slave */
-    if (s != bus->ifs && !s->bs)
+    if (s != bus->ifs && !s->blk) {
         return;
+    }
 
     /* Only DEVICE RESET is allowed while BSY or/and DRQ are set */
     if ((s->status & (BUSY_STAT|DRQ_STAT)) && val != WIN_DEVICE_RESET)
@@ -1836,59 +1838,66 @@ uint32_t ide_ioport_read(void *opaque, uint32_t addr1)
         ret = 0xff;
         break;
     case 1:
-        if ((!bus->ifs[0].bs && !bus->ifs[1].bs) ||
-            (s != bus->ifs && !s->bs))
+        if ((!bus->ifs[0].blk && !bus->ifs[1].blk) ||
+            (s != bus->ifs && !s->blk)) {
             ret = 0;
-        else if (!hob)
+        } else if (!hob) {
             ret = s->error;
-	else
+        } else {
 	    ret = s->hob_feature;
+        }
         break;
     case 2:
-        if (!bus->ifs[0].bs && !bus->ifs[1].bs)
+        if (!bus->ifs[0].blk && !bus->ifs[1].blk) {
             ret = 0;
-        else if (!hob)
+        } else if (!hob) {
             ret = s->nsector & 0xff;
-	else
+        } else {
 	    ret = s->hob_nsector;
+        }
         break;
     case 3:
-        if (!bus->ifs[0].bs && !bus->ifs[1].bs)
+        if (!bus->ifs[0].blk && !bus->ifs[1].blk) {
             ret = 0;
-        else if (!hob)
+        } else if (!hob) {
             ret = s->sector;
-	else
+        } else {
 	    ret = s->hob_sector;
+        }
         break;
     case 4:
-        if (!bus->ifs[0].bs && !bus->ifs[1].bs)
+        if (!bus->ifs[0].blk && !bus->ifs[1].blk) {
             ret = 0;
-        else if (!hob)
+        } else if (!hob) {
             ret = s->lcyl;
-	else
+        } else {
 	    ret = s->hob_lcyl;
+        }
         break;
     case 5:
-        if (!bus->ifs[0].bs && !bus->ifs[1].bs)
+        if (!bus->ifs[0].blk && !bus->ifs[1].blk) {
             ret = 0;
-        else if (!hob)
+        } else if (!hob) {
             ret = s->hcyl;
-	else
+        } else {
 	    ret = s->hob_hcyl;
+        }
         break;
     case 6:
-        if (!bus->ifs[0].bs && !bus->ifs[1].bs)
+        if (!bus->ifs[0].blk && !bus->ifs[1].blk) {
             ret = 0;
-        else
+        } else {
             ret = s->select;
+        }
         break;
     default:
     case 7:
-        if ((!bus->ifs[0].bs && !bus->ifs[1].bs) ||
-            (s != bus->ifs && !s->bs))
+        if ((!bus->ifs[0].blk && !bus->ifs[1].blk) ||
+            (s != bus->ifs && !s->blk)) {
             ret = 0;
-        else
+        } else {
             ret = s->status;
+        }
         qemu_irq_lower(bus->irq);
         break;
     }
@@ -1904,11 +1913,12 @@ uint32_t ide_status_read(void *opaque, uint32_t addr)
     IDEState *s = idebus_active_if(bus);
     int ret;
 
-    if ((!bus->ifs[0].bs && !bus->ifs[1].bs) ||
-        (s != bus->ifs && !s->bs))
+    if ((!bus->ifs[0].blk && !bus->ifs[1].blk) ||
+        (s != bus->ifs && !s->blk)) {
         ret = 0;
-    else
+    } else {
         ret = s->status;
+    }
 #ifdef DEBUG_IDE
     printf("ide: read status addr=0x%x val=%02x\n", addr, ret);
 #endif
@@ -2069,7 +2079,7 @@ static void ide_reset(IDEState *s)
 #endif
 
     if (s->pio_aiocb) {
-        bdrv_aio_cancel(s->pio_aiocb);
+        blk_aio_cancel(s->pio_aiocb);
         s->pio_aiocb = NULL;
     }
 
@@ -2133,7 +2143,7 @@ void ide_bus_reset(IDEBus *bus)
 #ifdef DEBUG_AIO
         printf("aio_cancel\n");
 #endif
-        bdrv_aio_cancel(bus->dma->aiocb);
+        blk_aio_cancel(bus->dma->aiocb);
         bus->dma->aiocb = NULL;
     }
 
@@ -2162,7 +2172,7 @@ static void ide_resize_cb(void *opaque)
         return;
     }
 
-    bdrv_get_geometry(s->bs, &nb_sectors);
+    blk_get_geometry(s->blk, &nb_sectors);
     s->nb_sectors = nb_sectors;
 
     /* Update the identify data buffer. */
@@ -2186,7 +2196,7 @@ static const BlockDevOps ide_hd_block_ops = {
     .resize_cb = ide_resize_cb,
 };
 
-int ide_init_drive(IDEState *s, BlockDriverState *bs, IDEDriveKind kind,
+int ide_init_drive(IDEState *s, BlockBackend *blk, IDEDriveKind kind,
                    const char *version, const char *serial, const char *model,
                    uint64_t wwn,
                    uint32_t cylinders, uint32_t heads, uint32_t secs,
@@ -2194,10 +2204,10 @@ int ide_init_drive(IDEState *s, BlockDriverState *bs, IDEDriveKind kind,
 {
     uint64_t nb_sectors;
 
-    s->bs = bs;
+    s->blk = blk;
     s->drive_kind = kind;
 
-    bdrv_get_geometry(bs, &nb_sectors);
+    blk_get_geometry(blk, &nb_sectors);
     s->cylinders = cylinders;
     s->heads = heads;
     s->sectors = secs;
@@ -2211,18 +2221,18 @@ int ide_init_drive(IDEState *s, BlockDriverState *bs, IDEDriveKind kind,
     s->smart_errors = 0;
     s->smart_selftest_count = 0;
     if (kind == IDE_CD) {
-        bdrv_set_dev_ops(bs, &ide_cd_block_ops, s);
-        bdrv_set_guest_block_size(bs, 2048);
+        blk_set_dev_ops(blk, &ide_cd_block_ops, s);
+        blk_set_guest_block_size(blk, 2048);
     } else {
-        if (!bdrv_is_inserted(s->bs)) {
+        if (!blk_is_inserted(s->blk)) {
             error_report("Device needs media, but drive is empty");
             return -1;
         }
-        if (bdrv_is_read_only(bs)) {
+        if (blk_is_read_only(blk)) {
             error_report("Can't use a read-only drive");
             return -1;
         }
-        bdrv_set_dev_ops(bs, &ide_hd_block_ops, s);
+        blk_set_dev_ops(blk, &ide_hd_block_ops, s);
     }
     if (serial) {
         pstrcpy(s->drive_serial_str, sizeof(s->drive_serial_str), serial);
@@ -2253,7 +2263,7 @@ int ide_init_drive(IDEState *s, BlockDriverState *bs, IDEDriveKind kind,
     }
 
     ide_reset(s);
-    bdrv_iostatus_enable(bs);
+    blk_iostatus_enable(blk);
     return 0;
 }
 
@@ -2270,7 +2280,7 @@ static void ide_init1(IDEBus *bus, int unit)
     s->io_buffer = qemu_memalign(2048, s->io_buffer_total_len);
     memset(s->io_buffer, 0, s->io_buffer_total_len);
 
-    s->smart_selftest_data = qemu_blockalign(s->bs, 512);
+    s->smart_selftest_data = blk_blockalign(s->blk, 512);
     memset(s->smart_selftest_data, 0, 512);
 
     s->sector_write_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL,
@@ -2365,7 +2375,7 @@ static int ide_drive_post_load(void *opaque, int version_id)
     IDEState *s = opaque;
 
     if (s->identify_set) {
-        bdrv_set_enable_write_cache(s->bs, !!(s->identify_data[85] & (1 << 5)));
+        blk_set_enable_write_cache(s->blk, !!(s->identify_data[85] & (1 << 5)));
     }
     return 0;
 }
diff --git a/hw/ide/ich.c b/hw/ide/ich.c
index a2f1639..6351363 100644
--- a/hw/ide/ich.c
+++ b/hw/ide/ich.c
@@ -65,7 +65,7 @@
 #include <hw/i386/pc.h>
 #include <hw/pci/pci.h>
 #include <hw/isa/isa.h>
-#include "block/block.h"
+#include "sysemu/block-backend.h"
 #include "sysemu/dma.h"
 
 #include <hw/ide/pci.h>
diff --git a/hw/ide/internal.h b/hw/ide/internal.h
index 9314c80..68ac610 100644
--- a/hw/ide/internal.h
+++ b/hw/ide/internal.h
@@ -373,7 +373,7 @@ struct IDEState {
 
     /* set for lba48 access */
     uint8_t lba48;
-    BlockDriverState *bs;
+    BlockBackend *blk;
     char version[9];
     /* ATAPI specific */
     struct unreported_events events;
@@ -537,7 +537,7 @@ uint32_t ide_data_readw(void *opaque, uint32_t addr);
 void ide_data_writel(void *opaque, uint32_t addr, uint32_t val);
 uint32_t ide_data_readl(void *opaque, uint32_t addr);
 
-int ide_init_drive(IDEState *s, BlockDriverState *bs, IDEDriveKind kind,
+int ide_init_drive(IDEState *s, BlockBackend *blk, IDEDriveKind kind,
                    const char *version, const char *serial, const char *model,
                    uint64_t wwn,
                    uint32_t cylinders, uint32_t heads, uint32_t secs,
@@ -555,7 +555,7 @@ void ide_transfer_start(IDEState *s, uint8_t *buf, int size,
                         EndTransferFunc *end_transfer_func);
 void ide_transfer_stop(IDEState *s);
 void ide_set_inactive(IDEState *s, bool more);
-BlockAIOCB *ide_issue_trim(BlockDriverState *bs,
+BlockAIOCB *ide_issue_trim(BlockBackend *blk,
         int64_t sector_num, QEMUIOVector *qiov, int nb_sectors,
         BlockCompletionFunc *cb, void *opaque);
 
diff --git a/hw/ide/isa.c b/hw/ide/isa.c
index 4cbcb1c..b084162 100644
--- a/hw/ide/isa.c
+++ b/hw/ide/isa.c
@@ -25,7 +25,7 @@
 #include <hw/hw.h>
 #include <hw/i386/pc.h>
 #include <hw/isa/isa.h>
-#include "block/block.h"
+#include "sysemu/block-backend.h"
 #include "sysemu/dma.h"
 
 #include <hw/ide/internal.h>
diff --git a/hw/ide/macio.c b/hw/ide/macio.c
index 371e172..ca8e834 100644
--- a/hw/ide/macio.c
+++ b/hw/ide/macio.c
@@ -25,7 +25,7 @@
 #include "hw/hw.h"
 #include "hw/ppc/mac.h"
 #include "hw/ppc/mac_dbdma.h"
-#include "block/block.h"
+#include "sysemu/block-backend.h"
 #include "sysemu/dma.h"
 
 #include <hw/ide/internal.h>
@@ -134,7 +134,7 @@ static void pmac_ide_atapi_transfer_cb(void *opaque, int ret)
         MACIO_DPRINTF("precopying unaligned %d bytes to %#" HWADDR_PRIx "\n",
                       unaligned, io->addr + io->len - unaligned);
 
-        bdrv_read(s->bs, sector_num + nsector, io->remainder, 1);
+        blk_read(s->blk, sector_num + nsector, io->remainder, 1);
         cpu_physical_memory_write(io->addr + io->len - unaligned,
                                   io->remainder, unaligned);
 
@@ -164,14 +164,14 @@ static void pmac_ide_atapi_transfer_cb(void *opaque, int ret)
                   (s->lba << 2) + (s->io_buffer_index >> 9),
                   s->packet_transfer_size, s->dma_cmd);
 
-    m->aiocb = dma_bdrv_read(s->bs, &s->sg,
-                             (int64_t)(s->lba << 2) + (s->io_buffer_index >> 9),
-                             pmac_ide_atapi_transfer_cb, io);
+    m->aiocb = dma_blk_read(s->blk, &s->sg,
+                            (int64_t)(s->lba << 2) + (s->io_buffer_index >> 9),
+                            pmac_ide_atapi_transfer_cb, io);
     return;
 
 done:
     MACIO_DPRINTF("done DMA\n");
-    bdrv_acct_done(s->bs, &s->acct);
+    blk_acct_done(s->blk, &s->acct);
     io->dma_end(opaque);
 }
 
@@ -254,8 +254,8 @@ static void pmac_ide_transfer_cb(void *opaque, int ret)
             qemu_iovec_reset(&io->iov);
             qemu_iovec_add(&io->iov, io->remainder, 0x200);
 
-            m->aiocb = bdrv_aio_writev(s->bs, sector_num - 1, &io->iov, 1,
-                                       pmac_ide_transfer_cb, io);
+            m->aiocb = blk_aio_writev(s->blk, sector_num - 1, &io->iov, 1,
+                                      pmac_ide_transfer_cb, io);
         }
     }
 
@@ -294,8 +294,8 @@ static void pmac_ide_transfer_cb(void *opaque, int ret)
             qemu_iovec_reset(&io->iov);
             qemu_iovec_add(&io->iov, io->remainder, 0x200);
 
-            m->aiocb = bdrv_aio_readv(s->bs, sector_num + nsector, &io->iov, 1,
-                                      pmac_ide_transfer_cb, io);
+            m->aiocb = blk_aio_readv(s->blk, sector_num + nsector, &io->iov, 1,
+                                     pmac_ide_transfer_cb, io);
             break;
         case IDE_DMA_WRITE:
             /* cache the contents in our io struct */
@@ -333,17 +333,17 @@ static void pmac_ide_transfer_cb(void *opaque, int ret)
 
     switch (s->dma_cmd) {
     case IDE_DMA_READ:
-        m->aiocb = dma_bdrv_read(s->bs, &s->sg, sector_num,
+        m->aiocb = dma_blk_read(s->blk, &s->sg, sector_num,
+                                pmac_ide_transfer_cb, io);
+        break;
+    case IDE_DMA_WRITE:
+        m->aiocb = dma_blk_write(s->blk, &s->sg, sector_num,
                                  pmac_ide_transfer_cb, io);
         break;
-    case IDE_DMA_WRITE:
-        m->aiocb = dma_bdrv_write(s->bs, &s->sg, sector_num,
-                                  pmac_ide_transfer_cb, io);
-        break;
     case IDE_DMA_TRIM:
-        m->aiocb = dma_bdrv_io(s->bs, &s->sg, sector_num,
-                               ide_issue_trim, pmac_ide_transfer_cb, io,
-                               DMA_DIRECTION_TO_DEVICE);
+        m->aiocb = dma_blk_io(s->blk, &s->sg, sector_num,
+                              ide_issue_trim, pmac_ide_transfer_cb, io,
+                              DMA_DIRECTION_TO_DEVICE);
         break;
     }
 
@@ -352,7 +352,7 @@ static void pmac_ide_transfer_cb(void *opaque, int ret)
 
 done:
     if (s->dma_cmd == IDE_DMA_READ || s->dma_cmd == IDE_DMA_WRITE) {
-        bdrv_acct_done(s->bs, &s->acct);
+        blk_acct_done(s->blk, &s->acct);
     }
     io->dma_end(io);
 }
@@ -370,8 +370,8 @@ static void pmac_ide_transfer(DBDMA_io *io)
         /* Handle non-block ATAPI DMA transfers */
         if (s->lba == -1) {
             s->io_buffer_size = MIN(io->len, s->packet_transfer_size);
-            bdrv_acct_start(s->bs, &s->acct, s->io_buffer_size,
-                            BDRV_ACCT_READ);
+            blk_acct_start(s->blk, &s->acct, s->io_buffer_size,
+                           BDRV_ACCT_READ);
             MACIO_DPRINTF("non-block ATAPI DMA transfer size: %d\n",
                           s->io_buffer_size);
 
@@ -382,22 +382,22 @@ static void pmac_ide_transfer(DBDMA_io *io)
             m->dma_active = false;
 
             MACIO_DPRINTF("end of non-block ATAPI DMA transfer\n");
-            bdrv_acct_done(s->bs, &s->acct);
+            blk_acct_done(s->blk, &s->acct);
             io->dma_end(io);
             return;
         }
 
-        bdrv_acct_start(s->bs, &s->acct, io->len, BDRV_ACCT_READ);
+        blk_acct_start(s->blk, &s->acct, io->len, BDRV_ACCT_READ);
         pmac_ide_atapi_transfer_cb(io, 0);
         return;
     }
 
     switch (s->dma_cmd) {
     case IDE_DMA_READ:
-        bdrv_acct_start(s->bs, &s->acct, io->len, BDRV_ACCT_READ);
+        blk_acct_start(s->blk, &s->acct, io->len, BDRV_ACCT_READ);
         break;
     case IDE_DMA_WRITE:
-        bdrv_acct_start(s->bs, &s->acct, io->len, BDRV_ACCT_WRITE);
+        blk_acct_start(s->blk, &s->acct, io->len, BDRV_ACCT_WRITE);
         break;
     default:
         break;
@@ -412,7 +412,7 @@ static void pmac_ide_flush(DBDMA_io *io)
     MACIOIDEState *m = io->opaque;
 
     if (m->aiocb) {
-        bdrv_drain_all();
+        blk_drain_all();
     }
 }
 
diff --git a/hw/ide/microdrive.c b/hw/ide/microdrive.c
index 15671b8..ed85185 100644
--- a/hw/ide/microdrive.c
+++ b/hw/ide/microdrive.c
@@ -25,7 +25,7 @@
 #include <hw/hw.h>
 #include <hw/i386/pc.h>
 #include <hw/pcmcia.h>
-#include "block/block.h"
+#include "sysemu/block-backend.h"
 #include "sysemu/dma.h"
 
 #include <hw/ide/internal.h>
@@ -247,7 +247,7 @@ static uint16_t md_common_read(PCMCIACardState *card, uint32_t at)
         return ide_ioport_read(&s->bus, 0x1);
     case 0xe:	/* Alternate Status */
         ifs = idebus_active_if(&s->bus);
-        if (ifs->bs) {
+        if (ifs->blk) {
             return ifs->status;
         } else {
             return 0;
diff --git a/hw/ide/mmio.c b/hw/ide/mmio.c
index 01c1d0e..5703be1 100644
--- a/hw/ide/mmio.c
+++ b/hw/ide/mmio.c
@@ -24,7 +24,7 @@
  */
 #include "hw/hw.h"
 #include "hw/sysbus.h"
-#include "block/block.h"
+#include "sysemu/block-backend.h"
 #include "sysemu/dma.h"
 
 #include <hw/ide/internal.h>
diff --git a/hw/ide/pci.c b/hw/ide/pci.c
index 6ff1c58..2dad50e 100644
--- a/hw/ide/pci.c
+++ b/hw/ide/pci.c
@@ -26,7 +26,7 @@
 #include <hw/i386/pc.h>
 #include <hw/pci/pci.h>
 #include <hw/isa/isa.h>
-#include "block/block.h"
+#include "sysemu/block-backend.h"
 #include "sysemu/dma.h"
 
 #include <hw/ide/pci.h>
@@ -302,7 +302,7 @@ void bmdma_cmd_writeb(BMDMAState *bm, uint32_t val)
              * aio operation with preadv/pwritev.
              */
             if (bm->bus->dma->aiocb) {
-                bdrv_drain_all();
+                blk_drain_all();
                 assert(bm->bus->dma->aiocb == NULL);
             }
             bm->status &= ~BM_STATUS_DMAING;
diff --git a/hw/ide/piix.c b/hw/ide/piix.c
index c6c256f..61958c6 100644
--- a/hw/ide/piix.c
+++ b/hw/ide/piix.c
@@ -28,7 +28,6 @@
 #include <hw/pci/pci.h>
 #include <hw/isa/isa.h>
 #include "sysemu/block-backend.h"
-#include "sysemu/blockdev.h"
 #include "sysemu/sysemu.h"
 #include "sysemu/dma.h"
 
@@ -179,12 +178,12 @@ int pci_piix3_xen_ide_unplug(DeviceState *dev)
     for (; i < 3; i++) {
         di = drive_get_by_index(IF_IDE, i);
         if (di != NULL && !di->media_cd) {
-            BlockDriverState *bs = blk_bs(blk_by_legacy_dinfo(di));
-            DeviceState *ds = bdrv_get_attached_dev(bs);
+            BlockBackend *blk = blk_by_legacy_dinfo(di);
+            DeviceState *ds = blk_get_attached_dev(blk);
             if (ds) {
-                bdrv_detach_dev(bs, ds);
+                blk_detach_dev(blk, ds);
             }
-            pci_ide->bus[di->bus].ifs[di->unit].bs = NULL;
+            pci_ide->bus[di->bus].ifs[di->unit].blk = NULL;
             drive_del(di);
         }
     }
diff --git a/hw/ide/qdev.c b/hw/ide/qdev.c
index 75e8eb3..4818334 100644
--- a/hw/ide/qdev.c
+++ b/hw/ide/qdev.c
@@ -72,7 +72,7 @@ static int ide_qdev_init(DeviceState *qdev)
     IDEDeviceClass *dc = IDE_DEVICE_GET_CLASS(dev);
     IDEBus *bus = DO_UPCAST(IDEBus, qbus, qdev->parent_bus);
 
-    if (!dev->conf.bs) {
+    if (!dev->conf.blk) {
         error_report("No drive specified");
         goto err;
     }
@@ -117,8 +117,7 @@ IDEDevice *ide_create_drive(IDEBus *bus, int unit, DriveInfo *drive)
 
     dev = qdev_create(&bus->qbus, drive->media_cd ? "ide-cd" : "ide-hd");
     qdev_prop_set_uint32(dev, "unit", unit);
-    qdev_prop_set_drive_nofail(dev, "drive",
-                               blk_bs(blk_by_legacy_dinfo(drive)));
+    qdev_prop_set_drive_nofail(dev, "drive", blk_by_legacy_dinfo(drive));
     qdev_init_nofail(dev);
     return DO_UPCAST(IDEDevice, qdev, dev);
 }
@@ -128,7 +127,7 @@ int ide_get_geometry(BusState *bus, int unit,
 {
     IDEState *s = &DO_UPCAST(IDEBus, qbus, bus)->ifs[unit];
 
-    if (s->drive_kind != IDE_HD || !s->bs) {
+    if (s->drive_kind != IDE_HD || !s->blk) {
         return -1;
     }
 
@@ -173,7 +172,7 @@ static int ide_dev_initfn(IDEDevice *dev, IDEDriveKind kind)
         }
     }
 
-    if (ide_init_drive(s, dev->conf.bs, kind,
+    if (ide_init_drive(s, dev->conf.blk, kind,
                        dev->version, dev->serial, dev->model, dev->wwn,
                        dev->conf.cyls, dev->conf.heads, dev->conf.secs,
                        dev->chs_trans) < 0) {
@@ -205,7 +204,7 @@ static int ide_cd_initfn(IDEDevice *dev)
 
 static int ide_drive_initfn(IDEDevice *dev)
 {
-    DriveInfo *dinfo = drive_get_by_blockdev(dev->conf.bs);
+    DriveInfo *dinfo = blk_legacy_dinfo(dev->conf.blk);
 
     return ide_dev_initfn(dev, dinfo->media_cd ? IDE_CD : IDE_HD);
 }
diff --git a/hw/ide/via.c b/hw/ide/via.c
index 89d27b4..4d8089d 100644
--- a/hw/ide/via.c
+++ b/hw/ide/via.c
@@ -27,7 +27,7 @@
 #include <hw/i386/pc.h>
 #include <hw/pci/pci.h>
 #include <hw/isa/isa.h>
-#include "block/block.h"
+#include "sysemu/block-backend.h"
 #include "sysemu/sysemu.h"
 #include "sysemu/dma.h"
 
diff --git a/hw/isa/pc87312.c b/hw/isa/pc87312.c
index b691a0c..40a1106 100644
--- a/hw/isa/pc87312.c
+++ b/hw/isa/pc87312.c
@@ -322,12 +322,12 @@ static void pc87312_realize(DeviceState *dev, Error **errp)
         drive = drive_get(IF_FLOPPY, 0, 0);
         if (drive != NULL) {
             qdev_prop_set_drive_nofail(d, "driveA",
-                                       blk_bs(blk_by_legacy_dinfo(drive)));
+                                       blk_by_legacy_dinfo(drive));
         }
         drive = drive_get(IF_FLOPPY, 0, 1);
         if (drive != NULL) {
             qdev_prop_set_drive_nofail(d, "driveB",
-                                       blk_bs(blk_by_legacy_dinfo(drive)));
+                                       blk_by_legacy_dinfo(drive));
         }
         qdev_init_nofail(d);
         s->fdc.dev = isa;
diff --git a/hw/lm32/lm32_boards.c b/hw/lm32/lm32_boards.c
index 17c5610..08e4ce3 100644
--- a/hw/lm32/lm32_boards.c
+++ b/hw/lm32/lm32_boards.c
@@ -24,7 +24,6 @@
 #include "hw/boards.h"
 #include "hw/loader.h"
 #include "sysemu/block-backend.h"
-#include "sysemu/blockdev.h"
 #include "elf.h"
 #include "lm32_hwsetup.h"
 #include "lm32.h"
@@ -119,7 +118,7 @@ static void lm32_evr_init(MachineState *machine)
     dinfo = drive_get(IF_PFLASH, 0, 0);
     /* Spansion S29NS128P */
     pflash_cfi02_register(flash_base, NULL, "lm32_evr.flash", flash_size,
-                          dinfo ? blk_bs(blk_by_legacy_dinfo(dinfo)) : NULL,
+                          dinfo ? blk_by_legacy_dinfo(dinfo) : NULL,
                           flash_sector_size, flash_size / flash_sector_size,
                           1, 2, 0x01, 0x7e, 0x43, 0x00, 0x555, 0x2aa, 1);
 
@@ -221,7 +220,7 @@ static void lm32_uclinux_init(MachineState *machine)
     dinfo = drive_get(IF_PFLASH, 0, 0);
     /* Spansion S29NS128P */
     pflash_cfi02_register(flash_base, NULL, "lm32_uclinux.flash", flash_size,
-                          dinfo ? blk_bs(blk_by_legacy_dinfo(dinfo)) : NULL,
+                          dinfo ? blk_by_legacy_dinfo(dinfo) : NULL,
                           flash_sector_size, flash_size / flash_sector_size,
                           1, 2, 0x01, 0x7e, 0x43, 0x00, 0x555, 0x2aa, 1);
 
diff --git a/hw/lm32/milkymist.c b/hw/lm32/milkymist.c
index 904b9c0..2589568 100644
--- a/hw/lm32/milkymist.c
+++ b/hw/lm32/milkymist.c
@@ -27,7 +27,6 @@
 #include "hw/loader.h"
 #include "elf.h"
 #include "sysemu/block-backend.h"
-#include "sysemu/blockdev.h"
 #include "milkymist-hw.h"
 #include "lm32.h"
 #include "exec/address-spaces.h"
@@ -126,7 +125,7 @@ milkymist_init(MachineState *machine)
     dinfo = drive_get(IF_PFLASH, 0, 0);
     /* Numonyx JS28F256J3F105 */
     pflash_cfi01_register(flash_base, NULL, "milkymist.flash", flash_size,
-                          dinfo ? blk_bs(blk_by_legacy_dinfo(dinfo)) : NULL,
+                          dinfo ? blk_by_legacy_dinfo(dinfo) : NULL,
                           flash_sector_size, flash_size / flash_sector_size,
                           2, 0x00, 0x89, 0x00, 0x1d, 1);
 
diff --git a/hw/microblaze/petalogix_ml605_mmu.c b/hw/microblaze/petalogix_ml605_mmu.c
index 2974791..12acea7 100644
--- a/hw/microblaze/petalogix_ml605_mmu.c
+++ b/hw/microblaze/petalogix_ml605_mmu.c
@@ -33,7 +33,6 @@
 #include "hw/devices.h"
 #include "hw/boards.h"
 #include "sysemu/block-backend.h"
-#include "sysemu/blockdev.h"
 #include "hw/char/serial.h"
 #include "exec/address-spaces.h"
 #include "hw/ssi.h"
@@ -113,7 +112,7 @@ petalogix_ml605_init(MachineState *machine)
      * 10th paremeter 0 means little-endian */
     pflash_cfi01_register(FLASH_BASEADDR,
                           NULL, "petalogix_ml605.flash", FLASH_SIZE,
-                          dinfo ? blk_bs(blk_by_legacy_dinfo(dinfo)) : NULL,
+                          dinfo ? blk_by_legacy_dinfo(dinfo) : NULL,
                           (64 * 1024), FLASH_SIZE >> 16,
                           2, 0x89, 0x18, 0x0000, 0x0, 0);
 
diff --git a/hw/microblaze/petalogix_s3adsp1800_mmu.c b/hw/microblaze/petalogix_s3adsp1800_mmu.c
index a69301f..8c90c56 100644
--- a/hw/microblaze/petalogix_s3adsp1800_mmu.c
+++ b/hw/microblaze/petalogix_s3adsp1800_mmu.c
@@ -31,7 +31,6 @@
 #include "hw/devices.h"
 #include "hw/boards.h"
 #include "sysemu/block-backend.h"
-#include "sysemu/blockdev.h"
 #include "exec/address-spaces.h"
 
 #include "boot.h"
@@ -93,7 +92,7 @@ petalogix_s3adsp1800_init(MachineState *machine)
     dinfo = drive_get(IF_PFLASH, 0, 0);
     pflash_cfi01_register(FLASH_BASEADDR,
                           NULL, "petalogix_s3adsp1800.flash", FLASH_SIZE,
-                          dinfo ? blk_bs(blk_by_legacy_dinfo(dinfo)) : NULL,
+                          dinfo ? blk_by_legacy_dinfo(dinfo) : NULL,
                           (64 * 1024), FLASH_SIZE >> 16,
                           1, 0x89, 0x18, 0x0000, 0x0, 1);
 
diff --git a/hw/mips/mips_fulong2e.c b/hw/mips/mips_fulong2e.c
index f7533ed..fc0e008 100644
--- a/hw/mips/mips_fulong2e.c
+++ b/hw/mips/mips_fulong2e.c
@@ -25,7 +25,7 @@
 #include "net/net.h"
 #include "hw/boards.h"
 #include "hw/i2c/smbus.h"
-#include "block/block.h"
+#include "sysemu/block-backend.h"
 #include "hw/block/flash.h"
 #include "hw/mips/mips.h"
 #include "hw/mips/cpudevs.h"
diff --git a/hw/mips/mips_jazz.c b/hw/mips/mips_jazz.c
index c113a80..5b24e45 100644
--- a/hw/mips/mips_jazz.c
+++ b/hw/mips/mips_jazz.c
@@ -39,7 +39,7 @@
 #include "hw/timer/mc146818rtc.h"
 #include "hw/timer/i8254.h"
 #include "hw/audio/pcspk.h"
-#include "sysemu/blockdev.h"
+#include "sysemu/block-backend.h"
 #include "hw/sysbus.h"
 #include "exec/address-spaces.h"
 #include "sysemu/qtest.h"
diff --git a/hw/mips/mips_malta.c b/hw/mips/mips_malta.c
index 9f84ad6..dc4b364 100644
--- a/hw/mips/mips_malta.c
+++ b/hw/mips/mips_malta.c
@@ -29,7 +29,7 @@
 #include "net/net.h"
 #include "hw/boards.h"
 #include "hw/i2c/smbus.h"
-#include "block/block.h"
+#include "sysemu/block-backend.h"
 #include "hw/block/flash.h"
 #include "hw/mips/mips.h"
 #include "hw/mips/cpudevs.h"
@@ -1032,12 +1032,12 @@ void mips_malta_init(MachineState *machine)
         printf("Register parallel flash %d size " TARGET_FMT_lx " at "
                "addr %08llx '%s' %x\n",
                fl_idx, bios_size, FLASH_ADDRESS,
-               bdrv_get_device_name(dinfo->bdrv), fl_sectors);
+               blk_name(dinfo->bdrv), fl_sectors);
     }
 #endif
     fl = pflash_cfi01_register(FLASH_ADDRESS, NULL, "mips_malta.bios",
                                BIOS_SIZE,
-                               dinfo ? blk_bs(blk_by_legacy_dinfo(dinfo)) : NULL,
+                               dinfo ? blk_by_legacy_dinfo(dinfo) : NULL,
                                65536, fl_sectors,
                                4, 0x0000, 0x0000, 0x0000, 0x0000, be);
     bios = pflash_cfi01_get_memory(fl);
diff --git a/hw/mips/mips_r4k.c b/hw/mips/mips_r4k.c
index 6fd69b9..b23ed06 100644
--- a/hw/mips/mips_r4k.c
+++ b/hw/mips/mips_r4k.c
@@ -25,7 +25,6 @@
 #include "hw/timer/mc146818rtc.h"
 #include "hw/timer/i8254.h"
 #include "sysemu/block-backend.h"
-#include "sysemu/blockdev.h"
 #include "exec/address-spaces.h"
 #include "sysemu/qtest.h"
 
@@ -241,7 +240,7 @@ void mips_r4k_init(MachineState *machine)
     } else if ((dinfo = drive_get(IF_PFLASH, 0, 0)) != NULL) {
         uint32_t mips_rom = 0x00400000;
         if (!pflash_cfi01_register(0x1fc00000, NULL, "mips_r4k.bios", mips_rom,
-                                   blk_bs(blk_by_legacy_dinfo(dinfo)),
+                                   blk_by_legacy_dinfo(dinfo),
                                    sector_len, mips_rom / sector_len,
                                    4, 0, 0, 0, 0, be)) {
             fprintf(stderr, "qemu: Error registering flash memory.\n");
diff --git a/hw/nvram/spapr_nvram.c b/hw/nvram/spapr_nvram.c
index 6a72ef4..10b5b2e 100644
--- a/hw/nvram/spapr_nvram.c
+++ b/hw/nvram/spapr_nvram.c
@@ -24,6 +24,7 @@
 
 #include <libfdt.h>
 
+#include "sysemu/block-backend.h"
 #include "sysemu/device_tree.h"
 #include "hw/sysbus.h"
 #include "hw/ppc/spapr.h"
@@ -33,7 +34,7 @@ typedef struct sPAPRNVRAM {
     VIOsPAPRDevice sdev;
     uint32_t size;
     uint8_t *buf;
-    BlockDriverState *drive;
+    BlockBackend *blk;
 } sPAPRNVRAM;
 
 #define TYPE_VIO_SPAPR_NVRAM "spapr-nvram"
@@ -77,8 +78,8 @@ static void rtas_nvram_fetch(PowerPCCPU *cpu, sPAPREnvironment *spapr,
     }
 
     membuf = cpu_physical_memory_map(buffer, &len, 1);
-    if (nvram->drive) {
-        alen = bdrv_pread(nvram->drive, offset, membuf, len);
+    if (nvram->blk) {
+        alen = blk_pread(nvram->blk, offset, membuf, len);
     } else {
         assert(nvram->buf);
 
@@ -122,8 +123,8 @@ static void rtas_nvram_store(PowerPCCPU *cpu, sPAPREnvironment *spapr,
     }
 
     membuf = cpu_physical_memory_map(buffer, &len, 0);
-    if (nvram->drive) {
-        alen = bdrv_pwrite(nvram->drive, offset, membuf, len);
+    if (nvram->blk) {
+        alen = blk_pwrite(nvram->blk, offset, membuf, len);
     } else {
         assert(nvram->buf);
 
@@ -140,8 +141,8 @@ static int spapr_nvram_init(VIOsPAPRDevice *dev)
 {
     sPAPRNVRAM *nvram = VIO_SPAPR_NVRAM(dev);
 
-    if (nvram->drive) {
-        nvram->size = bdrv_getlength(nvram->drive);
+    if (nvram->blk) {
+        nvram->size = blk_getlength(nvram->blk);
     } else {
         nvram->size = DEFAULT_NVRAM_SIZE;
         nvram->buf = g_malloc0(nvram->size);
@@ -168,7 +169,7 @@ static int spapr_nvram_devnode(VIOsPAPRDevice *dev, void *fdt, int node_off)
 
 static Property spapr_nvram_properties[] = {
     DEFINE_SPAPR_PROPERTIES(sPAPRNVRAM, sdev),
-    DEFINE_PROP_DRIVE("drive", sPAPRNVRAM, drive),
+    DEFINE_PROP_DRIVE("drive", sPAPRNVRAM, blk),
     DEFINE_PROP_END_OF_LIST(),
 };
 
diff --git a/hw/pci/pci-hotplug-old.c b/hw/pci/pci-hotplug-old.c
index e4d51de..23c80ca 100644
--- a/hw/pci/pci-hotplug-old.c
+++ b/hw/pci/pci-hotplug-old.c
@@ -34,7 +34,6 @@
 #include "hw/virtio/virtio-blk.h"
 #include "qemu/config-file.h"
 #include "sysemu/block-backend.h"
-#include "sysemu/blockdev.h"
 #include "qapi/error.h"
 
 static int pci_read_devaddr(Monitor *mon, const char *addr,
@@ -128,7 +127,7 @@ static int scsi_hot_add(Monitor *mon, DeviceState *adapter,
     dinfo->unit = qemu_opt_get_number(dinfo->opts, "unit", -1);
     dinfo->bus = scsibus->busnr;
     scsidev = scsi_bus_legacy_add_drive(scsibus,
-                                        blk_bs(blk_by_legacy_dinfo(dinfo)),
+                                        blk_by_legacy_dinfo(dinfo),
                                         dinfo->unit, false, -1, NULL, NULL);
     if (!scsidev) {
         return -1;
@@ -250,7 +249,7 @@ static PCIDevice *qemu_pci_hot_add_storage(Monitor *mon,
         }
         dev = pci_create(bus, devfn, "virtio-blk-pci");
         if (qdev_prop_set_drive(&dev->qdev, "drive",
-                                blk_bs(blk_by_legacy_dinfo(dinfo))) < 0) {
+                                blk_by_legacy_dinfo(dinfo)) < 0) {
             object_unparent(OBJECT(dev));
             dev = NULL;
             break;
diff --git a/hw/ppc/mac_newworld.c b/hw/ppc/mac_newworld.c
index 8453bfa..77d4416 100644
--- a/hw/ppc/mac_newworld.c
+++ b/hw/ppc/mac_newworld.c
@@ -65,7 +65,7 @@
 #include "sysemu/kvm.h"
 #include "kvm_ppc.h"
 #include "hw/usb.h"
-#include "sysemu/blockdev.h"
+#include "sysemu/block-backend.h"
 #include "exec/address-spaces.h"
 #include "hw/sysbus.h"
 
diff --git a/hw/ppc/mac_oldworld.c b/hw/ppc/mac_oldworld.c
index 630a9f9..8fce5e9 100644
--- a/hw/ppc/mac_oldworld.c
+++ b/hw/ppc/mac_oldworld.c
@@ -40,7 +40,7 @@
 #include "elf.h"
 #include "sysemu/kvm.h"
 #include "kvm_ppc.h"
-#include "sysemu/blockdev.h"
+#include "sysemu/block-backend.h"
 #include "exec/address-spaces.h"
 
 #define MAX_IDE_BUS 2
diff --git a/hw/ppc/ppc405_boards.c b/hw/ppc/ppc405_boards.c
index 7ff5ee5..371893b 100644
--- a/hw/ppc/ppc405_boards.c
+++ b/hw/ppc/ppc405_boards.c
@@ -28,7 +28,7 @@
 #include "hw/block/flash.h"
 #include "sysemu/sysemu.h"
 #include "sysemu/qtest.h"
-#include "block/block.h"
+#include "sysemu/block-backend.h"
 #include "hw/boards.h"
 #include "qemu/log.h"
 #include "qemu/error-report.h"
@@ -226,19 +226,19 @@ static void ref405ep_init(MachineState *machine)
 #ifdef USE_FLASH_BIOS
     dinfo = drive_get(IF_PFLASH, 0, fl_idx);
     if (dinfo) {
-        BlockDriverState *bs = blk_bs(blk_by_legacy_dinfo(dinfo));
+        BlockBackend *blk = blk_by_legacy_dinfo(dinfo);
 
-        bios_size = bdrv_getlength(bs);
+        bios_size = blk_getlength(blk);
         fl_sectors = (bios_size + 65535) >> 16;
 #ifdef DEBUG_BOARD_INIT
         printf("Register parallel flash %d size %lx"
                " at addr %lx '%s' %d\n",
                fl_idx, bios_size, -bios_size,
-               bdrv_get_device_name(bs), fl_sectors);
+               blk_name(blk), fl_sectors);
 #endif
         pflash_cfi02_register((uint32_t)(-bios_size),
                               NULL, "ef405ep.bios", bios_size,
-                              bs, 65536, fl_sectors, 1,
+                              blk, 65536, fl_sectors, 1,
                               2, 0x0001, 0x22DA, 0x0000, 0x0000, 0x555, 0x2AA,
                               1);
         fl_idx++;
@@ -550,9 +550,9 @@ static void taihu_405ep_init(MachineState *machine)
 #if defined(USE_FLASH_BIOS)
     dinfo = drive_get(IF_PFLASH, 0, fl_idx);
     if (dinfo) {
-        BlockDriverState *bs = blk_bs(blk_by_legacy_dinfo(dinfo));
+        BlockBackend *blk = blk_by_legacy_dinfo(dinfo);
 
-        bios_size = bdrv_getlength(bs);
+        bios_size = blk_getlength(blk);
         /* XXX: should check that size is 2MB */
         //        bios_size = 2 * 1024 * 1024;
         fl_sectors = (bios_size + 65535) >> 16;
@@ -560,11 +560,11 @@ static void taihu_405ep_init(MachineState *machine)
         printf("Register parallel flash %d size %lx"
                " at addr %lx '%s' %d\n",
                fl_idx, bios_size, -bios_size,
-               bdrv_get_device_name(bs), fl_sectors);
+               blk_name(blk), fl_sectors);
 #endif
         pflash_cfi02_register((uint32_t)(-bios_size),
                               NULL, "taihu_405ep.bios", bios_size,
-                              bs, 65536, fl_sectors, 1,
+                              blk, 65536, fl_sectors, 1,
                               4, 0x0001, 0x22DA, 0x0000, 0x0000, 0x555, 0x2AA,
                               1);
         fl_idx++;
@@ -598,9 +598,9 @@ static void taihu_405ep_init(MachineState *machine)
     /* Register Linux flash */
     dinfo = drive_get(IF_PFLASH, 0, fl_idx);
     if (dinfo) {
-        BlockDriverState *bs = blk_bs(blk_by_legacy_dinfo(dinfo));
+        BlockBackend *blk = blk_by_legacy_dinfo(dinfo);
 
-        bios_size = bdrv_getlength(bs);
+        bios_size = blk_getlength(blk);
         /* XXX: should check that size is 32MB */
         bios_size = 32 * 1024 * 1024;
         fl_sectors = (bios_size + 65535) >> 16;
@@ -608,10 +608,10 @@ static void taihu_405ep_init(MachineState *machine)
         printf("Register parallel flash %d size %lx"
                " at addr " TARGET_FMT_lx " '%s'\n",
                fl_idx, bios_size, (target_ulong)0xfc000000,
-               bdrv_get_device_name(bs));
+               blk_name(blk));
 #endif
         pflash_cfi02_register(0xfc000000, NULL, "taihu_405ep.flash", bios_size,
-                              bs, 65536, fl_sectors, 1,
+                              blk, 65536, fl_sectors, 1,
                               4, 0x0001, 0x22DA, 0x0000, 0x0000, 0x555, 0x2AA,
                               1);
         fl_idx++;
diff --git a/hw/ppc/prep.c b/hw/ppc/prep.c
index f0ef1af..37c582b 100644
--- a/hw/ppc/prep.c
+++ b/hw/ppc/prep.c
@@ -38,7 +38,7 @@
 #include "hw/loader.h"
 #include "hw/timer/mc146818rtc.h"
 #include "hw/isa/pc87312.h"
-#include "sysemu/blockdev.h"
+#include "sysemu/block-backend.h"
 #include "sysemu/arch_init.h"
 #include "sysemu/qtest.h"
 #include "exec/address-spaces.h"
diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
index a577812..78fb927 100644
--- a/hw/ppc/spapr.c
+++ b/hw/ppc/spapr.c
@@ -30,7 +30,6 @@
 #include "elf.h"
 #include "net/net.h"
 #include "sysemu/block-backend.h"
-#include "sysemu/blockdev.h"
 #include "sysemu/cpus.h"
 #include "sysemu/kvm.h"
 #include "kvm_ppc.h"
@@ -926,8 +925,7 @@ static void spapr_create_nvram(sPAPREnvironment *spapr)
     DriveInfo *dinfo = drive_get(IF_PFLASH, 0, 0);
 
     if (dinfo) {
-        qdev_prop_set_drive_nofail(dev, "drive",
-                                   blk_bs(blk_by_legacy_dinfo(dinfo)));
+        qdev_prop_set_drive_nofail(dev, "drive", blk_by_legacy_dinfo(dinfo));
     }
 
     qdev_init_nofail(dev);
diff --git a/hw/ppc/virtex_ml507.c b/hw/ppc/virtex_ml507.c
index a0ce447..6ebd5be 100644
--- a/hw/ppc/virtex_ml507.c
+++ b/hw/ppc/virtex_ml507.c
@@ -40,7 +40,6 @@
 #include "ppc405.h"
 
 #include "sysemu/block-backend.h"
-#include "sysemu/blockdev.h"
 #include "qapi/qmp/qerror.h"
 
 #define EPAPR_MAGIC    (0x45504150)
@@ -228,7 +227,7 @@ static void virtex_init(MachineState *machine)
 
     dinfo = drive_get(IF_PFLASH, 0, 0);
     pflash_cfi01_register(PFLASH_BASEADDR, NULL, "virtex.flash", FLASH_SIZE,
-                          dinfo ? blk_bs(blk_by_legacy_dinfo(dinfo)) : NULL,
+                          dinfo ? blk_by_legacy_dinfo(dinfo) : NULL,
                           (64 * 1024), FLASH_SIZE >> 16,
                           1, 0x89, 0x18, 0x0000, 0x0, 1);
 
diff --git a/hw/s390x/s390-virtio-bus.c b/hw/s390x/s390-virtio-bus.c
index 6b6fb61..81cf22a 100644
--- a/hw/s390x/s390-virtio-bus.c
+++ b/hw/s390x/s390-virtio-bus.c
@@ -18,7 +18,7 @@
  */
 
 #include "hw/hw.h"
-#include "block/block.h"
+#include "sysemu/block-backend.h"
 #include "sysemu/sysemu.h"
 #include "hw/boards.h"
 #include "monitor/monitor.h"
diff --git a/hw/s390x/s390-virtio.c b/hw/s390x/s390-virtio.c
index 4ca52b7..df0fdaf 100644
--- a/hw/s390x/s390-virtio.c
+++ b/hw/s390x/s390-virtio.c
@@ -22,7 +22,7 @@
  */
 
 #include "hw/hw.h"
-#include "block/block.h"
+#include "sysemu/block-backend.h"
 #include "sysemu/blockdev.h"
 #include "sysemu/sysemu.h"
 #include "net/net.h"
diff --git a/hw/s390x/virtio-ccw.c b/hw/s390x/virtio-ccw.c
index 33a1d86..6339f82 100644
--- a/hw/s390x/virtio-ccw.c
+++ b/hw/s390x/virtio-ccw.c
@@ -10,7 +10,7 @@
  */
 
 #include "hw/hw.h"
-#include "block/block.h"
+#include "sysemu/block-backend.h"
 #include "sysemu/blockdev.h"
 #include "sysemu/sysemu.h"
 #include "net/net.h"
diff --git a/hw/scsi/megasas.c b/hw/scsi/megasas.c
index eedc992..36a04f3 100644
--- a/hw/scsi/megasas.c
+++ b/hw/scsi/megasas.c
@@ -21,6 +21,7 @@
 #include "hw/hw.h"
 #include "hw/pci/pci.h"
 #include "sysemu/dma.h"
+#include "sysemu/block-backend.h"
 #include "hw/pci/msi.h"
 #include "hw/pci/msix.h"
 #include "qemu/iov.h"
@@ -976,7 +977,6 @@ static int megasas_pd_get_info_submit(SCSIDevice *sdev, int lun,
 {
     struct mfi_pd_info *info = cmd->iov_buf;
     size_t dcmd_size = sizeof(struct mfi_pd_info);
-    BlockConf *conf = &sdev->conf;
     uint64_t pd_size;
     uint16_t sdev_id = ((sdev->id & 0xFF) >> 8) | (lun & 0xFF);
     uint8_t cmdbuf[6];
@@ -1037,7 +1037,7 @@ static int megasas_pd_get_info_submit(SCSIDevice *sdev, int lun,
     info->ref.v.device_id = cpu_to_le16(sdev_id);
     info->state.ddf.pd_type = cpu_to_le16(MFI_PD_DDF_TYPE_IN_VD|
                                           MFI_PD_DDF_TYPE_INTF_SAS);
-    bdrv_get_geometry(conf->bs, &pd_size);
+    blk_get_geometry(sdev->conf.blk, &pd_size);
     info->raw_size = cpu_to_le64(pd_size);
     info->non_coerced_size = cpu_to_le64(pd_size);
     info->coerced_size = cpu_to_le64(pd_size);
@@ -1100,13 +1100,12 @@ static int megasas_dcmd_ld_get_list(MegasasState *s, MegasasCmd *cmd)
     }
     QTAILQ_FOREACH(kid, &s->bus.qbus.children, sibling) {
         SCSIDevice *sdev = DO_UPCAST(SCSIDevice, qdev, kid->child);
-        BlockConf *conf = &sdev->conf;
 
         if (num_ld_disks >= max_ld_disks) {
             break;
         }
         /* Logical device size is in blocks */
-        bdrv_get_geometry(conf->bs, &ld_size);
+        blk_get_geometry(sdev->conf.blk, &ld_size);
         info.ld_list[num_ld_disks].ld.v.target_id = sdev->id;
         info.ld_list[num_ld_disks].ld.v.lun_id = sdev->lun;
         info.ld_list[num_ld_disks].state = MFI_LD_STATE_OPTIMAL;
@@ -1144,7 +1143,6 @@ static int megasas_ld_get_info_submit(SCSIDevice *sdev, int lun,
     uint8_t cdb[6];
     SCSIRequest *req;
     ssize_t len, resid;
-    BlockConf *conf = &sdev->conf;
     uint16_t sdev_id = ((sdev->id & 0xFF) >> 8) | (lun & 0xFF);
     uint64_t ld_size;
 
@@ -1177,7 +1175,7 @@ static int megasas_ld_get_info_submit(SCSIDevice *sdev, int lun,
     info->ld_config.params.num_drives = 1;
     info->ld_config.params.is_consistent = 1;
     /* Logical device size is in blocks */
-    bdrv_get_geometry(conf->bs, &ld_size);
+    blk_get_geometry(sdev->conf.blk, &ld_size);
     info->size = cpu_to_le64(ld_size);
     memset(info->ld_config.span, 0, sizeof(info->ld_config.span));
     info->ld_config.span[0].start_block = 0;
@@ -1261,7 +1259,6 @@ static int megasas_dcmd_cfg_read(MegasasState *s, MegasasCmd *cmd)
 
     QTAILQ_FOREACH(kid, &s->bus.qbus.children, sibling) {
         SCSIDevice *sdev = DO_UPCAST(SCSIDevice, qdev, kid->child);
-        BlockConf *conf = &sdev->conf;
         uint16_t sdev_id = ((sdev->id & 0xFF) >> 8) | (sdev->lun & 0xFF);
         struct mfi_array *array;
         struct mfi_ld_config *ld;
@@ -1269,7 +1266,7 @@ static int megasas_dcmd_cfg_read(MegasasState *s, MegasasCmd *cmd)
         int i;
 
         array = (struct mfi_array *)(data + array_offset);
-        bdrv_get_geometry(conf->bs, &pd_size);
+        blk_get_geometry(sdev->conf.blk, &pd_size);
         array->size = cpu_to_le64(pd_size);
         array->num_drives = 1;
         array->array_ref = cpu_to_le16(sdev_id);
@@ -1340,7 +1337,7 @@ static int megasas_dcmd_get_properties(MegasasState *s, MegasasCmd *cmd)
 
 static int megasas_cache_flush(MegasasState *s, MegasasCmd *cmd)
 {
-    bdrv_drain_all();
+    blk_drain_all();
     return MFI_STAT_OK;
 }
 
diff --git a/hw/scsi/scsi-bus.c b/hw/scsi/scsi-bus.c
index f5156ae..869d616 100644
--- a/hw/scsi/scsi-bus.c
+++ b/hw/scsi/scsi-bus.c
@@ -220,7 +220,7 @@ static void scsi_qdev_unrealize(DeviceState *qdev, Error **errp)
 }
 
 /* handle legacy '-drive if=scsi,...' cmd line args */
-SCSIDevice *scsi_bus_legacy_add_drive(SCSIBus *bus, BlockDriverState *bdrv,
+SCSIDevice *scsi_bus_legacy_add_drive(SCSIBus *bus, BlockBackend *blk,
                                       int unit, bool removable, int bootindex,
                                       const char *serial, Error **errp)
 {
@@ -228,7 +228,7 @@ SCSIDevice *scsi_bus_legacy_add_drive(SCSIBus *bus, BlockDriverState *bdrv,
     DeviceState *dev;
     Error *err = NULL;
 
-    driver = bdrv_is_sg(bdrv) ? "scsi-generic" : "scsi-disk";
+    driver = blk_is_sg(blk) ? "scsi-generic" : "scsi-disk";
     dev = qdev_create(&bus->qbus, driver);
     qdev_prop_set_uint32(dev, "scsi-id", unit);
     if (bootindex >= 0) {
@@ -240,7 +240,7 @@ SCSIDevice *scsi_bus_legacy_add_drive(SCSIBus *bus, BlockDriverState *bdrv,
     if (serial && object_property_find(OBJECT(dev), "serial", NULL)) {
         qdev_prop_set_string(dev, "serial", serial);
     }
-    if (qdev_prop_set_drive(dev, "drive", bdrv) < 0) {
+    if (qdev_prop_set_drive(dev, "drive", blk) < 0) {
         error_setg(errp, "Setting drive property failed");
         object_unparent(OBJECT(dev));
         return NULL;
@@ -268,7 +268,7 @@ void scsi_bus_legacy_handle_cmdline(SCSIBus *bus, Error **errp)
             continue;
         }
         qemu_opts_loc_restore(dinfo->opts);
-        scsi_bus_legacy_add_drive(bus, blk_bs(blk_by_legacy_dinfo(dinfo)),
+        scsi_bus_legacy_add_drive(bus, blk_by_legacy_dinfo(dinfo),
                                   unit, false, -1, NULL, &err);
         if (err != NULL) {
             error_report("%s", error_get_pretty(err));
diff --git a/hw/scsi/scsi-disk.c b/hw/scsi/scsi-disk.c
index e34a544..768c1ad 100644
--- a/hw/scsi/scsi-disk.c
+++ b/hw/scsi/scsi-disk.c
@@ -33,6 +33,7 @@ do { printf("scsi-disk: " fmt , ## __VA_ARGS__); } while (0)
 #include "hw/scsi/scsi.h"
 #include "block/scsi.h"
 #include "sysemu/sysemu.h"
+#include "sysemu/block-backend.h"
 #include "sysemu/blockdev.h"
 #include "hw/block/block.h"
 #include "sysemu/dma.h"
@@ -112,11 +113,11 @@ static void scsi_cancel_io(SCSIRequest *req)
 
     DPRINTF("Cancel tag=0x%x\n", req->tag);
     if (r->req.aiocb) {
-        bdrv_aio_cancel(r->req.aiocb);
+        blk_aio_cancel(r->req.aiocb);
 
         /* This reference was left in by scsi_*_data.  We take ownership of
          * it the moment scsi_req_cancel is called, independent of whether
-         * bdrv_aio_cancel completes the request or not.  */
+         * blk_aio_cancel completes the request or not.  */
         scsi_req_unref(&r->req);
     }
     r->req.aiocb = NULL;
@@ -128,7 +129,7 @@ static uint32_t scsi_init_iovec(SCSIDiskReq *r, size_t size)
 
     if (!r->iov.iov_base) {
         r->buflen = size;
-        r->iov.iov_base = qemu_blockalign(s->qdev.conf.bs, r->buflen);
+        r->iov.iov_base = blk_blockalign(s->qdev.conf.blk, r->buflen);
     }
     r->iov.iov_len = MIN(r->sector_count * 512, r->buflen);
     qemu_iovec_init_external(&r->qiov, &r->iov, 1);
@@ -183,7 +184,7 @@ static void scsi_aio_complete(void *opaque, int ret)
 
     assert(r->req.aiocb != NULL);
     r->req.aiocb = NULL;
-    bdrv_acct_done(s->qdev.conf.bs, &r->acct);
+    blk_acct_done(s->qdev.conf.blk, &r->acct);
     if (r->req.io_canceled) {
         goto done;
     }
@@ -237,8 +238,8 @@ static void scsi_write_do_fua(SCSIDiskReq *r)
     }
 
     if (scsi_is_cmd_fua(&r->req.cmd)) {
-        bdrv_acct_start(s->qdev.conf.bs, &r->acct, 0, BDRV_ACCT_FLUSH);
-        r->req.aiocb = bdrv_aio_flush(s->qdev.conf.bs, scsi_aio_complete, r);
+        blk_acct_start(s->qdev.conf.blk, &r->acct, 0, BDRV_ACCT_FLUSH);
+        r->req.aiocb = blk_aio_flush(s->qdev.conf.blk, scsi_aio_complete, r);
         return;
     }
 
@@ -257,7 +258,7 @@ static void scsi_dma_complete_noio(void *opaque, int ret)
 
     if (r->req.aiocb != NULL) {
         r->req.aiocb = NULL;
-        bdrv_acct_done(s->qdev.conf.bs, &r->acct);
+        blk_acct_done(s->qdev.conf.blk, &r->acct);
     }
     if (r->req.io_canceled) {
         goto done;
@@ -300,7 +301,7 @@ static void scsi_read_complete(void * opaque, int ret)
 
     assert(r->req.aiocb != NULL);
     r->req.aiocb = NULL;
-    bdrv_acct_done(s->qdev.conf.bs, &r->acct);
+    blk_acct_done(s->qdev.conf.blk, &r->acct);
     if (r->req.io_canceled) {
         goto done;
     }
@@ -333,7 +334,7 @@ static void scsi_do_read(void *opaque, int ret)
 
     if (r->req.aiocb != NULL) {
         r->req.aiocb = NULL;
-        bdrv_acct_done(s->qdev.conf.bs, &r->acct);
+        blk_acct_done(s->qdev.conf.blk, &r->acct);
     }
     if (r->req.io_canceled) {
         goto done;
@@ -349,15 +350,16 @@ static void scsi_do_read(void *opaque, int ret)
     scsi_req_ref(&r->req);
 
     if (r->req.sg) {
-        dma_acct_start(s->qdev.conf.bs, &r->acct, r->req.sg, BDRV_ACCT_READ);
+        dma_acct_start(s->qdev.conf.blk, &r->acct, r->req.sg, BDRV_ACCT_READ);
         r->req.resid -= r->req.sg->size;
-        r->req.aiocb = dma_bdrv_read(s->qdev.conf.bs, r->req.sg, r->sector,
-                                     scsi_dma_complete, r);
+        r->req.aiocb = dma_blk_read(s->qdev.conf.blk, r->req.sg, r->sector,
+                                    scsi_dma_complete, r);
     } else {
         n = scsi_init_iovec(r, SCSI_DMA_BUF_SIZE);
-        bdrv_acct_start(s->qdev.conf.bs, &r->acct, n * BDRV_SECTOR_SIZE, BDRV_ACCT_READ);
-        r->req.aiocb = bdrv_aio_readv(s->qdev.conf.bs, r->sector, &r->qiov, n,
-                                      scsi_read_complete, r);
+        blk_acct_start(s->qdev.conf.blk, &r->acct, n * BDRV_SECTOR_SIZE,
+                       BDRV_ACCT_READ);
+        r->req.aiocb = blk_aio_readv(s->qdev.conf.blk, r->sector, &r->qiov, n,
+                                     scsi_read_complete, r);
     }
 
 done:
@@ -399,8 +401,8 @@ static void scsi_read_data(SCSIRequest *req)
     first = !r->started;
     r->started = true;
     if (first && scsi_is_cmd_fua(&r->req.cmd)) {
-        bdrv_acct_start(s->qdev.conf.bs, &r->acct, 0, BDRV_ACCT_FLUSH);
-        r->req.aiocb = bdrv_aio_flush(s->qdev.conf.bs, scsi_do_read, r);
+        blk_acct_start(s->qdev.conf.blk, &r->acct, 0, BDRV_ACCT_FLUSH);
+        r->req.aiocb = blk_aio_flush(s->qdev.conf.blk, scsi_do_read, r);
     } else {
         scsi_do_read(r, 0);
     }
@@ -417,7 +419,8 @@ static int scsi_handle_rw_error(SCSIDiskReq *r, int error)
 {
     bool is_read = (r->req.cmd.xfer == SCSI_XFER_FROM_DEV);
     SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, r->req.dev);
-    BlockErrorAction action = bdrv_get_error_action(s->qdev.conf.bs, is_read, error);
+    BlockErrorAction action = blk_get_error_action(s->qdev.conf.blk,
+                                                   is_read, error);
 
     if (action == BLOCK_ERROR_ACTION_REPORT) {
         switch (error) {
@@ -438,7 +441,7 @@ static int scsi_handle_rw_error(SCSIDiskReq *r, int error)
             break;
         }
     }
-    bdrv_error_action(s->qdev.conf.bs, action, is_read, error);
+    blk_error_action(s->qdev.conf.blk, action, is_read, error);
     if (action == BLOCK_ERROR_ACTION_STOP) {
         scsi_req_retry(&r->req);
     }
@@ -453,7 +456,7 @@ static void scsi_write_complete(void * opaque, int ret)
 
     if (r->req.aiocb != NULL) {
         r->req.aiocb = NULL;
-        bdrv_acct_done(s->qdev.conf.bs, &r->acct);
+        blk_acct_done(s->qdev.conf.blk, &r->acct);
     }
     if (r->req.io_canceled) {
         goto done;
@@ -522,15 +525,16 @@ static void scsi_write_data(SCSIRequest *req)
     }
 
     if (r->req.sg) {
-        dma_acct_start(s->qdev.conf.bs, &r->acct, r->req.sg, BDRV_ACCT_WRITE);
+        dma_acct_start(s->qdev.conf.blk, &r->acct, r->req.sg, BDRV_ACCT_WRITE);
         r->req.resid -= r->req.sg->size;
-        r->req.aiocb = dma_bdrv_write(s->qdev.conf.bs, r->req.sg, r->sector,
-                                      scsi_dma_complete, r);
+        r->req.aiocb = dma_blk_write(s->qdev.conf.blk, r->req.sg, r->sector,
+                                     scsi_dma_complete, r);
     } else {
         n = r->qiov.size / 512;
-        bdrv_acct_start(s->qdev.conf.bs, &r->acct, n * BDRV_SECTOR_SIZE, BDRV_ACCT_WRITE);
-        r->req.aiocb = bdrv_aio_writev(s->qdev.conf.bs, r->sector, &r->qiov, n,
-                                       scsi_write_complete, r);
+        blk_acct_start(s->qdev.conf.blk, &r->acct, n * BDRV_SECTOR_SIZE,
+                       BDRV_ACCT_WRITE);
+        r->req.aiocb = blk_aio_writev(s->qdev.conf.blk, r->sector, &r->qiov, n,
+                                      scsi_write_complete, r);
     }
 }
 
@@ -597,7 +601,7 @@ static int scsi_disk_emulate_inquiry(SCSIRequest *req, uint8_t *outbuf)
 
         case 0x83: /* Device identification page, mandatory */
         {
-            const char *str = s->serial ?: bdrv_get_device_name(s->qdev.conf.bs);
+            const char *str = s->serial ?: blk_name(s->qdev.conf.blk);
             int max_len = s->serial ? 20 : 255 - 8;
             int id_len = strlen(str);
 
@@ -758,10 +762,10 @@ static inline bool media_is_dvd(SCSIDiskState *s)
     if (s->qdev.type != TYPE_ROM) {
         return false;
     }
-    if (!bdrv_is_inserted(s->qdev.conf.bs)) {
+    if (!blk_is_inserted(s->qdev.conf.blk)) {
         return false;
     }
-    bdrv_get_geometry(s->qdev.conf.bs, &nb_sectors);
+    blk_get_geometry(s->qdev.conf.blk, &nb_sectors);
     return nb_sectors > CD_MAX_SECTORS;
 }
 
@@ -771,10 +775,10 @@ static inline bool media_is_cd(SCSIDiskState *s)
     if (s->qdev.type != TYPE_ROM) {
         return false;
     }
-    if (!bdrv_is_inserted(s->qdev.conf.bs)) {
+    if (!blk_is_inserted(s->qdev.conf.blk)) {
         return false;
     }
-    bdrv_get_geometry(s->qdev.conf.bs, &nb_sectors);
+    blk_get_geometry(s->qdev.conf.blk, &nb_sectors);
     return nb_sectors <= CD_MAX_SECTORS;
 }
 
@@ -835,7 +839,7 @@ static int scsi_read_dvd_structure(SCSIDiskState *s, SCSIDiskReq *r,
     }
 
     if (format != 0xff) {
-        if (s->tray_open || !bdrv_is_inserted(s->qdev.conf.bs)) {
+        if (s->tray_open || !blk_is_inserted(s->qdev.conf.blk)) {
             scsi_check_condition(r, SENSE_CODE(NO_MEDIUM));
             return -1;
         }
@@ -857,7 +861,7 @@ static int scsi_read_dvd_structure(SCSIDiskState *s, SCSIDiskReq *r,
         if (layer != 0) {
             goto fail;
         }
-        bdrv_get_geometry(s->qdev.conf.bs, &nb_sectors);
+        blk_get_geometry(s->qdev.conf.blk, &nb_sectors);
 
         outbuf[4] = 1;   /* DVD-ROM, part version 1 */
         outbuf[5] = 0xf; /* 120mm disc, minimum rate unspecified */
@@ -912,7 +916,7 @@ static int scsi_event_status_media(SCSIDiskState *s, uint8_t *outbuf)
     media_status = 0;
     if (s->tray_open) {
         media_status = MS_TRAY_OPEN;
-    } else if (bdrv_is_inserted(s->qdev.conf.bs)) {
+    } else if (blk_is_inserted(s->qdev.conf.blk)) {
         media_status = MS_MEDIA_PRESENT;
     }
 
@@ -1110,7 +1114,7 @@ static int mode_sense_page(SCSIDiskState *s, int page, uint8_t **p_outbuf,
     case MODE_PAGE_CACHING:
         length = 0x12;
         if (page_control == 1 || /* Changeable Values */
-            bdrv_enable_write_cache(s->qdev.conf.bs)) {
+            blk_enable_write_cache(s->qdev.conf.blk)) {
             p[0] = 4; /* WCE */
         }
         break;
@@ -1191,7 +1195,7 @@ static int scsi_disk_emulate_mode_sense(SCSIDiskReq *r, uint8_t *outbuf)
 
     if (s->qdev.type == TYPE_DISK) {
         dev_specific_param = s->features & (1 << SCSI_DISK_F_DPOFUA) ? 0x10 : 0;
-        if (bdrv_is_read_only(s->qdev.conf.bs)) {
+        if (blk_is_read_only(s->qdev.conf.blk)) {
             dev_specific_param |= 0x80; /* Readonly.  */
         }
     } else {
@@ -1213,7 +1217,7 @@ static int scsi_disk_emulate_mode_sense(SCSIDiskReq *r, uint8_t *outbuf)
         p += 8;
     }
 
-    bdrv_get_geometry(s->qdev.conf.bs, &nb_sectors);
+    blk_get_geometry(s->qdev.conf.blk, &nb_sectors);
     if (!dbd && nb_sectors) {
         if (r->req.cmd.buf[0] == MODE_SENSE) {
             outbuf[3] = 8; /* Block descriptor length  */
@@ -1276,7 +1280,7 @@ static int scsi_disk_emulate_read_toc(SCSIRequest *req, uint8_t *outbuf)
     msf = req->cmd.buf[1] & 2;
     format = req->cmd.buf[2] & 0xf;
     start_track = req->cmd.buf[6];
-    bdrv_get_geometry(s->qdev.conf.bs, &nb_sectors);
+    blk_get_geometry(s->qdev.conf.blk, &nb_sectors);
     DPRINTF("Read TOC (track %d format %d msf %d)\n", start_track, format, msf >> 1);
     nb_sectors /= s->qdev.blocksize / 512;
     switch (format) {
@@ -1316,14 +1320,14 @@ static int scsi_disk_emulate_start_stop(SCSIDiskReq *r)
     if ((s->features & (1 << SCSI_DISK_F_REMOVABLE)) && loej) {
         if (!start && !s->tray_open && s->tray_locked) {
             scsi_check_condition(r,
-                                 bdrv_is_inserted(s->qdev.conf.bs)
+                                 blk_is_inserted(s->qdev.conf.blk)
                                  ? SENSE_CODE(ILLEGAL_REQ_REMOVAL_PREVENTED)
                                  : SENSE_CODE(NOT_READY_REMOVAL_PREVENTED));
             return -1;
         }
 
         if (s->tray_open != !start) {
-            bdrv_eject(s->qdev.conf.bs, !start);
+            blk_eject(s->qdev.conf.blk, !start);
             s->tray_open = !start;
         }
     }
@@ -1390,7 +1394,7 @@ static void scsi_disk_apply_mode_select(SCSIDiskState *s, int page, uint8_t *p)
 {
     switch (page) {
     case MODE_PAGE_CACHING:
-        bdrv_set_enable_write_cache(s->qdev.conf.bs, (p[0] & 4) != 0);
+        blk_set_enable_write_cache(s->qdev.conf.blk, (p[0] & 4) != 0);
         break;
 
     default:
@@ -1493,11 +1497,11 @@ static void scsi_disk_emulate_mode_select(SCSIDiskReq *r, uint8_t *inbuf)
             return;
         }
     }
-    if (!bdrv_enable_write_cache(s->qdev.conf.bs)) {
+    if (!blk_enable_write_cache(s->qdev.conf.blk)) {
         /* The request is used as the AIO opaque value, so add a ref.  */
         scsi_req_ref(&r->req);
-        bdrv_acct_start(s->qdev.conf.bs, &r->acct, 0, BDRV_ACCT_FLUSH);
-        r->req.aiocb = bdrv_aio_flush(s->qdev.conf.bs, scsi_aio_complete, r);
+        blk_acct_start(s->qdev.conf.blk, &r->acct, 0, BDRV_ACCT_FLUSH);
+        r->req.aiocb = blk_aio_flush(s->qdev.conf.blk, scsi_aio_complete, r);
         return;
     }
 
@@ -1565,10 +1569,10 @@ static void scsi_unmap_complete(void *opaque, int ret)
             goto done;
         }
 
-        r->req.aiocb = bdrv_aio_discard(s->qdev.conf.bs,
-                                        sector_num * (s->qdev.blocksize / 512),
-                                        nb_sectors * (s->qdev.blocksize / 512),
-                                        scsi_unmap_complete, data);
+        r->req.aiocb = blk_aio_discard(s->qdev.conf.blk,
+                                       sector_num * (s->qdev.blocksize / 512),
+                                       nb_sectors * (s->qdev.blocksize / 512),
+                                       scsi_unmap_complete, data);
         data->count--;
         data->inbuf += 16;
         return;
@@ -1608,7 +1612,7 @@ static void scsi_disk_emulate_unmap(SCSIDiskReq *r, uint8_t *inbuf)
         goto invalid_param_len;
     }
 
-    if (bdrv_is_read_only(s->qdev.conf.bs)) {
+    if (blk_is_read_only(s->qdev.conf.blk)) {
         scsi_check_condition(r, SENSE_CODE(WRITE_PROTECTED));
         return;
     }
@@ -1647,7 +1651,7 @@ static void scsi_write_same_complete(void *opaque, int ret)
 
     assert(r->req.aiocb != NULL);
     r->req.aiocb = NULL;
-    bdrv_acct_done(s->qdev.conf.bs, &r->acct);
+    blk_acct_done(s->qdev.conf.blk, &r->acct);
     if (r->req.io_canceled) {
         goto done;
     }
@@ -1662,10 +1666,11 @@ static void scsi_write_same_complete(void *opaque, int ret)
     data->sector += data->iov.iov_len / 512;
     data->iov.iov_len = MIN(data->nb_sectors * 512, data->iov.iov_len);
     if (data->iov.iov_len) {
-        bdrv_acct_start(s->qdev.conf.bs, &r->acct, data->iov.iov_len, BDRV_ACCT_WRITE);
-        r->req.aiocb = bdrv_aio_writev(s->qdev.conf.bs, data->sector,
-                                       &data->qiov, data->iov.iov_len / 512,
-                                       scsi_write_same_complete, data);
+        blk_acct_start(s->qdev.conf.blk, &r->acct, data->iov.iov_len,
+                       BDRV_ACCT_WRITE);
+        r->req.aiocb = blk_aio_writev(s->qdev.conf.blk, data->sector,
+                                      &data->qiov, data->iov.iov_len / 512,
+                                      scsi_write_same_complete, data);
         return;
     }
 
@@ -1694,7 +1699,7 @@ static void scsi_disk_emulate_write_same(SCSIDiskReq *r, uint8_t *inbuf)
         return;
     }
 
-    if (bdrv_is_read_only(s->qdev.conf.bs)) {
+    if (blk_is_read_only(s->qdev.conf.blk)) {
         scsi_check_condition(r, SENSE_CODE(WRITE_PROTECTED));
         return;
     }
@@ -1708,12 +1713,12 @@ static void scsi_disk_emulate_write_same(SCSIDiskReq *r, uint8_t *inbuf)
 
         /* The request is used as the AIO opaque value, so add a ref.  */
         scsi_req_ref(&r->req);
-        bdrv_acct_start(s->qdev.conf.bs, &r->acct, nb_sectors * s->qdev.blocksize,
-                        BDRV_ACCT_WRITE);
-        r->req.aiocb = bdrv_aio_write_zeroes(s->qdev.conf.bs,
-                                             r->req.cmd.lba * (s->qdev.blocksize / 512),
-                                             nb_sectors * (s->qdev.blocksize / 512),
-                                             flags, scsi_aio_complete, r);
+        blk_acct_start(s->qdev.conf.blk, &r->acct,
+                       nb_sectors * s->qdev.blocksize, BDRV_ACCT_WRITE);
+        r->req.aiocb = blk_aio_write_zeroes(s->qdev.conf.blk,
+                                r->req.cmd.lba * (s->qdev.blocksize / 512),
+                                nb_sectors * (s->qdev.blocksize / 512),
+                                flags, scsi_aio_complete, r);
         return;
     }
 
@@ -1722,7 +1727,8 @@ static void scsi_disk_emulate_write_same(SCSIDiskReq *r, uint8_t *inbuf)
     data->sector = r->req.cmd.lba * (s->qdev.blocksize / 512);
     data->nb_sectors = nb_sectors * (s->qdev.blocksize / 512);
     data->iov.iov_len = MIN(data->nb_sectors * 512, SCSI_WRITE_SAME_MAX);
-    data->iov.iov_base = buf = qemu_blockalign(s->qdev.conf.bs, data->iov.iov_len);
+    data->iov.iov_base = buf = blk_blockalign(s->qdev.conf.blk,
+                                              data->iov.iov_len);
     qemu_iovec_init_external(&data->qiov, &data->iov, 1);
 
     for (i = 0; i < data->iov.iov_len; i += s->qdev.blocksize) {
@@ -1730,10 +1736,11 @@ static void scsi_disk_emulate_write_same(SCSIDiskReq *r, uint8_t *inbuf)
     }
 
     scsi_req_ref(&r->req);
-    bdrv_acct_start(s->qdev.conf.bs, &r->acct, data->iov.iov_len, BDRV_ACCT_WRITE);
-    r->req.aiocb = bdrv_aio_writev(s->qdev.conf.bs, data->sector,
-                                   &data->qiov, data->iov.iov_len / 512,
-                                   scsi_write_same_complete, data);
+    blk_acct_start(s->qdev.conf.blk, &r->acct, data->iov.iov_len,
+                   BDRV_ACCT_WRITE);
+    r->req.aiocb = blk_aio_writev(s->qdev.conf.blk, data->sector,
+                                  &data->qiov, data->iov.iov_len / 512,
+                                  scsi_write_same_complete, data);
 }
 
 static void scsi_disk_emulate_write_data(SCSIRequest *req)
@@ -1802,7 +1809,7 @@ static int32_t scsi_disk_emulate_command(SCSIRequest *req, uint8_t *buf)
         break;
 
     default:
-        if (s->tray_open || !bdrv_is_inserted(s->qdev.conf.bs)) {
+        if (s->tray_open || !blk_is_inserted(s->qdev.conf.blk)) {
             scsi_check_condition(r, SENSE_CODE(NO_MEDIUM));
             return 0;
         }
@@ -1823,7 +1830,7 @@ static int32_t scsi_disk_emulate_command(SCSIRequest *req, uint8_t *buf)
     r->buflen = MAX(4096, req->cmd.xfer);
 
     if (!r->iov.iov_base) {
-        r->iov.iov_base = qemu_blockalign(s->qdev.conf.bs, r->buflen);
+        r->iov.iov_base = blk_blockalign(s->qdev.conf.blk, r->buflen);
     }
 
     buflen = req->cmd.xfer;
@@ -1831,7 +1838,7 @@ static int32_t scsi_disk_emulate_command(SCSIRequest *req, uint8_t *buf)
     memset(outbuf, 0, r->buflen);
     switch (req->cmd.buf[0]) {
     case TEST_UNIT_READY:
-        assert(!s->tray_open && bdrv_is_inserted(s->qdev.conf.bs));
+        assert(!s->tray_open && blk_is_inserted(s->qdev.conf.blk));
         break;
     case INQUIRY:
         buflen = scsi_disk_emulate_inquiry(req, outbuf);
@@ -1879,12 +1886,12 @@ static int32_t scsi_disk_emulate_command(SCSIRequest *req, uint8_t *buf)
         break;
     case ALLOW_MEDIUM_REMOVAL:
         s->tray_locked = req->cmd.buf[4] & 1;
-        bdrv_lock_medium(s->qdev.conf.bs, req->cmd.buf[4] & 1);
+        blk_lock_medium(s->qdev.conf.blk, req->cmd.buf[4] & 1);
         break;
     case READ_CAPACITY_10:
         /* The normal LEN field for this command is zero.  */
         memset(outbuf, 0, 8);
-        bdrv_get_geometry(s->qdev.conf.bs, &nb_sectors);
+        blk_get_geometry(s->qdev.conf.blk, &nb_sectors);
         if (!nb_sectors) {
             scsi_check_condition(r, SENSE_CODE(LUN_NOT_READY));
             return 0;
@@ -1953,7 +1960,7 @@ static int32_t scsi_disk_emulate_command(SCSIRequest *req, uint8_t *buf)
         if ((req->cmd.buf[1] & 31) == SAI_READ_CAPACITY_16) {
             DPRINTF("SAI READ CAPACITY(16)\n");
             memset(outbuf, 0, req->cmd.xfer);
-            bdrv_get_geometry(s->qdev.conf.bs, &nb_sectors);
+            blk_get_geometry(s->qdev.conf.blk, &nb_sectors);
             if (!nb_sectors) {
                 scsi_check_condition(r, SENSE_CODE(LUN_NOT_READY));
                 return 0;
@@ -1994,8 +2001,8 @@ static int32_t scsi_disk_emulate_command(SCSIRequest *req, uint8_t *buf)
     case SYNCHRONIZE_CACHE:
         /* The request is used as the AIO opaque value, so add a ref.  */
         scsi_req_ref(&r->req);
-        bdrv_acct_start(s->qdev.conf.bs, &r->acct, 0, BDRV_ACCT_FLUSH);
-        r->req.aiocb = bdrv_aio_flush(s->qdev.conf.bs, scsi_aio_complete, r);
+        blk_acct_start(s->qdev.conf.blk, &r->acct, 0, BDRV_ACCT_FLUSH);
+        r->req.aiocb = blk_aio_flush(s->qdev.conf.blk, scsi_aio_complete, r);
         return 0;
     case SEEK_10:
         DPRINTF("Seek(10) (sector %" PRId64 ")\n", r->req.cmd.lba);
@@ -2069,7 +2076,7 @@ static int32_t scsi_disk_dma_command(SCSIRequest *req, uint8_t *buf)
 
     command = buf[0];
 
-    if (s->tray_open || !bdrv_is_inserted(s->qdev.conf.bs)) {
+    if (s->tray_open || !blk_is_inserted(s->qdev.conf.blk)) {
         scsi_check_condition(r, SENSE_CODE(NO_MEDIUM));
         return 0;
     }
@@ -2097,7 +2104,7 @@ static int32_t scsi_disk_dma_command(SCSIRequest *req, uint8_t *buf)
     case WRITE_VERIFY_10:
     case WRITE_VERIFY_12:
     case WRITE_VERIFY_16:
-        if (bdrv_is_read_only(s->qdev.conf.bs)) {
+        if (blk_is_read_only(s->qdev.conf.blk)) {
             scsi_check_condition(r, SENSE_CODE(WRITE_PROTECTED));
             return 0;
         }
@@ -2140,7 +2147,7 @@ static void scsi_disk_reset(DeviceState *dev)
 
     scsi_device_purge_requests(&s->qdev, SENSE_CODE(RESET));
 
-    bdrv_get_geometry(s->qdev.conf.bs, &nb_sectors);
+    blk_get_geometry(s->qdev.conf.blk, &nb_sectors);
     nb_sectors /= s->qdev.blocksize / 512;
     if (nb_sectors) {
         nb_sectors--;
@@ -2156,7 +2163,7 @@ static void scsi_unrealize(SCSIDevice *dev, Error **errp)
     SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, dev);
 
     scsi_device_purge_requests(&s->qdev, SENSE_CODE(NO_SENSE));
-    blockdev_mark_auto_del(s->qdev.conf.bs);
+    blockdev_mark_auto_del(s->qdev.conf.blk);
 }
 
 static void scsi_disk_resize_cb(void *opaque)
@@ -2239,13 +2246,13 @@ static void scsi_realize(SCSIDevice *dev, Error **errp)
     SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, dev);
     Error *err = NULL;
 
-    if (!s->qdev.conf.bs) {
+    if (!s->qdev.conf.blk) {
         error_setg(errp, "drive property not set");
         return;
     }
 
     if (!(s->features & (1 << SCSI_DISK_F_REMOVABLE)) &&
-        !bdrv_is_inserted(s->qdev.conf.bs)) {
+        !blk_is_inserted(s->qdev.conf.blk)) {
         error_setg(errp, "Device needs media, but drive is empty");
         return;
     }
@@ -2271,20 +2278,20 @@ static void scsi_realize(SCSIDevice *dev, Error **errp)
         s->vendor = g_strdup("QEMU");
     }
 
-    if (bdrv_is_sg(s->qdev.conf.bs)) {
+    if (blk_is_sg(s->qdev.conf.blk)) {
         error_setg(errp, "unwanted /dev/sg*");
         return;
     }
 
     if ((s->features & (1 << SCSI_DISK_F_REMOVABLE)) &&
             !(s->features & (1 << SCSI_DISK_F_NO_REMOVABLE_DEVOPS))) {
-        bdrv_set_dev_ops(s->qdev.conf.bs, &scsi_disk_removable_block_ops, s);
+        blk_set_dev_ops(s->qdev.conf.blk, &scsi_disk_removable_block_ops, s);
     } else {
-        bdrv_set_dev_ops(s->qdev.conf.bs, &scsi_disk_block_ops, s);
+        blk_set_dev_ops(s->qdev.conf.blk, &scsi_disk_block_ops, s);
     }
-    bdrv_set_guest_block_size(s->qdev.conf.bs, s->qdev.blocksize);
+    blk_set_guest_block_size(s->qdev.conf.blk, s->qdev.blocksize);
 
-    bdrv_iostatus_enable(s->qdev.conf.bs);
+    blk_iostatus_enable(s->qdev.conf.blk);
     add_boot_device_path(s->qdev.conf.bootindex, &dev->qdev, NULL);
 }
 
@@ -2316,14 +2323,14 @@ static void scsi_disk_realize(SCSIDevice *dev, Error **errp)
     DriveInfo *dinfo;
     Error *local_err = NULL;
 
-    if (!dev->conf.bs) {
+    if (!dev->conf.blk) {
         scsi_realize(dev, &local_err);
         assert(local_err);
         error_propagate(errp, local_err);
         return;
     }
 
-    dinfo = drive_get_by_blockdev(dev->conf.bs);
+    dinfo = blk_legacy_dinfo(dev->conf.blk);
     if (dinfo->media_cd) {
         scsi_cd_realize(dev, errp);
     } else {
@@ -2425,7 +2432,6 @@ static SCSIRequest *scsi_new_request(SCSIDevice *d, uint32_t tag, uint32_t lun,
 #ifdef __linux__
 static int get_device_type(SCSIDiskState *s)
 {
-    BlockDriverState *bdrv = s->qdev.conf.bs;
     uint8_t cmd[16];
     uint8_t buf[36];
     uint8_t sensebuf[8];
@@ -2448,7 +2454,7 @@ static int get_device_type(SCSIDiskState *s)
     io_header.sbp = sensebuf;
     io_header.timeout = 6000; /* XXX */
 
-    ret = bdrv_ioctl(bdrv, SG_IO, &io_header);
+    ret = blk_ioctl(s->qdev.conf.blk, SG_IO, &io_header);
     if (ret < 0 || io_header.driver_status || io_header.host_status) {
         return -1;
     }
@@ -2465,13 +2471,13 @@ static void scsi_block_realize(SCSIDevice *dev, Error **errp)
     int sg_version;
     int rc;
 
-    if (!s->qdev.conf.bs) {
+    if (!s->qdev.conf.blk) {
         error_setg(errp, "drive property not set");
         return;
     }
 
     /* check we are using a driver managing SG_IO (version 3 and after) */
-    rc = bdrv_ioctl(s->qdev.conf.bs, SG_GET_VERSION_NUM, &sg_version);
+    rc = blk_ioctl(s->qdev.conf.blk, SG_GET_VERSION_NUM, &sg_version);
     if (rc < 0) {
         error_setg(errp, "cannot get SG_IO version number: %s.  "
                      "Is this a SCSI device?",
@@ -2530,7 +2536,7 @@ static bool scsi_block_is_passthrough(SCSIDiskState *s, uint8_t *buf)
          * ones (such as WRITE SAME or EXTENDED COPY, etc.).  So, without
          * O_DIRECT everything must go through SG_IO.
          */
-        if (!(bdrv_get_flags(s->qdev.conf.bs) & BDRV_O_NOCACHE)) {
+        if (!(blk_get_flags(s->qdev.conf.blk) & BDRV_O_NOCACHE)) {
             break;
         }
 
@@ -2679,7 +2685,7 @@ static const TypeInfo scsi_cd_info = {
 
 #ifdef __linux__
 static Property scsi_block_properties[] = {
-    DEFINE_PROP_DRIVE("drive", SCSIDiskState, qdev.conf.bs),
+    DEFINE_PROP_DRIVE("drive", SCSIDiskState, qdev.conf.blk),
     DEFINE_PROP_INT32("bootindex", SCSIDiskState, qdev.conf.bootindex, -1),
     DEFINE_PROP_END_OF_LIST(),
 };
diff --git a/hw/scsi/scsi-generic.c b/hw/scsi/scsi-generic.c
index 5301886..ff2f920 100644
--- a/hw/scsi/scsi-generic.c
+++ b/hw/scsi/scsi-generic.c
@@ -14,6 +14,7 @@
 #include "qemu-common.h"
 #include "qemu/error-report.h"
 #include "hw/scsi/scsi.h"
+#include "sysemu/block-backend.h"
 #include "sysemu/blockdev.h"
 
 #ifdef __linux__
@@ -145,17 +146,17 @@ static void scsi_cancel_io(SCSIRequest *req)
 
     DPRINTF("Cancel tag=0x%x\n", req->tag);
     if (r->req.aiocb) {
-        bdrv_aio_cancel(r->req.aiocb);
+        blk_aio_cancel(r->req.aiocb);
 
         /* This reference was left in by scsi_*_data.  We take ownership of
-         * it independent of whether bdrv_aio_cancel completes the request
+         * it independent of whether blk_aio_cancel completes the request
          * or not.  */
         scsi_req_unref(&r->req);
     }
     r->req.aiocb = NULL;
 }
 
-static int execute_command(BlockDriverState *bdrv,
+static int execute_command(BlockBackend *blk,
                            SCSIGenericReq *r, int direction,
                            BlockCompletionFunc *complete)
 {
@@ -171,7 +172,7 @@ static int execute_command(BlockDriverState *bdrv,
     r->io_header.usr_ptr = r;
     r->io_header.flags |= SG_FLAG_DIRECT_IO;
 
-    r->req.aiocb = bdrv_aio_ioctl(bdrv, SG_IO, &r->io_header, complete, r);
+    r->req.aiocb = blk_aio_ioctl(blk, SG_IO, &r->io_header, complete, r);
     if (r->req.aiocb == NULL) {
         return -EIO;
     }
@@ -208,7 +209,7 @@ static void scsi_read_complete(void * opaque, int ret)
             s->blocksize = ldl_be_p(&r->buf[8]);
             s->max_lba = ldq_be_p(&r->buf[0]);
         }
-        bdrv_set_guest_block_size(s->conf.bs, s->blocksize);
+        blk_set_guest_block_size(s->conf.blk, s->blocksize);
 
         scsi_req_data(&r->req, len);
         if (!r->req.io_canceled) {
@@ -233,7 +234,8 @@ static void scsi_read_data(SCSIRequest *req)
         return;
     }
 
-    ret = execute_command(s->conf.bs, r, SG_DXFER_FROM_DEV, scsi_read_complete);
+    ret = execute_command(s->conf.blk, r, SG_DXFER_FROM_DEV,
+                          scsi_read_complete);
     if (ret < 0) {
         scsi_command_complete(r, ret);
     }
@@ -278,7 +280,7 @@ static void scsi_write_data(SCSIRequest *req)
 
     /* The request is used as the AIO opaque value, so add a ref.  */
     scsi_req_ref(&r->req);
-    ret = execute_command(s->conf.bs, r, SG_DXFER_TO_DEV, scsi_write_complete);
+    ret = execute_command(s->conf.blk, r, SG_DXFER_TO_DEV, scsi_write_complete);
     if (ret < 0) {
         scsi_command_complete(r, ret);
     }
@@ -320,7 +322,8 @@ static int32_t scsi_send_command(SCSIRequest *req, uint8_t *cmd)
         r->buf = NULL;
         /* The request is used as the AIO opaque value, so add a ref.  */
         scsi_req_ref(&r->req);
-        ret = execute_command(s->conf.bs, r, SG_DXFER_NONE, scsi_command_complete);
+        ret = execute_command(s->conf.blk, r, SG_DXFER_NONE,
+                              scsi_command_complete);
         if (ret < 0) {
             scsi_command_complete(r, ret);
             return 0;
@@ -345,7 +348,7 @@ static int32_t scsi_send_command(SCSIRequest *req, uint8_t *cmd)
     }
 }
 
-static int get_stream_blocksize(BlockDriverState *bdrv)
+static int get_stream_blocksize(BlockBackend *blk)
 {
     uint8_t cmd[6];
     uint8_t buf[12];
@@ -369,7 +372,7 @@ static int get_stream_blocksize(BlockDriverState *bdrv)
     io_header.sbp = sensebuf;
     io_header.timeout = 6000; /* XXX */
 
-    ret = bdrv_ioctl(bdrv, SG_IO, &io_header);
+    ret = blk_ioctl(blk, SG_IO, &io_header);
     if (ret < 0 || io_header.driver_status || io_header.host_status) {
         return -1;
     }
@@ -386,7 +389,7 @@ static void scsi_generic_reset(DeviceState *dev)
 static void scsi_unrealize(SCSIDevice *s, Error **errp)
 {
     scsi_device_purge_requests(s, SENSE_CODE(NO_SENSE));
-    blockdev_mark_auto_del(s->conf.bs);
+    blockdev_mark_auto_del(s->conf.blk);
 }
 
 static void scsi_generic_realize(SCSIDevice *s, Error **errp)
@@ -395,22 +398,22 @@ static void scsi_generic_realize(SCSIDevice *s, Error **errp)
     int sg_version;
     struct sg_scsi_id scsiid;
 
-    if (!s->conf.bs) {
+    if (!s->conf.blk) {
         error_setg(errp, "drive property not set");
         return;
     }
 
-    if (bdrv_get_on_error(s->conf.bs, 0) != BLOCKDEV_ON_ERROR_ENOSPC) {
+    if (blk_get_on_error(s->conf.blk, 0) != BLOCKDEV_ON_ERROR_ENOSPC) {
         error_setg(errp, "Device doesn't support drive option werror");
         return;
     }
-    if (bdrv_get_on_error(s->conf.bs, 1) != BLOCKDEV_ON_ERROR_REPORT) {
+    if (blk_get_on_error(s->conf.blk, 1) != BLOCKDEV_ON_ERROR_REPORT) {
         error_setg(errp, "Device doesn't support drive option rerror");
         return;
     }
 
     /* check we are using a driver managing SG_IO (version 3 and after */
-    rc = bdrv_ioctl(s->conf.bs, SG_GET_VERSION_NUM, &sg_version);
+    rc = blk_ioctl(s->conf.blk, SG_GET_VERSION_NUM, &sg_version);
     if (rc < 0) {
         error_setg(errp, "cannot get SG_IO version number: %s.  "
                          "Is this a SCSI device?",
@@ -423,7 +426,7 @@ static void scsi_generic_realize(SCSIDevice *s, Error **errp)
     }
 
     /* get LUN of the /dev/sg? */
-    if (bdrv_ioctl(s->conf.bs, SG_GET_SCSI_ID, &scsiid)) {
+    if (blk_ioctl(s->conf.blk, SG_GET_SCSI_ID, &scsiid)) {
         error_setg(errp, "SG_GET_SCSI_ID ioctl failed");
         return;
     }
@@ -437,7 +440,7 @@ static void scsi_generic_realize(SCSIDevice *s, Error **errp)
 
     switch (s->type) {
     case TYPE_TAPE:
-        s->blocksize = get_stream_blocksize(s->conf.bs);
+        s->blocksize = get_stream_blocksize(s->conf.blk);
         if (s->blocksize == -1) {
             s->blocksize = 0;
         }
@@ -481,7 +484,7 @@ static SCSIRequest *scsi_new_request(SCSIDevice *d, uint32_t tag, uint32_t lun,
 }
 
 static Property scsi_generic_properties[] = {
-    DEFINE_PROP_DRIVE("drive", SCSIDevice, conf.bs),
+    DEFINE_PROP_DRIVE("drive", SCSIDevice, conf.blk),
     DEFINE_PROP_INT32("bootindex", SCSIDevice, conf.bootindex, -1),
     DEFINE_PROP_END_OF_LIST(),
 };
diff --git a/hw/sd/milkymist-memcard.c b/hw/sd/milkymist-memcard.c
index 501aa3a..9661eaf 100644
--- a/hw/sd/milkymist-memcard.c
+++ b/hw/sd/milkymist-memcard.c
@@ -253,16 +253,16 @@ static int milkymist_memcard_init(SysBusDevice *dev)
 {
     MilkymistMemcardState *s = MILKYMIST_MEMCARD(dev);
     DriveInfo *dinfo;
-    BlockDriverState *bs;
+    BlockBackend *blk;
 
     dinfo = drive_get_next(IF_SD);
-    bs = dinfo ? blk_bs(blk_by_legacy_dinfo(dinfo)) : NULL;
-    s->card = sd_init(bs, false);
+    blk = dinfo ? blk_by_legacy_dinfo(dinfo) : NULL;
+    s->card = sd_init(blk, false);
     if (s->card == NULL) {
         return -1;
     }
 
-    s->enabled = bs && bdrv_is_inserted(bs);
+    s->enabled = blk && blk_is_inserted(blk);
 
     memory_region_init_io(&s->regs_region, OBJECT(s), &memcard_mmio_ops, s,
             "milkymist-memcard", R_MAX * 4);
diff --git a/hw/sd/omap_mmc.c b/hw/sd/omap_mmc.c
index 6c92149..86c477d 100644
--- a/hw/sd/omap_mmc.c
+++ b/hw/sd/omap_mmc.c
@@ -574,7 +574,7 @@ static void omap_mmc_cover_cb(void *opaque, int line, int level)
 
 struct omap_mmc_s *omap_mmc_init(hwaddr base,
                 MemoryRegion *sysmem,
-                BlockDriverState *bd,
+                BlockBackend *blk,
                 qemu_irq irq, qemu_irq dma[], omap_clk clk)
 {
     struct omap_mmc_s *s = (struct omap_mmc_s *)
@@ -592,7 +592,7 @@ struct omap_mmc_s *omap_mmc_init(hwaddr base,
     memory_region_add_subregion(sysmem, base, &s->iomem);
 
     /* Instantiate the storage */
-    s->card = sd_init(bd, false);
+    s->card = sd_init(blk, false);
     if (s->card == NULL) {
         exit(1);
     }
@@ -601,7 +601,7 @@ struct omap_mmc_s *omap_mmc_init(hwaddr base,
 }
 
 struct omap_mmc_s *omap2_mmc_init(struct omap_target_agent_s *ta,
-                BlockDriverState *bd, qemu_irq irq, qemu_irq dma[],
+                BlockBackend *blk, qemu_irq irq, qemu_irq dma[],
                 omap_clk fclk, omap_clk iclk)
 {
     struct omap_mmc_s *s = (struct omap_mmc_s *)
@@ -620,7 +620,7 @@ struct omap_mmc_s *omap2_mmc_init(struct omap_target_agent_s *ta,
     omap_l4_attach(ta, 0, &s->iomem);
 
     /* Instantiate the storage */
-    s->card = sd_init(bd, false);
+    s->card = sd_init(blk, false);
     if (s->card == NULL) {
         exit(1);
     }
diff --git a/hw/sd/pl181.c b/hw/sd/pl181.c
index 0501d40..e704b6e 100644
--- a/hw/sd/pl181.c
+++ b/hw/sd/pl181.c
@@ -491,7 +491,7 @@ static int pl181_init(SysBusDevice *sbd)
     sysbus_init_irq(sbd, &s->irq[1]);
     qdev_init_gpio_out(dev, s->cardstatus, 2);
     dinfo = drive_get_next(IF_SD);
-    s->card = sd_init(dinfo ? blk_bs(blk_by_legacy_dinfo(dinfo)) : NULL, false);
+    s->card = sd_init(dinfo ? blk_by_legacy_dinfo(dinfo) : NULL, false);
     if (s->card == NULL) {
         return -1;
     }
diff --git a/hw/sd/pxa2xx_mmci.c b/hw/sd/pxa2xx_mmci.c
index b9d8b1a..ac3ab39 100644
--- a/hw/sd/pxa2xx_mmci.c
+++ b/hw/sd/pxa2xx_mmci.c
@@ -523,7 +523,7 @@ static int pxa2xx_mmci_load(QEMUFile *f, void *opaque, int version_id)
 
 PXA2xxMMCIState *pxa2xx_mmci_init(MemoryRegion *sysmem,
                 hwaddr base,
-                BlockDriverState *bd, qemu_irq irq,
+                BlockBackend *blk, qemu_irq irq,
                 qemu_irq rx_dma, qemu_irq tx_dma)
 {
     PXA2xxMMCIState *s;
@@ -538,7 +538,7 @@ PXA2xxMMCIState *pxa2xx_mmci_init(MemoryRegion *sysmem,
     memory_region_add_subregion(sysmem, base, &s->iomem);
 
     /* Instantiate the actual storage */
-    s->card = sd_init(bd, false);
+    s->card = sd_init(blk, false);
     if (s->card == NULL) {
         exit(1);
     }
diff --git a/hw/sd/sd.c b/hw/sd/sd.c
index 5efe8c1..f955265 100644
--- a/hw/sd/sd.c
+++ b/hw/sd/sd.c
@@ -30,7 +30,7 @@
  */
 
 #include "hw/hw.h"
-#include "block/block.h"
+#include "sysemu/block-backend.h"
 #include "hw/sd.h"
 #include "qemu/bitmap.h"
 
@@ -110,7 +110,7 @@ struct SDState {
     uint8_t data[512];
     qemu_irq readonly_cb;
     qemu_irq inserted_cb;
-    BlockDriverState *bdrv;
+    BlockBackend *blk;
     uint8_t *buf;
 
     bool enable;
@@ -389,13 +389,13 @@ static inline uint64_t sd_addr_to_wpnum(uint64_t addr)
     return addr >> (HWBLOCK_SHIFT + SECTOR_SHIFT + WPGROUP_SHIFT);
 }
 
-static void sd_reset(SDState *sd, BlockDriverState *bdrv)
+static void sd_reset(SDState *sd, BlockBackend *blk)
 {
     uint64_t size;
     uint64_t sect;
 
-    if (bdrv) {
-        bdrv_get_geometry(bdrv, &sect);
+    if (blk) {
+        blk_get_geometry(blk, &sect);
     } else {
         sect = 0;
     }
@@ -412,11 +412,11 @@ static void sd_reset(SDState *sd, BlockDriverState *bdrv)
     sd_set_cardstatus(sd);
     sd_set_sdstatus(sd);
 
-    sd->bdrv = bdrv;
+    sd->blk = blk;
 
     if (sd->wp_groups)
         g_free(sd->wp_groups);
-    sd->wp_switch = bdrv ? bdrv_is_read_only(bdrv) : false;
+    sd->wp_switch = blk ? blk_is_read_only(blk) : false;
     sd->wpgrps_size = sect;
     sd->wp_groups = bitmap_new(sd->wpgrps_size);
     memset(sd->function_group, 0, sizeof(sd->function_group));
@@ -432,9 +432,9 @@ static void sd_cardchange(void *opaque, bool load)
 {
     SDState *sd = opaque;
 
-    qemu_set_irq(sd->inserted_cb, bdrv_is_inserted(sd->bdrv));
-    if (bdrv_is_inserted(sd->bdrv)) {
-        sd_reset(sd, sd->bdrv);
+    qemu_set_irq(sd->inserted_cb, blk_is_inserted(sd->blk));
+    if (blk_is_inserted(sd->blk)) {
+        sd_reset(sd, sd->blk);
         qemu_set_irq(sd->readonly_cb, sd->wp_switch);
     }
 }
@@ -479,23 +479,23 @@ static const VMStateDescription sd_vmstate = {
    whether card should be in SSI or MMC/SD mode.  It is also up to the
    board to ensure that ssi transfers only occur when the chip select
    is asserted.  */
-SDState *sd_init(BlockDriverState *bs, bool is_spi)
+SDState *sd_init(BlockBackend *blk, bool is_spi)
 {
     SDState *sd;
 
-    if (bs && bdrv_is_read_only(bs)) {
+    if (blk && blk_is_read_only(blk)) {
         fprintf(stderr, "sd_init: Cannot use read-only drive\n");
         return NULL;
     }
 
     sd = (SDState *) g_malloc0(sizeof(SDState));
-    sd->buf = qemu_blockalign(bs, 512);
+    sd->buf = blk_blockalign(blk, 512);
     sd->spi = is_spi;
     sd->enable = true;
-    sd_reset(sd, bs);
-    if (sd->bdrv) {
-        bdrv_attach_dev_nofail(sd->bdrv, sd);
-        bdrv_set_dev_ops(sd->bdrv, &sd_block_ops, sd);
+    sd_reset(sd, blk);
+    if (sd->blk) {
+        blk_attach_dev_nofail(sd->blk, sd);
+        blk_set_dev_ops(sd->blk, &sd_block_ops, sd);
     }
     vmstate_register(NULL, -1, &sd_vmstate, sd);
     return sd;
@@ -505,8 +505,8 @@ void sd_set_cb(SDState *sd, qemu_irq readonly, qemu_irq insert)
 {
     sd->readonly_cb = readonly;
     sd->inserted_cb = insert;
-    qemu_set_irq(readonly, sd->bdrv ? bdrv_is_read_only(sd->bdrv) : 0);
-    qemu_set_irq(insert, sd->bdrv ? bdrv_is_inserted(sd->bdrv) : 0);
+    qemu_set_irq(readonly, sd->blk ? blk_is_read_only(sd->blk) : 0);
+    qemu_set_irq(insert, sd->blk ? blk_is_inserted(sd->blk) : 0);
 }
 
 static void sd_erase(SDState *sd)
@@ -680,7 +680,7 @@ static sd_rsp_type_t sd_normal_command(SDState *sd,
 
         default:
             sd->state = sd_idle_state;
-            sd_reset(sd, sd->bdrv);
+            sd_reset(sd, sd->blk);
             return sd->spi ? sd_r1 : sd_r0;
         }
         break;
@@ -1347,7 +1347,7 @@ int sd_do_command(SDState *sd, SDRequest *req,
     sd_rsp_type_t rtype;
     int rsplen;
 
-    if (!sd->bdrv || !bdrv_is_inserted(sd->bdrv) || !sd->enable) {
+    if (!sd->blk || !blk_is_inserted(sd->blk) || !sd->enable) {
         return 0;
     }
 
@@ -1456,7 +1456,7 @@ static void sd_blk_read(SDState *sd, uint64_t addr, uint32_t len)
 
     DPRINTF("sd_blk_read: addr = 0x%08llx, len = %d\n",
             (unsigned long long) addr, len);
-    if (!sd->bdrv || bdrv_read(sd->bdrv, addr >> 9, sd->buf, 1) < 0) {
+    if (!sd->blk || blk_read(sd->blk, addr >> 9, sd->buf, 1) < 0) {
         fprintf(stderr, "sd_blk_read: read error on host side\n");
         return;
     }
@@ -1464,7 +1464,7 @@ static void sd_blk_read(SDState *sd, uint64_t addr, uint32_t len)
     if (end > (addr & ~511) + 512) {
         memcpy(sd->data, sd->buf + (addr & 511), 512 - (addr & 511));
 
-        if (bdrv_read(sd->bdrv, end >> 9, sd->buf, 1) < 0) {
+        if (blk_read(sd->blk, end >> 9, sd->buf, 1) < 0) {
             fprintf(stderr, "sd_blk_read: read error on host side\n");
             return;
         }
@@ -1478,29 +1478,29 @@ static void sd_blk_write(SDState *sd, uint64_t addr, uint32_t len)
     uint64_t end = addr + len;
 
     if ((addr & 511) || len < 512)
-        if (!sd->bdrv || bdrv_read(sd->bdrv, addr >> 9, sd->buf, 1) < 0) {
+        if (!sd->blk || blk_read(sd->blk, addr >> 9, sd->buf, 1) < 0) {
             fprintf(stderr, "sd_blk_write: read error on host side\n");
             return;
         }
 
     if (end > (addr & ~511) + 512) {
         memcpy(sd->buf + (addr & 511), sd->data, 512 - (addr & 511));
-        if (bdrv_write(sd->bdrv, addr >> 9, sd->buf, 1) < 0) {
+        if (blk_write(sd->blk, addr >> 9, sd->buf, 1) < 0) {
             fprintf(stderr, "sd_blk_write: write error on host side\n");
             return;
         }
 
-        if (bdrv_read(sd->bdrv, end >> 9, sd->buf, 1) < 0) {
+        if (blk_read(sd->blk, end >> 9, sd->buf, 1) < 0) {
             fprintf(stderr, "sd_blk_write: read error on host side\n");
             return;
         }
         memcpy(sd->buf, sd->data + 512 - (addr & 511), end & 511);
-        if (bdrv_write(sd->bdrv, end >> 9, sd->buf, 1) < 0) {
+        if (blk_write(sd->blk, end >> 9, sd->buf, 1) < 0) {
             fprintf(stderr, "sd_blk_write: write error on host side\n");
         }
     } else {
         memcpy(sd->buf + (addr & 511), sd->data, len);
-        if (!sd->bdrv || bdrv_write(sd->bdrv, addr >> 9, sd->buf, 1) < 0) {
+        if (!sd->blk || blk_write(sd->blk, addr >> 9, sd->buf, 1) < 0) {
             fprintf(stderr, "sd_blk_write: write error on host side\n");
         }
     }
@@ -1515,7 +1515,7 @@ void sd_write_data(SDState *sd, uint8_t value)
 {
     int i;
 
-    if (!sd->bdrv || !bdrv_is_inserted(sd->bdrv) || !sd->enable)
+    if (!sd->blk || !blk_is_inserted(sd->blk) || !sd->enable)
         return;
 
     if (sd->state != sd_receivingdata_state) {
@@ -1641,7 +1641,7 @@ uint8_t sd_read_data(SDState *sd)
     uint8_t ret;
     int io_len;
 
-    if (!sd->bdrv || !bdrv_is_inserted(sd->bdrv) || !sd->enable)
+    if (!sd->blk || !blk_is_inserted(sd->blk) || !sd->enable)
         return 0x00;
 
     if (sd->state != sd_sendingdata_state) {
diff --git a/hw/sd/sdhci.c b/hw/sd/sdhci.c
index 0b7d754..b380050 100644
--- a/hw/sd/sdhci.c
+++ b/hw/sd/sdhci.c
@@ -1166,7 +1166,7 @@ static void sdhci_initfn(Object *obj)
     DriveInfo *di;
 
     di = drive_get_next(IF_SD);
-    s->card = sd_init(di ? blk_bs(blk_by_legacy_dinfo(di)) : NULL, false);
+    s->card = sd_init(di ? blk_by_legacy_dinfo(di) : NULL, false);
     if (s->card == NULL) {
         exit(1);
     }
diff --git a/hw/sd/ssi-sd.c b/hw/sd/ssi-sd.c
index 6ae99e4..a71fbca 100644
--- a/hw/sd/ssi-sd.c
+++ b/hw/sd/ssi-sd.c
@@ -256,7 +256,7 @@ static int ssi_sd_init(SSISlave *d)
 
     s->mode = SSI_SD_CMD;
     dinfo = drive_get_next(IF_SD);
-    s->sd = sd_init(dinfo ? blk_bs(blk_by_legacy_dinfo(dinfo)) : NULL, true);
+    s->sd = sd_init(dinfo ? blk_by_legacy_dinfo(dinfo) : NULL, true);
     if (s->sd == NULL) {
         return -1;
     }
diff --git a/hw/sh4/r2d.c b/hw/sh4/r2d.c
index d652619..890a8eb 100644
--- a/hw/sh4/r2d.c
+++ b/hw/sh4/r2d.c
@@ -37,7 +37,6 @@
 #include "hw/usb.h"
 #include "hw/block/flash.h"
 #include "sysemu/block-backend.h"
-#include "sysemu/blockdev.h"
 #include "exec/address-spaces.h"
 
 #define FLASH_BASE 0x00000000
@@ -291,7 +290,7 @@ static void r2d_init(MachineState *machine)
     /* onboard flash memory */
     dinfo = drive_get(IF_PFLASH, 0, 0);
     pflash_cfi02_register(0x0, NULL, "r2d.flash", FLASH_SIZE,
-                          dinfo ? blk_bs(blk_by_legacy_dinfo(dinfo)) : NULL,
+                          dinfo ? blk_by_legacy_dinfo(dinfo) : NULL,
                           (16 * 1024), FLASH_SIZE >> 16,
                           1, 4, 0x0000, 0x0000, 0x0000, 0x0000,
                           0x555, 0x2aa, 0);
diff --git a/hw/sparc/sun4m.c b/hw/sparc/sun4m.c
index 67e3663..b6bc916 100644
--- a/hw/sparc/sun4m.c
+++ b/hw/sparc/sun4m.c
@@ -40,7 +40,7 @@
 #include "hw/empty_slot.h"
 #include "hw/loader.h"
 #include "elf.h"
-#include "sysemu/blockdev.h"
+#include "sysemu/block-backend.h"
 #include "trace.h"
 
 /*
diff --git a/hw/sparc64/sun4u.c b/hw/sparc64/sun4u.c
index b9f3bee..6aa1bd4 100644
--- a/hw/sparc64/sun4u.c
+++ b/hw/sparc64/sun4u.c
@@ -38,7 +38,7 @@
 #include "hw/ide.h"
 #include "hw/loader.h"
 #include "elf.h"
-#include "sysemu/blockdev.h"
+#include "sysemu/block-backend.h"
 #include "exec/address-spaces.h"
 
 //#define DEBUG_IRQ
diff --git a/hw/tpm/tpm_tis.c b/hw/tpm/tpm_tis.c
index 82747ee..c0e7cd7 100644
--- a/hw/tpm/tpm_tis.c
+++ b/hw/tpm/tpm_tis.c
@@ -21,7 +21,7 @@
 
 #include "sysemu/tpm_backend.h"
 #include "tpm_int.h"
-#include "block/block.h"
+#include "sysemu/block-backend.h"
 #include "exec/address-spaces.h"
 #include "hw/hw.h"
 #include "hw/i386/pc.h"
diff --git a/hw/tricore/tricore_testboard.c b/hw/tricore/tricore_testboard.c
index f412e27..dde1f6f 100644
--- a/hw/tricore/tricore_testboard.c
+++ b/hw/tricore/tricore_testboard.c
@@ -24,7 +24,7 @@
 #include "sysemu/sysemu.h"
 #include "hw/boards.h"
 #include "hw/loader.h"
-#include "sysemu/blockdev.h"
+#include "sysemu/block-backend.h"
 #include "exec/address-spaces.h"
 #include "hw/block/flash.h"
 #include "elf.h"
diff --git a/hw/usb/dev-storage.c b/hw/usb/dev-storage.c
index 0d6e7c6..a2b4810 100644
--- a/hw/usb/dev-storage.c
+++ b/hw/usb/dev-storage.c
@@ -594,11 +594,11 @@ static const struct SCSIBusInfo usb_msd_scsi_info_bot = {
 static int usb_msd_initfn_storage(USBDevice *dev)
 {
     MSDState *s = DO_UPCAST(MSDState, dev, dev);
-    BlockDriverState *bs = s->conf.bs;
+    BlockBackend *blk = s->conf.blk;
     SCSIDevice *scsi_dev;
     Error *err = NULL;
 
-    if (!bs) {
+    if (!blk) {
         error_report("drive property not set");
         return -1;
     }
@@ -614,14 +614,14 @@ static int usb_msd_initfn_storage(USBDevice *dev)
      *
      * The hack is probably a bad idea.
      */
-    bdrv_detach_dev(bs, &s->dev.qdev);
-    s->conf.bs = NULL;
+    blk_detach_dev(blk, &s->dev.qdev);
+    s->conf.blk = NULL;
 
     usb_desc_create_serial(dev);
     usb_desc_init(dev);
     scsi_bus_new(&s->bus, sizeof(s->bus), DEVICE(dev),
                  &usb_msd_scsi_info_storage, NULL);
-    scsi_dev = scsi_bus_legacy_add_drive(&s->bus, bs, 0, !!s->removable,
+    scsi_dev = scsi_bus_legacy_add_drive(&s->bus, blk, 0, !!s->removable,
                                          s->conf.bootindex, dev->serial,
                                          &err);
     if (!scsi_dev) {
@@ -630,9 +630,10 @@ static int usb_msd_initfn_storage(USBDevice *dev)
     s->bus.qbus.allow_hotplug = 0;
     usb_msd_handle_reset(dev);
 
-    if (bdrv_key_required(bs)) {
+    if (bdrv_key_required(blk_bs(blk))) {
         if (cur_mon) {
-            monitor_read_bdrv_key_start(cur_mon, bs, usb_msd_password_cb, s);
+            monitor_read_bdrv_key_start(cur_mon, blk_bs(blk),
+                                        usb_msd_password_cb, s);
             s->dev.auto_attach = 0;
         } else {
             autostart = 0;
@@ -706,7 +707,7 @@ static USBDevice *usb_msd_init(USBBus *bus, const char *filename)
         return NULL;
     }
     if (qdev_prop_set_drive(&dev->qdev, "drive",
-                            blk_bs(blk_by_legacy_dinfo(dinfo))) < 0) {
+                            blk_by_legacy_dinfo(dinfo)) < 0) {
         object_unparent(OBJECT(dev));
         return NULL;
     }
diff --git a/hw/virtio/virtio-pci.c b/hw/virtio/virtio-pci.c
index ddb5da1..28ddc73 100644
--- a/hw/virtio/virtio-pci.c
+++ b/hw/virtio/virtio-pci.c
@@ -29,7 +29,7 @@
 #include "hw/pci/msix.h"
 #include "hw/loader.h"
 #include "sysemu/kvm.h"
-#include "sysemu/blockdev.h"
+#include "sysemu/block-backend.h"
 #include "virtio-pci.h"
 #include "qemu/range.h"
 #include "hw/virtio/virtio-bus.h"
diff --git a/hw/xen/xen_devconfig.c b/hw/xen/xen_devconfig.c
index fa998ef..e138dbb 100644
--- a/hw/xen/xen_devconfig.c
+++ b/hw/xen/xen_devconfig.c
@@ -1,4 +1,5 @@
 #include "hw/xen/xen_backend.h"
+#include "sysemu/block-backend.h"
 #include "sysemu/blockdev.h"
 
 /* ------------------------------------------------------------- */
diff --git a/hw/xenpv/xen_machine_pv.c b/hw/xenpv/xen_machine_pv.c
index 3150064..2e545d2 100644
--- a/hw/xenpv/xen_machine_pv.c
+++ b/hw/xenpv/xen_machine_pv.c
@@ -26,7 +26,7 @@
 #include "hw/boards.h"
 #include "hw/xen/xen_backend.h"
 #include "xen_domainbuild.h"
-#include "sysemu/blockdev.h"
+#include "sysemu/block-backend.h"
 
 static void xen_init_pv(MachineState *machine)
 {
diff --git a/hw/xtensa/xtfpga.c b/hw/xtensa/xtfpga.c
index 7c4719e..a11bf68 100644
--- a/hw/xtensa/xtfpga.c
+++ b/hw/xtensa/xtfpga.c
@@ -36,7 +36,6 @@
 #include "hw/sysbus.h"
 #include "hw/block/flash.h"
 #include "sysemu/block-backend.h"
-#include "sysemu/blockdev.h"
 #include "sysemu/char.h"
 #include "sysemu/device_tree.h"
 #include "qemu/error-report.h"
@@ -230,7 +229,7 @@ static void lx_init(const LxBoardDesc *board, MachineState *machine)
     if (dinfo) {
         flash = pflash_cfi01_register(board->flash_base,
                 NULL, "lx60.io.flash", board->flash_size,
-                blk_bs(blk_by_legacy_dinfo(dinfo)),
+                blk_by_legacy_dinfo(dinfo),
                 board->flash_sector_size,
                 board->flash_size / board->flash_sector_size,
                 4, 0x0000, 0x0000, 0x0000, 0x0000, be);
diff --git a/include/hw/arm/omap.h b/include/hw/arm/omap.h
index b9655ee..0ad5fb8 100644
--- a/include/hw/arm/omap.h
+++ b/include/hw/arm/omap.h
@@ -755,10 +755,10 @@ void omap_rfbi_attach(struct omap_dss_s *s, int cs, struct rfbi_chip_s *chip);
 struct omap_mmc_s;
 struct omap_mmc_s *omap_mmc_init(hwaddr base,
                 MemoryRegion *sysmem,
-                BlockDriverState *bd,
+                BlockBackend *blk,
                 qemu_irq irq, qemu_irq dma[], omap_clk clk);
 struct omap_mmc_s *omap2_mmc_init(struct omap_target_agent_s *ta,
-                BlockDriverState *bd, qemu_irq irq, qemu_irq dma[],
+                BlockBackend *blk, qemu_irq irq, qemu_irq dma[],
                 omap_clk fclk, omap_clk iclk);
 void omap_mmc_reset(struct omap_mmc_s *s);
 void omap_mmc_handlers(struct omap_mmc_s *s, qemu_irq ro, qemu_irq cover);
diff --git a/include/hw/arm/pxa.h b/include/hw/arm/pxa.h
index c507906..259b852 100644
--- a/include/hw/arm/pxa.h
+++ b/include/hw/arm/pxa.h
@@ -87,7 +87,7 @@ void pxa2xx_lcdc_oritentation(void *opaque, int angle);
 typedef struct PXA2xxMMCIState PXA2xxMMCIState;
 PXA2xxMMCIState *pxa2xx_mmci_init(MemoryRegion *sysmem,
                 hwaddr base,
-                BlockDriverState *bd, qemu_irq irq,
+                BlockBackend *blk, qemu_irq irq,
                 qemu_irq rx_dma, qemu_irq tx_dma);
 void pxa2xx_mmci_handlers(PXA2xxMMCIState *s, qemu_irq readonly,
                 qemu_irq coverswitch);
diff --git a/include/hw/block/block.h b/include/hw/block/block.h
index 3a01488..c128589 100644
--- a/include/hw/block/block.h
+++ b/include/hw/block/block.h
@@ -17,7 +17,7 @@
 /* Configuration */
 
 typedef struct BlockConf {
-    BlockDriverState *bs;
+    BlockBackend *blk;
     uint16_t physical_block_size;
     uint16_t logical_block_size;
     uint16_t min_io_size;
@@ -42,7 +42,7 @@ static inline unsigned int get_physical_block_exp(BlockConf *conf)
 }
 
 #define DEFINE_BLOCK_PROPERTIES(_state, _conf)                          \
-    DEFINE_PROP_DRIVE("drive", _state, _conf.bs),                       \
+    DEFINE_PROP_DRIVE("drive", _state, _conf.blk),                      \
     DEFINE_PROP_BLOCKSIZE("logical_block_size", _state,                 \
                           _conf.logical_block_size, 512),               \
     DEFINE_PROP_BLOCKSIZE("physical_block_size", _state,                \
@@ -67,7 +67,7 @@ void blkconf_geometry(BlockConf *conf, int *trans,
 
 /* Hard disk geometry */
 
-void hd_geometry_guess(BlockDriverState *bs,
+void hd_geometry_guess(BlockBackend *blk,
                        uint32_t *pcyls, uint32_t *pheads, uint32_t *psecs,
                        int *ptrans);
 int hd_bios_chs_auto_trans(uint32_t cyls, uint32_t heads, uint32_t secs);
diff --git a/include/hw/block/flash.h b/include/hw/block/flash.h
index 920d759..50ccbbc 100644
--- a/include/hw/block/flash.h
+++ b/include/hw/block/flash.h
@@ -11,7 +11,7 @@ typedef struct pflash_t pflash_t;
 pflash_t *pflash_cfi01_register(hwaddr base,
                                 DeviceState *qdev, const char *name,
                                 hwaddr size,
-                                BlockDriverState *bs,
+                                BlockBackend *blk,
                                 uint32_t sector_len, int nb_blocs, int width,
                                 uint16_t id0, uint16_t id1,
                                 uint16_t id2, uint16_t id3, int be);
@@ -20,7 +20,7 @@ pflash_t *pflash_cfi01_register(hwaddr base,
 pflash_t *pflash_cfi02_register(hwaddr base,
                                 DeviceState *qdev, const char *name,
                                 hwaddr size,
-                                BlockDriverState *bs, uint32_t sector_len,
+                                BlockBackend *blk, uint32_t sector_len,
                                 int nb_blocs, int nb_mappings, int width,
                                 uint16_t id0, uint16_t id1,
                                 uint16_t id2, uint16_t id3,
@@ -30,7 +30,7 @@ pflash_t *pflash_cfi02_register(hwaddr base,
 MemoryRegion *pflash_cfi01_get_memory(pflash_t *fl);
 
 /* nand.c */
-DeviceState *nand_init(BlockDriverState *bdrv, int manf_id, int chip_id);
+DeviceState *nand_init(BlockBackend *blk, int manf_id, int chip_id);
 void nand_setpins(DeviceState *dev, uint8_t cle, uint8_t ale,
                   uint8_t ce, uint8_t wp, uint8_t gnd);
 void nand_getpins(DeviceState *dev, int *rb);
diff --git a/include/hw/qdev-properties.h b/include/hw/qdev-properties.h
index 77fe3a1..e560647 100644
--- a/include/hw/qdev-properties.h
+++ b/include/hw/qdev-properties.h
@@ -141,7 +141,7 @@ extern PropertyInfo qdev_prop_arraylen;
 #define DEFINE_PROP_VLAN(_n, _s, _f)             \
     DEFINE_PROP(_n, _s, _f, qdev_prop_vlan, NICPeers)
 #define DEFINE_PROP_DRIVE(_n, _s, _f) \
-    DEFINE_PROP(_n, _s, _f, qdev_prop_drive, BlockDriverState *)
+    DEFINE_PROP(_n, _s, _f, qdev_prop_drive, BlockBackend *)
 #define DEFINE_PROP_MACADDR(_n, _s, _f)         \
     DEFINE_PROP(_n, _s, _f, qdev_prop_macaddr, MACAddr)
 #define DEFINE_PROP_LOSTTICKPOLICY(_n, _s, _f, _d) \
@@ -168,8 +168,10 @@ void qdev_prop_set_uint64(DeviceState *dev, const char *name, uint64_t value);
 void qdev_prop_set_string(DeviceState *dev, const char *name, const char *value);
 void qdev_prop_set_chr(DeviceState *dev, const char *name, CharDriverState *value);
 void qdev_prop_set_netdev(DeviceState *dev, const char *name, NetClientState *value);
-int qdev_prop_set_drive(DeviceState *dev, const char *name, BlockDriverState *value) QEMU_WARN_UNUSED_RESULT;
-void qdev_prop_set_drive_nofail(DeviceState *dev, const char *name, BlockDriverState *value);
+int qdev_prop_set_drive(DeviceState *dev, const char *name,
+                        BlockBackend *value) QEMU_WARN_UNUSED_RESULT;
+void qdev_prop_set_drive_nofail(DeviceState *dev, const char *name,
+                                BlockBackend *value);
 void qdev_prop_set_macaddr(DeviceState *dev, const char *name, uint8_t *value);
 void qdev_prop_set_enum(DeviceState *dev, const char *name, int value);
 /* FIXME: Remove opaque pointer properties.  */
diff --git a/include/hw/scsi/scsi.h b/include/hw/scsi/scsi.h
index e3e27cb..444e450 100644
--- a/include/hw/scsi/scsi.h
+++ b/include/hw/scsi/scsi.h
@@ -2,7 +2,7 @@
 #define QEMU_HW_SCSI_H
 
 #include "hw/qdev.h"
-#include "block/block.h"
+#include "qemu/typedefs.h"
 #include "hw/block/block.h"
 #include "sysemu/sysemu.h"
 
@@ -167,7 +167,7 @@ static inline SCSIBus *scsi_bus_from_device(SCSIDevice *d)
     return DO_UPCAST(SCSIBus, qbus, d->qdev.parent_bus);
 }
 
-SCSIDevice *scsi_bus_legacy_add_drive(SCSIBus *bus, BlockDriverState *bdrv,
+SCSIDevice *scsi_bus_legacy_add_drive(SCSIBus *bus, BlockBackend *blk,
                                       int unit, bool removable, int bootindex,
                                       const char *serial, Error **errp);
 void scsi_bus_legacy_handle_cmdline(SCSIBus *bus, Error **errp);
diff --git a/include/hw/sd.h b/include/hw/sd.h
index d9b97e4..79adb5b 100644
--- a/include/hw/sd.h
+++ b/include/hw/sd.h
@@ -68,7 +68,7 @@ typedef struct {
 
 typedef struct SDState SDState;
 
-SDState *sd_init(BlockDriverState *bs, bool is_spi);
+SDState *sd_init(BlockBackend *bs, bool is_spi);
 int sd_do_command(SDState *sd, SDRequest *req,
                   uint8_t *response);
 void sd_write_data(SDState *sd, uint8_t value);
diff --git a/include/hw/virtio/virtio-blk.h b/include/hw/virtio/virtio-blk.h
index b30237f..f1b46e7 100644
--- a/include/hw/virtio/virtio-blk.h
+++ b/include/hw/virtio/virtio-blk.h
@@ -17,7 +17,7 @@
 #include "hw/virtio/virtio.h"
 #include "hw/block/block.h"
 #include "sysemu/iothread.h"
-#include "block/block.h"
+#include "sysemu/block-backend.h"
 
 #define TYPE_VIRTIO_BLK "virtio-blk-device"
 #define VIRTIO_BLK(obj) \
@@ -120,7 +120,7 @@ struct VirtIOBlockDataPlane;
 struct VirtIOBlockReq;
 typedef struct VirtIOBlock {
     VirtIODevice parent_obj;
-    BlockDriverState *bs;
+    BlockBackend *blk;
     VirtQueue *vq;
     void *rq;
     QEMUBH *bh;
@@ -160,6 +160,6 @@ int virtio_blk_handle_scsi_req(VirtIOBlock *blk,
 
 void virtio_blk_handle_request(VirtIOBlockReq *req, MultiReqBuffer *mrb);
 
-void virtio_submit_multiwrite(BlockDriverState *bs, MultiReqBuffer *mrb);
+void virtio_submit_multiwrite(BlockBackend *blk, MultiReqBuffer *mrb);
 
 #endif
diff --git a/include/qemu/typedefs.h b/include/qemu/typedefs.h
index 198da2e..8b3f352 100644
--- a/include/qemu/typedefs.h
+++ b/include/qemu/typedefs.h
@@ -37,6 +37,7 @@ typedef struct HCIInfo HCIInfo;
 typedef struct AudioState AudioState;
 typedef struct BlockBackend BlockBackend;
 typedef struct BlockDriverState BlockDriverState;
+typedef struct BlockBackend BlockBackend;
 typedef struct DriveInfo DriveInfo;
 typedef struct DisplayState DisplayState;
 typedef struct DisplayChangeListener DisplayChangeListener;
diff --git a/include/sysemu/block-backend.h b/include/sysemu/block-backend.h
index fa8f623..ac7e65f 100644
--- a/include/sysemu/block-backend.h
+++ b/include/sysemu/block-backend.h
@@ -16,6 +16,15 @@
 #include "qemu/typedefs.h"
 #include "qapi/error.h"
 
+/*
+ * TODO Have to include block/block.h for a bunch of block layer
+ * types.  Unfortunately, this pulls in the whole BlockDriverState
+ * API, which we don't want used by many BlockBackend users.  Some of
+ * the types belong here, and the rest should be split into a common
+ * header and one for the BlockDriverState API.
+ */
+#include "block/block.h"
+
 BlockBackend *blk_new(const char *name, Error **errp);
 BlockBackend *blk_new_with_bs(const char *name, Error **errp);
 void blk_ref(BlockBackend *blk);
@@ -28,4 +37,72 @@ BlockDriverState *blk_bs(BlockBackend *blk);
 
 void blk_hide_on_behalf_of_do_drive_del(BlockBackend *blk);
 
+void blk_iostatus_enable(BlockBackend *blk);
+int blk_attach_dev(BlockBackend *blk, void *dev);
+void blk_attach_dev_nofail(BlockBackend *blk, void *dev);
+void blk_detach_dev(BlockBackend *blk, void *dev);
+void *blk_get_attached_dev(BlockBackend *blk);
+void blk_set_dev_ops(BlockBackend *blk, const BlockDevOps *ops, void *opaque);
+int blk_read(BlockBackend *blk, int64_t sector_num, uint8_t *buf,
+             int nb_sectors);
+int blk_read_unthrottled(BlockBackend *blk, int64_t sector_num, uint8_t *buf,
+                         int nb_sectors);
+int blk_write(BlockBackend *blk, int64_t sector_num, const uint8_t *buf,
+              int nb_sectors);
+BlockAIOCB *blk_aio_write_zeroes(BlockBackend *blk, int64_t sector_num,
+                                 int nb_sectors, BdrvRequestFlags flags,
+                                 BlockCompletionFunc *cb, void *opaque);
+int blk_pread(BlockBackend *blk, int64_t offset, void *buf, int count);
+int blk_pwrite(BlockBackend *blk, int64_t offset, const void *buf, int count);
+int64_t blk_getlength(BlockBackend *blk);
+void blk_get_geometry(BlockBackend *blk, uint64_t *nb_sectors_ptr);
+BlockAIOCB *blk_aio_readv(BlockBackend *blk, int64_t sector_num,
+                          QEMUIOVector *iov, int nb_sectors,
+                          BlockCompletionFunc *cb, void *opaque);
+BlockAIOCB *blk_aio_writev(BlockBackend *blk, int64_t sector_num,
+                           QEMUIOVector *iov, int nb_sectors,
+                           BlockCompletionFunc *cb, void *opaque);
+BlockAIOCB *blk_aio_flush(BlockBackend *blk,
+                          BlockCompletionFunc *cb, void *opaque);
+BlockAIOCB *blk_aio_discard(BlockBackend *blk,
+                            int64_t sector_num, int nb_sectors,
+                            BlockCompletionFunc *cb, void *opaque);
+void blk_aio_cancel(BlockAIOCB *acb);
+int blk_aio_multiwrite(BlockBackend *blk, BlockRequest *reqs, int num_reqs);
+int blk_ioctl(BlockBackend *blk, unsigned long int req, void *buf);
+BlockAIOCB *blk_aio_ioctl(BlockBackend *blk, unsigned long int req, void *buf,
+                          BlockCompletionFunc *cb, void *opaque);
+int blk_flush(BlockBackend *blk);
+int blk_flush_all(void);
+void blk_drain_all(void);
+BlockdevOnError blk_get_on_error(BlockBackend *blk, bool is_read);
+BlockErrorAction blk_get_error_action(BlockBackend *blk, bool is_read,
+                                      int error);
+void blk_error_action(BlockBackend *blk, BlockErrorAction action,
+                      bool is_read, int error);
+int blk_is_read_only(BlockBackend *blk);
+int blk_is_sg(BlockBackend *blk);
+int blk_enable_write_cache(BlockBackend *blk);
+void blk_set_enable_write_cache(BlockBackend *blk, bool wce);
+int blk_is_inserted(BlockBackend *blk);
+void blk_lock_medium(BlockBackend *blk, bool locked);
+void blk_eject(BlockBackend *blk, bool eject_flag);
+int blk_get_flags(BlockBackend *blk);
+void blk_set_guest_block_size(BlockBackend *blk, int align);
+void *blk_blockalign(BlockBackend *blk, size_t size);
+bool blk_op_is_blocked(BlockBackend *blk, BlockOpType op, Error **errp);
+void blk_op_unblock(BlockBackend *blk, BlockOpType op, Error *reason);
+void blk_op_block_all(BlockBackend *blk, Error *reason);
+void blk_op_unblock_all(BlockBackend *blk, Error *reason);
+void blk_acct_start(BlockBackend *blk, BlockAcctCookie *cookie,
+                    int64_t bytes, enum BlockAcctType type);
+void blk_acct_done(BlockBackend *blk, BlockAcctCookie *cookie);
+AioContext *blk_get_aio_context(BlockBackend *blk);
+void blk_set_aio_context(BlockBackend *blk, AioContext *new_context);
+void blk_io_plug(BlockBackend *blk);
+void blk_io_unplug(BlockBackend *blk);
+
+void *blk_aio_get(const AIOCBInfo *aiocb_info, BlockBackend *blk,
+                  BlockCompletionFunc *cb, void *opaque);
+
 #endif
diff --git a/include/sysemu/blockdev.h b/include/sysemu/blockdev.h
index 75f6ac6..f66b89a 100644
--- a/include/sysemu/blockdev.h
+++ b/include/sysemu/blockdev.h
@@ -14,8 +14,8 @@
 #include "qapi/error.h"
 #include "qemu/queue.h"
 
-void blockdev_mark_auto_del(BlockDriverState *bs);
-void blockdev_auto_del(BlockDriverState *bs);
+void blockdev_mark_auto_del(BlockBackend *blk);
+void blockdev_auto_del(BlockBackend *blk);
 
 typedef enum {
     IF_DEFAULT = -1,            /* for use with drive_add() only */
@@ -52,7 +52,6 @@ DriveInfo *drive_get(BlockInterfaceType type, int bus, int unit);
 DriveInfo *drive_get_by_index(BlockInterfaceType type, int index);
 int drive_get_max_bus(BlockInterfaceType type);
 DriveInfo *drive_get_next(BlockInterfaceType type);
-DriveInfo *drive_get_by_blockdev(BlockDriverState *bs);
 
 QemuOpts *drive_def(const char *optstr);
 QemuOpts *drive_add(BlockInterfaceType type, int index, const char *file,
diff --git a/include/sysemu/dma.h b/include/sysemu/dma.h
index 464f9f7..ca055d4 100644
--- a/include/sysemu/dma.h
+++ b/include/sysemu/dma.h
@@ -196,24 +196,24 @@ void qemu_sglist_add(QEMUSGList *qsg, dma_addr_t base, dma_addr_t len);
 void qemu_sglist_destroy(QEMUSGList *qsg);
 #endif
 
-typedef BlockAIOCB *DMAIOFunc(BlockDriverState *bs, int64_t sector_num,
-                              QEMUIOVector *iov, int nb_sectors,
-                              BlockCompletionFunc *cb, void *opaque);
+typedef BlockAIOCB *DMAIOFunc(BlockBackend *blk, int64_t sector_num,
+                                 QEMUIOVector *iov, int nb_sectors,
+                                 BlockCompletionFunc *cb, void *opaque);
 
-BlockAIOCB *dma_bdrv_io(BlockDriverState *bs,
-                        QEMUSGList *sg, uint64_t sector_num,
-                        DMAIOFunc *io_func, BlockCompletionFunc *cb,
-                        void *opaque, DMADirection dir);
-BlockAIOCB *dma_bdrv_read(BlockDriverState *bs,
+BlockAIOCB *dma_blk_io(BlockBackend *blk,
+                       QEMUSGList *sg, uint64_t sector_num,
+                       DMAIOFunc *io_func, BlockCompletionFunc *cb,
+                       void *opaque, DMADirection dir);
+BlockAIOCB *dma_blk_read(BlockBackend *blk,
+                         QEMUSGList *sg, uint64_t sector,
+                         BlockCompletionFunc *cb, void *opaque);
+BlockAIOCB *dma_blk_write(BlockBackend *blk,
                           QEMUSGList *sg, uint64_t sector,
                           BlockCompletionFunc *cb, void *opaque);
-BlockAIOCB *dma_bdrv_write(BlockDriverState *bs,
-                           QEMUSGList *sg, uint64_t sector,
-                           BlockCompletionFunc *cb, void *opaque);
 uint64_t dma_buf_read(uint8_t *ptr, int32_t len, QEMUSGList *sg);
 uint64_t dma_buf_write(uint8_t *ptr, int32_t len, QEMUSGList *sg);
 
-void dma_acct_start(BlockDriverState *bs, BlockAcctCookie *cookie,
+void dma_acct_start(BlockBackend *blk, BlockAcctCookie *cookie,
                     QEMUSGList *sg, enum BlockAcctType type);
 
 #endif
diff --git a/trace-events b/trace-events
index 03ac5d2..4891e77 100644
--- a/trace-events
+++ b/trace-events
@@ -196,8 +196,8 @@ fw_cfg_add_file_dupe(void *s, char *name) "%p %s"
 fw_cfg_add_file(void *s, int index, char *name, size_t len) "%p #%d: %s (%zd bytes)"
 
 # hw/block/hd-geometry.c
-hd_geometry_lchs_guess(void *bs, int cyls, int heads, int secs) "bs %p LCHS %d %d %d"
-hd_geometry_guess(void *bs, uint32_t cyls, uint32_t heads, uint32_t secs, int trans) "bs %p CHS %u %u %u trans %d"
+hd_geometry_lchs_guess(void *blk, int cyls, int heads, int secs) "blk %p LCHS %d %d %d"
+hd_geometry_guess(void *blk, uint32_t cyls, uint32_t heads, uint32_t secs, int trans) "blk %p CHS %u %u %u trans %d"
 
 # hw/display/jazz_led.c
 jazz_led_read(uint64_t addr, uint8_t val) "read addr=0x%"PRIx64": 0x%x"
@@ -1031,10 +1031,10 @@ win_helper_done(uint32_t tl) "tl=%d"
 win_helper_retry(uint32_t tl) "tl=%d"
 
 # dma-helpers.c
-dma_bdrv_io(void *dbs, void *bs, int64_t sector_num, bool to_dev) "dbs=%p bs=%p sector_num=%" PRId64 " to_dev=%d"
+dma_blk_io(void *dbs, void *bs, int64_t sector_num, bool to_dev) "dbs=%p bs=%p sector_num=%" PRId64 " to_dev=%d"
 dma_aio_cancel(void *dbs) "dbs=%p"
 dma_complete(void *dbs, int ret, void *cb) "dbs=%p ret=%d cb=%p"
-dma_bdrv_cb(void *dbs, int ret) "dbs=%p ret=%d"
+dma_blk_cb(void *dbs, int ret) "dbs=%p ret=%d"
 dma_map_wait(void *dbs) "dbs=%p"
 
 # ui/console.c
-- 
1.9.3

^ permalink raw reply related	[flat|nested] 56+ messages in thread

* [Qemu-devel] [PATCH v2 15/23] ide: Complete conversion from BlockDriverState to BlockBackend
  2014-09-13 15:00 [Qemu-devel] [PATCH v2 00/23] Split BlockBackend off BDS with an axe Markus Armbruster
                   ` (13 preceding siblings ...)
  2014-09-13 15:00 ` [Qemu-devel] [PATCH v2 14/23] hw: Convert from BlockDriverState to BlockBackend, mostly Markus Armbruster
@ 2014-09-13 15:00 ` Markus Armbruster
  2014-09-13 15:00 ` [Qemu-devel] [PATCH v2 16/23] pc87312: Drop unused members of PC87312State Markus Armbruster
                   ` (8 subsequent siblings)
  23 siblings, 0 replies; 56+ messages in thread
From: Markus Armbruster @ 2014-09-13 15:00 UTC (permalink / raw)
  To: qemu-devel; +Cc: kwolf, benoit.canet, stefanha

Add a BlockBackend member to TrimAIOCB, so ide_issue_trim_cb() can use
blk_aio_discard() instead of bdrv_aio_discard().

Signed-off-by: Markus Armbruster <armbru@redhat.com>
---
 hw/ide/core.c | 6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/hw/ide/core.c b/hw/ide/core.c
index fe12145..c043dbe 100644
--- a/hw/ide/core.c
+++ b/hw/ide/core.c
@@ -362,6 +362,7 @@ static void ide_set_signature(IDEState *s)
 
 typedef struct TrimAIOCB {
     BlockAIOCB common;
+    BlockBackend *blk;
     QEMUBH *bh;
     int ret;
     QEMUIOVector *qiov;
@@ -423,8 +424,8 @@ static void ide_issue_trim_cb(void *opaque, int ret)
                 }
 
                 /* Got an entry! Submit and exit.  */
-                iocb->aiocb = bdrv_aio_discard(iocb->common.bs, sector, count,
-                                               ide_issue_trim_cb, opaque);
+                iocb->aiocb = blk_aio_discard(iocb->blk, sector, count,
+                                              ide_issue_trim_cb, opaque);
                 return;
             }
 
@@ -448,6 +449,7 @@ BlockAIOCB *ide_issue_trim(BlockBackend *blk,
     TrimAIOCB *iocb;
 
     iocb = blk_aio_get(&trim_aiocb_info, blk, cb, opaque);
+    iocb->blk = blk;
     iocb->bh = qemu_bh_new(ide_trim_bh_cb, iocb);
     iocb->ret = 0;
     iocb->qiov = qiov;
-- 
1.9.3

^ permalink raw reply related	[flat|nested] 56+ messages in thread

* [Qemu-devel] [PATCH v2 16/23] pc87312: Drop unused members of PC87312State
  2014-09-13 15:00 [Qemu-devel] [PATCH v2 00/23] Split BlockBackend off BDS with an axe Markus Armbruster
                   ` (14 preceding siblings ...)
  2014-09-13 15:00 ` [Qemu-devel] [PATCH v2 15/23] ide: Complete conversion from BlockDriverState to BlockBackend Markus Armbruster
@ 2014-09-13 15:00 ` Markus Armbruster
  2014-09-13 15:00 ` [Qemu-devel] [PATCH v2 17/23] blockdev: Drop superfluous DriveInfo member id Markus Armbruster
                   ` (7 subsequent siblings)
  23 siblings, 0 replies; 56+ messages in thread
From: Markus Armbruster @ 2014-09-13 15:00 UTC (permalink / raw)
  To: qemu-devel; +Cc: kwolf, benoit.canet, stefanha

Signed-off-by: Markus Armbruster <armbru@redhat.com>
---
 include/hw/isa/pc87312.h | 3 ---
 1 file changed, 3 deletions(-)

diff --git a/include/hw/isa/pc87312.h b/include/hw/isa/pc87312.h
index befc8bd..bf74470 100644
--- a/include/hw/isa/pc87312.h
+++ b/include/hw/isa/pc87312.h
@@ -47,13 +47,10 @@ typedef struct PC87312State {
 
     struct {
         ISADevice *dev;
-        BlockDriverState *drive[2];
-        uint32_t base;
     } fdc;
 
     struct {
         ISADevice *dev;
-        uint32_t base;
     } ide;
 
     MemoryRegion io;
-- 
1.9.3

^ permalink raw reply related	[flat|nested] 56+ messages in thread

* [Qemu-devel] [PATCH v2 17/23] blockdev: Drop superfluous DriveInfo member id
  2014-09-13 15:00 [Qemu-devel] [PATCH v2 00/23] Split BlockBackend off BDS with an axe Markus Armbruster
                   ` (15 preceding siblings ...)
  2014-09-13 15:00 ` [Qemu-devel] [PATCH v2 16/23] pc87312: Drop unused members of PC87312State Markus Armbruster
@ 2014-09-13 15:00 ` Markus Armbruster
  2014-09-13 15:00 ` [Qemu-devel] [PATCH v2 18/23] blockdev: Fix blockdev-add not to create IDE drive (0, 0) Markus Armbruster
                   ` (6 subsequent siblings)
  23 siblings, 0 replies; 56+ messages in thread
From: Markus Armbruster @ 2014-09-13 15:00 UTC (permalink / raw)
  To: qemu-devel; +Cc: kwolf, benoit.canet, stefanha

Signed-off-by: Markus Armbruster <armbru@redhat.com>
---
 block/block-backend.c     | 1 -
 blockdev.c                | 3 +--
 include/sysemu/blockdev.h | 1 -
 3 files changed, 1 insertion(+), 4 deletions(-)

diff --git a/block/block-backend.c b/block/block-backend.c
index 472b545..9b146c8 100644
--- a/block/block-backend.c
+++ b/block/block-backend.c
@@ -103,7 +103,6 @@ static void drive_info_del(DriveInfo *dinfo)
     if (dinfo->opts) {
         qemu_opts_del(dinfo->opts);
     }
-    g_free(dinfo->id);
     g_free(dinfo->serial);
     g_free(dinfo);
 }
diff --git a/blockdev.c b/blockdev.c
index e87bf4b..2def256 100644
--- a/blockdev.c
+++ b/blockdev.c
@@ -458,7 +458,6 @@ static BlockBackend *blockdev_init(const char *file, QDict *bs_opts,
     }
 
     dinfo = g_malloc0(sizeof(*dinfo));
-    dinfo->id = g_strdup(qemu_opts_id(opts));
     blk_set_legacy_dinfo(blk, dinfo);
 
     if (!file || !*file) {
@@ -492,7 +491,7 @@ static BlockBackend *blockdev_init(const char *file, QDict *bs_opts,
 
     if (ret < 0) {
         error_setg(errp, "could not open disk image %s: %s",
-                   file ?: dinfo->id, error_get_pretty(error));
+                   file ?: blk_name(blk), error_get_pretty(error));
         error_free(error);
         goto err;
     }
diff --git a/include/sysemu/blockdev.h b/include/sysemu/blockdev.h
index f66b89a..27a40d5 100644
--- a/include/sysemu/blockdev.h
+++ b/include/sysemu/blockdev.h
@@ -30,7 +30,6 @@ typedef enum {
 } BlockInterfaceType;
 
 struct DriveInfo {
-    char *id;
     const char *devaddr;
     BlockInterfaceType type;
     int bus;
-- 
1.9.3

^ permalink raw reply related	[flat|nested] 56+ messages in thread

* [Qemu-devel] [PATCH v2 18/23] blockdev: Fix blockdev-add not to create IDE drive (0, 0)
  2014-09-13 15:00 [Qemu-devel] [PATCH v2 00/23] Split BlockBackend off BDS with an axe Markus Armbruster
                   ` (16 preceding siblings ...)
  2014-09-13 15:00 ` [Qemu-devel] [PATCH v2 17/23] blockdev: Drop superfluous DriveInfo member id Markus Armbruster
@ 2014-09-13 15:00 ` Markus Armbruster
  2014-09-13 15:00 ` [Qemu-devel] [PATCH v2 19/23] blockdev: Drop DriveInfo member enable_auto_del Markus Armbruster
                   ` (5 subsequent siblings)
  23 siblings, 0 replies; 56+ messages in thread
From: Markus Armbruster @ 2014-09-13 15:00 UTC (permalink / raw)
  To: qemu-devel; +Cc: kwolf, benoit.canet, stefanha

blockdev_init() always creates a DriveInfo, but only drive_new() fills
it in.  qmp_blockdev_add() leaves it blank.  This results in a drive
with type = IF_IDE, bus = 0, unit = 0.  Screwed up in commit ee13ed1c.

Board initialization code looking for IDE drive (0,0) can pick up one
of these bogus drives.  Not sure whether getting the QMP command
executed early enough is likely in practice, though.

Fix by creating DriveInfo in drive_new().  Block backends created by
blockdev-add don't get one.

A few places assume a block backend always has a DriveInfo.  Fix them
up.

Signed-off-by: Markus Armbruster <armbru@redhat.com>
---
 block/block-backend.c |  4 +---
 blockdev.c            | 10 ++--------
 hw/block/block.c      | 16 ++++++++++------
 hw/ide/qdev.c         |  2 +-
 hw/scsi/scsi-disk.c   |  2 +-
 5 files changed, 15 insertions(+), 19 deletions(-)

diff --git a/block/block-backend.c b/block/block-backend.c
index 9b146c8..ac3d774 100644
--- a/block/block-backend.c
+++ b/block/block-backend.c
@@ -100,9 +100,7 @@ static void drive_info_del(DriveInfo *dinfo)
     if (!dinfo) {
         return;
     }
-    if (dinfo->opts) {
-        qemu_opts_del(dinfo->opts);
-    }
+    qemu_opts_del(dinfo->opts);
     g_free(dinfo->serial);
     g_free(dinfo);
 }
diff --git a/blockdev.c b/blockdev.c
index 2def256..0d99be0 100644
--- a/blockdev.c
+++ b/blockdev.c
@@ -285,7 +285,6 @@ static BlockBackend *blockdev_init(const char *file, QDict *bs_opts,
     int on_read_error, on_write_error;
     BlockBackend *blk;
     BlockDriverState *bs;
-    DriveInfo *dinfo;
     ThrottleConfig cfg;
     int snapshot = 0;
     bool copy_on_read;
@@ -457,9 +456,6 @@ static BlockBackend *blockdev_init(const char *file, QDict *bs_opts,
         bdrv_set_io_limits(bs, &cfg);
     }
 
-    dinfo = g_malloc0(sizeof(*dinfo));
-    blk_set_legacy_dinfo(blk, dinfo);
-
     if (!file || !*file) {
         if (has_driver_specific_opts) {
             file = NULL;
@@ -903,21 +899,19 @@ DriveInfo *drive_new(QemuOpts *all_opts, BlockInterfaceType block_default_type)
     }
 
     /* Set legacy DriveInfo fields */
-    dinfo = blk_legacy_dinfo(blk);
+    dinfo = g_malloc0(sizeof(*dinfo));
     dinfo->enable_auto_del = true;
     dinfo->opts = all_opts;
-
     dinfo->cyls = cyls;
     dinfo->heads = heads;
     dinfo->secs = secs;
     dinfo->trans = translation;
-
     dinfo->type = type;
     dinfo->bus = bus_id;
     dinfo->unit = unit_id;
     dinfo->devaddr = devaddr;
-
     dinfo->serial = g_strdup(serial);
+    blk_set_legacy_dinfo(blk, dinfo);
 
     switch(type) {
     case IF_IDE:
diff --git a/hw/block/block.c b/hw/block/block.c
index 0666dd3..a625773 100644
--- a/hw/block/block.c
+++ b/hw/block/block.c
@@ -19,7 +19,9 @@ void blkconf_serial(BlockConf *conf, char **serial)
     if (!*serial) {
         /* try to fall back to value set with legacy -drive serial=... */
         dinfo = blk_legacy_dinfo(conf->blk);
-        *serial = g_strdup(dinfo->serial);
+        if (dinfo) {
+            *serial = g_strdup(dinfo->serial);
+        }
     }
 }
 
@@ -32,11 +34,13 @@ void blkconf_geometry(BlockConf *conf, int *ptrans,
     if (!conf->cyls && !conf->heads && !conf->secs) {
         /* try to fall back to value set with legacy -drive cyls=... */
         dinfo = blk_legacy_dinfo(conf->blk);
-        conf->cyls  = dinfo->cyls;
-        conf->heads = dinfo->heads;
-        conf->secs  = dinfo->secs;
-        if (ptrans) {
-            *ptrans = dinfo->trans;
+        if (dinfo) {
+            conf->cyls  = dinfo->cyls;
+            conf->heads = dinfo->heads;
+            conf->secs  = dinfo->secs;
+            if (ptrans) {
+                *ptrans = dinfo->trans;
+            }
         }
     }
     if (!conf->cyls && !conf->heads && !conf->secs) {
diff --git a/hw/ide/qdev.c b/hw/ide/qdev.c
index 4818334..a74c81e 100644
--- a/hw/ide/qdev.c
+++ b/hw/ide/qdev.c
@@ -206,7 +206,7 @@ static int ide_drive_initfn(IDEDevice *dev)
 {
     DriveInfo *dinfo = blk_legacy_dinfo(dev->conf.blk);
 
-    return ide_dev_initfn(dev, dinfo->media_cd ? IDE_CD : IDE_HD);
+    return ide_dev_initfn(dev, dinfo && dinfo->media_cd ? IDE_CD : IDE_HD);
 }
 
 #define DEFINE_IDE_DEV_PROPERTIES()                     \
diff --git a/hw/scsi/scsi-disk.c b/hw/scsi/scsi-disk.c
index 768c1ad..e0c5ed3 100644
--- a/hw/scsi/scsi-disk.c
+++ b/hw/scsi/scsi-disk.c
@@ -2331,7 +2331,7 @@ static void scsi_disk_realize(SCSIDevice *dev, Error **errp)
     }
 
     dinfo = blk_legacy_dinfo(dev->conf.blk);
-    if (dinfo->media_cd) {
+    if (dinfo && dinfo->media_cd) {
         scsi_cd_realize(dev, errp);
     } else {
         scsi_hd_realize(dev, errp);
-- 
1.9.3

^ permalink raw reply related	[flat|nested] 56+ messages in thread

* [Qemu-devel] [PATCH v2 19/23] blockdev: Drop DriveInfo member enable_auto_del
  2014-09-13 15:00 [Qemu-devel] [PATCH v2 00/23] Split BlockBackend off BDS with an axe Markus Armbruster
                   ` (17 preceding siblings ...)
  2014-09-13 15:00 ` [Qemu-devel] [PATCH v2 18/23] blockdev: Fix blockdev-add not to create IDE drive (0, 0) Markus Armbruster
@ 2014-09-13 15:00 ` Markus Armbruster
  2014-09-15  7:30   ` Fam Zheng
  2014-09-13 15:00 ` [Qemu-devel] [PATCH v2 20/23] block/qapi: Convert qmp_query_block() to BlockBackend Markus Armbruster
                   ` (4 subsequent siblings)
  23 siblings, 1 reply; 56+ messages in thread
From: Markus Armbruster @ 2014-09-13 15:00 UTC (permalink / raw)
  To: qemu-devel; +Cc: kwolf, benoit.canet, stefanha

Commit 2d246f0 introduced DriveInfo member enable_auto_del to
distinguish DriveInfo created via drive_new() from DriveInfo created
via qmp_blockdev_add().  The latter no longer exist.  Drop
enable_auto_del.

Signed-off-by: Markus Armbruster <armbru@redhat.com>
---
 blockdev.c                | 11 +++--------
 include/sysemu/blockdev.h |  1 -
 2 files changed, 3 insertions(+), 9 deletions(-)

diff --git a/blockdev.c b/blockdev.c
index 0d99be0..e218c59 100644
--- a/blockdev.c
+++ b/blockdev.c
@@ -90,16 +90,14 @@ void blockdev_mark_auto_del(BlockBackend *blk)
     DriveInfo *dinfo = blk_legacy_dinfo(blk);
     BlockDriverState *bs = blk_bs(blk);
 
-    if (dinfo && !dinfo->enable_auto_del) {
+    if (!dinfo) {
         return;
     }
 
     if (bs->job) {
         block_job_cancel(bs->job);
     }
-    if (dinfo) {
-        dinfo->auto_del = 1;
-    }
+    dinfo->auto_del = 1;
 }
 
 void blockdev_auto_del(BlockBackend *blk)
@@ -900,7 +898,6 @@ DriveInfo *drive_new(QemuOpts *all_opts, BlockInterfaceType block_default_type)
 
     /* Set legacy DriveInfo fields */
     dinfo = g_malloc0(sizeof(*dinfo));
-    dinfo->enable_auto_del = true;
     dinfo->opts = all_opts;
     dinfo->cyls = cyls;
     dinfo->heads = heads;
@@ -1716,7 +1713,6 @@ int do_drive_del(Monitor *mon, const QDict *qdict, QObject **ret_data)
     const char *id = qdict_get_str(qdict, "id");
     BlockBackend *blk;
     BlockDriverState *bs;
-    DriveInfo *dinfo;
     AioContext *aio_context;
     Error *local_err = NULL;
 
@@ -1727,8 +1723,7 @@ int do_drive_del(Monitor *mon, const QDict *qdict, QObject **ret_data)
     }
     bs = blk_bs(blk);
 
-    dinfo = blk_legacy_dinfo(blk);
-    if (dinfo && !dinfo->enable_auto_del) {
+    if (!blk_legacy_dinfo(blk)) {
         error_report("Deleting device added with blockdev-add"
                      " is not supported");
         return -1;
diff --git a/include/sysemu/blockdev.h b/include/sysemu/blockdev.h
index 27a40d5..2129d81 100644
--- a/include/sysemu/blockdev.h
+++ b/include/sysemu/blockdev.h
@@ -35,7 +35,6 @@ struct DriveInfo {
     int bus;
     int unit;
     int auto_del;               /* see blockdev_mark_auto_del() */
-    bool enable_auto_del;       /* Only for legacy drive_new() */
     int media_cd;
     int cyls, heads, secs, trans;
     QemuOpts *opts;
-- 
1.9.3

^ permalink raw reply related	[flat|nested] 56+ messages in thread

* [Qemu-devel] [PATCH v2 20/23] block/qapi: Convert qmp_query_block() to BlockBackend
  2014-09-13 15:00 [Qemu-devel] [PATCH v2 00/23] Split BlockBackend off BDS with an axe Markus Armbruster
                   ` (18 preceding siblings ...)
  2014-09-13 15:00 ` [Qemu-devel] [PATCH v2 19/23] blockdev: Drop DriveInfo member enable_auto_del Markus Armbruster
@ 2014-09-13 15:00 ` Markus Armbruster
  2014-09-13 15:00 ` [Qemu-devel] [PATCH v2 21/23] blockdev: Convert qmp_eject(), qmp_change_blockdev() " Markus Armbruster
                   ` (3 subsequent siblings)
  23 siblings, 0 replies; 56+ messages in thread
From: Markus Armbruster @ 2014-09-13 15:00 UTC (permalink / raw)
  To: qemu-devel; +Cc: kwolf, benoit.canet, stefanha

Much more command code needs conversion.  I start with this one
because it's using bdrv_dev_* functions, which I'm about to lift into
BlockBackend.

While there, give bdrv_query_info() internal linkage.

Signed-off-by: Markus Armbruster <armbru@redhat.com>
---
 block/qapi.c         | 15 ++++++++-------
 include/block/qapi.h |  3 ---
 2 files changed, 8 insertions(+), 10 deletions(-)

diff --git a/block/qapi.c b/block/qapi.c
index cc8f711..02121b2 100644
--- a/block/qapi.c
+++ b/block/qapi.c
@@ -28,6 +28,7 @@
 #include "qapi-visit.h"
 #include "qapi/qmp-output-visitor.h"
 #include "qapi/qmp/types.h"
+#include "sysemu/block-backend.h"
 #ifdef __linux__
 #include <linux/fs.h>
 #include <sys/ioctl.h>
@@ -264,15 +265,15 @@ void bdrv_query_image_info(BlockDriverState *bs,
 }
 
 /* @p_info will be set only on success. */
-void bdrv_query_info(BlockDriverState *bs,
-                     BlockInfo **p_info,
-                     Error **errp)
+static void bdrv_query_info(BlockBackend *blk, BlockInfo **p_info,
+                            Error **errp)
 {
     BlockInfo *info = g_malloc0(sizeof(*info));
+    BlockDriverState *bs = blk_bs(blk);
     BlockDriverState *bs0;
     ImageInfo **p_image_info;
     Error *local_err = NULL;
-    info->device = g_strdup(bdrv_get_device_name(bs));
+    info->device = g_strdup(blk_name(blk));
     info->type = g_strdup("unknown");
     info->locked = bdrv_dev_is_medium_locked(bs);
     info->removable = bdrv_dev_has_removable_media(bs);
@@ -359,12 +360,12 @@ static BlockStats *bdrv_query_stats(const BlockDriverState *bs)
 BlockInfoList *qmp_query_block(Error **errp)
 {
     BlockInfoList *head = NULL, **p_next = &head;
-    BlockDriverState *bs = NULL;
+    BlockBackend *blk;
     Error *local_err = NULL;
 
-     while ((bs = bdrv_next(bs))) {
+    for (blk = blk_next(NULL); blk; blk = blk_next(blk)) {
         BlockInfoList *info = g_malloc0(sizeof(*info));
-        bdrv_query_info(bs, &info->value, &local_err);
+        bdrv_query_info(blk, &info->value, &local_err);
         if (local_err) {
             error_propagate(errp, local_err);
             goto err;
diff --git a/include/block/qapi.h b/include/block/qapi.h
index 0374546..168d788 100644
--- a/include/block/qapi.h
+++ b/include/block/qapi.h
@@ -36,9 +36,6 @@ int bdrv_query_snapshot_info_list(BlockDriverState *bs,
 void bdrv_query_image_info(BlockDriverState *bs,
                            ImageInfo **p_info,
                            Error **errp);
-void bdrv_query_info(BlockDriverState *bs,
-                     BlockInfo **p_info,
-                     Error **errp);
 
 void bdrv_snapshot_dump(fprintf_function func_fprintf, void *f,
                         QEMUSnapshotInfo *sn);
-- 
1.9.3

^ permalink raw reply related	[flat|nested] 56+ messages in thread

* [Qemu-devel] [PATCH v2 21/23] blockdev: Convert qmp_eject(), qmp_change_blockdev() to BlockBackend
  2014-09-13 15:00 [Qemu-devel] [PATCH v2 00/23] Split BlockBackend off BDS with an axe Markus Armbruster
                   ` (19 preceding siblings ...)
  2014-09-13 15:00 ` [Qemu-devel] [PATCH v2 20/23] block/qapi: Convert qmp_query_block() to BlockBackend Markus Armbruster
@ 2014-09-13 15:00 ` Markus Armbruster
  2014-09-13 15:00 ` [Qemu-devel] [PATCH v2 22/23] block: Lift device model API into BlockBackend Markus Armbruster
                   ` (2 subsequent siblings)
  23 siblings, 0 replies; 56+ messages in thread
From: Markus Armbruster @ 2014-09-13 15:00 UTC (permalink / raw)
  To: qemu-devel; +Cc: kwolf, benoit.canet, stefanha

Much more command code needs conversion.  I'm converting these now
because they's using bdrv_dev_* functions, which I'm about to lift
into BlockBackend.

Signed-off-by: Markus Armbruster <armbru@redhat.com>
---
 blockdev.c | 20 ++++++++++++--------
 1 file changed, 12 insertions(+), 8 deletions(-)

diff --git a/blockdev.c b/blockdev.c
index e218c59..e115bde 100644
--- a/blockdev.c
+++ b/blockdev.c
@@ -1502,8 +1502,10 @@ exit:
 }
 
 
-static void eject_device(BlockDriverState *bs, int force, Error **errp)
+static void eject_device(BlockBackend *blk, int force, Error **errp)
 {
+    BlockDriverState *bs = blk_bs(blk);
+
     if (bdrv_op_is_blocked(bs, BLOCK_OP_TYPE_EJECT, errp)) {
         return;
     }
@@ -1527,15 +1529,15 @@ static void eject_device(BlockDriverState *bs, int force, Error **errp)
 
 void qmp_eject(const char *device, bool has_force, bool force, Error **errp)
 {
-    BlockDriverState *bs;
+    BlockBackend *blk;
 
-    bs = bdrv_find(device);
-    if (!bs) {
+    blk = blk_by_name(device);
+    if (!blk) {
         error_set(errp, QERR_DEVICE_NOT_FOUND, device);
         return;
     }
 
-    eject_device(bs, force, errp);
+    eject_device(blk, force, errp);
 }
 
 void qmp_block_passwd(bool has_device, const char *device,
@@ -1594,16 +1596,18 @@ static void qmp_bdrv_open_encrypted(BlockDriverState *bs, const char *filename,
 void qmp_change_blockdev(const char *device, const char *filename,
                          const char *format, Error **errp)
 {
+    BlockBackend *blk;
     BlockDriverState *bs;
     BlockDriver *drv = NULL;
     int bdrv_flags;
     Error *err = NULL;
 
-    bs = bdrv_find(device);
-    if (!bs) {
+    blk = blk_by_name(device);
+    if (!blk) {
         error_set(errp, QERR_DEVICE_NOT_FOUND, device);
         return;
     }
+    bs = blk_bs(blk);
 
     if (format) {
         drv = bdrv_find_whitelisted_format(format, bs->read_only);
@@ -1613,7 +1617,7 @@ void qmp_change_blockdev(const char *device, const char *filename,
         }
     }
 
-    eject_device(bs, 0, &err);
+    eject_device(blk, 0, &err);
     if (err) {
         error_propagate(errp, err);
         return;
-- 
1.9.3

^ permalink raw reply related	[flat|nested] 56+ messages in thread

* [Qemu-devel] [PATCH v2 22/23] block: Lift device model API into BlockBackend
  2014-09-13 15:00 [Qemu-devel] [PATCH v2 00/23] Split BlockBackend off BDS with an axe Markus Armbruster
                   ` (20 preceding siblings ...)
  2014-09-13 15:00 ` [Qemu-devel] [PATCH v2 21/23] blockdev: Convert qmp_eject(), qmp_change_blockdev() " Markus Armbruster
@ 2014-09-13 15:00 ` Markus Armbruster
  2014-09-13 15:00 ` [Qemu-devel] [PATCH v2 23/23] block: Make device model's references to BlockBackend strong Markus Armbruster
  2014-09-16 12:22 ` [Qemu-devel] [PATCH v2 00/23] Split BlockBackend off BDS with an axe Markus Armbruster
  23 siblings, 0 replies; 56+ messages in thread
From: Markus Armbruster @ 2014-09-13 15:00 UTC (permalink / raw)
  To: qemu-devel; +Cc: kwolf, benoit.canet, stefanha

Move device model attachment / detachment and the BlockDevOps device
model callbacks and their wrappers from BlockDriverState to
BlockBackend.

Signed-off-by: Markus Armbruster <armbru@redhat.com>
---
 block.c                        | 126 ++++------------------------------
 block/block-backend.c          | 151 ++++++++++++++++++++++++++++++++++++++---
 block/qapi.c                   |   8 +--
 blockdev.c                     |   8 +--
 include/block/block.h          |  45 ------------
 include/block/block_int.h      |  12 ++--
 include/sysemu/block-backend.h |  35 ++++++++++
 7 files changed, 203 insertions(+), 182 deletions(-)

diff --git a/block.c b/block.c
index 9c6d467..0ef5182 100644
--- a/block.c
+++ b/block.c
@@ -58,9 +58,6 @@ struct BdrvDirtyBitmap {
 
 #define NOT_DONE 0x7fffffff /* used while emulated sync operation in progress */
 
-#define COROUTINE_POOL_RESERVATION 64 /* number of coroutines to reserve */
-
-static void bdrv_dev_change_media_cb(BlockDriverState *bs, bool load);
 static BlockAIOCB *bdrv_aio_readv_em(BlockDriverState *bs,
         int64_t sector_num, QEMUIOVector *qiov, int nb_sectors,
         BlockCompletionFunc *cb, void *opaque);
@@ -1527,7 +1524,9 @@ int bdrv_open(BlockDriverState **pbs, const char *filename,
     }
 
     if (!bdrv_key_required(bs)) {
-        bdrv_dev_change_media_cb(bs, true);
+        if (bs->blk) {
+            blk_dev_change_media_cb(bs->blk, true);
+        }
     } else if (!runstate_check(RUN_STATE_PRELAUNCH)
                && !runstate_check(RUN_STATE_INMIGRATE)
                && !runstate_check(RUN_STATE_PAUSED)) { /* HACK */
@@ -1852,7 +1851,9 @@ void bdrv_close(BlockDriverState *bs)
         }
     }
 
-    bdrv_dev_change_media_cb(bs, false);
+    if (bs->blk) {
+        blk_dev_change_media_cb(bs->blk, false);
+    }
 
     /*throttling disk I/O limits*/
     if (bs->io_limits_enabled) {
@@ -1964,9 +1965,6 @@ static void bdrv_move_feature_fields(BlockDriverState *bs_dest,
     /* move some fields that need to stay attached to the device */
 
     /* dev info */
-    bs_dest->dev_ops            = bs_src->dev_ops;
-    bs_dest->dev_opaque         = bs_src->dev_opaque;
-    bs_dest->dev                = bs_src->dev;
     bs_dest->guest_block_size   = bs_src->guest_block_size;
     bs_dest->copy_on_read       = bs_src->copy_on_read;
 
@@ -2034,7 +2032,6 @@ void bdrv_swap(BlockDriverState *bs_new, BlockDriverState *bs_old)
     assert(!bs_new->blk);
     assert(QLIST_EMPTY(&bs_new->dirty_bitmaps));
     assert(bs_new->job == NULL);
-    assert(bs_new->dev == NULL);
     assert(bs_new->io_limits_enabled == false);
     assert(!throttle_have_timer(&bs_new->throttle_state));
 
@@ -2051,7 +2048,6 @@ void bdrv_swap(BlockDriverState *bs_new, BlockDriverState *bs_old)
     assert(!bs_new->blk);
 
     /* Check a few fields that should remain attached to the device */
-    assert(bs_new->dev == NULL);
     assert(bs_new->job == NULL);
     assert(bs_new->io_limits_enabled == false);
     assert(!throttle_have_timer(&bs_new->throttle_state));
@@ -2090,7 +2086,6 @@ void bdrv_append(BlockDriverState *bs_new, BlockDriverState *bs_top)
 
 static void bdrv_delete(BlockDriverState *bs)
 {
-    assert(!bs->dev);
     assert(!bs->job);
     assert(bdrv_op_blocker_is_empty(bs));
     assert(!bs->refcnt);
@@ -2104,105 +2099,6 @@ static void bdrv_delete(BlockDriverState *bs)
     g_free(bs);
 }
 
-int bdrv_attach_dev(BlockDriverState *bs, void *dev)
-/* TODO change to DeviceState *dev when all users are qdevified */
-{
-    if (bs->dev) {
-        return -EBUSY;
-    }
-    bs->dev = dev;
-    bdrv_iostatus_reset(bs);
-
-    /* We're expecting I/O from the device so bump up coroutine pool size */
-    qemu_coroutine_adjust_pool_size(COROUTINE_POOL_RESERVATION);
-    return 0;
-}
-
-/* TODO qdevified devices don't use this, remove when devices are qdevified */
-void bdrv_attach_dev_nofail(BlockDriverState *bs, void *dev)
-{
-    if (bdrv_attach_dev(bs, dev) < 0) {
-        abort();
-    }
-}
-
-void bdrv_detach_dev(BlockDriverState *bs, void *dev)
-/* TODO change to DeviceState *dev when all users are qdevified */
-{
-    assert(bs->dev == dev);
-    bs->dev = NULL;
-    bs->dev_ops = NULL;
-    bs->dev_opaque = NULL;
-    bs->guest_block_size = 512;
-    qemu_coroutine_adjust_pool_size(-COROUTINE_POOL_RESERVATION);
-}
-
-/* TODO change to return DeviceState * when all users are qdevified */
-void *bdrv_get_attached_dev(BlockDriverState *bs)
-{
-    return bs->dev;
-}
-
-void bdrv_set_dev_ops(BlockDriverState *bs, const BlockDevOps *ops,
-                      void *opaque)
-{
-    bs->dev_ops = ops;
-    bs->dev_opaque = opaque;
-}
-
-static void bdrv_dev_change_media_cb(BlockDriverState *bs, bool load)
-{
-    if (bs->dev_ops && bs->dev_ops->change_media_cb) {
-        bool tray_was_closed = !bdrv_dev_is_tray_open(bs);
-        bs->dev_ops->change_media_cb(bs->dev_opaque, load);
-        if (tray_was_closed) {
-            /* tray open */
-            qapi_event_send_device_tray_moved(bdrv_get_device_name(bs),
-                                              true, &error_abort);
-        }
-        if (load) {
-            /* tray close */
-            qapi_event_send_device_tray_moved(bdrv_get_device_name(bs),
-                                              false, &error_abort);
-        }
-    }
-}
-
-bool bdrv_dev_has_removable_media(BlockDriverState *bs)
-{
-    return !bs->dev || (bs->dev_ops && bs->dev_ops->change_media_cb);
-}
-
-void bdrv_dev_eject_request(BlockDriverState *bs, bool force)
-{
-    if (bs->dev_ops && bs->dev_ops->eject_request_cb) {
-        bs->dev_ops->eject_request_cb(bs->dev_opaque, force);
-    }
-}
-
-bool bdrv_dev_is_tray_open(BlockDriverState *bs)
-{
-    if (bs->dev_ops && bs->dev_ops->is_tray_open) {
-        return bs->dev_ops->is_tray_open(bs->dev_opaque);
-    }
-    return false;
-}
-
-static void bdrv_dev_resize_cb(BlockDriverState *bs)
-{
-    if (bs->dev_ops && bs->dev_ops->resize_cb) {
-        bs->dev_ops->resize_cb(bs->dev_opaque);
-    }
-}
-
-bool bdrv_dev_is_medium_locked(BlockDriverState *bs)
-{
-    if (bs->dev_ops && bs->dev_ops->is_medium_locked) {
-        return bs->dev_ops->is_medium_locked(bs->dev_opaque);
-    }
-    return false;
-}
-
 /*
  * Run consistency checks on an image
  *
@@ -3537,7 +3433,9 @@ int bdrv_truncate(BlockDriverState *bs, int64_t offset)
     ret = drv->bdrv_truncate(bs, offset);
     if (ret == 0) {
         ret = refresh_total_sectors(bs, offset >> BDRV_SECTOR_BITS);
-        bdrv_dev_resize_cb(bs);
+        if (bs->blk) {
+            blk_dev_resize_cb(bs->blk);
+        }
     }
     return ret;
 }
@@ -3731,8 +3629,10 @@ int bdrv_set_key(BlockDriverState *bs, const char *key)
         bs->valid_key = 0;
     } else if (!bs->valid_key) {
         bs->valid_key = 1;
-        /* call the change callback now, we skipped it on open */
-        bdrv_dev_change_media_cb(bs, true);
+        if (bs->blk) {
+            /* call the change callback now, we skipped it on open */
+            blk_dev_change_media_cb(bs->blk, true);
+        }
     }
     return ret;
 }
diff --git a/block/block-backend.c b/block/block-backend.c
index ac3d774..9c504f3 100644
--- a/block/block-backend.c
+++ b/block/block-backend.c
@@ -13,6 +13,10 @@
 #include "sysemu/block-backend.h"
 #include "block/block_int.h"
 #include "sysemu/blockdev.h"
+#include "qapi-event.h"
+
+/* Number of coroutines to reserve per attached device model */
+#define COROUTINE_POOL_RESERVATION 64
 
 struct BlockBackend {
     char *name;
@@ -20,6 +24,11 @@ struct BlockBackend {
     BlockDriverState *bs;
     DriveInfo *legacy_dinfo;
     QTAILQ_ENTRY(BlockBackend) link; /* for blk_backends */
+
+    void *dev;                  /* attached device model, if any */
+    /* TODO change to DeviceState when all users are qdevified */
+    const BlockDevOps *dev_ops;
+    void *dev_opaque;
 };
 
 static void drive_info_del(DriveInfo *dinfo);
@@ -81,6 +90,7 @@ BlockBackend *blk_new_with_bs(const char *name, Error **errp)
 static void blk_delete(BlockBackend *blk)
 {
     assert(!blk->refcnt);
+    assert(!blk->dev);
     if (blk->bs) {
         assert(blk->bs->blk == blk);
         blk->bs->blk = NULL;
@@ -231,34 +241,153 @@ void blk_hide_on_behalf_of_do_drive_del(BlockBackend *blk)
     }
 }
 
-void blk_iostatus_enable(BlockBackend *blk)
-{
-    bdrv_iostatus_enable(blk->bs);
-}
-
+/*
+ * Attach device model @dev to @blk.
+ * Return 0 on success, -EBUSY when a device model is attached already.
+ */
 int blk_attach_dev(BlockBackend *blk, void *dev)
+/* TODO change to DeviceState *dev when all users are qdevified */
 {
-    return bdrv_attach_dev(blk->bs, dev);
+    if (blk->dev) {
+        return -EBUSY;
+    }
+    blk->dev = dev;
+    bdrv_iostatus_reset(blk->bs);
+
+    /* We're expecting I/O from the device so bump up coroutine pool size */
+    qemu_coroutine_adjust_pool_size(COROUTINE_POOL_RESERVATION);
+    return 0;
 }
 
+/*
+ * Attach device model @dev to @blk.
+ * @blk must not have a device model attached already.
+ * TODO qdevified devices don't use this, remove when devices are qdevified
+ */
 void blk_attach_dev_nofail(BlockBackend *blk, void *dev)
 {
-    bdrv_attach_dev_nofail(blk->bs, dev);
+    if (blk_attach_dev(blk, dev) < 0) {
+        abort();
+    }
 }
 
+/*
+ * Detach device model @dev from @blk.
+ * @dev must be currently attached to @blk.
+ */
 void blk_detach_dev(BlockBackend *blk, void *dev)
+/* TODO change to DeviceState *dev when all users are qdevified */
 {
-    bdrv_detach_dev(blk->bs, dev);
+    assert(blk->dev == dev);
+    blk->dev = NULL;
+    blk->dev_ops = NULL;
+    blk->dev_opaque = NULL;
+    bdrv_set_guest_block_size(blk->bs, 512);
+    qemu_coroutine_adjust_pool_size(-COROUTINE_POOL_RESERVATION);
 }
 
+/*
+ * Return the device model attached to @blk if any, else null.
+ */
 void *blk_get_attached_dev(BlockBackend *blk)
+/* TODO change to return DeviceState * when all users are qdevified */
 {
-    return bdrv_get_attached_dev(blk->bs);
+    return blk->dev;
 }
 
-void blk_set_dev_ops(BlockBackend *blk, const BlockDevOps *ops, void *opaque)
+/*
+ * Set @blk's device model callbacks to @ops.
+ * @opaque is the opaque argument to pass to the callbacks.
+ * This is for use by device models.
+ */
+void blk_set_dev_ops(BlockBackend *blk, const BlockDevOps *ops,
+                     void *opaque)
 {
-    bdrv_set_dev_ops(blk->bs, ops, opaque);
+    blk->dev_ops = ops;
+    blk->dev_opaque = opaque;
+}
+
+/*
+ * Notify @blk's attached device model of media change.
+ * If @load is true, notify of media load.
+ * Else, notify of media eject.
+ * Also send DEVICE_TRAY_MOVED events as appropriate.
+ */
+void blk_dev_change_media_cb(BlockBackend *blk, bool load)
+{
+    if (blk->dev_ops && blk->dev_ops->change_media_cb) {
+        bool tray_was_closed = !blk_dev_is_tray_open(blk);
+
+        blk->dev_ops->change_media_cb(blk->dev_opaque, load);
+        if (tray_was_closed) {
+            /* tray open */
+            qapi_event_send_device_tray_moved(blk_name(blk),
+                                              true, &error_abort);
+        }
+        if (load) {
+            /* tray close */
+            qapi_event_send_device_tray_moved(blk_name(blk),
+                                              false, &error_abort);
+        }
+    }
+}
+
+/*
+ * Does @blk's attached device model have removable media?
+ * %true if no device model is attached.
+ */
+bool blk_dev_has_removable_media(BlockBackend *blk)
+{
+    return !blk->dev || (blk->dev_ops && blk->dev_ops->change_media_cb);
+}
+
+/*
+ * Notify @blk's attached device model of a media eject request.
+ * If @force is true, the medium is about to be yanked out forcefully.
+ */
+void blk_dev_eject_request(BlockBackend *blk, bool force)
+{
+    if (blk->dev_ops && blk->dev_ops->eject_request_cb) {
+        blk->dev_ops->eject_request_cb(blk->dev_opaque, force);
+    }
+}
+
+/*
+ * Does @blk's attached device model have a tray, and is it open?
+ */
+bool blk_dev_is_tray_open(BlockBackend *blk)
+{
+    if (blk->dev_ops && blk->dev_ops->is_tray_open) {
+        return blk->dev_ops->is_tray_open(blk->dev_opaque);
+    }
+    return false;
+}
+
+/*
+ * Does @blk's attached device model have the medium locked?
+ * %false if the device model has no such lock.
+ */
+bool blk_dev_is_medium_locked(BlockBackend *blk)
+{
+    if (blk->dev_ops && blk->dev_ops->is_medium_locked) {
+        return blk->dev_ops->is_medium_locked(blk->dev_opaque);
+    }
+    return false;
+}
+
+/*
+ * Notify @blk's attached device model of a backend size change.
+ */
+void blk_dev_resize_cb(BlockBackend *blk)
+{
+    if (blk->dev_ops && blk->dev_ops->resize_cb) {
+        blk->dev_ops->resize_cb(blk->dev_opaque);
+    }
+}
+
+void blk_iostatus_enable(BlockBackend *blk)
+{
+    bdrv_iostatus_enable(blk->bs);
 }
 
 int blk_read(BlockBackend *blk, int64_t sector_num, uint8_t *buf,
diff --git a/block/qapi.c b/block/qapi.c
index 02121b2..921e620 100644
--- a/block/qapi.c
+++ b/block/qapi.c
@@ -275,12 +275,12 @@ static void bdrv_query_info(BlockBackend *blk, BlockInfo **p_info,
     Error *local_err = NULL;
     info->device = g_strdup(blk_name(blk));
     info->type = g_strdup("unknown");
-    info->locked = bdrv_dev_is_medium_locked(bs);
-    info->removable = bdrv_dev_has_removable_media(bs);
+    info->locked = blk_dev_is_medium_locked(blk);
+    info->removable = blk_dev_has_removable_media(blk);
 
-    if (bdrv_dev_has_removable_media(bs)) {
+    if (blk_dev_has_removable_media(blk)) {
         info->has_tray_open = true;
-        info->tray_open = bdrv_dev_is_tray_open(bs);
+        info->tray_open = blk_dev_is_tray_open(blk);
     }
 
     if (bdrv_iostatus_is_enabled(bs)) {
diff --git a/blockdev.c b/blockdev.c
index e115bde..d3dccb9 100644
--- a/blockdev.c
+++ b/blockdev.c
@@ -1509,14 +1509,14 @@ static void eject_device(BlockBackend *blk, int force, Error **errp)
     if (bdrv_op_is_blocked(bs, BLOCK_OP_TYPE_EJECT, errp)) {
         return;
     }
-    if (!bdrv_dev_has_removable_media(bs)) {
+    if (!blk_dev_has_removable_media(blk)) {
         error_setg(errp, "Device '%s' is not removable",
                    bdrv_get_device_name(bs));
         return;
     }
 
-    if (bdrv_dev_is_medium_locked(bs) && !bdrv_dev_is_tray_open(bs)) {
-        bdrv_dev_eject_request(bs, force);
+    if (blk_dev_is_medium_locked(blk) && !blk_dev_is_tray_open(blk)) {
+        blk_dev_eject_request(blk, force);
         if (!force) {
             error_setg(errp, "Device '%s' is locked",
                        bdrv_get_device_name(bs));
@@ -1753,7 +1753,7 @@ int do_drive_del(Monitor *mon, const QDict *qdict, QObject **ret_data)
      * can be removed.  If this is a drive with no device backing
      * then we can just get rid of the block driver state right here.
      */
-    if (bdrv_get_attached_dev(bs)) {
+    if (blk_get_attached_dev(blk)) {
         blk_hide_on_behalf_of_do_drive_del(blk);
         /* Further I/O must not pause the guest */
         bdrv_set_on_error(bs, BLOCKDEV_ON_ERROR_REPORT,
diff --git a/include/block/block.h b/include/block/block.h
index 0d8e5f7..2929023 100644
--- a/include/block/block.h
+++ b/include/block/block.h
@@ -47,41 +47,6 @@ typedef struct BlockFragInfo {
     uint64_t compressed_clusters;
 } BlockFragInfo;
 
-/* Callbacks for block device models */
-typedef struct BlockDevOps {
-    /*
-     * Runs when virtual media changed (monitor commands eject, change)
-     * Argument load is true on load and false on eject.
-     * Beware: doesn't run when a host device's physical media
-     * changes.  Sure would be useful if it did.
-     * Device models with removable media must implement this callback.
-     */
-    void (*change_media_cb)(void *opaque, bool load);
-    /*
-     * Runs when an eject request is issued from the monitor, the tray
-     * is closed, and the medium is locked.
-     * Device models that do not implement is_medium_locked will not need
-     * this callback.  Device models that can lock the medium or tray might
-     * want to implement the callback and unlock the tray when "force" is
-     * true, even if they do not support eject requests.
-     */
-    void (*eject_request_cb)(void *opaque, bool force);
-    /*
-     * Is the virtual tray open?
-     * Device models implement this only when the device has a tray.
-     */
-    bool (*is_tray_open)(void *opaque);
-    /*
-     * Is the virtual medium locked into the device?
-     * Device models implement this only when device has such a lock.
-     */
-    bool (*is_medium_locked)(void *opaque);
-    /*
-     * Runs when the size changed (e.g. monitor command block_resize)
-     */
-    void (*resize_cb)(void *opaque);
-} BlockDevOps;
-
 typedef enum {
     BDRV_REQ_COPY_ON_READ = 0x1,
     BDRV_REQ_ZERO_WRITE   = 0x2,
@@ -229,16 +194,6 @@ void bdrv_reopen_commit(BDRVReopenState *reopen_state);
 void bdrv_reopen_abort(BDRVReopenState *reopen_state);
 void bdrv_close(BlockDriverState *bs);
 void bdrv_add_close_notifier(BlockDriverState *bs, Notifier *notify);
-int bdrv_attach_dev(BlockDriverState *bs, void *dev);
-void bdrv_attach_dev_nofail(BlockDriverState *bs, void *dev);
-void bdrv_detach_dev(BlockDriverState *bs, void *dev);
-void *bdrv_get_attached_dev(BlockDriverState *bs);
-void bdrv_set_dev_ops(BlockDriverState *bs, const BlockDevOps *ops,
-                      void *opaque);
-void bdrv_dev_eject_request(BlockDriverState *bs, bool force);
-bool bdrv_dev_has_removable_media(BlockDriverState *bs);
-bool bdrv_dev_is_tray_open(BlockDriverState *bs);
-bool bdrv_dev_is_medium_locked(BlockDriverState *bs);
 int bdrv_read(BlockDriverState *bs, int64_t sector_num,
               uint8_t *buf, int nb_sectors);
 int bdrv_read_unthrottled(BlockDriverState *bs, int64_t sector_num,
diff --git a/include/block/block_int.h b/include/block/block_int.h
index 4d6a802..1834302 100644
--- a/include/block/block_int.h
+++ b/include/block/block_int.h
@@ -325,11 +325,6 @@ struct BlockDriverState {
 
     BlockBackend *blk;          /* owning backend, if any */
 
-    void *dev;                  /* attached device model, if any */
-    /* TODO change to DeviceState when all users are qdevified */
-    const BlockDevOps *dev_ops;
-    void *dev_opaque;
-
     AioContext *aio_context; /* event loop used for fd handlers, timers, etc */
     /* long-running tasks intended to always use the same AioContext as this
      * BDS may register themselves in this list to be notified of changes
@@ -589,4 +584,11 @@ void backup_start(BlockDriverState *bs, BlockDriverState *target,
                   BlockCompletionFunc *cb, void *opaque,
                   Error **errp);
 
+void blk_dev_change_media_cb(BlockBackend *blk, bool load);
+bool blk_dev_has_removable_media(BlockBackend *blk);
+void blk_dev_eject_request(BlockBackend *blk, bool force);
+bool blk_dev_is_tray_open(BlockBackend *blk);
+bool blk_dev_is_medium_locked(BlockBackend *blk);
+void blk_dev_resize_cb(BlockBackend *blk);
+
 #endif /* BLOCK_INT_H */
diff --git a/include/sysemu/block-backend.h b/include/sysemu/block-backend.h
index ac7e65f..eeef812 100644
--- a/include/sysemu/block-backend.h
+++ b/include/sysemu/block-backend.h
@@ -25,6 +25,41 @@
  */
 #include "block/block.h"
 
+/* Callbacks for block device models */
+typedef struct BlockDevOps {
+    /*
+     * Runs when virtual media changed (monitor commands eject, change)
+     * Argument load is true on load and false on eject.
+     * Beware: doesn't run when a host device's physical media
+     * changes.  Sure would be useful if it did.
+     * Device models with removable media must implement this callback.
+     */
+    void (*change_media_cb)(void *opaque, bool load);
+    /*
+     * Runs when an eject request is issued from the monitor, the tray
+     * is closed, and the medium is locked.
+     * Device models that do not implement is_medium_locked will not need
+     * this callback.  Device models that can lock the medium or tray might
+     * want to implement the callback and unlock the tray when "force" is
+     * true, even if they do not support eject requests.
+     */
+    void (*eject_request_cb)(void *opaque, bool force);
+    /*
+     * Is the virtual tray open?
+     * Device models implement this only when the device has a tray.
+     */
+    bool (*is_tray_open)(void *opaque);
+    /*
+     * Is the virtual medium locked into the device?
+     * Device models implement this only when device has such a lock.
+     */
+    bool (*is_medium_locked)(void *opaque);
+    /*
+     * Runs when the size changed (e.g. monitor command block_resize)
+     */
+    void (*resize_cb)(void *opaque);
+} BlockDevOps;
+
 BlockBackend *blk_new(const char *name, Error **errp);
 BlockBackend *blk_new_with_bs(const char *name, Error **errp);
 void blk_ref(BlockBackend *blk);
-- 
1.9.3

^ permalink raw reply related	[flat|nested] 56+ messages in thread

* [Qemu-devel] [PATCH v2 23/23] block: Make device model's references to BlockBackend strong
  2014-09-13 15:00 [Qemu-devel] [PATCH v2 00/23] Split BlockBackend off BDS with an axe Markus Armbruster
                   ` (21 preceding siblings ...)
  2014-09-13 15:00 ` [Qemu-devel] [PATCH v2 22/23] block: Lift device model API into BlockBackend Markus Armbruster
@ 2014-09-13 15:00 ` Markus Armbruster
  2014-09-16 12:22 ` [Qemu-devel] [PATCH v2 00/23] Split BlockBackend off BDS with an axe Markus Armbruster
  23 siblings, 0 replies; 56+ messages in thread
From: Markus Armbruster @ 2014-09-13 15:00 UTC (permalink / raw)
  To: qemu-devel; +Cc: kwolf, benoit.canet, stefanha

Doesn't make a difference just yet, but it's the right thing to do.

Signed-off-by: Markus Armbruster <armbru@redhat.com>
---
 block/block-backend.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/block/block-backend.c b/block/block-backend.c
index 9c504f3..17285ba 100644
--- a/block/block-backend.c
+++ b/block/block-backend.c
@@ -251,6 +251,7 @@ int blk_attach_dev(BlockBackend *blk, void *dev)
     if (blk->dev) {
         return -EBUSY;
     }
+    blk_ref(blk);
     blk->dev = dev;
     bdrv_iostatus_reset(blk->bs);
 
@@ -279,9 +280,10 @@ void blk_detach_dev(BlockBackend *blk, void *dev)
 /* TODO change to DeviceState *dev when all users are qdevified */
 {
     assert(blk->dev == dev);
-    blk->dev = NULL;
     blk->dev_ops = NULL;
     blk->dev_opaque = NULL;
+    blk->dev = NULL;
+    blk_unref(blk);
     bdrv_set_guest_block_size(blk->bs, 512);
     qemu_coroutine_adjust_pool_size(-COROUTINE_POOL_RESERVATION);
 }
-- 
1.9.3

^ permalink raw reply related	[flat|nested] 56+ messages in thread

* Re: [Qemu-devel] [PATCH v2 01/23] block: Split bdrv_new_root() off bdrv_new()
  2014-09-13 15:00 ` [Qemu-devel] [PATCH v2 01/23] block: Split bdrv_new_root() off bdrv_new() Markus Armbruster
@ 2014-09-13 20:45   ` Max Reitz
  2014-09-15 12:00   ` Benoît Canet
  1 sibling, 0 replies; 56+ messages in thread
From: Max Reitz @ 2014-09-13 20:45 UTC (permalink / raw)
  To: Markus Armbruster, qemu-devel; +Cc: kwolf, stefanha, benoit.canet

On 13.09.2014 17:00, Markus Armbruster wrote:
> Creating an anonymous BDS can't fail.  Make that obvious.
>
> Signed-off-by: Markus Armbruster <armbru@redhat.com>
> ---
>   block.c               | 28 +++++++++++++++++++---------
>   block/iscsi.c         |  2 +-
>   block/vvfat.c         |  2 +-
>   blockdev.c            |  2 +-
>   hw/block/xen_disk.c   |  2 +-
>   include/block/block.h |  3 ++-
>   qemu-img.c            |  6 +++---
>   qemu-io.c             |  2 +-
>   qemu-nbd.c            |  2 +-
>   9 files changed, 30 insertions(+), 19 deletions(-)

Reviewed-by: Max Reitz <mreitz@redhat.com>

^ permalink raw reply	[flat|nested] 56+ messages in thread

* Re: [Qemu-devel] [PATCH v2 02/23] block: New BlockBackend
  2014-09-13 15:00 ` [Qemu-devel] [PATCH v2 02/23] block: New BlockBackend Markus Armbruster
@ 2014-09-13 21:41   ` Max Reitz
  2014-09-15  6:37     ` Markus Armbruster
  2014-09-15 13:02   ` Benoît Canet
  1 sibling, 1 reply; 56+ messages in thread
From: Max Reitz @ 2014-09-13 21:41 UTC (permalink / raw)
  To: Markus Armbruster, qemu-devel; +Cc: kwolf, stefanha, benoit.canet

On 13.09.2014 17:00, Markus Armbruster wrote:
> A block device consists of a frontend device model and a backend.
>
> A block backend has a tree of block drivers doing the actual work.
> The tree is managed by the block layer.
>
> We currently use a single abstraction BlockDriverState both for tree
> nodes and the backend as a whole.  Drawbacks:
>
> * Its API includes both stuff that makes sense only at the block
>    backend level (root of the tree) and stuff that's only for use
>    within the block layer.  This makes the API bigger and more complex
>    than necessary.  Moreover, it's not obvious which interfaces are
>    meant for device models, and which really aren't.
>
> * Since device models keep a reference to their backend, the backend
>    object can't just be destroyed.  But for media change, we need to
>    replace the tree.  Our solution is to make the BlockDriverState
>    generic, with actual driver state in a separate object, pointed to
>    by member opaque.  That lets us replace the tree by deinitializing
>    and reinitializing its root.  This special need of the root makes
>    the data structure awkward everywhere in the tree.
>
> The general plan is to separate the APIs into "block backend", for use
> by device models, monitor and whatever other code dealing with block
> backends, and "block driver", for use by the block layer and whatever
> other code (if any) dealing with trees and tree nodes.
>
> Code dealing with block backends, device models in particular, should
> become completely oblivious of BlockDriverState.  This should let us
> clean up both APIs, and the tree data structures.
>
> This commit is a first step.  It creates a minimal "block backend"
> API: type BlockBackend and functions to create, destroy and find them.
>
> BlockBackend objects are created and destroyed exactly when root
> BlockDriverState objects are created and destroyed.  "Root" in the
> sense of "in bdrv_states".  They're not yet used for anything; that'll
> come shortly.
>
> BlockBackend is reference-counted.  Its reference count never exceeds
> one so far, but that's going to change.
>
> Signed-off-by: Markus Armbruster <armbru@redhat.com>
> ---
>   block.c                        |   3 +-
>   block/Makefile.objs            |   2 +-
>   block/block-backend.c          | 119 +++++++++++++++++++++++++++++++++++++++++
>   blockdev.c                     |  21 +++++++-
>   hw/block/xen_disk.c            |  11 ++++
>   include/qemu/typedefs.h        |   1 +
>   include/sysemu/block-backend.h |  26 +++++++++
>   qemu-img.c                     |  70 +++++++++++++++++++++---
>   qemu-io.c                      |   8 +++
>   qemu-nbd.c                     |   5 +-
>   10 files changed, 253 insertions(+), 13 deletions(-)
>   create mode 100644 block/block-backend.c
>   create mode 100644 include/sysemu/block-backend.h

[snip]

> diff --git a/qemu-img.c b/qemu-img.c
> index 58d59d0..acb272e 100644
> --- a/qemu-img.c
> +++ b/qemu-img.c

[snip]

> @@ -942,6 +952,7 @@ static int check_empty_sectors(BlockDriverState *bs, int64_t sect_num,
>   static int img_compare(int argc, char **argv)
>   {
>       const char *fmt1 = NULL, *fmt2 = NULL, *cache, *filename1, *filename2;
> +    BlockBackend *blk1, *blk2;
>       BlockDriverState *bs1, *bs2;

By initializing all of these to NULL we could remove out1, out2 and 
out3, and just always go to out. But of course it's not wrong this way.

Reviewed-by: Max Reitz <mreitz@redhat.com>

^ permalink raw reply	[flat|nested] 56+ messages in thread

* Re: [Qemu-devel] [PATCH v2 03/23] block: Connect BlockBackend to BlockDriverState
  2014-09-13 15:00 ` [Qemu-devel] [PATCH v2 03/23] block: Connect BlockBackend to BlockDriverState Markus Armbruster
@ 2014-09-13 22:13   ` Max Reitz
  2014-09-15  6:59     ` Markus Armbruster
  2014-09-15 15:00   ` Benoît Canet
  1 sibling, 1 reply; 56+ messages in thread
From: Max Reitz @ 2014-09-13 22:13 UTC (permalink / raw)
  To: Markus Armbruster, qemu-devel; +Cc: kwolf, stefanha, benoit.canet

On 13.09.2014 17:00, Markus Armbruster wrote:
> The pointer from BlockBackend to BlockDriverState is a strong
> reference, managed with bdrv_ref() / bdrv_unref(), the back-pointer is
> a weak one.
>
> Convenience function blk_new_with_bs() creates a BlockBackend with its
> BlockDriverState.  Callers have to unref both.  The commit after next
> will relieve them of the need to unref the BlockDriverState.
>
> Complication: due to the silly way drive_del works, we need a way to
> hide a BlockBackend, just like bdrv_make_anon().  To emphasize its
> "special" status, give the function a suitably off-putting name:

So you're trying to force people with a sense of aesthetics to solve 
this problem? I don't know why this isn't taught in Software Engineering 
in university, but it definitely should be.

> blk_hide_on_behalf_of_do_drive_del().  Unfortunately, hiding turns the
> BlockBackend's name into the empty string.  Can't avoid that without
> breaking the blk->bs->device_name equals blk->name invariant.
>
> Signed-off-by: Markus Armbruster <armbru@redhat.com>
> ---
>   block.c                        |  10 ++--
>   block/block-backend.c          |  70 ++++++++++++++++++++++-
>   blockdev.c                     |  26 +++------
>   hw/block/xen_disk.c            |   8 +--
>   include/block/block_int.h      |   2 +
>   include/sysemu/block-backend.h |   5 ++
>   qemu-img.c                     | 125 +++++++++++++++++++----------------------
>   qemu-io.c                      |   4 +-
>   qemu-nbd.c                     |   2 +-
>   9 files changed, 152 insertions(+), 100 deletions(-)

[snip]

> diff --git a/block/block-backend.c b/block/block-backend.c
> index 919dd4c..b118b38 100644
> --- a/block/block-backend.c
> +++ b/block/block-backend.c
> @@ -16,10 +16,11 @@
>   struct BlockBackend {
>       char *name;
>       int refcnt;
> +    BlockDriverState *bs;
>       QTAILQ_ENTRY(BlockBackend) link; /* for blk_backends */
>   };
>   
> -/* All the BlockBackends */
> +/* All the BlockBackends (except for hidden ones) */
>   static QTAILQ_HEAD(, BlockBackend) blk_backends =
>       QTAILQ_HEAD_INITIALIZER(blk_backends);
>   
> @@ -47,10 +48,43 @@ BlockBackend *blk_new(const char *name, Error **errp)
>       return blk;
>   }
>   
> +/*
> + * Create a new BlockBackend with a new BlockDriverState attached.
> + * Both have a reference count of one.  Caller owns *both* references.
> + * TODO Let caller own only the BlockBackend reference
> + * Otherwise just like blk_new(), which see.

Could be my lack of profoundness in English, but I don't understand what 
"which see" is supposed to mean or how its grammar works. An imperative?

> + */
> +BlockBackend *blk_new_with_bs(const char *name, Error **errp)
> +{
> +    BlockBackend *blk;
> +    BlockDriverState *bs;
> +
> +    blk = blk_new(name, errp);
> +    if (!blk) {
> +        return NULL;
> +    }
> +
> +    bs = bdrv_new_root(name, errp);
> +    if (!bs) {
> +        blk_unref(blk);
> +        return NULL;
> +    }
> +
> +    blk->bs = bs;
> +    bs->blk = blk;
> +    return blk;
> +}
> +

[snip]

> diff --git a/blockdev.c b/blockdev.c
> index 5873205..21f4c67 100644
> --- a/blockdev.c
> +++ b/blockdev.c
> @@ -229,14 +229,7 @@ void drive_info_del(DriveInfo *dinfo)
>           qemu_opts_del(dinfo->opts);
>       }
>   
> -    /*
> -     * Hairy special case: if do_drive_del() has made dinfo->bdrv
> -     * anonymous, it also unref'ed the associated BlockBackend.
> -     */
> -    if (dinfo->bdrv->device_name[0]) {
> -        blk_unref(blk_by_name(dinfo->bdrv->device_name));
> -    }
> -
> +    blk_unref(blk_by_name(dinfo->bdrv->device_name));

So if !device_name[0], the BB is hidden. Hidden BBs are removed from the 
BB list and therefore not returned by blk_by_name(). Therefore, the BB 
is leaked here.

I guess this will be fixed up in a later patch, though...

>       g_free(dinfo->id);
>       QTAILQ_REMOVE(&drives, dinfo, next);
>       g_free(dinfo->serial);

[snip]

> diff --git a/qemu-nbd.c b/qemu-nbd.c
> index ff95da6..fa8a7d0 100644
> --- a/qemu-nbd.c
> +++ b/qemu-nbd.c
> @@ -689,7 +689,7 @@ int main(int argc, char **argv)
>       }
>   
>       blk = blk_new("hda", &error_abort);
> -    bs = bdrv_new_root("hda", &error_abort);
> +    bs = blk_bs(blk);

Shouldn't that be a blk_new_with_bs() then, just like every other case?

>       srcpath = argv[optind];
>       ret = bdrv_open(&bs, srcpath, NULL, NULL, flags, drv, &local_err);

Max

^ permalink raw reply	[flat|nested] 56+ messages in thread

* Re: [Qemu-devel] [PATCH v2 05/23] block: Code motion to get rid of stubs/blockdev.c
  2014-09-13 15:00 ` [Qemu-devel] [PATCH v2 05/23] block: Code motion to get rid of stubs/blockdev.c Markus Armbruster
@ 2014-09-15  6:28   ` Fam Zheng
  2014-09-15  7:21     ` Markus Armbruster
  2014-09-16 12:40   ` Benoît Canet
  1 sibling, 1 reply; 56+ messages in thread
From: Fam Zheng @ 2014-09-15  6:28 UTC (permalink / raw)
  To: Markus Armbruster; +Cc: kwolf, stefanha, qemu-devel, benoit.canet

On Sat, 09/13 17:00, Markus Armbruster wrote:
> Signed-off-by: Markus Armbruster <armbru@redhat.com>
> ---
>  block/block-backend.c     | 15 +++++++++++++++
>  blockdev.c                | 13 -------------
>  include/sysemu/blockdev.h |  1 -
>  stubs/Makefile.objs       |  1 -
>  stubs/blockdev.c          | 12 ------------

Where is the stubs/blockdev.c from? I don't see it in qemu.git.

Fam

^ permalink raw reply	[flat|nested] 56+ messages in thread

* Re: [Qemu-devel] [PATCH v2 02/23] block: New BlockBackend
  2014-09-13 21:41   ` Max Reitz
@ 2014-09-15  6:37     ` Markus Armbruster
  0 siblings, 0 replies; 56+ messages in thread
From: Markus Armbruster @ 2014-09-15  6:37 UTC (permalink / raw)
  To: Max Reitz; +Cc: kwolf, qemu-devel, stefanha, benoit.canet

Max Reitz <mreitz@redhat.com> writes:

> On 13.09.2014 17:00, Markus Armbruster wrote:
>> A block device consists of a frontend device model and a backend.
>>
>> A block backend has a tree of block drivers doing the actual work.
>> The tree is managed by the block layer.
>>
>> We currently use a single abstraction BlockDriverState both for tree
>> nodes and the backend as a whole.  Drawbacks:
>>
>> * Its API includes both stuff that makes sense only at the block
>>    backend level (root of the tree) and stuff that's only for use
>>    within the block layer.  This makes the API bigger and more complex
>>    than necessary.  Moreover, it's not obvious which interfaces are
>>    meant for device models, and which really aren't.
>>
>> * Since device models keep a reference to their backend, the backend
>>    object can't just be destroyed.  But for media change, we need to
>>    replace the tree.  Our solution is to make the BlockDriverState
>>    generic, with actual driver state in a separate object, pointed to
>>    by member opaque.  That lets us replace the tree by deinitializing
>>    and reinitializing its root.  This special need of the root makes
>>    the data structure awkward everywhere in the tree.
>>
>> The general plan is to separate the APIs into "block backend", for use
>> by device models, monitor and whatever other code dealing with block
>> backends, and "block driver", for use by the block layer and whatever
>> other code (if any) dealing with trees and tree nodes.
>>
>> Code dealing with block backends, device models in particular, should
>> become completely oblivious of BlockDriverState.  This should let us
>> clean up both APIs, and the tree data structures.
>>
>> This commit is a first step.  It creates a minimal "block backend"
>> API: type BlockBackend and functions to create, destroy and find them.
>>
>> BlockBackend objects are created and destroyed exactly when root
>> BlockDriverState objects are created and destroyed.  "Root" in the
>> sense of "in bdrv_states".  They're not yet used for anything; that'll
>> come shortly.
>>
>> BlockBackend is reference-counted.  Its reference count never exceeds
>> one so far, but that's going to change.
>>
>> Signed-off-by: Markus Armbruster <armbru@redhat.com>
>> ---
>>   block.c                        |   3 +-
>>   block/Makefile.objs            |   2 +-
>>   block/block-backend.c          | 119 +++++++++++++++++++++++++++++++++++++++++
>>   blockdev.c                     |  21 +++++++-
>>   hw/block/xen_disk.c            |  11 ++++
>>   include/qemu/typedefs.h        |   1 +
>>   include/sysemu/block-backend.h |  26 +++++++++
>>   qemu-img.c                     |  70 +++++++++++++++++++++---
>>   qemu-io.c                      |   8 +++
>>   qemu-nbd.c                     |   5 +-
>>   10 files changed, 253 insertions(+), 13 deletions(-)
>>   create mode 100644 block/block-backend.c
>>   create mode 100644 include/sysemu/block-backend.h
>
> [snip]
>
>> diff --git a/qemu-img.c b/qemu-img.c
>> index 58d59d0..acb272e 100644
>> --- a/qemu-img.c
>> +++ b/qemu-img.c
>
> [snip]
>
>> @@ -942,6 +952,7 @@ static int check_empty_sectors(BlockDriverState *bs, int64_t sect_num,
>>   static int img_compare(int argc, char **argv)
>>   {
>>       const char *fmt1 = NULL, *fmt2 = NULL, *cache, *filename1, *filename2;
>> +    BlockBackend *blk1, *blk2;
>>       BlockDriverState *bs1, *bs2;
>
> By initializing all of these to NULL we could remove out1, out2 and
> out3, and just always go to out. But of course it's not wrong this
> way.

Indeed, and I actually like that way to free stuff on error.  But it
would be yet another preliminary cleanup patch.  If you guys want it,
I'll cook it up.

> Reviewed-by: Max Reitz <mreitz@redhat.com>

Thanks!

^ permalink raw reply	[flat|nested] 56+ messages in thread

* Re: [Qemu-devel] [PATCH v2 10/23] block: Eliminate DriveInfo member bdrv, use blk_by_legacy_dinfo()
  2014-09-13 15:00 ` [Qemu-devel] [PATCH v2 10/23] block: Eliminate DriveInfo member bdrv, use blk_by_legacy_dinfo() Markus Armbruster
@ 2014-09-15  6:58   ` Fam Zheng
  2014-09-15  7:21     ` Markus Armbruster
  0 siblings, 1 reply; 56+ messages in thread
From: Fam Zheng @ 2014-09-15  6:58 UTC (permalink / raw)
  To: Markus Armbruster; +Cc: kwolf, stefanha, qemu-devel, benoit.canet

On Sat, 09/13 17:00, Markus Armbruster wrote:
> The patch is big, but all it really does is replacing
> 
>     dinfo->bdrv
> 
> by
> 
>     blk_bs(blk_legacy_dinfo(dinfo))

s/blk_legacy_dinfo/blk_by_legacy_dinfo/

Otherwise looks good,

Reviewed-by: Fam Zheng <famz@redhat.com>

> 
> The replacement is repetitive, but the conversion of device models to
> BlockBackend is imminent, and will shorten it to just
> blk_legacy_dinfo(dinfo).
> 
> Line wrapping muddies the waters a bit.  I also omit tests whether
> dinfo->bdrv is null, because it never is.
> 
> Signed-off-by: Markus Armbruster <armbru@redhat.com>
> ---
>  blockdev.c                               |  3 +--
>  hw/arm/collie.c                          |  9 +++++----
>  hw/arm/gumstix.c                         |  5 +++--
>  hw/arm/mainstone.c                       |  8 ++++----
>  hw/arm/musicpal.c                        | 11 ++++++-----
>  hw/arm/nseries.c                         |  6 ++++--
>  hw/arm/omap1.c                           |  4 +++-
>  hw/arm/omap2.c                           |  4 +++-
>  hw/arm/omap_sx1.c                        |  9 +++++----
>  hw/arm/pxa2xx.c                          |  7 +++++--
>  hw/arm/spitz.c                           |  4 +++-
>  hw/arm/versatilepb.c                     |  4 +++-
>  hw/arm/vexpress.c                        |  4 +++-
>  hw/arm/xilinx_zynq.c                     |  4 +++-
>  hw/arm/z2.c                              |  7 ++++---
>  hw/block/fdc.c                           | 16 +++++++++++-----
>  hw/block/m25p80.c                        |  5 +++--
>  hw/block/xen_disk.c                      |  2 +-
>  hw/cris/axis_dev88.c                     |  3 ++-
>  hw/display/tc6393xb.c                    |  4 +++-
>  hw/i386/pc_sysfw.c                       |  3 ++-
>  hw/ide/piix.c                            |  6 ++++--
>  hw/ide/qdev.c                            |  4 +++-
>  hw/isa/pc87312.c                         |  7 +++++--
>  hw/lm32/lm32_boards.c                    | 13 +++++++------
>  hw/lm32/milkymist.c                      |  7 ++++---
>  hw/microblaze/petalogix_ml605_mmu.c      |  5 +++--
>  hw/microblaze/petalogix_s3adsp1800_mmu.c |  5 +++--
>  hw/mips/mips_malta.c                     |  4 +++-
>  hw/mips/mips_r4k.c                       |  5 +++--
>  hw/pci/pci-hotplug-old.c                 |  9 ++++++---
>  hw/ppc/ppc405_boards.c                   | 25 ++++++++++++++++---------
>  hw/ppc/spapr.c                           |  4 +++-
>  hw/ppc/virtex_ml507.c                    |  5 +++--
>  hw/scsi/scsi-bus.c                       |  5 +++--
>  hw/sd/milkymist-memcard.c                |  7 +++++--
>  hw/sd/pl181.c                            |  3 ++-
>  hw/sd/sdhci.c                            |  3 ++-
>  hw/sd/ssi-sd.c                           |  3 ++-
>  hw/sh4/r2d.c                             |  5 +++--
>  hw/usb/dev-storage.c                     |  4 +++-
>  hw/xtensa/xtfpga.c                       |  4 +++-
>  include/sysemu/blockdev.h                |  1 -
>  43 files changed, 163 insertions(+), 93 deletions(-)
> 
> diff --git a/blockdev.c b/blockdev.c
> index 85f574b..49496b6 100644
> --- a/blockdev.c
> +++ b/blockdev.c
> @@ -472,7 +472,6 @@ static BlockBackend *blockdev_init(const char *file, QDict *bs_opts,
>  
>      dinfo = g_malloc0(sizeof(*dinfo));
>      dinfo->id = g_strdup(qemu_opts_id(opts));
> -    dinfo->bdrv = bs;
>      blk_set_legacy_dinfo(blk, dinfo);
>  
>      if (!file || !*file) {
> @@ -502,7 +501,7 @@ static BlockBackend *blockdev_init(const char *file, QDict *bs_opts,
>  
>      QINCREF(bs_opts);
>      ret = bdrv_open(&bs, file, NULL, bs_opts, bdrv_flags, drv, &error);
> -    assert(bs == dinfo->bdrv);
> +    assert(bs == blk_bs(blk));
>  
>      if (ret < 0) {
>          error_setg(errp, "could not open disk image %s: %s",
> diff --git a/hw/arm/collie.c b/hw/arm/collie.c
> index ed7851f..0247290 100644
> --- a/hw/arm/collie.c
> +++ b/hw/arm/collie.c
> @@ -15,6 +15,7 @@
>  #include "strongarm.h"
>  #include "hw/arm/arm.h"
>  #include "hw/block/flash.h"
> +#include "sysemu/block-backend.h"
>  #include "sysemu/blockdev.h"
>  #include "exec/address-spaces.h"
>  
> @@ -41,13 +42,13 @@ static void collie_init(MachineState *machine)
>  
>      dinfo = drive_get(IF_PFLASH, 0, 0);
>      pflash_cfi01_register(SA_CS0, NULL, "collie.fl1", 0x02000000,
> -                    dinfo ? dinfo->bdrv : NULL, (64 * 1024),
> -                    512, 4, 0x00, 0x00, 0x00, 0x00, 0);
> +                    dinfo ? blk_bs(blk_by_legacy_dinfo(dinfo)) : NULL,
> +                    (64 * 1024), 512, 4, 0x00, 0x00, 0x00, 0x00, 0);
>  
>      dinfo = drive_get(IF_PFLASH, 0, 1);
>      pflash_cfi01_register(SA_CS1, NULL, "collie.fl2", 0x02000000,
> -                    dinfo ? dinfo->bdrv : NULL, (64 * 1024),
> -                    512, 4, 0x00, 0x00, 0x00, 0x00, 0);
> +                    dinfo ? blk_bs(blk_by_legacy_dinfo(dinfo)) : NULL,
> +                    (64 * 1024), 512, 4, 0x00, 0x00, 0x00, 0x00, 0);
>  
>      sysbus_create_simple("scoop", 0x40800000, NULL);
>  
> diff --git a/hw/arm/gumstix.c b/hw/arm/gumstix.c
> index 3f8465e..49f9339 100644
> --- a/hw/arm/gumstix.c
> +++ b/hw/arm/gumstix.c
> @@ -40,6 +40,7 @@
>  #include "hw/block/flash.h"
>  #include "hw/devices.h"
>  #include "hw/boards.h"
> +#include "sysemu/block-backend.h"
>  #include "sysemu/blockdev.h"
>  #include "exec/address-spaces.h"
>  #include "sysemu/qtest.h"
> @@ -71,7 +72,7 @@ static void connex_init(MachineState *machine)
>      be = 0;
>  #endif
>      if (!pflash_cfi01_register(0x00000000, NULL, "connext.rom", connex_rom,
> -                               dinfo ? dinfo->bdrv : NULL,
> +                               dinfo ? blk_bs(blk_by_legacy_dinfo(dinfo)) : NULL,
>                                 sector_len, connex_rom / sector_len,
>                                 2, 0, 0, 0, 0, be)) {
>          fprintf(stderr, "qemu: Error registering flash memory.\n");
> @@ -109,7 +110,7 @@ static void verdex_init(MachineState *machine)
>      be = 0;
>  #endif
>      if (!pflash_cfi01_register(0x00000000, NULL, "verdex.rom", verdex_rom,
> -                               dinfo ? dinfo->bdrv : NULL,
> +                               dinfo ? blk_bs(blk_by_legacy_dinfo(dinfo)) : NULL,
>                                 sector_len, verdex_rom / sector_len,
>                                 2, 0, 0, 0, 0, be)) {
>          fprintf(stderr, "qemu: Error registering flash memory.\n");
> diff --git a/hw/arm/mainstone.c b/hw/arm/mainstone.c
> index 44f1873..fb17d85 100644
> --- a/hw/arm/mainstone.c
> +++ b/hw/arm/mainstone.c
> @@ -18,7 +18,7 @@
>  #include "hw/devices.h"
>  #include "hw/boards.h"
>  #include "hw/block/flash.h"
> -#include "sysemu/blockdev.h"
> +#include "sysemu/block-backend.h"
>  #include "hw/sysbus.h"
>  #include "exec/address-spaces.h"
>  #include "sysemu/qtest.h"
> @@ -148,9 +148,9 @@ static void mainstone_common_init(MemoryRegion *address_space_mem,
>          if (!pflash_cfi01_register(mainstone_flash_base[i], NULL,
>                                     i ? "mainstone.flash1" : "mainstone.flash0",
>                                     MAINSTONE_FLASH,
> -                                   dinfo->bdrv, sector_len,
> -                                   MAINSTONE_FLASH / sector_len, 4, 0, 0, 0, 0,
> -                                   be)) {
> +                                   blk_bs(blk_by_legacy_dinfo(dinfo)),
> +                                   sector_len, MAINSTONE_FLASH / sector_len,
> +                                   4, 0, 0, 0, 0, be)) {
>              fprintf(stderr, "qemu: Error registering flash memory.\n");
>              exit(1);
>          }
> diff --git a/hw/arm/musicpal.c b/hw/arm/musicpal.c
> index 6a134f2..6a41d9c 100644
> --- a/hw/arm/musicpal.c
> +++ b/hw/arm/musicpal.c
> @@ -22,6 +22,7 @@
>  #include "hw/block/flash.h"
>  #include "ui/console.h"
>  #include "hw/i2c/i2c.h"
> +#include "sysemu/block-backend.h"
>  #include "sysemu/blockdev.h"
>  #include "exec/address-spaces.h"
>  #include "ui/pixel_ops.h"
> @@ -1630,7 +1631,9 @@ static void musicpal_init(MachineState *machine)
>      /* Register flash */
>      dinfo = drive_get(IF_PFLASH, 0, 0);
>      if (dinfo) {
> -        flash_size = bdrv_getlength(dinfo->bdrv);
> +        BlockDriverState *bs = blk_bs(blk_by_legacy_dinfo(dinfo));
> +
> +        flash_size = bdrv_getlength(bs);
>          if (flash_size != 8*1024*1024 && flash_size != 16*1024*1024 &&
>              flash_size != 32*1024*1024) {
>              fprintf(stderr, "Invalid flash image size\n");
> @@ -1645,16 +1648,14 @@ static void musicpal_init(MachineState *machine)
>  #ifdef TARGET_WORDS_BIGENDIAN
>          pflash_cfi02_register(0x100000000ULL-MP_FLASH_SIZE_MAX, NULL,
>                                "musicpal.flash", flash_size,
> -                              dinfo->bdrv, 0x10000,
> -                              (flash_size + 0xffff) >> 16,
> +                              bs, 0x10000, (flash_size + 0xffff) >> 16,
>                                MP_FLASH_SIZE_MAX / flash_size,
>                                2, 0x00BF, 0x236D, 0x0000, 0x0000,
>                                0x5555, 0x2AAA, 1);
>  #else
>          pflash_cfi02_register(0x100000000ULL-MP_FLASH_SIZE_MAX, NULL,
>                                "musicpal.flash", flash_size,
> -                              dinfo->bdrv, 0x10000,
> -                              (flash_size + 0xffff) >> 16,
> +                              bs, 0x10000, (flash_size + 0xffff) >> 16,
>                                MP_FLASH_SIZE_MAX / flash_size,
>                                2, 0x00BF, 0x236D, 0x0000, 0x0000,
>                                0x5555, 0x2AAA, 0);
> diff --git a/hw/arm/nseries.c b/hw/arm/nseries.c
> index 4f092d6..2536078 100644
> --- a/hw/arm/nseries.c
> +++ b/hw/arm/nseries.c
> @@ -31,6 +31,7 @@
>  #include "hw/hw.h"
>  #include "hw/bt.h"
>  #include "hw/loader.h"
> +#include "sysemu/block-backend.h"
>  #include "sysemu/blockdev.h"
>  #include "hw/sysbus.h"
>  #include "exec/address-spaces.h"
> @@ -172,8 +173,9 @@ static void n8x0_nand_setup(struct n800_s *s)
>      qdev_prop_set_uint16(s->nand, "version_id", 0);
>      qdev_prop_set_int32(s->nand, "shift", 1);
>      dinfo = drive_get(IF_MTD, 0, 0);
> -    if (dinfo && dinfo->bdrv) {
> -        qdev_prop_set_drive_nofail(s->nand, "drive", dinfo->bdrv);
> +    if (dinfo) {
> +        qdev_prop_set_drive_nofail(s->nand, "drive",
> +                                   blk_bs(blk_by_legacy_dinfo(dinfo)));
>      }
>      qdev_init_nofail(s->nand);
>      sysbus_connect_irq(SYS_BUS_DEVICE(s->nand), 0,
> diff --git a/hw/arm/omap1.c b/hw/arm/omap1.c
> index e7cc5d7..e38e07f 100644
> --- a/hw/arm/omap1.c
> +++ b/hw/arm/omap1.c
> @@ -21,6 +21,7 @@
>  #include "hw/arm/omap.h"
>  #include "sysemu/sysemu.h"
>  #include "hw/arm/soc_dma.h"
> +#include "sysemu/block-backend.h"
>  #include "sysemu/blockdev.h"
>  #include "qemu/range.h"
>  #include "hw/sysbus.h"
> @@ -3976,7 +3977,8 @@ struct omap_mpu_state_s *omap310_mpu_init(MemoryRegion *system_memory,
>          fprintf(stderr, "qemu: missing SecureDigital device\n");
>          exit(1);
>      }
> -    s->mmc = omap_mmc_init(0xfffb7800, system_memory, dinfo->bdrv,
> +    s->mmc = omap_mmc_init(0xfffb7800, system_memory,
> +                           blk_bs(blk_by_legacy_dinfo(dinfo)),
>                             qdev_get_gpio_in(s->ih[1], OMAP_INT_OQN),
>                             &s->drq[OMAP_DMA_MMC_TX],
>                      omap_findclk(s, "mmc_ck"));
> diff --git a/hw/arm/omap2.c b/hw/arm/omap2.c
> index dc53a7a..e47dd63 100644
> --- a/hw/arm/omap2.c
> +++ b/hw/arm/omap2.c
> @@ -18,6 +18,7 @@
>   * with this program; if not, see <http://www.gnu.org/licenses/>.
>   */
>  
> +#include "sysemu/block-backend.h"
>  #include "sysemu/blockdev.h"
>  #include "hw/hw.h"
>  #include "hw/arm/arm.h"
> @@ -2459,7 +2460,8 @@ struct omap_mpu_state_s *omap2420_mpu_init(MemoryRegion *sysmem,
>          fprintf(stderr, "qemu: missing SecureDigital device\n");
>          exit(1);
>      }
> -    s->mmc = omap2_mmc_init(omap_l4tao(s->l4, 9), dinfo->bdrv,
> +    s->mmc = omap2_mmc_init(omap_l4tao(s->l4, 9),
> +                    blk_bs(blk_by_legacy_dinfo(dinfo)),
>                      qdev_get_gpio_in(s->ih[0], OMAP_INT_24XX_MMC_IRQ),
>                      &s->drq[OMAP24XX_DMA_MMC1_TX],
>                      omap_findclk(s, "mmc_fclk"), omap_findclk(s, "mmc_iclk"));
> diff --git a/hw/arm/omap_sx1.c b/hw/arm/omap_sx1.c
> index b4f6da6..f475afc 100644
> --- a/hw/arm/omap_sx1.c
> +++ b/hw/arm/omap_sx1.c
> @@ -31,6 +31,7 @@
>  #include "hw/boards.h"
>  #include "hw/arm/arm.h"
>  #include "hw/block/flash.h"
> +#include "sysemu/block-backend.h"
>  #include "sysemu/blockdev.h"
>  #include "sysemu/qtest.h"
>  #include "exec/address-spaces.h"
> @@ -153,8 +154,8 @@ static void sx1_init(MachineState *machine, const int version)
>      if ((dinfo = drive_get(IF_PFLASH, 0, fl_idx)) != NULL) {
>          if (!pflash_cfi01_register(OMAP_CS0_BASE, NULL,
>                                     "omap_sx1.flash0-1", flash_size,
> -                                   dinfo->bdrv, sector_size,
> -                                   flash_size / sector_size,
> +                                   blk_bs(blk_by_legacy_dinfo(dinfo)),
> +                                   sector_size, flash_size / sector_size,
>                                     4, 0, 0, 0, 0, be)) {
>              fprintf(stderr, "qemu: Error registering flash memory %d.\n",
>                             fl_idx);
> @@ -176,8 +177,8 @@ static void sx1_init(MachineState *machine, const int version)
>  
>          if (!pflash_cfi01_register(OMAP_CS1_BASE, NULL,
>                                     "omap_sx1.flash1-1", flash1_size,
> -                                   dinfo->bdrv, sector_size,
> -                                   flash1_size / sector_size,
> +                                   blk_bs(blk_by_legacy_dinfo(dinfo)),
> +                                   sector_size, flash1_size / sector_size,
>                                     4, 0, 0, 0, 0, be)) {
>              fprintf(stderr, "qemu: Error registering flash memory %d.\n",
>                             fl_idx);
> diff --git a/hw/arm/pxa2xx.c b/hw/arm/pxa2xx.c
> index 557e0f1..7ec0da8 100644
> --- a/hw/arm/pxa2xx.c
> +++ b/hw/arm/pxa2xx.c
> @@ -14,6 +14,7 @@
>  #include "hw/i2c/i2c.h"
>  #include "hw/ssi.h"
>  #include "sysemu/char.h"
> +#include "sysemu/block-backend.h"
>  #include "sysemu/blockdev.h"
>  
>  static struct {
> @@ -2083,7 +2084,8 @@ PXA2xxState *pxa270_init(MemoryRegion *address_space,
>          fprintf(stderr, "qemu: missing SecureDigital device\n");
>          exit(1);
>      }
> -    s->mmc = pxa2xx_mmci_init(address_space, 0x41100000, dinfo->bdrv,
> +    s->mmc = pxa2xx_mmci_init(address_space, 0x41100000,
> +                    blk_bs(blk_by_legacy_dinfo(dinfo)),
>                      qdev_get_gpio_in(s->pic, PXA2XX_PIC_MMC),
>                      qdev_get_gpio_in(s->dma, PXA2XX_RX_RQ_MMCI),
>                      qdev_get_gpio_in(s->dma, PXA2XX_TX_RQ_MMCI));
> @@ -2214,7 +2216,8 @@ PXA2xxState *pxa255_init(MemoryRegion *address_space, unsigned int sdram_size)
>          fprintf(stderr, "qemu: missing SecureDigital device\n");
>          exit(1);
>      }
> -    s->mmc = pxa2xx_mmci_init(address_space, 0x41100000, dinfo->bdrv,
> +    s->mmc = pxa2xx_mmci_init(address_space, 0x41100000,
> +                    blk_bs(blk_by_legacy_dinfo(dinfo)),
>                      qdev_get_gpio_in(s->pic, PXA2XX_PIC_MMC),
>                      qdev_get_gpio_in(s->dma, PXA2XX_RX_RQ_MMCI),
>                      qdev_get_gpio_in(s->dma, PXA2XX_TX_RQ_MMCI));
> diff --git a/hw/arm/spitz.c b/hw/arm/spitz.c
> index 03cc6ce..5d684a2 100644
> --- a/hw/arm/spitz.c
> +++ b/hw/arm/spitz.c
> @@ -25,6 +25,7 @@
>  #include "block/block.h"
>  #include "audio/audio.h"
>  #include "hw/boards.h"
> +#include "sysemu/block-backend.h"
>  #include "sysemu/blockdev.h"
>  #include "hw/sysbus.h"
>  #include "exec/address-spaces.h"
> @@ -170,7 +171,8 @@ static int sl_nand_init(SysBusDevice *dev)
>  
>      s->ctl = 0;
>      nand = drive_get(IF_MTD, 0, 0);
> -    s->nand = nand_init(nand ? nand->bdrv : NULL, s->manf_id, s->chip_id);
> +    s->nand = nand_init(nand ? blk_bs(blk_by_legacy_dinfo(nand)) : NULL,
> +                        s->manf_id, s->chip_id);
>  
>      memory_region_init_io(&s->iomem, OBJECT(s), &sl_ops, s, "sl", 0x40);
>      sysbus_init_mmio(dev, &s->iomem);
> diff --git a/hw/arm/versatilepb.c b/hw/arm/versatilepb.c
> index dea5fc7..c88be6b 100644
> --- a/hw/arm/versatilepb.c
> +++ b/hw/arm/versatilepb.c
> @@ -15,6 +15,7 @@
>  #include "hw/pci/pci.h"
>  #include "hw/i2c/i2c.h"
>  #include "hw/boards.h"
> +#include "sysemu/block-backend.h"
>  #include "sysemu/blockdev.h"
>  #include "exec/address-spaces.h"
>  #include "hw/block/flash.h"
> @@ -337,7 +338,8 @@ static void versatile_init(MachineState *machine, int board_id)
>  
>      dinfo = drive_get(IF_PFLASH, 0, 0);
>      if (!pflash_cfi01_register(VERSATILE_FLASH_ADDR, NULL, "versatile.flash",
> -                          VERSATILE_FLASH_SIZE, dinfo ? dinfo->bdrv : NULL,
> +                          VERSATILE_FLASH_SIZE,
> +                          dinfo ? blk_bs(blk_by_legacy_dinfo(dinfo)) : NULL,
>                            VERSATILE_FLASH_SECT_SIZE,
>                            VERSATILE_FLASH_SIZE / VERSATILE_FLASH_SECT_SIZE,
>                            4, 0x0089, 0x0018, 0x0000, 0x0, 0)) {
> diff --git a/hw/arm/vexpress.c b/hw/arm/vexpress.c
> index a88732c..a492c22 100644
> --- a/hw/arm/vexpress.c
> +++ b/hw/arm/vexpress.c
> @@ -30,6 +30,7 @@
>  #include "hw/boards.h"
>  #include "hw/loader.h"
>  #include "exec/address-spaces.h"
> +#include "sysemu/block-backend.h"
>  #include "sysemu/blockdev.h"
>  #include "hw/block/flash.h"
>  #include "sysemu/device_tree.h"
> @@ -488,7 +489,8 @@ static pflash_t *ve_pflash_cfi01_register(hwaddr base, const char *name,
>  {
>      DeviceState *dev = qdev_create(NULL, "cfi.pflash01");
>  
> -    if (di && qdev_prop_set_drive(dev, "drive", di->bdrv)) {
> +    if (di && qdev_prop_set_drive(dev, "drive",
> +                                  blk_bs(blk_by_legacy_dinfo(di)))) {
>          abort();
>      }
>  
> diff --git a/hw/arm/xilinx_zynq.c b/hw/arm/xilinx_zynq.c
> index ba5aa82..78e6934 100644
> --- a/hw/arm/xilinx_zynq.c
> +++ b/hw/arm/xilinx_zynq.c
> @@ -22,6 +22,7 @@
>  #include "sysemu/sysemu.h"
>  #include "hw/boards.h"
>  #include "hw/block/flash.h"
> +#include "sysemu/block-backend.h"
>  #include "sysemu/blockdev.h"
>  #include "hw/loader.h"
>  #include "hw/ssi.h"
> @@ -162,7 +163,8 @@ static void zynq_init(MachineState *machine)
>  
>      /* AMD */
>      pflash_cfi02_register(0xe2000000, NULL, "zynq.pflash", FLASH_SIZE,
> -                          dinfo ? dinfo->bdrv : NULL, FLASH_SECTOR_SIZE,
> +                          dinfo ? blk_bs(blk_by_legacy_dinfo(dinfo)) : NULL,
> +                          FLASH_SECTOR_SIZE,
>                            FLASH_SIZE/FLASH_SECTOR_SIZE, 1,
>                            1, 0x0066, 0x0022, 0x0000, 0x0000, 0x0555, 0x2aa,
>                                0);
> diff --git a/hw/arm/z2.c b/hw/arm/z2.c
> index 36b3b50..9b38a2b 100644
> --- a/hw/arm/z2.c
> +++ b/hw/arm/z2.c
> @@ -20,6 +20,7 @@
>  #include "hw/boards.h"
>  #include "sysemu/sysemu.h"
>  #include "hw/block/flash.h"
> +#include "sysemu/block-backend.h"
>  #include "sysemu/blockdev.h"
>  #include "ui/console.h"
>  #include "audio/audio.h"
> @@ -336,9 +337,9 @@ static void z2_init(MachineState *machine)
>  
>      if (!pflash_cfi01_register(Z2_FLASH_BASE,
>                                 NULL, "z2.flash0", Z2_FLASH_SIZE,
> -                               dinfo ? dinfo->bdrv : NULL, sector_len,
> -                               Z2_FLASH_SIZE / sector_len, 4, 0, 0, 0, 0,
> -                               be)) {
> +                               dinfo ? blk_bs(blk_by_legacy_dinfo(dinfo)) : NULL,
> +                               sector_len, Z2_FLASH_SIZE / sector_len,
> +                               4, 0, 0, 0, 0, be)) {
>          fprintf(stderr, "qemu: Error registering flash memory.\n");
>          exit(1);
>      }
> diff --git a/hw/block/fdc.c b/hw/block/fdc.c
> index 490d127..19f215f 100644
> --- a/hw/block/fdc.c
> +++ b/hw/block/fdc.c
> @@ -33,6 +33,7 @@
>  #include "qemu/timer.h"
>  #include "hw/isa/isa.h"
>  #include "hw/sysbus.h"
> +#include "sysemu/block-backend.h"
>  #include "sysemu/blockdev.h"
>  #include "sysemu/sysemu.h"
>  #include "qemu/log.h"
> @@ -2033,10 +2034,12 @@ ISADevice *fdctrl_init_isa(ISABus *bus, DriveInfo **fds)
>      dev = DEVICE(isadev);
>  
>      if (fds[0]) {
> -        qdev_prop_set_drive_nofail(dev, "driveA", fds[0]->bdrv);
> +        qdev_prop_set_drive_nofail(dev, "driveA",
> +                                   blk_bs(blk_by_legacy_dinfo(fds[0])));
>      }
>      if (fds[1]) {
> -        qdev_prop_set_drive_nofail(dev, "driveB", fds[1]->bdrv);
> +        qdev_prop_set_drive_nofail(dev, "driveB",
> +                                   blk_bs(blk_by_legacy_dinfo(fds[1])));
>      }
>      qdev_init_nofail(dev);
>  
> @@ -2056,10 +2059,12 @@ void fdctrl_init_sysbus(qemu_irq irq, int dma_chann,
>      fdctrl = &sys->state;
>      fdctrl->dma_chann = dma_chann; /* FIXME */
>      if (fds[0]) {
> -        qdev_prop_set_drive_nofail(dev, "driveA", fds[0]->bdrv);
> +        qdev_prop_set_drive_nofail(dev, "driveA",
> +                                   blk_bs(blk_by_legacy_dinfo(fds[0])));
>      }
>      if (fds[1]) {
> -        qdev_prop_set_drive_nofail(dev, "driveB", fds[1]->bdrv);
> +        qdev_prop_set_drive_nofail(dev, "driveB",
> +                                   blk_bs(blk_by_legacy_dinfo(fds[1])));
>      }
>      qdev_init_nofail(dev);
>      sbd = SYS_BUS_DEVICE(dev);
> @@ -2075,7 +2080,8 @@ void sun4m_fdctrl_init(qemu_irq irq, hwaddr io_base,
>  
>      dev = qdev_create(NULL, "SUNW,fdtwo");
>      if (fds[0]) {
> -        qdev_prop_set_drive_nofail(dev, "drive", fds[0]->bdrv);
> +        qdev_prop_set_drive_nofail(dev, "drive",
> +                                   blk_bs(blk_by_legacy_dinfo(fds[0])));
>      }
>      qdev_init_nofail(dev);
>      sys = SYSBUS_FDC(dev);
> diff --git a/hw/block/m25p80.c b/hw/block/m25p80.c
> index 5893773..78280a8 100644
> --- a/hw/block/m25p80.c
> +++ b/hw/block/m25p80.c
> @@ -22,6 +22,7 @@
>   */
>  
>  #include "hw/hw.h"
> +#include "sysemu/block-backend.h"
>  #include "sysemu/blockdev.h"
>  #include "hw/ssi.h"
>  
> @@ -624,9 +625,9 @@ static int m25p80_init(SSISlave *ss)
>  
>      dinfo = drive_get_next(IF_MTD);
>  
> -    if (dinfo && dinfo->bdrv) {
> +    if (dinfo) {
>          DB_PRINT_L(0, "Binding to IF_MTD drive\n");
> -        s->bdrv = dinfo->bdrv;
> +        s->bdrv = blk_bs(blk_by_legacy_dinfo(dinfo));
>  
>          /* FIXME: Move to late init */
>          if (bdrv_read(s->bdrv, 0, s->storage, DIV_ROUND_UP(s->size,
> diff --git a/hw/block/xen_disk.c b/hw/block/xen_disk.c
> index 6d474b9..b571bbe 100644
> --- a/hw/block/xen_disk.c
> +++ b/hw/block/xen_disk.c
> @@ -877,7 +877,7 @@ static int blk_connect(struct XenDevice *xendev)
>      } else {
>          /* setup via qemu cmdline -> already setup for us */
>          xen_be_printf(&blkdev->xendev, 2, "get configured bdrv (cmdline setup)\n");
> -        blkdev->bs = blkdev->dinfo->bdrv;
> +        blkdev->bs = blk_bs(blk_by_legacy_dinfo(blkdev->dinfo));
>          if (bdrv_is_read_only(blkdev->bs) && !readonly) {
>              xen_be_printf(&blkdev->xendev, 0, "Unexpected read-only drive");
>              blkdev->bs = NULL;
> diff --git a/hw/cris/axis_dev88.c b/hw/cris/axis_dev88.c
> index 1849338..280722d 100644
> --- a/hw/cris/axis_dev88.c
> +++ b/hw/cris/axis_dev88.c
> @@ -30,6 +30,7 @@
>  #include "hw/loader.h"
>  #include "elf.h"
>  #include "boot.h"
> +#include "sysemu/block-backend.h"
>  #include "sysemu/blockdev.h"
>  #include "exec/address-spaces.h"
>  #include "sysemu/qtest.h"
> @@ -282,7 +283,7 @@ void axisdev88_init(MachineState *machine)
>  
>        /* Attach a NAND flash to CS1.  */
>      nand = drive_get(IF_MTD, 0, 0);
> -    nand_state.nand = nand_init(nand ? nand->bdrv : NULL,
> +    nand_state.nand = nand_init(nand ? blk_bs(blk_by_legacy_dinfo(nand)) : NULL,
>                                  NAND_MFR_STMICRO, 0x39);
>      memory_region_init_io(&nand_state.iomem, NULL, &nand_ops, &nand_state,
>                            "nand", 0x05000000);
> diff --git a/hw/display/tc6393xb.c b/hw/display/tc6393xb.c
> index f4011d2..62d6663 100644
> --- a/hw/display/tc6393xb.c
> +++ b/hw/display/tc6393xb.c
> @@ -15,6 +15,7 @@
>  #include "hw/block/flash.h"
>  #include "ui/console.h"
>  #include "ui/pixel_ops.h"
> +#include "sysemu/block-backend.h"
>  #include "sysemu/blockdev.h"
>  
>  #define IRQ_TC6393_NAND		0
> @@ -576,7 +577,8 @@ TC6393xbState *tc6393xb_init(MemoryRegion *sysmem, uint32_t base, qemu_irq irq)
>      s->sub_irqs = qemu_allocate_irqs(tc6393xb_sub_irq, s, TC6393XB_NR_IRQS);
>  
>      nand = drive_get(IF_MTD, 0, 0);
> -    s->flash = nand_init(nand ? nand->bdrv : NULL, NAND_MFR_TOSHIBA, 0x76);
> +    s->flash = nand_init(nand ? blk_bs(blk_by_legacy_dinfo(nand)) : NULL,
> +                         NAND_MFR_TOSHIBA, 0x76);
>  
>      memory_region_init_io(&s->iomem, NULL, &tc6393xb_ops, s, "tc6393xb", 0x10000);
>      memory_region_add_subregion(sysmem, base, &s->iomem);
> diff --git a/hw/i386/pc_sysfw.c b/hw/i386/pc_sysfw.c
> index 75a7ebb..6cd264a 100644
> --- a/hw/i386/pc_sysfw.c
> +++ b/hw/i386/pc_sysfw.c
> @@ -23,6 +23,7 @@
>   * THE SOFTWARE.
>   */
>  
> +#include "sysemu/block-backend.h"
>  #include "sysemu/blockdev.h"
>  #include "qemu/error-report.h"
>  #include "hw/sysbus.h"
> @@ -118,7 +119,7 @@ static void pc_system_flash_init(MemoryRegion *rom_memory)
>           (unit < FLASH_MAP_UNIT_MAX &&
>            (pflash_drv = drive_get(IF_PFLASH, 0, unit)) != NULL);
>           ++unit) {
> -        bdrv = pflash_drv->bdrv;
> +        bdrv = blk_bs(blk_by_legacy_dinfo(pflash_drv));
>          size = bdrv_getlength(bdrv);
>          if (size < 0) {
>              fatal_errmsg = g_strdup_printf("failed to get backing file size");
> diff --git a/hw/ide/piix.c b/hw/ide/piix.c
> index 49e78a7..c6c256f 100644
> --- a/hw/ide/piix.c
> +++ b/hw/ide/piix.c
> @@ -27,6 +27,7 @@
>  #include <hw/i386/pc.h>
>  #include <hw/pci/pci.h>
>  #include <hw/isa/isa.h>
> +#include "sysemu/block-backend.h"
>  #include "sysemu/blockdev.h"
>  #include "sysemu/sysemu.h"
>  #include "sysemu/dma.h"
> @@ -178,9 +179,10 @@ int pci_piix3_xen_ide_unplug(DeviceState *dev)
>      for (; i < 3; i++) {
>          di = drive_get_by_index(IF_IDE, i);
>          if (di != NULL && !di->media_cd) {
> -            DeviceState *ds = bdrv_get_attached_dev(di->bdrv);
> +            BlockDriverState *bs = blk_bs(blk_by_legacy_dinfo(di));
> +            DeviceState *ds = bdrv_get_attached_dev(bs);
>              if (ds) {
> -                bdrv_detach_dev(di->bdrv, ds);
> +                bdrv_detach_dev(bs, ds);
>              }
>              pci_ide->bus[di->bus].ifs[di->unit].bs = NULL;
>              drive_del(di);
> diff --git a/hw/ide/qdev.c b/hw/ide/qdev.c
> index efab95b..75e8eb3 100644
> --- a/hw/ide/qdev.c
> +++ b/hw/ide/qdev.c
> @@ -20,6 +20,7 @@
>  #include "sysemu/dma.h"
>  #include "qemu/error-report.h"
>  #include <hw/ide/internal.h>
> +#include "sysemu/block-backend.h"
>  #include "sysemu/blockdev.h"
>  #include "hw/block/block.h"
>  #include "sysemu/sysemu.h"
> @@ -116,7 +117,8 @@ IDEDevice *ide_create_drive(IDEBus *bus, int unit, DriveInfo *drive)
>  
>      dev = qdev_create(&bus->qbus, drive->media_cd ? "ide-cd" : "ide-hd");
>      qdev_prop_set_uint32(dev, "unit", unit);
> -    qdev_prop_set_drive_nofail(dev, "drive", drive->bdrv);
> +    qdev_prop_set_drive_nofail(dev, "drive",
> +                               blk_bs(blk_by_legacy_dinfo(drive)));
>      qdev_init_nofail(dev);
>      return DO_UPCAST(IDEDevice, qdev, dev);
>  }
> diff --git a/hw/isa/pc87312.c b/hw/isa/pc87312.c
> index 9327c53..b691a0c 100644
> --- a/hw/isa/pc87312.c
> +++ b/hw/isa/pc87312.c
> @@ -25,6 +25,7 @@
>  
>  #include "hw/isa/pc87312.h"
>  #include "qemu/error-report.h"
> +#include "sysemu/block-backend.h"
>  #include "sysemu/blockdev.h"
>  #include "sysemu/sysemu.h"
>  #include "sysemu/char.h"
> @@ -320,11 +321,13 @@ static void pc87312_realize(DeviceState *dev, Error **errp)
>          qdev_prop_set_uint32(d, "irq", 6);
>          drive = drive_get(IF_FLOPPY, 0, 0);
>          if (drive != NULL) {
> -            qdev_prop_set_drive_nofail(d, "driveA", drive->bdrv);
> +            qdev_prop_set_drive_nofail(d, "driveA",
> +                                       blk_bs(blk_by_legacy_dinfo(drive)));
>          }
>          drive = drive_get(IF_FLOPPY, 0, 1);
>          if (drive != NULL) {
> -            qdev_prop_set_drive_nofail(d, "driveB", drive->bdrv);
> +            qdev_prop_set_drive_nofail(d, "driveB",
> +                                       blk_bs(blk_by_legacy_dinfo(drive)));
>          }
>          qdev_init_nofail(d);
>          s->fdc.dev = isa;
> diff --git a/hw/lm32/lm32_boards.c b/hw/lm32/lm32_boards.c
> index 0e01340..17c5610 100644
> --- a/hw/lm32/lm32_boards.c
> +++ b/hw/lm32/lm32_boards.c
> @@ -23,6 +23,7 @@
>  #include "hw/devices.h"
>  #include "hw/boards.h"
>  #include "hw/loader.h"
> +#include "sysemu/block-backend.h"
>  #include "sysemu/blockdev.h"
>  #include "elf.h"
>  #include "lm32_hwsetup.h"
> @@ -118,9 +119,9 @@ static void lm32_evr_init(MachineState *machine)
>      dinfo = drive_get(IF_PFLASH, 0, 0);
>      /* Spansion S29NS128P */
>      pflash_cfi02_register(flash_base, NULL, "lm32_evr.flash", flash_size,
> -                          dinfo ? dinfo->bdrv : NULL, flash_sector_size,
> -                          flash_size / flash_sector_size, 1, 2,
> -                          0x01, 0x7e, 0x43, 0x00, 0x555, 0x2aa, 1);
> +                          dinfo ? blk_bs(blk_by_legacy_dinfo(dinfo)) : NULL,
> +                          flash_sector_size, flash_size / flash_sector_size,
> +                          1, 2, 0x01, 0x7e, 0x43, 0x00, 0x555, 0x2aa, 1);
>  
>      /* create irq lines */
>      cpu_irq = qemu_allocate_irqs(cpu_irq_handler, cpu, 1);
> @@ -220,9 +221,9 @@ static void lm32_uclinux_init(MachineState *machine)
>      dinfo = drive_get(IF_PFLASH, 0, 0);
>      /* Spansion S29NS128P */
>      pflash_cfi02_register(flash_base, NULL, "lm32_uclinux.flash", flash_size,
> -                          dinfo ? dinfo->bdrv : NULL, flash_sector_size,
> -                          flash_size / flash_sector_size, 1, 2,
> -                          0x01, 0x7e, 0x43, 0x00, 0x555, 0x2aa, 1);
> +                          dinfo ? blk_bs(blk_by_legacy_dinfo(dinfo)) : NULL,
> +                          flash_sector_size, flash_size / flash_sector_size,
> +                          1, 2, 0x01, 0x7e, 0x43, 0x00, 0x555, 0x2aa, 1);
>  
>      /* create irq lines */
>      cpu_irq = qemu_allocate_irqs(cpu_irq_handler, env, 1);
> diff --git a/hw/lm32/milkymist.c b/hw/lm32/milkymist.c
> index 81c3933..904b9c0 100644
> --- a/hw/lm32/milkymist.c
> +++ b/hw/lm32/milkymist.c
> @@ -26,6 +26,7 @@
>  #include "hw/boards.h"
>  #include "hw/loader.h"
>  #include "elf.h"
> +#include "sysemu/block-backend.h"
>  #include "sysemu/blockdev.h"
>  #include "milkymist-hw.h"
>  #include "lm32.h"
> @@ -125,9 +126,9 @@ milkymist_init(MachineState *machine)
>      dinfo = drive_get(IF_PFLASH, 0, 0);
>      /* Numonyx JS28F256J3F105 */
>      pflash_cfi01_register(flash_base, NULL, "milkymist.flash", flash_size,
> -                          dinfo ? dinfo->bdrv : NULL, flash_sector_size,
> -                          flash_size / flash_sector_size, 2,
> -                          0x00, 0x89, 0x00, 0x1d, 1);
> +                          dinfo ? blk_bs(blk_by_legacy_dinfo(dinfo)) : NULL,
> +                          flash_sector_size, flash_size / flash_sector_size,
> +                          2, 0x00, 0x89, 0x00, 0x1d, 1);
>  
>      /* create irq lines */
>      cpu_irq = qemu_allocate_irqs(cpu_irq_handler, cpu, 1);
> diff --git a/hw/microblaze/petalogix_ml605_mmu.c b/hw/microblaze/petalogix_ml605_mmu.c
> index 6843abf..2974791 100644
> --- a/hw/microblaze/petalogix_ml605_mmu.c
> +++ b/hw/microblaze/petalogix_ml605_mmu.c
> @@ -32,6 +32,7 @@
>  #include "sysemu/sysemu.h"
>  #include "hw/devices.h"
>  #include "hw/boards.h"
> +#include "sysemu/block-backend.h"
>  #include "sysemu/blockdev.h"
>  #include "hw/char/serial.h"
>  #include "exec/address-spaces.h"
> @@ -112,8 +113,8 @@ petalogix_ml605_init(MachineState *machine)
>       * 10th paremeter 0 means little-endian */
>      pflash_cfi01_register(FLASH_BASEADDR,
>                            NULL, "petalogix_ml605.flash", FLASH_SIZE,
> -                          dinfo ? dinfo->bdrv : NULL, (64 * 1024),
> -                          FLASH_SIZE >> 16,
> +                          dinfo ? blk_bs(blk_by_legacy_dinfo(dinfo)) : NULL,
> +                          (64 * 1024), FLASH_SIZE >> 16,
>                            2, 0x89, 0x18, 0x0000, 0x0, 0);
>  
>  
> diff --git a/hw/microblaze/petalogix_s3adsp1800_mmu.c b/hw/microblaze/petalogix_s3adsp1800_mmu.c
> index 49dc6d1..a69301f 100644
> --- a/hw/microblaze/petalogix_s3adsp1800_mmu.c
> +++ b/hw/microblaze/petalogix_s3adsp1800_mmu.c
> @@ -30,6 +30,7 @@
>  #include "sysemu/sysemu.h"
>  #include "hw/devices.h"
>  #include "hw/boards.h"
> +#include "sysemu/block-backend.h"
>  #include "sysemu/blockdev.h"
>  #include "exec/address-spaces.h"
>  
> @@ -92,8 +93,8 @@ petalogix_s3adsp1800_init(MachineState *machine)
>      dinfo = drive_get(IF_PFLASH, 0, 0);
>      pflash_cfi01_register(FLASH_BASEADDR,
>                            NULL, "petalogix_s3adsp1800.flash", FLASH_SIZE,
> -                          dinfo ? dinfo->bdrv : NULL, (64 * 1024),
> -                          FLASH_SIZE >> 16,
> +                          dinfo ? blk_bs(blk_by_legacy_dinfo(dinfo)) : NULL,
> +                          (64 * 1024), FLASH_SIZE >> 16,
>                            1, 0x89, 0x18, 0x0000, 0x0, 1);
>  
>      dev = qdev_create(NULL, "xlnx.xps-intc");
> diff --git a/hw/mips/mips_malta.c b/hw/mips/mips_malta.c
> index cfb60af..9f84ad6 100644
> --- a/hw/mips/mips_malta.c
> +++ b/hw/mips/mips_malta.c
> @@ -44,6 +44,7 @@
>  #include "elf.h"
>  #include "hw/timer/mc146818rtc.h"
>  #include "hw/timer/i8254.h"
> +#include "sysemu/block-backend.h"
>  #include "sysemu/blockdev.h"
>  #include "exec/address-spaces.h"
>  #include "hw/sysbus.h"             /* SysBusDevice */
> @@ -1035,7 +1036,8 @@ void mips_malta_init(MachineState *machine)
>      }
>  #endif
>      fl = pflash_cfi01_register(FLASH_ADDRESS, NULL, "mips_malta.bios",
> -                               BIOS_SIZE, dinfo ? dinfo->bdrv : NULL,
> +                               BIOS_SIZE,
> +                               dinfo ? blk_bs(blk_by_legacy_dinfo(dinfo)) : NULL,
>                                 65536, fl_sectors,
>                                 4, 0x0000, 0x0000, 0x0000, 0x0000, be);
>      bios = pflash_cfi01_get_memory(fl);
> diff --git a/hw/mips/mips_r4k.c b/hw/mips/mips_r4k.c
> index 7120293..6fd69b9 100644
> --- a/hw/mips/mips_r4k.c
> +++ b/hw/mips/mips_r4k.c
> @@ -24,6 +24,7 @@
>  #include "elf.h"
>  #include "hw/timer/mc146818rtc.h"
>  #include "hw/timer/i8254.h"
> +#include "sysemu/block-backend.h"
>  #include "sysemu/blockdev.h"
>  #include "exec/address-spaces.h"
>  #include "sysemu/qtest.h"
> @@ -240,8 +241,8 @@ void mips_r4k_init(MachineState *machine)
>      } else if ((dinfo = drive_get(IF_PFLASH, 0, 0)) != NULL) {
>          uint32_t mips_rom = 0x00400000;
>          if (!pflash_cfi01_register(0x1fc00000, NULL, "mips_r4k.bios", mips_rom,
> -                                   dinfo->bdrv, sector_len,
> -                                   mips_rom / sector_len,
> +                                   blk_bs(blk_by_legacy_dinfo(dinfo)),
> +                                   sector_len, mips_rom / sector_len,
>                                     4, 0, 0, 0, 0, be)) {
>              fprintf(stderr, "qemu: Error registering flash memory.\n");
>  	}
> diff --git a/hw/pci/pci-hotplug-old.c b/hw/pci/pci-hotplug-old.c
> index cf2caeb..e4d51de 100644
> --- a/hw/pci/pci-hotplug-old.c
> +++ b/hw/pci/pci-hotplug-old.c
> @@ -33,6 +33,7 @@
>  #include "hw/scsi/scsi.h"
>  #include "hw/virtio/virtio-blk.h"
>  #include "qemu/config-file.h"
> +#include "sysemu/block-backend.h"
>  #include "sysemu/blockdev.h"
>  #include "qapi/error.h"
>  
> @@ -126,8 +127,9 @@ static int scsi_hot_add(Monitor *mon, DeviceState *adapter,
>       */
>      dinfo->unit = qemu_opt_get_number(dinfo->opts, "unit", -1);
>      dinfo->bus = scsibus->busnr;
> -    scsidev = scsi_bus_legacy_add_drive(scsibus, dinfo->bdrv, dinfo->unit,
> -                                        false, -1, NULL, NULL);
> +    scsidev = scsi_bus_legacy_add_drive(scsibus,
> +                                        blk_bs(blk_by_legacy_dinfo(dinfo)),
> +                                        dinfo->unit, false, -1, NULL, NULL);
>      if (!scsidev) {
>          return -1;
>      }
> @@ -247,7 +249,8 @@ static PCIDevice *qemu_pci_hot_add_storage(Monitor *mon,
>              return NULL;
>          }
>          dev = pci_create(bus, devfn, "virtio-blk-pci");
> -        if (qdev_prop_set_drive(&dev->qdev, "drive", dinfo->bdrv) < 0) {
> +        if (qdev_prop_set_drive(&dev->qdev, "drive",
> +                                blk_bs(blk_by_legacy_dinfo(dinfo))) < 0) {
>              object_unparent(OBJECT(dev));
>              dev = NULL;
>              break;
> diff --git a/hw/ppc/ppc405_boards.c b/hw/ppc/ppc405_boards.c
> index 11d3379..7ff5ee5 100644
> --- a/hw/ppc/ppc405_boards.c
> +++ b/hw/ppc/ppc405_boards.c
> @@ -33,6 +33,7 @@
>  #include "qemu/log.h"
>  #include "qemu/error-report.h"
>  #include "hw/loader.h"
> +#include "sysemu/block-backend.h"
>  #include "sysemu/blockdev.h"
>  #include "exec/address-spaces.h"
>  
> @@ -225,17 +226,19 @@ static void ref405ep_init(MachineState *machine)
>  #ifdef USE_FLASH_BIOS
>      dinfo = drive_get(IF_PFLASH, 0, fl_idx);
>      if (dinfo) {
> -        bios_size = bdrv_getlength(dinfo->bdrv);
> +        BlockDriverState *bs = blk_bs(blk_by_legacy_dinfo(dinfo));
> +
> +        bios_size = bdrv_getlength(bs);
>          fl_sectors = (bios_size + 65535) >> 16;
>  #ifdef DEBUG_BOARD_INIT
>          printf("Register parallel flash %d size %lx"
>                 " at addr %lx '%s' %d\n",
>                 fl_idx, bios_size, -bios_size,
> -               bdrv_get_device_name(dinfo->bdrv), fl_sectors);
> +               bdrv_get_device_name(bs), fl_sectors);
>  #endif
>          pflash_cfi02_register((uint32_t)(-bios_size),
>                                NULL, "ef405ep.bios", bios_size,
> -                              dinfo->bdrv, 65536, fl_sectors, 1,
> +                              bs, 65536, fl_sectors, 1,
>                                2, 0x0001, 0x22DA, 0x0000, 0x0000, 0x555, 0x2AA,
>                                1);
>          fl_idx++;
> @@ -547,7 +550,9 @@ static void taihu_405ep_init(MachineState *machine)
>  #if defined(USE_FLASH_BIOS)
>      dinfo = drive_get(IF_PFLASH, 0, fl_idx);
>      if (dinfo) {
> -        bios_size = bdrv_getlength(dinfo->bdrv);
> +        BlockDriverState *bs = blk_bs(blk_by_legacy_dinfo(dinfo));
> +
> +        bios_size = bdrv_getlength(bs);
>          /* XXX: should check that size is 2MB */
>          //        bios_size = 2 * 1024 * 1024;
>          fl_sectors = (bios_size + 65535) >> 16;
> @@ -555,11 +560,11 @@ static void taihu_405ep_init(MachineState *machine)
>          printf("Register parallel flash %d size %lx"
>                 " at addr %lx '%s' %d\n",
>                 fl_idx, bios_size, -bios_size,
> -               bdrv_get_device_name(dinfo->bdrv), fl_sectors);
> +               bdrv_get_device_name(bs), fl_sectors);
>  #endif
>          pflash_cfi02_register((uint32_t)(-bios_size),
>                                NULL, "taihu_405ep.bios", bios_size,
> -                              dinfo->bdrv, 65536, fl_sectors, 1,
> +                              bs, 65536, fl_sectors, 1,
>                                4, 0x0001, 0x22DA, 0x0000, 0x0000, 0x555, 0x2AA,
>                                1);
>          fl_idx++;
> @@ -593,7 +598,9 @@ static void taihu_405ep_init(MachineState *machine)
>      /* Register Linux flash */
>      dinfo = drive_get(IF_PFLASH, 0, fl_idx);
>      if (dinfo) {
> -        bios_size = bdrv_getlength(dinfo->bdrv);
> +        BlockDriverState *bs = blk_bs(blk_by_legacy_dinfo(dinfo));
> +
> +        bios_size = bdrv_getlength(bs);
>          /* XXX: should check that size is 32MB */
>          bios_size = 32 * 1024 * 1024;
>          fl_sectors = (bios_size + 65535) >> 16;
> @@ -601,10 +608,10 @@ static void taihu_405ep_init(MachineState *machine)
>          printf("Register parallel flash %d size %lx"
>                 " at addr " TARGET_FMT_lx " '%s'\n",
>                 fl_idx, bios_size, (target_ulong)0xfc000000,
> -               bdrv_get_device_name(dinfo->bdrv));
> +               bdrv_get_device_name(bs));
>  #endif
>          pflash_cfi02_register(0xfc000000, NULL, "taihu_405ep.flash", bios_size,
> -                              dinfo->bdrv, 65536, fl_sectors, 1,
> +                              bs, 65536, fl_sectors, 1,
>                                4, 0x0001, 0x22DA, 0x0000, 0x0000, 0x555, 0x2AA,
>                                1);
>          fl_idx++;
> diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
> index 2ab4460..a577812 100644
> --- a/hw/ppc/spapr.c
> +++ b/hw/ppc/spapr.c
> @@ -29,6 +29,7 @@
>  #include "hw/fw-path-provider.h"
>  #include "elf.h"
>  #include "net/net.h"
> +#include "sysemu/block-backend.h"
>  #include "sysemu/blockdev.h"
>  #include "sysemu/cpus.h"
>  #include "sysemu/kvm.h"
> @@ -925,7 +926,8 @@ static void spapr_create_nvram(sPAPREnvironment *spapr)
>      DriveInfo *dinfo = drive_get(IF_PFLASH, 0, 0);
>  
>      if (dinfo) {
> -        qdev_prop_set_drive_nofail(dev, "drive", dinfo->bdrv);
> +        qdev_prop_set_drive_nofail(dev, "drive",
> +                                   blk_bs(blk_by_legacy_dinfo(dinfo)));
>      }
>  
>      qdev_init_nofail(dev);
> diff --git a/hw/ppc/virtex_ml507.c b/hw/ppc/virtex_ml507.c
> index 0de5148..a0ce447 100644
> --- a/hw/ppc/virtex_ml507.c
> +++ b/hw/ppc/virtex_ml507.c
> @@ -39,6 +39,7 @@
>  #include "hw/ppc/ppc4xx.h"
>  #include "ppc405.h"
>  
> +#include "sysemu/block-backend.h"
>  #include "sysemu/blockdev.h"
>  #include "qapi/qmp/qerror.h"
>  
> @@ -227,8 +228,8 @@ static void virtex_init(MachineState *machine)
>  
>      dinfo = drive_get(IF_PFLASH, 0, 0);
>      pflash_cfi01_register(PFLASH_BASEADDR, NULL, "virtex.flash", FLASH_SIZE,
> -                          dinfo ? dinfo->bdrv : NULL, (64 * 1024),
> -                          FLASH_SIZE >> 16,
> +                          dinfo ? blk_bs(blk_by_legacy_dinfo(dinfo)) : NULL,
> +                          (64 * 1024), FLASH_SIZE >> 16,
>                            1, 0x89, 0x18, 0x0000, 0x0, 1);
>  
>      cpu_irq = (qemu_irq *) &env->irq_inputs[PPC40x_INPUT_INT];
> diff --git a/hw/scsi/scsi-bus.c b/hw/scsi/scsi-bus.c
> index 954c607..f5156ae 100644
> --- a/hw/scsi/scsi-bus.c
> +++ b/hw/scsi/scsi-bus.c
> @@ -3,6 +3,7 @@
>  #include "hw/scsi/scsi.h"
>  #include "block/scsi.h"
>  #include "hw/qdev.h"
> +#include "sysemu/block-backend.h"
>  #include "sysemu/blockdev.h"
>  #include "trace.h"
>  #include "sysemu/dma.h"
> @@ -267,8 +268,8 @@ void scsi_bus_legacy_handle_cmdline(SCSIBus *bus, Error **errp)
>              continue;
>          }
>          qemu_opts_loc_restore(dinfo->opts);
> -        scsi_bus_legacy_add_drive(bus, dinfo->bdrv, unit, false, -1, NULL,
> -                                  &err);
> +        scsi_bus_legacy_add_drive(bus, blk_bs(blk_by_legacy_dinfo(dinfo)),
> +                                  unit, false, -1, NULL, &err);
>          if (err != NULL) {
>              error_report("%s", error_get_pretty(err));
>              error_propagate(errp, err);
> diff --git a/hw/sd/milkymist-memcard.c b/hw/sd/milkymist-memcard.c
> index 2a40f92..501aa3a 100644
> --- a/hw/sd/milkymist-memcard.c
> +++ b/hw/sd/milkymist-memcard.c
> @@ -26,6 +26,7 @@
>  #include "sysemu/sysemu.h"
>  #include "trace.h"
>  #include "qemu/error-report.h"
> +#include "sysemu/block-backend.h"
>  #include "sysemu/blockdev.h"
>  #include "hw/sd.h"
>  
> @@ -252,14 +253,16 @@ static int milkymist_memcard_init(SysBusDevice *dev)
>  {
>      MilkymistMemcardState *s = MILKYMIST_MEMCARD(dev);
>      DriveInfo *dinfo;
> +    BlockDriverState *bs;
>  
>      dinfo = drive_get_next(IF_SD);
> -    s->card = sd_init(dinfo ? dinfo->bdrv : NULL, false);
> +    bs = dinfo ? blk_bs(blk_by_legacy_dinfo(dinfo)) : NULL;
> +    s->card = sd_init(bs, false);
>      if (s->card == NULL) {
>          return -1;
>      }
>  
> -    s->enabled = dinfo ? bdrv_is_inserted(dinfo->bdrv) : 0;
> +    s->enabled = bs && bdrv_is_inserted(bs);
>  
>      memory_region_init_io(&s->regs_region, OBJECT(s), &memcard_mmio_ops, s,
>              "milkymist-memcard", R_MAX * 4);
> diff --git a/hw/sd/pl181.c b/hw/sd/pl181.c
> index 462558b..0501d40 100644
> --- a/hw/sd/pl181.c
> +++ b/hw/sd/pl181.c
> @@ -7,6 +7,7 @@
>   * This code is licensed under the GPL.
>   */
>  
> +#include "sysemu/block-backend.h"
>  #include "sysemu/blockdev.h"
>  #include "hw/sysbus.h"
>  #include "hw/sd.h"
> @@ -490,7 +491,7 @@ static int pl181_init(SysBusDevice *sbd)
>      sysbus_init_irq(sbd, &s->irq[1]);
>      qdev_init_gpio_out(dev, s->cardstatus, 2);
>      dinfo = drive_get_next(IF_SD);
> -    s->card = sd_init(dinfo ? dinfo->bdrv : NULL, false);
> +    s->card = sd_init(dinfo ? blk_bs(blk_by_legacy_dinfo(dinfo)) : NULL, false);
>      if (s->card == NULL) {
>          return -1;
>      }
> diff --git a/hw/sd/sdhci.c b/hw/sd/sdhci.c
> index f9fe700..0b7d754 100644
> --- a/hw/sd/sdhci.c
> +++ b/hw/sd/sdhci.c
> @@ -23,6 +23,7 @@
>   */
>  
>  #include "hw/hw.h"
> +#include "sysemu/block-backend.h"
>  #include "sysemu/blockdev.h"
>  #include "sysemu/dma.h"
>  #include "qemu/timer.h"
> @@ -1165,7 +1166,7 @@ static void sdhci_initfn(Object *obj)
>      DriveInfo *di;
>  
>      di = drive_get_next(IF_SD);
> -    s->card = sd_init(di ? di->bdrv : NULL, false);
> +    s->card = sd_init(di ? blk_bs(blk_by_legacy_dinfo(di)) : NULL, false);
>      if (s->card == NULL) {
>          exit(1);
>      }
> diff --git a/hw/sd/ssi-sd.c b/hw/sd/ssi-sd.c
> index b012e57..6ae99e4 100644
> --- a/hw/sd/ssi-sd.c
> +++ b/hw/sd/ssi-sd.c
> @@ -10,6 +10,7 @@
>   * GNU GPL, version 2 or (at your option) any later version.
>   */
>  
> +#include "sysemu/block-backend.h"
>  #include "sysemu/blockdev.h"
>  #include "hw/ssi.h"
>  #include "hw/sd.h"
> @@ -255,7 +256,7 @@ static int ssi_sd_init(SSISlave *d)
>  
>      s->mode = SSI_SD_CMD;
>      dinfo = drive_get_next(IF_SD);
> -    s->sd = sd_init(dinfo ? dinfo->bdrv : NULL, true);
> +    s->sd = sd_init(dinfo ? blk_bs(blk_by_legacy_dinfo(dinfo)) : NULL, true);
>      if (s->sd == NULL) {
>          return -1;
>      }
> diff --git a/hw/sh4/r2d.c b/hw/sh4/r2d.c
> index 95c0246..d652619 100644
> --- a/hw/sh4/r2d.c
> +++ b/hw/sh4/r2d.c
> @@ -36,6 +36,7 @@
>  #include "hw/loader.h"
>  #include "hw/usb.h"
>  #include "hw/block/flash.h"
> +#include "sysemu/block-backend.h"
>  #include "sysemu/blockdev.h"
>  #include "exec/address-spaces.h"
>  
> @@ -290,8 +291,8 @@ static void r2d_init(MachineState *machine)
>      /* onboard flash memory */
>      dinfo = drive_get(IF_PFLASH, 0, 0);
>      pflash_cfi02_register(0x0, NULL, "r2d.flash", FLASH_SIZE,
> -                          dinfo ? dinfo->bdrv : NULL, (16 * 1024),
> -                          FLASH_SIZE >> 16,
> +                          dinfo ? blk_bs(blk_by_legacy_dinfo(dinfo)) : NULL,
> +                          (16 * 1024), FLASH_SIZE >> 16,
>                            1, 4, 0x0000, 0x0000, 0x0000, 0x0000,
>                            0x555, 0x2aa, 0);
>  
> diff --git a/hw/usb/dev-storage.c b/hw/usb/dev-storage.c
> index eb75f6a..0d6e7c6 100644
> --- a/hw/usb/dev-storage.c
> +++ b/hw/usb/dev-storage.c
> @@ -16,6 +16,7 @@
>  #include "ui/console.h"
>  #include "monitor/monitor.h"
>  #include "sysemu/sysemu.h"
> +#include "sysemu/block-backend.h"
>  #include "sysemu/blockdev.h"
>  
>  //#define DEBUG_MSD
> @@ -704,7 +705,8 @@ static USBDevice *usb_msd_init(USBBus *bus, const char *filename)
>      if (!dev) {
>          return NULL;
>      }
> -    if (qdev_prop_set_drive(&dev->qdev, "drive", dinfo->bdrv) < 0) {
> +    if (qdev_prop_set_drive(&dev->qdev, "drive",
> +                            blk_bs(blk_by_legacy_dinfo(dinfo))) < 0) {
>          object_unparent(OBJECT(dev));
>          return NULL;
>      }
> diff --git a/hw/xtensa/xtfpga.c b/hw/xtensa/xtfpga.c
> index a2dff5a..7c4719e 100644
> --- a/hw/xtensa/xtfpga.c
> +++ b/hw/xtensa/xtfpga.c
> @@ -35,6 +35,7 @@
>  #include "net/net.h"
>  #include "hw/sysbus.h"
>  #include "hw/block/flash.h"
> +#include "sysemu/block-backend.h"
>  #include "sysemu/blockdev.h"
>  #include "sysemu/char.h"
>  #include "sysemu/device_tree.h"
> @@ -229,7 +230,8 @@ static void lx_init(const LxBoardDesc *board, MachineState *machine)
>      if (dinfo) {
>          flash = pflash_cfi01_register(board->flash_base,
>                  NULL, "lx60.io.flash", board->flash_size,
> -                dinfo->bdrv, board->flash_sector_size,
> +                blk_bs(blk_by_legacy_dinfo(dinfo)),
> +                board->flash_sector_size,
>                  board->flash_size / board->flash_sector_size,
>                  4, 0x0000, 0x0000, 0x0000, 0x0000, be);
>          if (flash == NULL) {
> diff --git a/include/sysemu/blockdev.h b/include/sysemu/blockdev.h
> index 2ed297b..75f6ac6 100644
> --- a/include/sysemu/blockdev.h
> +++ b/include/sysemu/blockdev.h
> @@ -30,7 +30,6 @@ typedef enum {
>  } BlockInterfaceType;
>  
>  struct DriveInfo {
> -    BlockDriverState *bdrv;
>      char *id;
>      const char *devaddr;
>      BlockInterfaceType type;
> -- 
> 1.9.3
> 
> 

^ permalink raw reply	[flat|nested] 56+ messages in thread

* Re: [Qemu-devel] [PATCH v2 03/23] block: Connect BlockBackend to BlockDriverState
  2014-09-13 22:13   ` Max Reitz
@ 2014-09-15  6:59     ` Markus Armbruster
  0 siblings, 0 replies; 56+ messages in thread
From: Markus Armbruster @ 2014-09-15  6:59 UTC (permalink / raw)
  To: Max Reitz; +Cc: kwolf, qemu-devel, stefanha, benoit.canet

Max Reitz <mreitz@redhat.com> writes:

> On 13.09.2014 17:00, Markus Armbruster wrote:
>> The pointer from BlockBackend to BlockDriverState is a strong
>> reference, managed with bdrv_ref() / bdrv_unref(), the back-pointer is
>> a weak one.
>>
>> Convenience function blk_new_with_bs() creates a BlockBackend with its
>> BlockDriverState.  Callers have to unref both.  The commit after next
>> will relieve them of the need to unref the BlockDriverState.
>>
>> Complication: due to the silly way drive_del works, we need a way to
>> hide a BlockBackend, just like bdrv_make_anon().  To emphasize its
>> "special" status, give the function a suitably off-putting name:
>
> So you're trying to force people with a sense of aesthetics to solve
> this problem? I don't know why this isn't taught in Software
> Engineering in university, but it definitely should be.

Ha!

Actually, I only want to deter additional use of this bad idea.

Once we have a decent solution for the problem drive_del is trying to
solve, we can deprecate drive_del, then remove it after a couple of
releases (it's only HMP, not a stable interface).  So the solution to
the problem will hopefully be "throw it away".

>> blk_hide_on_behalf_of_do_drive_del().  Unfortunately, hiding turns the
>> BlockBackend's name into the empty string.  Can't avoid that without
>> breaking the blk->bs->device_name equals blk->name invariant.
>>
>> Signed-off-by: Markus Armbruster <armbru@redhat.com>
>> ---
>>   block.c                        |  10 ++--
>>   block/block-backend.c          |  70 ++++++++++++++++++++++-
>>   blockdev.c                     |  26 +++------
>>   hw/block/xen_disk.c            |   8 +--
>>   include/block/block_int.h      |   2 +
>>   include/sysemu/block-backend.h |   5 ++
>>   qemu-img.c | 125 +++++++++++++++++++----------------------
>>   qemu-io.c                      |   4 +-
>>   qemu-nbd.c                     |   2 +-
>>   9 files changed, 152 insertions(+), 100 deletions(-)
>
> [snip]
>
>> diff --git a/block/block-backend.c b/block/block-backend.c
>> index 919dd4c..b118b38 100644
>> --- a/block/block-backend.c
>> +++ b/block/block-backend.c
>> @@ -16,10 +16,11 @@
>>   struct BlockBackend {
>>       char *name;
>>       int refcnt;
>> +    BlockDriverState *bs;
>>       QTAILQ_ENTRY(BlockBackend) link; /* for blk_backends */
>>   };
>>   -/* All the BlockBackends */
>> +/* All the BlockBackends (except for hidden ones) */
>>   static QTAILQ_HEAD(, BlockBackend) blk_backends =
>>       QTAILQ_HEAD_INITIALIZER(blk_backends);
>>   @@ -47,10 +48,43 @@ BlockBackend *blk_new(const char *name, Error
>> **errp)
>>       return blk;
>>   }
>>   +/*
>> + * Create a new BlockBackend with a new BlockDriverState attached.
>> + * Both have a reference count of one.  Caller owns *both* references.
>> + * TODO Let caller own only the BlockBackend reference
>> + * Otherwise just like blk_new(), which see.
>
> Could be my lack of profoundness in English, but I don't understand
> what "which see" is supposed to mean or how its grammar works. An
> imperative?

I guess I picked this up in my reading.  Wikipedia recognizes it, so it
must be okay ;-}

https://en.wikipedia.org/wiki/Which_see

>> + */
>> +BlockBackend *blk_new_with_bs(const char *name, Error **errp)
>> +{
>> +    BlockBackend *blk;
>> +    BlockDriverState *bs;
>> +
>> +    blk = blk_new(name, errp);
>> +    if (!blk) {
>> +        return NULL;
>> +    }
>> +
>> +    bs = bdrv_new_root(name, errp);
>> +    if (!bs) {
>> +        blk_unref(blk);
>> +        return NULL;
>> +    }
>> +
>> +    blk->bs = bs;
>> +    bs->blk = blk;
>> +    return blk;
>> +}
>> +
>
> [snip]
>
>> diff --git a/blockdev.c b/blockdev.c
>> index 5873205..21f4c67 100644
>> --- a/blockdev.c
>> +++ b/blockdev.c
>> @@ -229,14 +229,7 @@ void drive_info_del(DriveInfo *dinfo)
>>           qemu_opts_del(dinfo->opts);
>>       }
>>   -    /*
>> -     * Hairy special case: if do_drive_del() has made dinfo->bdrv
>> -     * anonymous, it also unref'ed the associated BlockBackend.
>> -     */
>> -    if (dinfo->bdrv->device_name[0]) {
>> -        blk_unref(blk_by_name(dinfo->bdrv->device_name));
>> -    }
>> -
>> +    blk_unref(blk_by_name(dinfo->bdrv->device_name));
>
> So if !device_name[0], the BB is hidden. Hidden BBs are removed from
> the BB list and therefore not returned by blk_by_name(). Therefore,
> the BB is leaked here.

You're right.  This part of the patches went through a couple of
iterations already, and at some point I zapped device_name without
realizing it introduces a leak here.  I'll try to avoid the zapping.

> I guess this will be fixed up in a later patch, though...

Right again.

>>       g_free(dinfo->id);
>>       QTAILQ_REMOVE(&drives, dinfo, next);
>>       g_free(dinfo->serial);
>
> [snip]
>
>> diff --git a/qemu-nbd.c b/qemu-nbd.c
>> index ff95da6..fa8a7d0 100644
>> --- a/qemu-nbd.c
>> +++ b/qemu-nbd.c
>> @@ -689,7 +689,7 @@ int main(int argc, char **argv)
>>       }
>>         blk = blk_new("hda", &error_abort);
>> -    bs = bdrv_new_root("hda", &error_abort);
>> +    bs = blk_bs(blk);
>
> Shouldn't that be a blk_new_with_bs() then, just like every other case?

Fixing...

>>       srcpath = argv[optind];
>>       ret = bdrv_open(&bs, srcpath, NULL, NULL, flags, drv, &local_err);

Thanks!

^ permalink raw reply	[flat|nested] 56+ messages in thread

* Re: [Qemu-devel] [PATCH v2 05/23] block: Code motion to get rid of stubs/blockdev.c
  2014-09-15  6:28   ` Fam Zheng
@ 2014-09-15  7:21     ` Markus Armbruster
  2014-09-15  7:23       ` Fam Zheng
  0 siblings, 1 reply; 56+ messages in thread
From: Markus Armbruster @ 2014-09-15  7:21 UTC (permalink / raw)
  To: Fam Zheng; +Cc: kwolf, qemu-devel, stefanha, benoit.canet

Fam Zheng <famz@redhat.com> writes:

> On Sat, 09/13 17:00, Markus Armbruster wrote:
>> Signed-off-by: Markus Armbruster <armbru@redhat.com>
>> ---
>>  block/block-backend.c     | 15 +++++++++++++++
>>  blockdev.c                | 13 -------------
>>  include/sysemu/blockdev.h |  1 -
>>  stubs/Makefile.objs       |  1 -
>>  stubs/blockdev.c          | 12 ------------
>
> Where is the stubs/blockdev.c from? I don't see it in qemu.git.

It's from
[PATCH 2/4] block: Keep DriveInfo alive until BlockDriverState dies
part of
[PATCH 0/4] Miscellaneous block fixes

See cover letter for additional dependencies.

^ permalink raw reply	[flat|nested] 56+ messages in thread

* Re: [Qemu-devel] [PATCH v2 10/23] block: Eliminate DriveInfo member bdrv, use blk_by_legacy_dinfo()
  2014-09-15  6:58   ` Fam Zheng
@ 2014-09-15  7:21     ` Markus Armbruster
  0 siblings, 0 replies; 56+ messages in thread
From: Markus Armbruster @ 2014-09-15  7:21 UTC (permalink / raw)
  To: Fam Zheng; +Cc: kwolf, qemu-devel, stefanha, benoit.canet

Fam Zheng <famz@redhat.com> writes:

> On Sat, 09/13 17:00, Markus Armbruster wrote:
>> The patch is big, but all it really does is replacing
>> 
>>     dinfo->bdrv
>> 
>> by
>> 
>>     blk_bs(blk_legacy_dinfo(dinfo))
>
> s/blk_legacy_dinfo/blk_by_legacy_dinfo/
>
> Otherwise looks good,
>
> Reviewed-by: Fam Zheng <famz@redhat.com>

Fixed & thanks!

^ permalink raw reply	[flat|nested] 56+ messages in thread

* Re: [Qemu-devel] [PATCH v2 05/23] block: Code motion to get rid of stubs/blockdev.c
  2014-09-15  7:21     ` Markus Armbruster
@ 2014-09-15  7:23       ` Fam Zheng
  0 siblings, 0 replies; 56+ messages in thread
From: Fam Zheng @ 2014-09-15  7:23 UTC (permalink / raw)
  To: Markus Armbruster; +Cc: kwolf, qemu-devel, stefanha, benoit.canet

On Mon, 09/15 09:21, Markus Armbruster wrote:
> Fam Zheng <famz@redhat.com> writes:
> 
> > On Sat, 09/13 17:00, Markus Armbruster wrote:
> >> Signed-off-by: Markus Armbruster <armbru@redhat.com>
> >> ---
> >>  block/block-backend.c     | 15 +++++++++++++++
> >>  blockdev.c                | 13 -------------
> >>  include/sysemu/blockdev.h |  1 -
> >>  stubs/Makefile.objs       |  1 -
> >>  stubs/blockdev.c          | 12 ------------
> >
> > Where is the stubs/blockdev.c from? I don't see it in qemu.git.
> 
> It's from
> [PATCH 2/4] block: Keep DriveInfo alive until BlockDriverState dies
> part of
> [PATCH 0/4] Miscellaneous block fixes
> 
> See cover letter for additional dependencies.

Missed that, thanks!

Fam

^ permalink raw reply	[flat|nested] 56+ messages in thread

* Re: [Qemu-devel] [PATCH v2 19/23] blockdev: Drop DriveInfo member enable_auto_del
  2014-09-13 15:00 ` [Qemu-devel] [PATCH v2 19/23] blockdev: Drop DriveInfo member enable_auto_del Markus Armbruster
@ 2014-09-15  7:30   ` Fam Zheng
  2014-09-15  8:40     ` Markus Armbruster
  0 siblings, 1 reply; 56+ messages in thread
From: Fam Zheng @ 2014-09-15  7:30 UTC (permalink / raw)
  To: Markus Armbruster; +Cc: kwolf, stefanha, qemu-devel, benoit.canet

On Sat, 09/13 17:00, Markus Armbruster wrote:
> Commit 2d246f0 introduced DriveInfo member enable_auto_del to
> distinguish DriveInfo created via drive_new() from DriveInfo created
> via qmp_blockdev_add().  The latter no longer exist.  Drop
> enable_auto_del.
> 
> Signed-off-by: Markus Armbruster <armbru@redhat.com>
> ---
>  blockdev.c                | 11 +++--------
>  include/sysemu/blockdev.h |  1 -
>  2 files changed, 3 insertions(+), 9 deletions(-)
> 
> diff --git a/blockdev.c b/blockdev.c
> index 0d99be0..e218c59 100644
> --- a/blockdev.c
> +++ b/blockdev.c
> @@ -90,16 +90,14 @@ void blockdev_mark_auto_del(BlockBackend *blk)
>      DriveInfo *dinfo = blk_legacy_dinfo(blk);
>      BlockDriverState *bs = blk_bs(blk);
>  
> -    if (dinfo && !dinfo->enable_auto_del) {
> +    if (!dinfo) {
>          return;
>      }
>  
>      if (bs->job) {
>          block_job_cancel(bs->job);
>      }
> -    if (dinfo) {
> -        dinfo->auto_del = 1;
> -    }
> +    dinfo->auto_del = 1;
>  }

Looks good.

Based on the explanation in the commit message of patch 18, previouly, dinfo is
always non-NULL, so enable_auto_del distinguishes whether the device is created
by drive_new() or qmp_blockdev_add().

Now dinfo is NULL iff created by qmp_blockdev_add(), so enable_auto_del is not
necessary any more.

If I'm reading correctly, the dropped two "if (dinfo.."'s are also redundant.

Reviewed-by: Fam Zheng <famz@redhat.com>

>  
>  void blockdev_auto_del(BlockBackend *blk)
> @@ -900,7 +898,6 @@ DriveInfo *drive_new(QemuOpts *all_opts, BlockInterfaceType block_default_type)
>  
>      /* Set legacy DriveInfo fields */
>      dinfo = g_malloc0(sizeof(*dinfo));
> -    dinfo->enable_auto_del = true;
>      dinfo->opts = all_opts;
>      dinfo->cyls = cyls;
>      dinfo->heads = heads;
> @@ -1716,7 +1713,6 @@ int do_drive_del(Monitor *mon, const QDict *qdict, QObject **ret_data)
>      const char *id = qdict_get_str(qdict, "id");
>      BlockBackend *blk;
>      BlockDriverState *bs;
> -    DriveInfo *dinfo;
>      AioContext *aio_context;
>      Error *local_err = NULL;
>  
> @@ -1727,8 +1723,7 @@ int do_drive_del(Monitor *mon, const QDict *qdict, QObject **ret_data)
>      }
>      bs = blk_bs(blk);
>  
> -    dinfo = blk_legacy_dinfo(blk);
> -    if (dinfo && !dinfo->enable_auto_del) {
> +    if (!blk_legacy_dinfo(blk)) {
>          error_report("Deleting device added with blockdev-add"
>                       " is not supported");
>          return -1;
> diff --git a/include/sysemu/blockdev.h b/include/sysemu/blockdev.h
> index 27a40d5..2129d81 100644
> --- a/include/sysemu/blockdev.h
> +++ b/include/sysemu/blockdev.h
> @@ -35,7 +35,6 @@ struct DriveInfo {
>      int bus;
>      int unit;
>      int auto_del;               /* see blockdev_mark_auto_del() */
> -    bool enable_auto_del;       /* Only for legacy drive_new() */
>      int media_cd;
>      int cyls, heads, secs, trans;
>      QemuOpts *opts;
> -- 
> 1.9.3
> 
> 

^ permalink raw reply	[flat|nested] 56+ messages in thread

* Re: [Qemu-devel] [PATCH v2 19/23] blockdev: Drop DriveInfo member enable_auto_del
  2014-09-15  7:30   ` Fam Zheng
@ 2014-09-15  8:40     ` Markus Armbruster
  0 siblings, 0 replies; 56+ messages in thread
From: Markus Armbruster @ 2014-09-15  8:40 UTC (permalink / raw)
  To: Fam Zheng; +Cc: kwolf, qemu-devel, stefanha, benoit.canet

Fam Zheng <famz@redhat.com> writes:

> On Sat, 09/13 17:00, Markus Armbruster wrote:
>> Commit 2d246f0 introduced DriveInfo member enable_auto_del to
>> distinguish DriveInfo created via drive_new() from DriveInfo created
>> via qmp_blockdev_add().  The latter no longer exist.  Drop
>> enable_auto_del.
>> 
>> Signed-off-by: Markus Armbruster <armbru@redhat.com>
>> ---
>>  blockdev.c                | 11 +++--------
>>  include/sysemu/blockdev.h |  1 -
>>  2 files changed, 3 insertions(+), 9 deletions(-)
>> 
>> diff --git a/blockdev.c b/blockdev.c
>> index 0d99be0..e218c59 100644
>> --- a/blockdev.c
>> +++ b/blockdev.c
>> @@ -90,16 +90,14 @@ void blockdev_mark_auto_del(BlockBackend *blk)
>>      DriveInfo *dinfo = blk_legacy_dinfo(blk);
>>      BlockDriverState *bs = blk_bs(blk);
>>  
>> -    if (dinfo && !dinfo->enable_auto_del) {
>> +    if (!dinfo) {
>>          return;
>>      }
>>  
>>      if (bs->job) {
>>          block_job_cancel(bs->job);
>>      }
>> -    if (dinfo) {
>> -        dinfo->auto_del = 1;
>> -    }
>> +    dinfo->auto_del = 1;
>>  }
>
> Looks good.
>
> Based on the explanation in the commit message of patch 18, previouly,
> dinfo is always non-NULL, so enable_auto_del distinguishes whether the
> device is created by drive_new() or qmp_blockdev_add().

Correct.

> Now dinfo is NULL iff created by qmp_blockdev_add(), so
> enable_auto_del is not necessary any more.

Correct again.

> If I'm reading correctly, the dropped two "if (dinfo.."'s are also redundant.

Yes.  Let me explain why.

The two cases to distinguish are "created by drive_new()" and "created
by qmp_blockdev_add()".

Commit 2d246f0 introduced DriveInfo member enable_auto_del to exactly
that.

The code tests for "created by qmp_blockdev_add()" like this:

    dinfo && !dinfo->enable_auto_del

Before PATCH 18, this was actually unnecessarily careful, because dinfo
could never be null, but that's okay.

PATCH 18 changes the "created by qmp_blockdev_add() case: now dinfo is
null there.  The test remains correct, only now its second rather than
first part is unnecessary: dinfo now implies dinfo->enable_auto_del.

Before PATCH 18         dinfo != NULL	!dinfo->enable_auto_del   &&
by drive_new()          true            false                     false
by qmp_blockdev_add()   true            true                      true

After PATCH 18          dinfo != NULL	!dinfo->enable_auto_del   &&
by drive_new()          true            false                     false
by qmp_blockdev_add()   false           N/A                       false

Oops.

After PATCH 19          dinfo                                     !dinfo
by drive_new()          true                                      false
by qmp_blockdev_add()   false                                     true

Looks like I need to squash PATCH 19 into PATCH 18...  Thanks for making
me think!

[...]

^ permalink raw reply	[flat|nested] 56+ messages in thread

* Re: [Qemu-devel] [PATCH v2 01/23] block: Split bdrv_new_root() off bdrv_new()
  2014-09-13 15:00 ` [Qemu-devel] [PATCH v2 01/23] block: Split bdrv_new_root() off bdrv_new() Markus Armbruster
  2014-09-13 20:45   ` Max Reitz
@ 2014-09-15 12:00   ` Benoît Canet
  2014-09-15 13:19     ` Markus Armbruster
  1 sibling, 1 reply; 56+ messages in thread
From: Benoît Canet @ 2014-09-15 12:00 UTC (permalink / raw)
  To: Markus Armbruster; +Cc: kwolf, qemu-devel, stefanha, benoit.canet

On Sat, Sep 13, 2014 at 05:00:05PM +0200, Markus Armbruster wrote:
> Creating an anonymous BDS can't fail.  Make that obvious.
> 
> Signed-off-by: Markus Armbruster <armbru@redhat.com>
> ---
>  block.c               | 28 +++++++++++++++++++---------
>  block/iscsi.c         |  2 +-
>  block/vvfat.c         |  2 +-
>  blockdev.c            |  2 +-
>  hw/block/xen_disk.c   |  2 +-
>  include/block/block.h |  3 ++-
>  qemu-img.c            |  6 +++---
>  qemu-io.c             |  2 +-
>  qemu-nbd.c            |  2 +-
>  9 files changed, 30 insertions(+), 19 deletions(-)
> 
> diff --git a/block.c b/block.c
> index 02ea90f..4fe3b62 100644
> --- a/block.c
> +++ b/block.c
> @@ -336,10 +336,11 @@ void bdrv_register(BlockDriver *bdrv)
>  }
>  

>  /* create a new block device (by default it is empty) */
I wonder if this comment is stale.
What is the emptiness of a block device anyway ?

> -BlockDriverState *bdrv_new(const char *device_name, Error **errp)
> +BlockDriverState *bdrv_new_root(const char *device_name, Error **errp)
>  {
>      BlockDriverState *bs;
> -    int i;
> +
> +    assert(*device_name);
>  
>      if (bdrv_find(device_name)) {
>          error_setg(errp, "Device with id '%s' already exists",
> @@ -353,12 +354,21 @@ BlockDriverState *bdrv_new(const char *device_name, Error **errp)
>          return NULL;
>      }
>  
> +    bs = bdrv_new();
> +
> +    pstrcpy(bs->device_name, sizeof(bs->device_name), device_name);
> +    QTAILQ_INSERT_TAIL(&bdrv_states, bs, device_list);
> +
> +    return bs;
> +}
> +
> +BlockDriverState *bdrv_new(void)
> +{
> +    BlockDriverState *bs;
> +    int i;
> +
>      bs = g_new0(BlockDriverState, 1);
>      QLIST_INIT(&bs->dirty_bitmaps);
> -    pstrcpy(bs->device_name, sizeof(bs->device_name), device_name);
> -    if (device_name[0] != '\0') {
> -        QTAILQ_INSERT_TAIL(&bdrv_states, bs, device_list);
> -    }
>      for (i = 0; i < BLOCK_OP_TYPE_MAX; i++) {
>          QLIST_INIT(&bs->op_blockers[i]);
>      }
> @@ -1219,7 +1229,7 @@ int bdrv_open_backing_file(BlockDriverState *bs, QDict *options, Error **errp)
>          goto free_exit;
>      }
>  
> -    backing_hd = bdrv_new("", errp);
> +    backing_hd = bdrv_new();
>  
>      if (bs->backing_format[0] != '\0') {
>          back_drv = bdrv_find_format(bs->backing_format);
> @@ -1348,7 +1358,7 @@ int bdrv_append_temp_snapshot(BlockDriverState *bs, int flags, Error **errp)
>      qdict_put(snapshot_options, "file.filename",
>                qstring_from_str(tmp_filename));
>  
> -    bs_snapshot = bdrv_new("", &error_abort);
> +    bs_snapshot = bdrv_new();
>  
>      ret = bdrv_open(&bs_snapshot, NULL, NULL, snapshot_options,
>                      flags, bdrv_qcow2, &local_err);
> @@ -1419,7 +1429,7 @@ int bdrv_open(BlockDriverState **pbs, const char *filename,
>      if (*pbs) {
>          bs = *pbs;
>      } else {
> -        bs = bdrv_new("", &error_abort);
> +        bs = bdrv_new();
>      }
>  
>      /* NULL means an empty set of options */
> diff --git a/block/iscsi.c b/block/iscsi.c
> index 3e19202..af3d0f6 100644
> --- a/block/iscsi.c
> +++ b/block/iscsi.c
> @@ -1528,7 +1528,7 @@ static int iscsi_create(const char *filename, QemuOpts *opts, Error **errp)
>      IscsiLun *iscsilun = NULL;
>      QDict *bs_options;
>  
> -    bs = bdrv_new("", &error_abort);
> +    bs = bdrv_new();
>  
>      /* Read out options */
>      total_size =
> diff --git a/block/vvfat.c b/block/vvfat.c
> index 731e591..6c9fde0 100644
> --- a/block/vvfat.c
> +++ b/block/vvfat.c
> @@ -2939,7 +2939,7 @@ static int enable_write_target(BDRVVVFATState *s, Error **errp)
>      unlink(s->qcow_filename);
>  #endif
>  
> -    bdrv_set_backing_hd(s->bs, bdrv_new("", &error_abort));
> +    bdrv_set_backing_hd(s->bs, bdrv_new());
>      s->bs->backing_hd->drv = &vvfat_write_target;
>      s->bs->backing_hd->opaque = g_new(void *, 1);
>      *(void**)s->bs->backing_hd->opaque = s;
> diff --git a/blockdev.c b/blockdev.c
> index 450f95c..c9463e3 100644
> --- a/blockdev.c
> +++ b/blockdev.c
> @@ -463,7 +463,7 @@ static DriveInfo *blockdev_init(const char *file, QDict *bs_opts,
>      }
>  
>      /* init */
> -    bs = bdrv_new(qemu_opts_id(opts), errp);
> +    bs = bdrv_new_root(qemu_opts_id(opts), errp);
>      if (!bs) {
>          goto early_err;
>      }
> diff --git a/hw/block/xen_disk.c b/hw/block/xen_disk.c
> index 2dcef07..71f0953 100644
> --- a/hw/block/xen_disk.c
> +++ b/hw/block/xen_disk.c
> @@ -856,7 +856,7 @@ static int blk_connect(struct XenDevice *xendev)
>  
>          /* setup via xenbus -> create new block driver instance */
>          xen_be_printf(&blkdev->xendev, 2, "create new bdrv (xenbus setup)\n");
> -        blkdev->bs = bdrv_new(blkdev->dev, NULL);
> +        blkdev->bs = bdrv_new_root(blkdev->dev, NULL);
>          if (!blkdev->bs) {
>              return -1;
>          }
> diff --git a/include/block/block.h b/include/block/block.h
> index 8f4ad16..6cabc98 100644
> --- a/include/block/block.h
> +++ b/include/block/block.h
> @@ -203,7 +203,8 @@ BlockDriver *bdrv_find_whitelisted_format(const char *format_name,
>  int bdrv_create(BlockDriver *drv, const char* filename,
>                  QemuOpts *opts, Error **errp);
>  int bdrv_create_file(const char *filename, QemuOpts *opts, Error **errp);
> -BlockDriverState *bdrv_new(const char *device_name, Error **errp);
> +BlockDriverState *bdrv_new_root(const char *device_name, Error **errp);
> +BlockDriverState *bdrv_new(void);
>  void bdrv_make_anon(BlockDriverState *bs);
>  void bdrv_swap(BlockDriverState *bs_new, BlockDriverState *bs_old);
>  void bdrv_append(BlockDriverState *bs_new, BlockDriverState *bs_top);
> diff --git a/qemu-img.c b/qemu-img.c
> index 91d1ac3..58d59d0 100644
> --- a/qemu-img.c
> +++ b/qemu-img.c
> @@ -296,7 +296,7 @@ static BlockDriverState *bdrv_new_open(const char *id,
>      Error *local_err = NULL;
>      int ret;
>  
> -    bs = bdrv_new(id, &error_abort);
> +    bs = bdrv_new_root(id, &error_abort);
>  
>      if (fmt) {
>          drv = bdrv_find_format(fmt);
> @@ -2425,7 +2425,7 @@ static int img_rebase(int argc, char **argv)
>      if (!unsafe) {
>          char backing_name[1024];
>  
> -        bs_old_backing = bdrv_new("old_backing", &error_abort);
> +        bs_old_backing = bdrv_new_root("old_backing", &error_abort);
>          bdrv_get_backing_filename(bs, backing_name, sizeof(backing_name));
>          ret = bdrv_open(&bs_old_backing, backing_name, NULL, NULL, src_flags,
>                          old_backing_drv, &local_err);
> @@ -2436,7 +2436,7 @@ static int img_rebase(int argc, char **argv)
>              goto out;
>          }
>          if (out_baseimg[0]) {
> -            bs_new_backing = bdrv_new("new_backing", &error_abort);
> +            bs_new_backing = bdrv_new_root("new_backing", &error_abort);
>              ret = bdrv_open(&bs_new_backing, out_baseimg, NULL, NULL, src_flags,
>                              new_backing_drv, &local_err);
>              if (ret) {
> diff --git a/qemu-io.c b/qemu-io.c
> index d2ab694..24ca59c 100644
> --- a/qemu-io.c
> +++ b/qemu-io.c
> @@ -58,7 +58,7 @@ static int openfile(char *name, int flags, int growable, QDict *opts)
>          return 1;
>      }
>  
> -    qemuio_bs = bdrv_new("hda", &error_abort);
> +    qemuio_bs = bdrv_new_root("hda", &error_abort);
>  
>      if (growable) {
>          flags |= BDRV_O_PROTOCOL;
> diff --git a/qemu-nbd.c b/qemu-nbd.c
> index f3cf8a2..24b8454 100644
> --- a/qemu-nbd.c
> +++ b/qemu-nbd.c
> @@ -687,7 +687,7 @@ int main(int argc, char **argv)
>          drv = NULL;
>      }
>  
> -    bs = bdrv_new("hda", &error_abort);
> +    bs = bdrv_new_root("hda", &error_abort);
>  
>      srcpath = argv[optind];
>      ret = bdrv_open(&bs, srcpath, NULL, NULL, flags, drv, &local_err);
> -- 
> 1.9.3
> 
Reviewed-by: Benoît Canet <benoit.canet@nodalink.com>

^ permalink raw reply	[flat|nested] 56+ messages in thread

* Re: [Qemu-devel] [PATCH v2 02/23] block: New BlockBackend
  2014-09-13 15:00 ` [Qemu-devel] [PATCH v2 02/23] block: New BlockBackend Markus Armbruster
  2014-09-13 21:41   ` Max Reitz
@ 2014-09-15 13:02   ` Benoît Canet
  2014-09-15 13:53     ` Markus Armbruster
  1 sibling, 1 reply; 56+ messages in thread
From: Benoît Canet @ 2014-09-15 13:02 UTC (permalink / raw)
  To: Markus Armbruster; +Cc: kwolf, qemu-devel, stefanha, benoit.canet

> --- a/block.c
> +++ b/block.c
> @@ -2119,10 +2119,11 @@ static void bdrv_delete(BlockDriverState *bs)
>  
>      bdrv_close(bs);
>  


> +    drive_info_del(drive_get_by_blockdev(bs));
> +
>      /* remove from list, if necessary */
>      bdrv_make_anon(bs);
>  
> -    drive_info_del(drive_get_by_blockdev(bs));

Do we really want this move ?
Or is it an artefact of your work on the preparation series ?

>      g_free(bs);
>  }
>  

> + * Return the BlockBackend with name @name if it exists, else null.

> + * @name must not be null.
The contract is that no one will call blk_by_name(NULL);

> + */
> +BlockBackend *blk_by_name(const char *name)
> +{
> +    BlockBackend *blk;

Can we ?

     assert(name);

> +
> +    QTAILQ_FOREACH(blk, &blk_backends, link) {
> +        if (!strcmp(name, blk->name)) {
> +            return blk;
> +        }
> +    }
> +    return NULL;
> +}


> +    /*
> +     * Hairy special case: if do_drive_del() has made dinfo->bdrv
> +     * anonymous, it also unref'ed the associated BlockBackend.
> +     */

Then you are filling the other case here.

maybe

    /*
     * Hairy special case: if do_drive_del() has made dinfo->bdrv
     * anonymous, it also unref'ed the associated BlockBackend.
     * Process the other case here.
     */

would further explain you intents.


> +    if (dinfo->bdrv->device_name[0]) {
> +        blk_unref(blk_by_name(dinfo->bdrv->device_name));
> +    }
> +
>      g_free(dinfo->id);
>      QTAILQ_REMOVE(&drives, dinfo, next);
>      g_free(dinfo->serial);
> @@ -307,6 +317,7 @@ static DriveInfo *blockdev_init(const char *file, QDict *bs_opts,
>      int ro = 0;
>      int bdrv_flags = 0;
>      int on_read_error, on_write_error;
> +    BlockBackend *blk;
>      BlockDriverState *bs;
>      DriveInfo *dinfo;
>      ThrottleConfig cfg;
> @@ -463,9 +474,13 @@ static DriveInfo *blockdev_init(const char *file, QDict *bs_opts,
>      }

>      const char *fmt1 = NULL, *fmt2 = NULL, *cache, *filename1, *filename2;
> +    BlockBackend *blk1, *blk2;
>      BlockDriverState *bs1, *bs2;
>      int64_t total_sectors1, total_sectors2;
>      uint8_t *buf1 = NULL, *buf2 = NULL;
> @@ -1011,18 +1022,20 @@ static int img_compare(int argc, char **argv)
>          goto out3;
>      }
>  
> +    blk1 = blk_new("image 1", &error_abort);
>      bs1 = bdrv_new_open("image 1", filename1, fmt1, flags, true, quiet);
>      if (!bs1) {
>          error_report("Can't open file %s", filename1);
>          ret = 2;
> -        goto out3;
> +        goto out2;

Here we allocate blk1 and bs1 an if bs1 is null (error) we jump to out2 which is:

>  out2:
>      bdrv_unref(bs1);
> +    blk_unref(blk1);

It's a bit strange that we will bdrv_unref(NULL) in this case.

This goto chain seems odd.

>      }
>  
> +    blk2 = blk_new("image 2", &error_abort);
>      bs2 = bdrv_new_open("image 2", filename2, fmt2, flags, true, quiet);
>      if (!bs2) {
>          error_report("Can't open file %s", filename2);
>          ret = 2;
> -        goto out2;
> +        goto out1;
>      }
>  
>      buf1 = qemu_blockalign(bs1, IO_BUF_SIZE);
> @@ -1183,11 +1196,14 @@ static int img_compare(int argc, char **argv)
>      ret = 0;
>  
>  out:
> -    bdrv_unref(bs2);
>      qemu_vfree(buf1);
>      qemu_vfree(buf2);
> +out1:
> +    bdrv_unref(bs2);
> +    blk_unref(blk2);
>  out2:
>      bdrv_unref(bs1);
> +    blk_unref(blk1);
>  out3:
>      qemu_progress_end();
>      return ret;
> @@ -1200,6 +1216,7 @@ static int img_convert(int argc, char **argv)
>      int progress = 0, flags, src_flags;
>      const char *fmt, *out_fmt, *cache, *src_cache, *out_baseimg, *out_filename;
>      BlockDriver *drv, *proto_drv;
> +    BlockBackend **blk = NULL, *out_blk = NULL;

Should blk be blks or blkes ? They are multiple.

>      BlockDriverState **bs = NULL, *out_bs = NULL;
>      int64_t total_sectors, nb_sectors, sector_num, bs_offset;
>      int64_t *bs_sectors = NULL;
> @@ -1354,6 +1371,7 @@ static int img_convert(int argc, char **argv)
>  
>      qemu_progress_print(0, 100);
>  
> +    blk = g_new0(BlockBackend *, bs_n);
>      bs = g_new0(BlockDriverState *, bs_n);
>      bs_sectors = g_new(int64_t, bs_n);
>  
> @@ -1361,6 +1379,7 @@ static int img_convert(int argc, char **argv)
>      for (bs_i = 0; bs_i < bs_n; bs_i++) {
>          char *id = bs_n > 1 ? g_strdup_printf("source %d", bs_i)
>                              : g_strdup("source");
> +        blk[bs_i] = blk_new(id, &error_abort);
>          bs[bs_i] = bdrv_new_open(id, argv[optind + bs_i], fmt, src_flags,
>                                   true, quiet);
>          g_free(id);
> @@ -1486,6 +1505,7 @@ static int img_convert(int argc, char **argv)
>          goto out;
>      }
>  
> +    out_blk = blk_new("target", &error_abort);
>      out_bs = bdrv_new_open("target", out_filename, out_fmt, flags, true, quiet);
>      if (!out_bs) {
>          ret = -1;
> @@ -1742,6 +1762,7 @@ out:
>      if (out_bs) {
>          bdrv_unref(out_bs);
>      }
> +    blk_unref(out_blk);
>      if (bs) {
>          for (bs_i = 0; bs_i < bs_n; bs_i++) {
>              if (bs[bs_i]) {
> @@ -1750,6 +1771,12 @@ out:
>          }
>          g_free(bs);
>      }
> +    if (blk) {
> +        for (bs_i = 0; bs_i < bs_n; bs_i++) {
> +            blk_unref(blk[bs_i]);
> +        }
> +        g_free(blk);
> +    }
>      g_free(bs_sectors);
>  fail_getopt:
>      g_free(options);
> @@ -1858,6 +1885,7 @@ static ImageInfoList *collect_image_info_list(const char *filename,
>      filenames = g_hash_table_new_full(g_str_hash, str_equal_func, NULL, NULL);
>  
>      while (filename) {
> +        BlockBackend *blk;
>          BlockDriverState *bs;
>          ImageInfo *info;
>          ImageInfoList *elem;
> @@ -1869,9 +1897,11 @@ static ImageInfoList *collect_image_info_list(const char *filename,
>          }
>          g_hash_table_insert(filenames, (gpointer)filename, NULL);
>  
> +        blk = blk_new("image", &error_abort);
>          bs = bdrv_new_open("image", filename, fmt,
>                             BDRV_O_FLAGS | BDRV_O_NO_BACKING, false, false);
>          if (!bs) {
> +            blk_unref(blk);
>              goto err;
>          }
>  
> @@ -1880,6 +1910,7 @@ static ImageInfoList *collect_image_info_list(const char *filename,
>              error_report("%s", error_get_pretty(err));
>              error_free(err);
>              bdrv_unref(bs);
> +            blk_unref(blk);
>              goto err;
>          }
>  
> @@ -1889,6 +1920,7 @@ static ImageInfoList *collect_image_info_list(const char *filename,
>          last = &elem->next;
>  
>          bdrv_unref(bs);
> +        blk_unref(blk);
>  
>          filename = fmt = NULL;
>          if (chain) {
> @@ -2082,6 +2114,7 @@ static int img_map(int argc, char **argv)
>  {
>      int c;
>      OutputFormat output_format = OFORMAT_HUMAN;
> +    BlockBackend *blk;
>      BlockDriverState *bs;
>      const char *filename, *fmt, *output;
>      int64_t length;
> @@ -2130,9 +2163,11 @@ static int img_map(int argc, char **argv)
>          return 1;
>      }
>  
> +    blk = blk_new("image", &error_abort);
>      bs = bdrv_new_open("image", filename, fmt, BDRV_O_FLAGS, true, false);
>      if (!bs) {
> -        return 1;
> +        ret = -1;


> +        goto out;
>      }
>  
>      if (output_format == OFORMAT_HUMAN) {
> @@ -2175,6 +2210,7 @@ static int img_map(int argc, char **argv)
>  
>  out:
>      bdrv_unref(bs);
> +    blk_unref(blk);
>      return ret < 0;
>  }
>  
> @@ -2185,6 +2221,7 @@ out:
>  
>  static int img_snapshot(int argc, char **argv)
>  {
> +    BlockBackend *blk;
>      BlockDriverState *bs;
>      QEMUSnapshotInfo sn;
>      char *filename, *snapshot_name = NULL;
> @@ -2250,9 +2287,11 @@ static int img_snapshot(int argc, char **argv)
>      filename = argv[optind++];
>  
>      /* Open the image */
> +    blk = blk_new("image", &error_abort);
>      bs = bdrv_new_open("image", filename, NULL, bdrv_oflags, true, quiet);
>      if (!bs) {
> -        return 1;
> +        ret = -1;
> +        goto out;
>      }
>  
>      /* Perform the requested action */
> @@ -2296,7 +2335,9 @@ static int img_snapshot(int argc, char **argv)
>      }
>  
>      /* Cleanup */
> +out:
>      bdrv_unref(bs);
> +    blk_unref(blk);
>      if (ret) {
>          return 1;
>      }
> @@ -2305,6 +2346,7 @@ static int img_snapshot(int argc, char **argv)
>  
>  static int img_rebase(int argc, char **argv)
>  {
> +    BlockBackend *blk = NULL, *blk_old_backing = NULL, *blk_new_backing = NULL;
>      BlockDriverState *bs = NULL, *bs_old_backing = NULL, *bs_new_backing = NULL;
>      BlockDriver *old_backing_drv, *new_backing_drv;
>      char *filename;
> @@ -2393,6 +2435,7 @@ static int img_rebase(int argc, char **argv)
>       * Ignore the old backing file for unsafe rebase in case we want to correct
>       * the reference to a renamed or moved backing file.
>       */
> +    blk = blk_new("image", &error_abort);
>      bs = bdrv_new_open("image", filename, fmt, flags, true, quiet);
>      if (!bs) {
>          ret = -1;
> @@ -2425,6 +2468,7 @@ static int img_rebase(int argc, char **argv)
>      if (!unsafe) {
>          char backing_name[1024];
>  
> +        blk_old_backing = blk_new("old_backing", &error_abort);
>          bs_old_backing = bdrv_new_root("old_backing", &error_abort);
>          bdrv_get_backing_filename(bs, backing_name, sizeof(backing_name));
>          ret = bdrv_open(&bs_old_backing, backing_name, NULL, NULL, src_flags,
> @@ -2436,6 +2480,7 @@ static int img_rebase(int argc, char **argv)
>              goto out;
>          }
>          if (out_baseimg[0]) {
> +            blk_new_backing = blk_new("new_backing", &error_abort);
>              bs_new_backing = bdrv_new_root("new_backing", &error_abort);
>              ret = bdrv_open(&bs_new_backing, out_baseimg, NULL, NULL, src_flags,
>                              new_backing_drv, &local_err);
> @@ -2614,12 +2659,15 @@ out:
>          if (bs_old_backing != NULL) {
>              bdrv_unref(bs_old_backing);
>          }
> +        blk_unref(blk_old_backing);
>          if (bs_new_backing != NULL) {
>              bdrv_unref(bs_new_backing);
>          }
> +        blk_unref(blk_new_backing);
>      }
>  
>      bdrv_unref(bs);
> +    blk_unref(blk);
>      if (ret) {
>          return 1;
>      }
> @@ -2632,6 +2680,7 @@ static int img_resize(int argc, char **argv)
>      const char *filename, *fmt, *size;
>      int64_t n, total_size;
>      bool quiet = false;
> +    BlockBackend *blk = NULL;
>      BlockDriverState *bs = NULL;
>      QemuOpts *param;
>      static QemuOptsList resize_options = {
> @@ -2708,6 +2757,7 @@ static int img_resize(int argc, char **argv)
>      n = qemu_opt_get_size(param, BLOCK_OPT_SIZE, 0);
>      qemu_opts_del(param);
>  
> +    blk = blk_new("image", &error_abort);
>      bs = bdrv_new_open("image", filename, fmt, BDRV_O_FLAGS | BDRV_O_RDWR,
>                         true, quiet);
>      if (!bs) {
> @@ -2745,6 +2795,7 @@ out:
>      if (bs) {
>          bdrv_unref(bs);
>      }
> +    blk_unref(blk);
>      if (ret) {
>          return 1;
>      }
> @@ -2760,6 +2811,7 @@ static int img_amend(int argc, char **argv)
>      const char *fmt = NULL, *filename, *cache;
>      int flags;
>      bool quiet = false;
> +    BlockBackend *blk = NULL;
>      BlockDriverState *bs = NULL;
>  
>      cache = BDRV_DEFAULT_CACHE;
> @@ -2823,6 +2875,7 @@ static int img_amend(int argc, char **argv)
>          goto out;
>      }
>  
> +    blk = blk_new("image", &error_abort);
>      bs = bdrv_new_open("image", filename, fmt, flags, true, quiet);
>      if (!bs) {
>          error_report("Could not open image '%s'", filename);
> @@ -2856,6 +2909,7 @@ out:
>      if (bs) {
>          bdrv_unref(bs);
>      }
> +    blk_unref(blk);
>      qemu_opts_del(opts);
>      qemu_opts_free(create_opts);
>      g_free(options);
> diff --git a/qemu-io.c b/qemu-io.c
> index 24ca59c..57090de 100644
> --- a/qemu-io.c
> +++ b/qemu-io.c
> @@ -19,6 +19,7 @@
>  #include "qemu/option.h"
>  #include "qemu/config-file.h"
>  #include "qemu/readline.h"
> +#include "sysemu/block-backend.h"
>  #include "block/block_int.h"
>  #include "trace/control.h"
>  
> @@ -26,6 +27,7 @@
>  
>  static char *progname;
>  
> +static BlockBackend *qemuio_blk;
>  static BlockDriverState *qemuio_bs;
>  
>  /* qemu-io commands passed using -c */
> @@ -37,7 +39,9 @@ static ReadLineState *readline_state;
>  static int close_f(BlockDriverState *bs, int argc, char **argv)
>  {
>      bdrv_unref(bs);
> +    blk_unref(qemuio_blk);
>      qemuio_bs = NULL;
> +    qemuio_blk = NULL;
>      return 0;
>  }
>  
> @@ -58,6 +62,7 @@ static int openfile(char *name, int flags, int growable, QDict *opts)
>          return 1;
>      }
>  
> +    qemuio_blk = blk_new("hda", &error_abort);
>      qemuio_bs = bdrv_new_root("hda", &error_abort);
>  
>      if (growable) {
> @@ -70,7 +75,9 @@ static int openfile(char *name, int flags, int growable, QDict *opts)
>                  error_get_pretty(local_err));
>          error_free(local_err);
>          bdrv_unref(qemuio_bs);
> +        blk_unref(qemuio_blk);
>          qemuio_bs = NULL;
> +        qemuio_blk = NULL;
>          return 1;
>      }
>  
> @@ -479,6 +486,7 @@ int main(int argc, char **argv)
>      if (qemuio_bs) {
>          bdrv_unref(qemuio_bs);
>      }
> +    blk_unref(qemuio_blk);
>      g_free(readline_state);
>      return 0;
>  }
> diff --git a/qemu-nbd.c b/qemu-nbd.c
> index 24b8454..ff95da6 100644
> --- a/qemu-nbd.c
> +++ b/qemu-nbd.c
> @@ -17,7 +17,7 @@
>   */
>  
>  #include "qemu-common.h"
> -#include "block/block.h"
> +#include "sysemu/block-backend.h"
>  #include "block/block_int.h"
>  #include "block/nbd.h"
>  #include "qemu/main-loop.h"
> @@ -384,6 +384,7 @@ static void nbd_accept(void *opaque)
>  
>  int main(int argc, char **argv)
>  {
> +    BlockBackend *blk;
>      BlockDriverState *bs;
>      BlockDriver *drv;
>      off_t dev_offset = 0;
> @@ -687,6 +688,7 @@ int main(int argc, char **argv)
>          drv = NULL;
>      }
>  
> +    blk = blk_new("hda", &error_abort);
>      bs = bdrv_new_root("hda", &error_abort);
>  
>      srcpath = argv[optind];
> @@ -770,6 +772,7 @@ int main(int argc, char **argv)
>      } while (state != TERMINATED);
>  
>      bdrv_unref(bs);
> +    blk_unref(blk);
>      if (sockpath) {
>          unlink(sockpath);
>      }
> -- 
> 1.9.3
> 

^ permalink raw reply	[flat|nested] 56+ messages in thread

* Re: [Qemu-devel] [PATCH v2 01/23] block: Split bdrv_new_root() off bdrv_new()
  2014-09-15 12:00   ` Benoît Canet
@ 2014-09-15 13:19     ` Markus Armbruster
  0 siblings, 0 replies; 56+ messages in thread
From: Markus Armbruster @ 2014-09-15 13:19 UTC (permalink / raw)
  To: Benoît Canet; +Cc: kwolf, qemu-devel, stefanha

Benoît Canet <benoit.canet@nodalink.com> writes:

> On Sat, Sep 13, 2014 at 05:00:05PM +0200, Markus Armbruster wrote:
>> Creating an anonymous BDS can't fail.  Make that obvious.
>> 
>> Signed-off-by: Markus Armbruster <armbru@redhat.com>
>> ---
>>  block.c               | 28 +++++++++++++++++++---------
>>  block/iscsi.c         |  2 +-
>>  block/vvfat.c         |  2 +-
>>  blockdev.c            |  2 +-
>>  hw/block/xen_disk.c   |  2 +-
>>  include/block/block.h |  3 ++-
>>  qemu-img.c            |  6 +++---
>>  qemu-io.c             |  2 +-
>>  qemu-nbd.c            |  2 +-
>>  9 files changed, 30 insertions(+), 19 deletions(-)
>> 
>> diff --git a/block.c b/block.c
>> index 02ea90f..4fe3b62 100644
>> --- a/block.c
>> +++ b/block.c
>> @@ -336,10 +336,11 @@ void bdrv_register(BlockDriver *bdrv)
>>  }
>>  
>
>>  /* create a new block device (by default it is empty) */
> I wonder if this comment is stale.
> What is the emptiness of a block device anyway ?

No medium.

To make an empty BDS non-empty, bdrv_open() an image.  To make it empty
again, bdrv_close() it.

The comment still applies.

In the BB world, there's no such thing as an empty BDS.  A BB without
medium simply has no BDS.  This series doesn't get us there, it's just a
first step.  When we get there, bdrv_new() will be folded into
bdrv_open(), and bdrv_close() into bdrv_delete().

[...]
> Reviewed-by: Benoît Canet <benoit.canet@nodalink.com>

Thanks!

^ permalink raw reply	[flat|nested] 56+ messages in thread

* Re: [Qemu-devel] [PATCH v2 02/23] block: New BlockBackend
  2014-09-15 13:02   ` Benoît Canet
@ 2014-09-15 13:53     ` Markus Armbruster
  2014-09-15 14:55       ` Markus Armbruster
  0 siblings, 1 reply; 56+ messages in thread
From: Markus Armbruster @ 2014-09-15 13:53 UTC (permalink / raw)
  To: Benoît Canet; +Cc: kwolf, qemu-devel, stefanha

Benoît Canet <benoit.canet@nodalink.com> writes:

>> --- a/block.c
>> +++ b/block.c
>> @@ -2119,10 +2119,11 @@ static void bdrv_delete(BlockDriverState *bs)
>>  
>>      bdrv_close(bs);
>>  
>
>
>> +    drive_info_del(drive_get_by_blockdev(bs));
>> +
>>      /* remove from list, if necessary */
>>      bdrv_make_anon(bs);
>>  
>> -    drive_info_del(drive_get_by_blockdev(bs));
>
> Do we really want this move ?

Yes, we do.  If bdrv_make_anon() runs before drive_info_del(), this
conditional in drive_info_del() is always false:

    if (dinfo->bdrv->device_name[0]) {
        blk_unref(blk_by_name(dinfo->bdrv->device_name));
    }

I apologize for the hairiness.  Things will become *way* simpler in
PATCH 4.

> Or is it an artefact of your work on the preparation series ?

I added the line in "[PATCH 2/4] block: Keep DriveInfo alive until
BlockDriverState dies" in the wrong place for this patch, so I have to
move it here.  When I noticed, the patch was already out.  If I have to
respin, I'll avoid the churn.

>>      g_free(bs);
>>  }
>>  
>
>> + * Return the BlockBackend with name @name if it exists, else null.
>
>> + * @name must not be null.
> The contract is that no one will call blk_by_name(NULL);
>
>> + */
>> +BlockBackend *blk_by_name(const char *name)
>> +{
>> +    BlockBackend *blk;
>
> Can we ?
>
>      assert(name);

Sure, why not.

>> +
>> +    QTAILQ_FOREACH(blk, &blk_backends, link) {
>> +        if (!strcmp(name, blk->name)) {
>> +            return blk;
>> +        }
>> +    }
>> +    return NULL;
>> +}
[...]
>> @@ -227,6 +228,15 @@ void drive_info_del(DriveInfo *dinfo)
>>      if (dinfo->opts) {
>>          qemu_opts_del(dinfo->opts);
>>      }
>> +    /*
>> +     * Hairy special case: if do_drive_del() has made dinfo->bdrv
>> +     * anonymous, it also unref'ed the associated BlockBackend.
>> +     */
>
> Then you are filling the other case here.
>
> maybe
>
>     /*
>      * Hairy special case: if do_drive_del() has made dinfo->bdrv
>      * anonymous, it also unref'ed the associated BlockBackend.
>      * Process the other case here.
>      */
>
> would further explain you intents.

Okay.

>> +    if (dinfo->bdrv->device_name[0]) {
>> +        blk_unref(blk_by_name(dinfo->bdrv->device_name));
>> +    }
>> +
>>      g_free(dinfo->id);
>>      QTAILQ_REMOVE(&drives, dinfo, next);
>>      g_free(dinfo->serial);
>> @@ -307,6 +317,7 @@ static DriveInfo *blockdev_init(const char *file, QDict *bs_opts,
>>      int ro = 0;
>>      int bdrv_flags = 0;
>>      int on_read_error, on_write_error;
>> +    BlockBackend *blk;
>>      BlockDriverState *bs;
>>      DriveInfo *dinfo;
>>      ThrottleConfig cfg;
>> @@ -463,9 +474,13 @@ static DriveInfo *blockdev_init(const char *file, QDict *bs_opts,
>>      }
>
>>      const char *fmt1 = NULL, *fmt2 = NULL, *cache, *filename1, *filename2;
>> +    BlockBackend *blk1, *blk2;
>>      BlockDriverState *bs1, *bs2;
>>      int64_t total_sectors1, total_sectors2;
>>      uint8_t *buf1 = NULL, *buf2 = NULL;
>> @@ -1011,18 +1022,20 @@ static int img_compare(int argc, char **argv)
>>          goto out3;
>>      }
>>  
>> +    blk1 = blk_new("image 1", &error_abort);
>>      bs1 = bdrv_new_open("image 1", filename1, fmt1, flags, true, quiet);
>>      if (!bs1) {
>>          error_report("Can't open file %s", filename1);
>>          ret = 2;
>> -        goto out3;
>> +        goto out2;
>
> Here we allocate blk1 and bs1 an if bs1 is null (error) we jump to
> out2 which is:
>
>>  out2:
>>      bdrv_unref(bs1);
>> +    blk_unref(blk1);
>
> It's a bit strange that we will bdrv_unref(NULL) in this case.
>
> This goto chain seems odd.

You can solve the "on error, destroy the things already created" problem
like this:

    Foo *foo;
    Bar *bar;
    Baz *baz;
    [...]
    foo = new_foo();
    if (!foo) {
        goto out_foo;
    }
    bar = new_bar();
    if (!bar) {
        goto out_bar;
    }
    baz = new_baz();
    if (!baz) {
        goto out_baz;
    }
    [...]
out_baz:
    del_baz(baz);
out_bar:
    del_bar(bar);
out_foo:
    del_foo(foo);

Works, but keeping track of where exactly to go to is somewhat tedious
and error prone.

If the del_ functions do nothing for null arguments, the following also
works:

    Foo *foo = NULL;
    Bar *bar = NULL;
    Baz *baz = NULL;
    [...]
    foo = new_foo();
    if (!foo) {
        goto out;
    }
    bar = new_bar();
    if (!bar) {
        goto out;
    }
    baz = new_baz();
    if (!baz) {
        goto out;
    }
    [...]
out:
    del_baz(baz);
    del_bar(bar);
    del_foo(foo);

Simpler.  This is the reason why free(NULL) does nothing.

>>      }
>>  
>> +    blk2 = blk_new("image 2", &error_abort);
>>      bs2 = bdrv_new_open("image 2", filename2, fmt2, flags, true, quiet);
>>      if (!bs2) {
>>          error_report("Can't open file %s", filename2);
>>          ret = 2;
>> -        goto out2;
>> +        goto out1;
>>      }
>>  
>>      buf1 = qemu_blockalign(bs1, IO_BUF_SIZE);
>> @@ -1183,11 +1196,14 @@ static int img_compare(int argc, char **argv)
>>      ret = 0;
>>  
>>  out:
>> -    bdrv_unref(bs2);
>>      qemu_vfree(buf1);
>>      qemu_vfree(buf2);
>> +out1:
>> +    bdrv_unref(bs2);
>> +    blk_unref(blk2);
>>  out2:
>>      bdrv_unref(bs1);
>> +    blk_unref(blk1);
>>  out3:
>>      qemu_progress_end();
>>      return ret;
>> @@ -1200,6 +1216,7 @@ static int img_convert(int argc, char **argv)
>>      int progress = 0, flags, src_flags;
>>      const char *fmt, *out_fmt, *cache, *src_cache, *out_baseimg, *out_filename;
>>      BlockDriver *drv, *proto_drv;
>> +    BlockBackend **blk = NULL, *out_blk = NULL;
>
> Should blk be blks or blkes ? They are multiple.

I follow the bs precedence (next line).

In general, I feel using plural for array names doesn't work so well,
because most uses tend to be subscripted, and there plural feels
awkward.

>>      BlockDriverState **bs = NULL, *out_bs = NULL;
>>      int64_t total_sectors, nb_sectors, sector_num, bs_offset;
>>      int64_t *bs_sectors = NULL;
[...]

^ permalink raw reply	[flat|nested] 56+ messages in thread

* Re: [Qemu-devel] [PATCH v2 02/23] block: New BlockBackend
  2014-09-15 13:53     ` Markus Armbruster
@ 2014-09-15 14:55       ` Markus Armbruster
  2014-09-15 15:54         ` Markus Armbruster
  0 siblings, 1 reply; 56+ messages in thread
From: Markus Armbruster @ 2014-09-15 14:55 UTC (permalink / raw)
  To: Benoît Canet; +Cc: kwolf, qemu-devel, stefanha

Markus Armbruster <armbru@redhat.com> writes:

> Benoît Canet <benoit.canet@nodalink.com> writes:
>
>>> --- a/block.c
>>> +++ b/block.c
>>> @@ -2119,10 +2119,11 @@ static void bdrv_delete(BlockDriverState *bs)
>>>  
>>>      bdrv_close(bs);
>>>  
>>
>>
>>> +    drive_info_del(drive_get_by_blockdev(bs));
>>> +
>>>      /* remove from list, if necessary */
>>>      bdrv_make_anon(bs);
>>>  
>>> -    drive_info_del(drive_get_by_blockdev(bs));
>>
>> Do we really want this move ?
>
> Yes, we do.  If bdrv_make_anon() runs before drive_info_del(), this
> conditional in drive_info_del() is always false:
>
>     if (dinfo->bdrv->device_name[0]) {
>         blk_unref(blk_by_name(dinfo->bdrv->device_name));
>     }
>
> I apologize for the hairiness.  Things will become *way* simpler in
> PATCH 4.

It's not just temporarily hairy, it's temporarily wrong: double unref is
possible.

drive_del, the gift that keeps on giving...

[...]

^ permalink raw reply	[flat|nested] 56+ messages in thread

* Re: [Qemu-devel] [PATCH v2 03/23] block: Connect BlockBackend to BlockDriverState
  2014-09-13 15:00 ` [Qemu-devel] [PATCH v2 03/23] block: Connect BlockBackend to BlockDriverState Markus Armbruster
  2014-09-13 22:13   ` Max Reitz
@ 2014-09-15 15:00   ` Benoît Canet
  2014-09-15 15:34     ` Markus Armbruster
  1 sibling, 1 reply; 56+ messages in thread
From: Benoît Canet @ 2014-09-15 15:00 UTC (permalink / raw)
  To: Markus Armbruster; +Cc: kwolf, qemu-devel, stefanha, benoit.canet

> index ff95da6..fa8a7d0 100644
> --- a/qemu-nbd.c
> +++ b/qemu-nbd.c
> @@ -689,7 +689,7 @@ int main(int argc, char **argv)
>      }
>  

>      blk = blk_new("hda", &error_abort);
Is a blk_new_with_bs converssion missing here ?

> -    bs = bdrv_new_root("hda", &error_abort);
> +    bs = blk_bs(blk);
>  
>      srcpath = argv[optind];
>      ret = bdrv_open(&bs, srcpath, NULL, NULL, flags, drv, &local_err);
> -- 
> 1.9.3
> 

^ permalink raw reply	[flat|nested] 56+ messages in thread

* Re: [Qemu-devel] [PATCH v2 03/23] block: Connect BlockBackend to BlockDriverState
  2014-09-15 15:00   ` Benoît Canet
@ 2014-09-15 15:34     ` Markus Armbruster
  0 siblings, 0 replies; 56+ messages in thread
From: Markus Armbruster @ 2014-09-15 15:34 UTC (permalink / raw)
  To: Benoît Canet; +Cc: kwolf, qemu-devel, stefanha

Benoît Canet <benoit.canet@nodalink.com> writes:

>> index ff95da6..fa8a7d0 100644
>> --- a/qemu-nbd.c
>> +++ b/qemu-nbd.c
>> @@ -689,7 +689,7 @@ int main(int argc, char **argv)
>>      }
>>  
>
>>      blk = blk_new("hda", &error_abort);
> Is a blk_new_with_bs converssion missing here ?

Yes.  Max spotted it, too :)

>> -    bs = bdrv_new_root("hda", &error_abort);
>> +    bs = blk_bs(blk);
>>  
>>      srcpath = argv[optind];
>>      ret = bdrv_open(&bs, srcpath, NULL, NULL, flags, drv, &local_err);
>> -- 
>> 1.9.3
>> 

^ permalink raw reply	[flat|nested] 56+ messages in thread

* Re: [Qemu-devel] [PATCH v2 02/23] block: New BlockBackend
  2014-09-15 14:55       ` Markus Armbruster
@ 2014-09-15 15:54         ` Markus Armbruster
  0 siblings, 0 replies; 56+ messages in thread
From: Markus Armbruster @ 2014-09-15 15:54 UTC (permalink / raw)
  To: Benoît Canet; +Cc: kwolf, qemu-devel, stefanha

Markus Armbruster <armbru@redhat.com> writes:

> Markus Armbruster <armbru@redhat.com> writes:
>
>> Benoît Canet <benoit.canet@nodalink.com> writes:
>>
>>>> --- a/block.c
>>>> +++ b/block.c
>>>> @@ -2119,10 +2119,11 @@ static void bdrv_delete(BlockDriverState *bs)
>>>>  
>>>>      bdrv_close(bs);
>>>>  
>>>
>>>
>>>> +    drive_info_del(drive_get_by_blockdev(bs));
>>>> +
>>>>      /* remove from list, if necessary */
>>>>      bdrv_make_anon(bs);
>>>>  
>>>> -    drive_info_del(drive_get_by_blockdev(bs));
>>>
>>> Do we really want this move ?
>>
>> Yes, we do.  If bdrv_make_anon() runs before drive_info_del(), this
>> conditional in drive_info_del() is always false:
>>
>>     if (dinfo->bdrv->device_name[0]) {
>>         blk_unref(blk_by_name(dinfo->bdrv->device_name));
>>     }
>>
>> I apologize for the hairiness.  Things will become *way* simpler in
>> PATCH 4.
>
> It's not just temporarily hairy, it's temporarily wrong: double unref is
> possible.

Clarification: wrong in my tree, after I tried to plug the leak Max
found in PATCH 3.  v2 as posted has no double unref.

I'm afraid getting this exactly right at every step is too hard to be
worth it.  I think I'll go for a temporary memory leak in v3.

> drive_del, the gift that keeps on giving...
>
> [...]

^ permalink raw reply	[flat|nested] 56+ messages in thread

* Re: [Qemu-devel] [PATCH v2 00/23] Split BlockBackend off BDS with an axe
  2014-09-13 15:00 [Qemu-devel] [PATCH v2 00/23] Split BlockBackend off BDS with an axe Markus Armbruster
                   ` (22 preceding siblings ...)
  2014-09-13 15:00 ` [Qemu-devel] [PATCH v2 23/23] block: Make device model's references to BlockBackend strong Markus Armbruster
@ 2014-09-16 12:22 ` Markus Armbruster
  23 siblings, 0 replies; 56+ messages in thread
From: Markus Armbruster @ 2014-09-16 12:22 UTC (permalink / raw)
  To: qemu-devel; +Cc: kwolf, Fam Zheng, benoit.canet, stefanha, Max Reitz

Conflicts with current master now.  I'll rebase.

^ permalink raw reply	[flat|nested] 56+ messages in thread

* Re: [Qemu-devel] [PATCH v2 04/23] block: Connect BlockBackend and DriveInfo
  2014-09-13 15:00 ` [Qemu-devel] [PATCH v2 04/23] block: Connect BlockBackend and DriveInfo Markus Armbruster
@ 2014-09-16 12:38   ` Benoît Canet
  2014-09-16 13:51     ` Markus Armbruster
  0 siblings, 1 reply; 56+ messages in thread
From: Benoît Canet @ 2014-09-16 12:38 UTC (permalink / raw)
  To: Markus Armbruster; +Cc: kwolf, qemu-devel, stefanha, benoit.canet

> +DriveInfo *blk_legacy_dinfo(BlockBackend *blk)
> +{
> +    return blk->legacy_dinfo;
> +}
> +
> +/*
> + * Set @blk's DriveInfo to @dinfo, and return it.
> + * @blk must not have a DriveInfo set already.

> + * No other BlockBackend may have the same DriveInfo set.
Must we try to assert this ?
This would require an extra linked list traversal but I don't think it's a
performance path anyway.

Reviewed-by: Benoît Canet <benoit.canet@nodalink.com>

^ permalink raw reply	[flat|nested] 56+ messages in thread

* Re: [Qemu-devel] [PATCH v2 05/23] block: Code motion to get rid of stubs/blockdev.c
  2014-09-13 15:00 ` [Qemu-devel] [PATCH v2 05/23] block: Code motion to get rid of stubs/blockdev.c Markus Armbruster
  2014-09-15  6:28   ` Fam Zheng
@ 2014-09-16 12:40   ` Benoît Canet
  1 sibling, 0 replies; 56+ messages in thread
From: Benoît Canet @ 2014-09-16 12:40 UTC (permalink / raw)
  To: Markus Armbruster; +Cc: kwolf, qemu-devel, stefanha, benoit.canet

On Sat, Sep 13, 2014 at 05:00:09PM +0200, Markus Armbruster wrote:
> Signed-off-by: Markus Armbruster <armbru@redhat.com>
> ---
>  block/block-backend.c     | 15 +++++++++++++++
>  blockdev.c                | 13 -------------
>  include/sysemu/blockdev.h |  1 -
>  stubs/Makefile.objs       |  1 -
>  stubs/blockdev.c          | 12 ------------
>  5 files changed, 15 insertions(+), 27 deletions(-)
>  delete mode 100644 stubs/blockdev.c
> 
> diff --git a/block/block-backend.c b/block/block-backend.c
> index 7b8c062..0842abe 100644
> --- a/block/block-backend.c
> +++ b/block/block-backend.c
> @@ -22,6 +22,8 @@ struct BlockBackend {
>      QTAILQ_ENTRY(BlockBackend) link; /* for blk_backends */
>  };
>  
> +static void drive_info_del(DriveInfo *dinfo);
> +
>  /* All the BlockBackends (except for hidden ones) */
>  static QTAILQ_HEAD(, BlockBackend) blk_backends =
>      QTAILQ_HEAD_INITIALIZER(blk_backends);
> @@ -92,6 +94,19 @@ static void blk_delete(BlockBackend *blk)
>      g_free(blk);
>  }
>  
> +static void drive_info_del(DriveInfo *dinfo)
> +{
> +    if (!dinfo) {
> +        return;
> +    }
> +    if (dinfo->opts) {
> +        qemu_opts_del(dinfo->opts);
> +    }
> +    g_free(dinfo->id);
> +    g_free(dinfo->serial);
> +    g_free(dinfo);
> +}
> +
>  /*
>   * Increment @blk's reference count.
>   * @blk must not be null.
> diff --git a/blockdev.c b/blockdev.c
> index aec9f0e..0ed108d 100644
> --- a/blockdev.c
> +++ b/blockdev.c
> @@ -223,19 +223,6 @@ void drive_del(DriveInfo *dinfo)
>      blk_unref(blk_by_legacy_dinfo(dinfo));
>  }
>  
> -void drive_info_del(DriveInfo *dinfo)
> -{
> -    if (!dinfo) {
> -        return;
> -    }
> -    if (dinfo->opts) {
> -        qemu_opts_del(dinfo->opts);
> -    }
> -    g_free(dinfo->id);
> -    g_free(dinfo->serial);
> -    g_free(dinfo);
> -}
> -
>  typedef struct {
>      QEMUBH *bh;
>      BlockDriverState *bs;
> diff --git a/include/sysemu/blockdev.h b/include/sysemu/blockdev.h
> index 1dc5906..2ed297b 100644
> --- a/include/sysemu/blockdev.h
> +++ b/include/sysemu/blockdev.h
> @@ -60,7 +60,6 @@ QemuOpts *drive_add(BlockInterfaceType type, int index, const char *file,
>                      const char *optstr);
>  DriveInfo *drive_new(QemuOpts *arg, BlockInterfaceType block_default_type);
>  void drive_del(DriveInfo *dinfo);
> -void drive_info_del(DriveInfo *dinfo);
>  
>  /* device-hotplug */
>  
> diff --git a/stubs/Makefile.objs b/stubs/Makefile.objs
> index c0b1f6a..5e347d0 100644
> --- a/stubs/Makefile.objs
> +++ b/stubs/Makefile.objs
> @@ -1,6 +1,5 @@
>  stub-obj-y += arch-query-cpu-def.o
>  stub-obj-y += bdrv-commit-all.o
> -stub-obj-y += blockdev.o
>  stub-obj-y += chr-baum-init.o
>  stub-obj-y += chr-msmouse.o
>  stub-obj-y += chr-testdev.o
> diff --git a/stubs/blockdev.c b/stubs/blockdev.c
> deleted file mode 100644
> index 5d0a79c..0000000
> --- a/stubs/blockdev.c
> +++ /dev/null
> @@ -1,12 +0,0 @@
> -#include <assert.h>
> -#include "sysemu/blockdev.h"
> -
> -DriveInfo *drive_get_by_blockdev(BlockDriverState *bs)
> -{
> -    return NULL;
> -}
> -
> -void drive_info_del(DriveInfo *dinfo)
> -{
> -    assert(!dinfo);
> -}
> -- 
> 1.9.3
> 
Reviewed-by: Benoît Canet <benoit.canet@nodalink.com>

^ permalink raw reply	[flat|nested] 56+ messages in thread

* Re: [Qemu-devel] [PATCH v2 06/23] block: Make BlockBackend own its BlockDriverState
  2014-09-13 15:00 ` [Qemu-devel] [PATCH v2 06/23] block: Make BlockBackend own its BlockDriverState Markus Armbruster
@ 2014-09-16 12:56   ` Benoît Canet
  2014-09-16 14:01     ` Markus Armbruster
  0 siblings, 1 reply; 56+ messages in thread
From: Benoît Canet @ 2014-09-16 12:56 UTC (permalink / raw)
  To: Markus Armbruster; +Cc: kwolf, qemu-devel, stefanha, benoit.canet

>          /* blkdev->bs is not create by us, we get a reference
>           * so we can bdrv_unref() unconditionally */
> -        bdrv_ref(blkdev->bs);

> +        /* Except we don't bdrv_unref() anymore, we blk_unref().
Is this dot extra ?                                               ^
The following line seems to make better sense without this dot and the initial cap.
> +         * Conditionally, because we can't easily blk_ref() here.

> @@ -712,9 +711,7 @@ static int img_check(int argc, char **argv)
>  
>  fail:
>      qapi_free_ImageCheck(check);
> -    bdrv_unref(bs);
>      blk_unref(blk);
> -
Spurious blank line removal here.

> @@ -483,9 +481,6 @@ int main(int argc, char **argv)
>       */
>      bdrv_drain_all();
>  
> -    if (qemuio_bs) {
> -        bdrv_unref(qemuio_bs);
> -    }
>      blk_unref(qemuio_blk);
>      g_free(readline_state);
>      return 0;
> diff --git a/qemu-nbd.c b/qemu-nbd.c
> index fa8a7d0..0c496af 100644
> --- a/qemu-nbd.c
> +++ b/qemu-nbd.c
> @@ -771,7 +771,6 @@ int main(int argc, char **argv)

Well that does seems to simplify things a lot.

^ permalink raw reply	[flat|nested] 56+ messages in thread

* Re: [Qemu-devel] [PATCH v2 07/23] block: Eliminate bdrv_iterate(), use bdrv_next()
  2014-09-13 15:00 ` [Qemu-devel] [PATCH v2 07/23] block: Eliminate bdrv_iterate(), use bdrv_next() Markus Armbruster
@ 2014-09-16 13:04   ` Benoît Canet
  0 siblings, 0 replies; 56+ messages in thread
From: Benoît Canet @ 2014-09-16 13:04 UTC (permalink / raw)
  To: Markus Armbruster; +Cc: kwolf, qemu-devel, stefanha, benoit.canet

> @@ -4717,10 +4699,14 @@ static void monitor_find_completion_by_table(Monitor *mon,
>              break;
>          case 'B':
>              /* block device name completion */
> -            mbs.mon = mon;
> -            mbs.input = str;
>              readline_set_completion_index(mon->rs, strlen(str));
> -            bdrv_iterate(block_completion_it, &mbs);
> +            for (bs = bdrv_next(NULL); bs; bs = bdrv_next(bs)) {
> +                name = bdrv_get_device_name(bs);
> +                if (str[0] == '\0' ||
> +                    !strncmp(name, str, strlen(str))) {
> +                    readline_add_completion(mon->rs, name);
> +                }
> +            }
>              break;
>          case 's':
>          case 'S':
> -- 
> 1.9.3
> 
Reviewed-by: Benoît Canet <benoit.canet@nodalink.com>

^ permalink raw reply	[flat|nested] 56+ messages in thread

* Re: [Qemu-devel] [PATCH v2 08/23] block: Eliminate BlockDriverState member device_name[]
  2014-09-13 15:00 ` [Qemu-devel] [PATCH v2 08/23] block: Eliminate BlockDriverState member device_name[] Markus Armbruster
@ 2014-09-16 13:18   ` Benoît Canet
  2014-09-16 14:08     ` Markus Armbruster
  0 siblings, 1 reply; 56+ messages in thread
From: Benoît Canet @ 2014-09-16 13:18 UTC (permalink / raw)
  To: Markus Armbruster; +Cc: kwolf, qemu-devel, stefanha, benoit.canet



>  #include "qemu-common.h"
> -#include "block/block_int.h"
> +#include "block/block.h"
> +#include "qemu/error-report.h"
> +#include "qemu/main-loop.h"

That's a lot of include fiddling I am not sure to understand them while looking
at the following diff.

>  #include "hw/hw.h"
>  #include "qemu/queue.h"
>  #include "qemu/timer.h"
> @@ -130,9 +132,9 @@ static void blk_send(QEMUFile *f, BlkMigBlock * blk)
>                       | flags);
>  
>      /* device name */
> -    len = strlen(blk->bmds->bs->device_name);
> +    len = strlen(bdrv_get_device_name(blk->bmds->bs));
>      qemu_put_byte(f, len);
> -    qemu_put_buffer(f, (uint8_t *)blk->bmds->bs->device_name, len);
> +    qemu_put_buffer(f, (uint8_t *)bdrv_get_device_name(blk->bmds->bs), len);
>  
>      /* if a block is zero we need to flush here since the network
>       * bandwidth is now a lot higher than the storage device bandwidth.
> @@ -382,9 +384,9 @@ static void init_blk_migration(QEMUFile *f)
>  
>          if (bmds->shared_base) {
>              DPRINTF("Start migration for %s with shared base image\n",
> -                    bs->device_name);
> +                    bdrv_get_device_name(bs));
>          } else {
> -            DPRINTF("Start full migration for %s\n", bs->device_name);
> +            DPRINTF("Start full migration for %s\n", bdrv_get_device_name(bs));
>          }
>  
>          QSIMPLEQ_INSERT_TAIL(&block_mig_state.bmds_list, bmds, entry);


> @@ -1959,10 +1941,10 @@ void bdrv_drain_all(void)
>   V  Also, NULL terminate the device_name to prevent double remove */
>  void bdrv_make_anon(BlockDriverState *bs)
>  {
> -    if (bs->device_name[0] != '\0') {


> +    if (bs->device_list.tqe_prev) {
>          QTAILQ_REMOVE(&bdrv_states, bs, device_list);
> +        bs->device_list.tqe_prev = NULL;

I think a comments explaining the trick you are doing here would be worthy:
after all you are touching directly the inner parts of a linked list and
bypassing the list API.


>      }
> -    bs->device_name[0] = '\0';
>      if (bs->node_name[0] != '\0') {
>          QTAILQ_REMOVE(&graph_bdrv_states, bs, node_list);
>      }

^ permalink raw reply	[flat|nested] 56+ messages in thread

* Re: [Qemu-devel] [PATCH v2 09/23] block: Merge BlockBackend and BlockDriverState name spaces
  2014-09-13 15:00 ` [Qemu-devel] [PATCH v2 09/23] block: Merge BlockBackend and BlockDriverState name spaces Markus Armbruster
@ 2014-09-16 13:25   ` Benoît Canet
  0 siblings, 0 replies; 56+ messages in thread
From: Benoît Canet @ 2014-09-16 13:25 UTC (permalink / raw)
  To: Markus Armbruster; +Cc: kwolf, qemu-devel, stefanha, benoit.canet

> 1.9.3
> 
Reviewed-by: Benoît Canet <benoit.canet@nodalink.com>

^ permalink raw reply	[flat|nested] 56+ messages in thread

* Re: [Qemu-devel] [PATCH v2 04/23] block: Connect BlockBackend and DriveInfo
  2014-09-16 12:38   ` Benoît Canet
@ 2014-09-16 13:51     ` Markus Armbruster
  0 siblings, 0 replies; 56+ messages in thread
From: Markus Armbruster @ 2014-09-16 13:51 UTC (permalink / raw)
  To: Benoît Canet; +Cc: kwolf, qemu-devel, stefanha

Benoît Canet <benoit.canet@nodalink.com> writes:

>> +DriveInfo *blk_legacy_dinfo(BlockBackend *blk)
>> +{
>> +    return blk->legacy_dinfo;
>> +}
>> +
>> +/*
>> + * Set @blk's DriveInfo to @dinfo, and return it.
>> + * @blk must not have a DriveInfo set already.
>
>> + * No other BlockBackend may have the same DriveInfo set.
> Must we try to assert this ?
> This would require an extra linked list traversal but I don't think it's a
> performance path anyway.

Must, no.  We could.

However, the obvious

    assert(!blk_by_legacy_dinfo(dinfo);

doesn't work, because blk_by_legacy_dinfo() asserts it returns a
non-null value.  Either we sacrifice that assertion, or we duplicate the
search loop here (yuck), or we factor it out into a helper function.  I
don't particularly like either of the three.  But if you guys really
want the precondition checked, I'll check it.

> Reviewed-by: Benoît Canet <benoit.canet@nodalink.com>

Thanks!

^ permalink raw reply	[flat|nested] 56+ messages in thread

* Re: [Qemu-devel] [PATCH v2 06/23] block: Make BlockBackend own its BlockDriverState
  2014-09-16 12:56   ` Benoît Canet
@ 2014-09-16 14:01     ` Markus Armbruster
  0 siblings, 0 replies; 56+ messages in thread
From: Markus Armbruster @ 2014-09-16 14:01 UTC (permalink / raw)
  To: Benoît Canet; +Cc: kwolf, qemu-devel, stefanha

Benoît Canet <benoit.canet@nodalink.com> writes:

>>          /* blkdev->bs is not create by us, we get a reference
>>           * so we can bdrv_unref() unconditionally */
>> -        bdrv_ref(blkdev->bs);
>
>> +        /* Except we don't bdrv_unref() anymore, we blk_unref().
> Is this dot extra ?                                               ^

No, I wrote two sentences intentionally.

The whole comment gets replaced in PATCH 14.

> The following line seems to make better sense without this dot and the
> initial cap.
>> +         * Conditionally, because we can't easily blk_ref() here.
>
>> @@ -712,9 +711,7 @@ static int img_check(int argc, char **argv)
>>  
>>  fail:
>>      qapi_free_ImageCheck(check);
>> -    bdrv_unref(bs);
>>      blk_unref(blk);
>> -
> Spurious blank line removal here.

Intentional.  Without it, the code looks like this:

    if (check->corruptions) {
        ret = 2;
    } else if (check->leaks) {
        ret = 3;
    } else {
        ret = 0;
    }

fail:
    qapi_free_ImageCheck(check);
    blk_unref(blk);

    return ret;
}

I don't think the blank line helps readability here.

>> @@ -483,9 +481,6 @@ int main(int argc, char **argv)
>>       */
>>      bdrv_drain_all();
>>  
>> -    if (qemuio_bs) {
>> -        bdrv_unref(qemuio_bs);
>> -    }
>>      blk_unref(qemuio_blk);
>>      g_free(readline_state);
>>      return 0;
>> diff --git a/qemu-nbd.c b/qemu-nbd.c
>> index fa8a7d0..0c496af 100644
>> --- a/qemu-nbd.c
>> +++ b/qemu-nbd.c
>> @@ -771,7 +771,6 @@ int main(int argc, char **argv)
>
> Well that does seems to simplify things a lot.

:)

^ permalink raw reply	[flat|nested] 56+ messages in thread

* Re: [Qemu-devel] [PATCH v2 08/23] block: Eliminate BlockDriverState member device_name[]
  2014-09-16 13:18   ` Benoît Canet
@ 2014-09-16 14:08     ` Markus Armbruster
  2014-09-16 14:32       ` Paolo Bonzini
  0 siblings, 1 reply; 56+ messages in thread
From: Markus Armbruster @ 2014-09-16 14:08 UTC (permalink / raw)
  To: Benoît Canet; +Cc: kwolf, qemu-devel, stefanha

Benoît Canet <benoit.canet@nodalink.com> writes:

>>  #include "qemu-common.h"
>> -#include "block/block_int.h"
>> +#include "block/block.h"
>> +#include "qemu/error-report.h"
>> +#include "qemu/main-loop.h"
>
> That's a lot of include fiddling I am not sure to understand them while looking
> at the following diff.

Before the patch, we need block_int.h because we dereference bs.

After the patch, we don't, so I can drop block_int.h.  But then I have
to add back those includes included by block_int.h we actually need
here.

>>  #include "hw/hw.h"
>>  #include "qemu/queue.h"
>>  #include "qemu/timer.h"
>> @@ -130,9 +132,9 @@ static void blk_send(QEMUFile *f, BlkMigBlock * blk)
>>                       | flags);
>>  
>>      /* device name */
>> -    len = strlen(blk->bmds->bs->device_name);
>> +    len = strlen(bdrv_get_device_name(blk->bmds->bs));
>>      qemu_put_byte(f, len);
>> -    qemu_put_buffer(f, (uint8_t *)blk->bmds->bs->device_name, len);
>> +    qemu_put_buffer(f, (uint8_t *)bdrv_get_device_name(blk->bmds->bs), len);
>>  
>>      /* if a block is zero we need to flush here since the network
>>       * bandwidth is now a lot higher than the storage device bandwidth.
>> @@ -382,9 +384,9 @@ static void init_blk_migration(QEMUFile *f)
>>  
>>          if (bmds->shared_base) {
>>              DPRINTF("Start migration for %s with shared base image\n",
>> -                    bs->device_name);
>> +                    bdrv_get_device_name(bs));
>>          } else {
>> -            DPRINTF("Start full migration for %s\n", bs->device_name);
>> +            DPRINTF("Start full migration for %s\n", bdrv_get_device_name(bs));
>>          }
>>  
>>          QSIMPLEQ_INSERT_TAIL(&block_mig_state.bmds_list, bmds, entry);
>
>
>> @@ -1959,10 +1941,10 @@ void bdrv_drain_all(void)
>>   V  Also, NULL terminate the device_name to prevent double remove */
>>  void bdrv_make_anon(BlockDriverState *bs)
>>  {
>> -    if (bs->device_name[0] != '\0') {
>
>
>> +    if (bs->device_list.tqe_prev) {
>>          QTAILQ_REMOVE(&bdrv_states, bs, device_list);
>> +        bs->device_list.tqe_prev = NULL;
>
> I think a comments explaining the trick you are doing here would be worthy:
> after all you are touching directly the inner parts of a linked list and
> bypassing the list API.

Fair enough.

>>      }
>> -    bs->device_name[0] = '\0';
>>      if (bs->node_name[0] != '\0') {
>>          QTAILQ_REMOVE(&graph_bdrv_states, bs, node_list);
>>      }

^ permalink raw reply	[flat|nested] 56+ messages in thread

* Re: [Qemu-devel] [PATCH v2 08/23] block: Eliminate BlockDriverState member device_name[]
  2014-09-16 14:08     ` Markus Armbruster
@ 2014-09-16 14:32       ` Paolo Bonzini
  2014-09-16 17:39         ` Markus Armbruster
  0 siblings, 1 reply; 56+ messages in thread
From: Paolo Bonzini @ 2014-09-16 14:32 UTC (permalink / raw)
  To: Markus Armbruster, Benoît Canet; +Cc: kwolf, qemu-devel, stefanha

Il 16/09/2014 16:08, Markus Armbruster ha scritto:
>>> >> +    if (bs->device_list.tqe_prev) {
>>> >>          QTAILQ_REMOVE(&bdrv_states, bs, device_list);
>>> >> +        bs->device_list.tqe_prev = NULL;
>> >
>> > I think a comments explaining the trick you are doing here would be worthy:
>> > after all you are touching directly the inner parts of a linked list and
>> > bypassing the list API.
> Fair enough.

Or just add tqe_prev = NULL to QTAILQ_REMOVE.

Paolo

^ permalink raw reply	[flat|nested] 56+ messages in thread

* Re: [Qemu-devel] [PATCH v2 08/23] block: Eliminate BlockDriverState member device_name[]
  2014-09-16 14:32       ` Paolo Bonzini
@ 2014-09-16 17:39         ` Markus Armbruster
  0 siblings, 0 replies; 56+ messages in thread
From: Markus Armbruster @ 2014-09-16 17:39 UTC (permalink / raw)
  To: Paolo Bonzini; +Cc: kwolf, stefanha, qemu-devel, Benoît Canet

Paolo Bonzini <pbonzini@redhat.com> writes:

> Il 16/09/2014 16:08, Markus Armbruster ha scritto:
>>>> >> +    if (bs->device_list.tqe_prev) {
>>>> >>          QTAILQ_REMOVE(&bdrv_states, bs, device_list);
>>>> >> +        bs->device_list.tqe_prev = NULL;
>>> >
>>> > I think a comments explaining the trick you are doing here would be worthy:
>>> > after all you are touching directly the inner parts of a linked list and
>>> > bypassing the list API.
>> Fair enough.
>
> Or just add tqe_prev = NULL to QTAILQ_REMOVE.

And add a QTAILQ_IN_ANY_QUEUE() macro, so I get rid of both .tqe_prev
uses.  I'll consider it, but either in v4 or as a follow-up patch,
because I want to grep the source for similar trickery.

^ permalink raw reply	[flat|nested] 56+ messages in thread

end of thread, other threads:[~2014-09-16 17:39 UTC | newest]

Thread overview: 56+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2014-09-13 15:00 [Qemu-devel] [PATCH v2 00/23] Split BlockBackend off BDS with an axe Markus Armbruster
2014-09-13 15:00 ` [Qemu-devel] [PATCH v2 01/23] block: Split bdrv_new_root() off bdrv_new() Markus Armbruster
2014-09-13 20:45   ` Max Reitz
2014-09-15 12:00   ` Benoît Canet
2014-09-15 13:19     ` Markus Armbruster
2014-09-13 15:00 ` [Qemu-devel] [PATCH v2 02/23] block: New BlockBackend Markus Armbruster
2014-09-13 21:41   ` Max Reitz
2014-09-15  6:37     ` Markus Armbruster
2014-09-15 13:02   ` Benoît Canet
2014-09-15 13:53     ` Markus Armbruster
2014-09-15 14:55       ` Markus Armbruster
2014-09-15 15:54         ` Markus Armbruster
2014-09-13 15:00 ` [Qemu-devel] [PATCH v2 03/23] block: Connect BlockBackend to BlockDriverState Markus Armbruster
2014-09-13 22:13   ` Max Reitz
2014-09-15  6:59     ` Markus Armbruster
2014-09-15 15:00   ` Benoît Canet
2014-09-15 15:34     ` Markus Armbruster
2014-09-13 15:00 ` [Qemu-devel] [PATCH v2 04/23] block: Connect BlockBackend and DriveInfo Markus Armbruster
2014-09-16 12:38   ` Benoît Canet
2014-09-16 13:51     ` Markus Armbruster
2014-09-13 15:00 ` [Qemu-devel] [PATCH v2 05/23] block: Code motion to get rid of stubs/blockdev.c Markus Armbruster
2014-09-15  6:28   ` Fam Zheng
2014-09-15  7:21     ` Markus Armbruster
2014-09-15  7:23       ` Fam Zheng
2014-09-16 12:40   ` Benoît Canet
2014-09-13 15:00 ` [Qemu-devel] [PATCH v2 06/23] block: Make BlockBackend own its BlockDriverState Markus Armbruster
2014-09-16 12:56   ` Benoît Canet
2014-09-16 14:01     ` Markus Armbruster
2014-09-13 15:00 ` [Qemu-devel] [PATCH v2 07/23] block: Eliminate bdrv_iterate(), use bdrv_next() Markus Armbruster
2014-09-16 13:04   ` Benoît Canet
2014-09-13 15:00 ` [Qemu-devel] [PATCH v2 08/23] block: Eliminate BlockDriverState member device_name[] Markus Armbruster
2014-09-16 13:18   ` Benoît Canet
2014-09-16 14:08     ` Markus Armbruster
2014-09-16 14:32       ` Paolo Bonzini
2014-09-16 17:39         ` Markus Armbruster
2014-09-13 15:00 ` [Qemu-devel] [PATCH v2 09/23] block: Merge BlockBackend and BlockDriverState name spaces Markus Armbruster
2014-09-16 13:25   ` Benoît Canet
2014-09-13 15:00 ` [Qemu-devel] [PATCH v2 10/23] block: Eliminate DriveInfo member bdrv, use blk_by_legacy_dinfo() Markus Armbruster
2014-09-15  6:58   ` Fam Zheng
2014-09-15  7:21     ` Markus Armbruster
2014-09-13 15:00 ` [Qemu-devel] [PATCH v2 11/23] block: Rename BlockDriverAIOCB* to BlockAIOCB* Markus Armbruster
2014-09-13 15:00 ` [Qemu-devel] [PATCH v2 12/23] virtio-blk: Drop redundant VirtIOBlock member conf Markus Armbruster
2014-09-13 15:00 ` [Qemu-devel] [PATCH v2 13/23] virtio-blk: Rename VirtIOBlkConf variables to conf Markus Armbruster
2014-09-13 15:00 ` [Qemu-devel] [PATCH v2 14/23] hw: Convert from BlockDriverState to BlockBackend, mostly Markus Armbruster
2014-09-13 15:00 ` [Qemu-devel] [PATCH v2 15/23] ide: Complete conversion from BlockDriverState to BlockBackend Markus Armbruster
2014-09-13 15:00 ` [Qemu-devel] [PATCH v2 16/23] pc87312: Drop unused members of PC87312State Markus Armbruster
2014-09-13 15:00 ` [Qemu-devel] [PATCH v2 17/23] blockdev: Drop superfluous DriveInfo member id Markus Armbruster
2014-09-13 15:00 ` [Qemu-devel] [PATCH v2 18/23] blockdev: Fix blockdev-add not to create IDE drive (0, 0) Markus Armbruster
2014-09-13 15:00 ` [Qemu-devel] [PATCH v2 19/23] blockdev: Drop DriveInfo member enable_auto_del Markus Armbruster
2014-09-15  7:30   ` Fam Zheng
2014-09-15  8:40     ` Markus Armbruster
2014-09-13 15:00 ` [Qemu-devel] [PATCH v2 20/23] block/qapi: Convert qmp_query_block() to BlockBackend Markus Armbruster
2014-09-13 15:00 ` [Qemu-devel] [PATCH v2 21/23] blockdev: Convert qmp_eject(), qmp_change_blockdev() " Markus Armbruster
2014-09-13 15:00 ` [Qemu-devel] [PATCH v2 22/23] block: Lift device model API into BlockBackend Markus Armbruster
2014-09-13 15:00 ` [Qemu-devel] [PATCH v2 23/23] block: Make device model's references to BlockBackend strong Markus Armbruster
2014-09-16 12:22 ` [Qemu-devel] [PATCH v2 00/23] Split BlockBackend off BDS with an axe Markus Armbruster

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.