diff mbox

[12/21] block: Use BlockBackend more

Message ID 1422300468-16216-13-git-send-email-mreitz@redhat.com
State New
Headers show

Commit Message

Max Reitz Jan. 26, 2015, 7:27 p.m. UTC
Replace bdrv_drain_all(), bdrv_commmit_all(), bdrv_flush_all(),
bdrv_invalidate_cache_all(), bdrv_next() and occurrences of bdrv_states
by their BlockBackend equivalents.

Signed-off-by: Max Reitz <mreitz@redhat.com>
---
 block.c               | 22 ++++++++---------
 block/block-backend.c |  8 +++----
 block/qapi.c          | 13 ++++++++--
 block/snapshot.c      |  3 ++-
 blockdev.c            | 14 ++++++-----
 cpus.c                |  7 +++---
 migration/block.c     | 10 +++++---
 migration/migration.c |  4 ++--
 monitor.c             | 13 ++++++----
 qemu-char.c           |  3 ++-
 qemu-io.c             |  2 +-
 qmp.c                 | 14 +++++------
 savevm.c              | 66 ++++++++++++++++++++++++++++++---------------------
 xen-mapcache.c        |  3 ++-
 14 files changed, 107 insertions(+), 75 deletions(-)

Comments

Eric Blake Jan. 30, 2015, 1:12 a.m. UTC | #1
On 01/26/2015 12:27 PM, Max Reitz wrote:
> Replace bdrv_drain_all(), bdrv_commmit_all(), bdrv_flush_all(),
> bdrv_invalidate_cache_all(), bdrv_next() and occurrences of bdrv_states
> by their BlockBackend equivalents.
> 
> Signed-off-by: Max Reitz <mreitz@redhat.com>
> ---
>  block.c               | 22 ++++++++---------
>  block/block-backend.c |  8 +++----
>  block/qapi.c          | 13 ++++++++--
>  block/snapshot.c      |  3 ++-
>  blockdev.c            | 14 ++++++-----
>  cpus.c                |  7 +++---
>  migration/block.c     | 10 +++++---
>  migration/migration.c |  4 ++--
>  monitor.c             | 13 ++++++----
>  qemu-char.c           |  3 ++-
>  qemu-io.c             |  2 +-
>  qmp.c                 | 14 +++++------
>  savevm.c              | 66 ++++++++++++++++++++++++++++++---------------------
>  xen-mapcache.c        |  3 ++-
>  14 files changed, 107 insertions(+), 75 deletions(-)
> 

> +++ b/block/qapi.c
> @@ -393,15 +393,24 @@ BlockStatsList *qmp_query_blockstats(bool has_query_nodes,
>  {
>      BlockStatsList *head = NULL, **p_next = &head;
>      BlockDriverState *bs = NULL;
> +    BlockBackend *blk = NULL;
>  
>      /* Just to be safe if query_nodes is not always initialized */
>      query_nodes = has_query_nodes && query_nodes;
>  
> -    while ((bs = query_nodes ? bdrv_next_node(bs) : bdrv_next(bs))) {
> +    while (query_nodes ? (bs = bdrv_next_node(bs)) != NULL
> +                       : (blk = blk_next_inserted(blk)) != NULL)

Don't we still want to list empty BBs in the query (that is,
intentionally list that there are no stats because there is no medium)
rather than silently omitting them?


> @@ -348,6 +349,7 @@ static void unset_dirty_tracking(void)
>  static void init_blk_migration(QEMUFile *f)
>  {
>      BlockDriverState *bs;
> +    BlockBackend *blk = NULL;
>      BlkMigDevState *bmds;
>      int64_t sectors;
>  
> @@ -359,7 +361,9 @@ static void init_blk_migration(QEMUFile *f)
>      block_mig_state.bulk_completed = 0;
>      block_mig_state.zero_blocks = migrate_zero_blocks();
>  
> -    for (bs = bdrv_next(NULL); bs; bs = bdrv_next(bs)) {
> +    while ((blk = blk_next_inserted(blk)) != NULL) {
> +        bs = blk_bs(blk);
> +

What happens if someone initiates a live migration, then inserts the
medium?  It looks like this will skip over the drive that was empty at
the time the migration started.
Max Reitz Feb. 6, 2015, 9:43 p.m. UTC | #2
On 2015-01-29 at 20:12, Eric Blake wrote:
> On 01/26/2015 12:27 PM, Max Reitz wrote:
>> Replace bdrv_drain_all(), bdrv_commmit_all(), bdrv_flush_all(),
>> bdrv_invalidate_cache_all(), bdrv_next() and occurrences of bdrv_states
>> by their BlockBackend equivalents.
>>
>> Signed-off-by: Max Reitz <mreitz@redhat.com>
>> ---
>>   block.c               | 22 ++++++++---------
>>   block/block-backend.c |  8 +++----
>>   block/qapi.c          | 13 ++++++++--
>>   block/snapshot.c      |  3 ++-
>>   blockdev.c            | 14 ++++++-----
>>   cpus.c                |  7 +++---
>>   migration/block.c     | 10 +++++---
>>   migration/migration.c |  4 ++--
>>   monitor.c             | 13 ++++++----
>>   qemu-char.c           |  3 ++-
>>   qemu-io.c             |  2 +-
>>   qmp.c                 | 14 +++++------
>>   savevm.c              | 66 ++++++++++++++++++++++++++++++---------------------
>>   xen-mapcache.c        |  3 ++-
>>   14 files changed, 107 insertions(+), 75 deletions(-)
>>
>> +++ b/block/qapi.c
>> @@ -393,15 +393,24 @@ BlockStatsList *qmp_query_blockstats(bool has_query_nodes,
>>   {
>>       BlockStatsList *head = NULL, **p_next = &head;
>>       BlockDriverState *bs = NULL;
>> +    BlockBackend *blk = NULL;
>>   
>>       /* Just to be safe if query_nodes is not always initialized */
>>       query_nodes = has_query_nodes && query_nodes;
>>   
>> -    while ((bs = query_nodes ? bdrv_next_node(bs) : bdrv_next(bs))) {
>> +    while (query_nodes ? (bs = bdrv_next_node(bs)) != NULL
>> +                       : (blk = blk_next_inserted(blk)) != NULL)
> Don't we still want to list empty BBs in the query (that is,
> intentionally list that there are no stats because there is no medium)
> rather than silently omitting them?

Well, maybe, but this patch does not change that behavior. Actually, the 
behavior is changed in the "BlockBackend and media" series, and I guess 
it's probably the patch "blockdev: Do not create BDS for empty drive". 
As of that series in general, there is no BDS for empty drives any more 
and subsequently there are no blockstats any more.

So if anywhere, I'd need to fix it in that series, probably in the "Move 
BlockAcctStats into BlockBackend" patch.

>> @@ -348,6 +349,7 @@ static void unset_dirty_tracking(void)
>>   static void init_blk_migration(QEMUFile *f)
>>   {
>>       BlockDriverState *bs;
>> +    BlockBackend *blk = NULL;
>>       BlkMigDevState *bmds;
>>       int64_t sectors;
>>   
>> @@ -359,7 +361,9 @@ static void init_blk_migration(QEMUFile *f)
>>       block_mig_state.bulk_completed = 0;
>>       block_mig_state.zero_blocks = migrate_zero_blocks();
>>   
>> -    for (bs = bdrv_next(NULL); bs; bs = bdrv_next(bs)) {
>> +    while ((blk = blk_next_inserted(blk)) != NULL) {
>> +        bs = blk_bs(blk);
>> +
> What happens if someone initiates a live migration, then inserts the
> medium?  It looks like this will skip over the drive that was empty at
> the time the migration started.

Well, to me it looks like its your own fault then. Also, there is no 
difference between using blk_next_inserted() like here and using 
blk_next() + blk_is_inserted(), so you probably can still insert a 
medium during this loop. Maybe. I'm not sure, but I don't think anything 
changed from the old bdrv_next() behavior.

(blk_bext_inserted() iterates over all the BlockBackends and if the one 
you're looking for is not inserted by the time the BB is iterated over, 
it is skipped; if it is inserted, it is not skipped. It doesn't matter 
whether it was inserted at the beginning.)

Max
diff mbox

Patch

diff --git a/block.c b/block.c
index 8eef0c5..ca6a587 100644
--- a/block.c
+++ b/block.c
@@ -1689,7 +1689,7 @@  int bdrv_reopen_multiple(BlockReopenQueue *bs_queue, Error **errp)
 
     assert(bs_queue != NULL);
 
-    bdrv_drain_all();
+    blk_drain_all();
 
     QSIMPLEQ_FOREACH(bs_entry, bs_queue, entry) {
         if (bdrv_reopen_prepare(&bs_entry->state, bs_queue, &local_err)) {
@@ -1859,9 +1859,9 @@  static void bdrv_close(BlockDriverState *bs)
     if (bs->job) {
         block_job_cancel_sync(bs->job);
     }
-    bdrv_drain_all(); /* complete I/O */
+    blk_drain_all(); /* complete I/O */
     bdrv_flush(bs);
-    bdrv_drain_all(); /* in case flush left pending I/O */
+    blk_drain_all(); /* in case flush left pending I/O */
 
     if (bs->drv) {
         if (bs->backing_hd) {
@@ -1909,15 +1909,15 @@  static void bdrv_close(BlockDriverState *bs)
 
 void bdrv_close_all(void)
 {
-    BlockDriverState *bs;
+    BlockBackend *blk = NULL;
 
     notifier_list_notify(&close_all_notifiers, NULL);
 
-    QTAILQ_FOREACH(bs, &bdrv_states, device_list) {
-        AioContext *aio_context = bdrv_get_aio_context(bs);
+    while ((blk = blk_next_inserted(blk)) != NULL) {
+        AioContext *aio_context = blk_get_aio_context(blk);
 
         aio_context_acquire(aio_context);
-        bdrv_close(bs);
+        bdrv_close(blk_bs(blk));
         aio_context_release(aio_context);
     }
 }
@@ -5690,7 +5690,7 @@  void bdrv_attach_aio_context(BlockDriverState *bs,
 
 void bdrv_set_aio_context(BlockDriverState *bs, AioContext *new_context)
 {
-    bdrv_drain_all(); /* ensure there are no in-flight requests */
+    blk_drain_all(); /* ensure there are no in-flight requests */
 
     bdrv_detach_aio_context(bs);
 
@@ -5793,14 +5793,14 @@  bool bdrv_recurse_is_first_non_filter(BlockDriverState *bs,
  */
 bool bdrv_is_first_non_filter(BlockDriverState *candidate)
 {
-    BlockDriverState *bs;
+    BlockBackend *blk = NULL;
 
     /* walk down the bs forest recursively */
-    QTAILQ_FOREACH(bs, &bdrv_states, device_list) {
+    while ((blk = blk_next_inserted(blk)) != NULL) {
         bool perm;
 
         /* try to recurse in this top level bs */
-        perm = bdrv_recurse_is_first_non_filter(bs, candidate);
+        perm = bdrv_recurse_is_first_non_filter(blk_bs(blk), candidate);
 
         /* candidate is the first non filter */
         if (perm) {
diff --git a/block/block-backend.c b/block/block-backend.c
index 27c9b99..f136fc8 100644
--- a/block/block-backend.c
+++ b/block/block-backend.c
@@ -262,10 +262,10 @@  const char *blk_name(BlockBackend *blk)
  */
 BlockBackend *blk_by_name(const char *name)
 {
-    BlockBackend *blk;
+    BlockBackend *blk = NULL;
 
     assert(name);
-    QTAILQ_FOREACH(blk, &blk_backends, link) {
+    while ((blk = blk_next(blk)) != NULL) {
         if (!strcmp(name, blk->name)) {
             return blk;
         }
@@ -323,9 +323,9 @@  DriveInfo *blk_set_legacy_dinfo(BlockBackend *blk, DriveInfo *dinfo)
  */
 BlockBackend *blk_by_legacy_dinfo(DriveInfo *dinfo)
 {
-    BlockBackend *blk;
+    BlockBackend *blk = NULL;
 
-    QTAILQ_FOREACH(blk, &blk_backends, link) {
+    while ((blk = blk_next(blk)) != NULL) {
         if (blk->legacy_dinfo == dinfo) {
             return blk;
         }
diff --git a/block/qapi.c b/block/qapi.c
index db42a6e..79ca32a 100644
--- a/block/qapi.c
+++ b/block/qapi.c
@@ -393,15 +393,24 @@  BlockStatsList *qmp_query_blockstats(bool has_query_nodes,
 {
     BlockStatsList *head = NULL, **p_next = &head;
     BlockDriverState *bs = NULL;
+    BlockBackend *blk = NULL;
 
     /* Just to be safe if query_nodes is not always initialized */
     query_nodes = has_query_nodes && query_nodes;
 
-    while ((bs = query_nodes ? bdrv_next_node(bs) : bdrv_next(bs))) {
+    while (query_nodes ? (bs = bdrv_next_node(bs)) != NULL
+                       : (blk = blk_next_inserted(blk)) != NULL)
+    {
         BlockStatsList *info = g_malloc0(sizeof(*info));
-        AioContext *ctx = bdrv_get_aio_context(bs);
+        AioContext *ctx = blk ? blk_get_aio_context(blk)
+                              : bdrv_get_aio_context(bs);
 
         aio_context_acquire(ctx);
+
+        if (blk) {
+            bs = blk_bs(blk);
+        }
+
         info->value = bdrv_query_stats(bs, !query_nodes);
         aio_context_release(ctx);
 
diff --git a/block/snapshot.c b/block/snapshot.c
index 698e1a1..e92e2d4 100644
--- a/block/snapshot.c
+++ b/block/snapshot.c
@@ -24,6 +24,7 @@ 
 
 #include "block/snapshot.h"
 #include "block/block_int.h"
+#include "sysemu/block-backend.h"
 
 QemuOptsList internal_snapshot_opts = {
     .name = "snapshot",
@@ -238,7 +239,7 @@  int bdrv_snapshot_delete(BlockDriverState *bs,
     }
 
     /* drain all pending i/o before deleting snapshot */
-    bdrv_drain_all();
+    blk_drain_all();
 
     if (drv->bdrv_snapshot_delete) {
         return drv->bdrv_snapshot_delete(bs, snapshot_id, name, errp);
diff --git a/blockdev.c b/blockdev.c
index ccf5469..22d7ceb 100644
--- a/blockdev.c
+++ b/blockdev.c
@@ -1156,7 +1156,7 @@  void do_commit(Monitor *mon, const QDict *qdict)
     int ret;
 
     if (!strcmp(device, "all")) {
-        ret = bdrv_commit_all();
+        ret = blk_commit_all();
     } else {
         bs = bdrv_find(device);
         if (!bs) {
@@ -1830,7 +1830,7 @@  void qmp_transaction(TransactionActionList *dev_list, Error **errp)
     QSIMPLEQ_INIT(&snap_bdrv_states);
 
     /* drain all i/o before any operations */
-    bdrv_drain_all();
+    blk_drain_all();
 
     /* We don't do anything in this loop that commits us to the operations */
     while (NULL != dev_entry) {
@@ -2341,7 +2341,7 @@  void qmp_block_resize(bool has_device, const char *device,
     }
 
     /* complete all in-flight operations before resizing the device */
-    bdrv_drain_all();
+    blk_drain_all();
 
     ret = bdrv_truncate(bs, size);
     switch (ret) {
@@ -2508,7 +2508,7 @@  void qmp_block_commit(const char *device,
     bs = blk_bs(blk);
 
     /* drain all i/o before commits */
-    bdrv_drain_all();
+    blk_drain_all();
 
     if (bdrv_op_is_blocked(bs, BLOCK_OP_TYPE_COMMIT_SOURCE, errp)) {
         goto out;
@@ -3238,12 +3238,14 @@  BlockJobInfoList *qmp_query_block_jobs(Error **errp)
 {
     BlockJobInfoList *head = NULL, **p_next = &head;
     BlockDriverState *bs;
+    BlockBackend *blk = NULL;
 
-    for (bs = bdrv_next(NULL); bs; bs = bdrv_next(bs)) {
-        AioContext *aio_context = bdrv_get_aio_context(bs);
+    while ((blk = blk_next_inserted(blk)) != NULL) {
+        AioContext *aio_context = blk_get_aio_context(blk);
 
         aio_context_acquire(aio_context);
 
+        bs = blk_bs(blk);
         if (bs->job) {
             BlockJobInfoList *elem = g_new0(BlockJobInfoList, 1);
             elem->value = block_job_query(bs->job);
diff --git a/cpus.c b/cpus.c
index 3a5323b..ccfd299 100644
--- a/cpus.c
+++ b/cpus.c
@@ -28,6 +28,7 @@ 
 #include "monitor/monitor.h"
 #include "qapi/qmp/qerror.h"
 #include "sysemu/sysemu.h"
+#include "sysemu/block-backend.h"
 #include "exec/gdbstub.h"
 #include "sysemu/dma.h"
 #include "sysemu/kvm.h"
@@ -620,8 +621,8 @@  static int do_vm_stop(RunState state)
         qapi_event_send_stop(&error_abort);
     }
 
-    bdrv_drain_all();
-    ret = bdrv_flush_all();
+    blk_drain_all();
+    ret = blk_flush_all();
 
     return ret;
 }
@@ -1319,7 +1320,7 @@  int vm_stop_force_state(RunState state)
         runstate_set(state);
         /* Make sure to return an error if the flush in a previous vm_stop()
          * failed. */
-        return bdrv_flush_all();
+        return blk_flush_all();
     }
 }
 
diff --git a/migration/block.c b/migration/block.c
index 0c76106..ec435db 100644
--- a/migration/block.c
+++ b/migration/block.c
@@ -23,6 +23,7 @@ 
 #include "migration/block.h"
 #include "migration/migration.h"
 #include "sysemu/blockdev.h"
+#include "sysemu/block-backend.h"
 #include <assert.h>
 
 #define BLOCK_SIZE                       (1 << 20)
@@ -348,6 +349,7 @@  static void unset_dirty_tracking(void)
 static void init_blk_migration(QEMUFile *f)
 {
     BlockDriverState *bs;
+    BlockBackend *blk = NULL;
     BlkMigDevState *bmds;
     int64_t sectors;
 
@@ -359,7 +361,9 @@  static void init_blk_migration(QEMUFile *f)
     block_mig_state.bulk_completed = 0;
     block_mig_state.zero_blocks = migrate_zero_blocks();
 
-    for (bs = bdrv_next(NULL); bs; bs = bdrv_next(bs)) {
+    while ((blk = blk_next_inserted(blk)) != NULL) {
+        bs = blk_bs(blk);
+
         if (bdrv_is_read_only(bs)) {
             continue;
         }
@@ -456,7 +460,7 @@  static int mig_save_device_dirty(QEMUFile *f, BlkMigDevState *bmds,
         blk_mig_lock();
         if (bmds_aio_inflight(bmds, sector)) {
             blk_mig_unlock();
-            bdrv_drain_all();
+            blk_drain_all();
         } else {
             blk_mig_unlock();
         }
@@ -596,7 +600,7 @@  static void blk_mig_cleanup(void)
     BlkMigDevState *bmds;
     BlkMigBlock *blk;
 
-    bdrv_drain_all();
+    blk_drain_all();
 
     unset_dirty_tracking();
 
diff --git a/migration/migration.c b/migration/migration.c
index b3adbc6..f08cd6d 100644
--- a/migration/migration.c
+++ b/migration/migration.c
@@ -19,7 +19,7 @@ 
 #include "monitor/monitor.h"
 #include "migration/qemu-file.h"
 #include "sysemu/sysemu.h"
-#include "block/block.h"
+#include "sysemu/block-backend.h"
 #include "qemu/sockets.h"
 #include "migration/block.h"
 #include "qemu/thread.h"
@@ -104,7 +104,7 @@  static void process_incoming_migration_co(void *opaque)
     qemu_announce_self();
 
     /* Make sure all file formats flush their mutable metadata */
-    bdrv_invalidate_cache_all(&local_err);
+    blk_invalidate_cache_all(&local_err);
     if (local_err) {
         qerror_report_err(local_err);
         error_free(local_err);
diff --git a/monitor.c b/monitor.c
index 7e4f605..25ea682 100644
--- a/monitor.c
+++ b/monitor.c
@@ -40,6 +40,7 @@ 
 #include "ui/console.h"
 #include "ui/input.h"
 #include "sysemu/blockdev.h"
+#include "sysemu/block-backend.h"
 #include "audio/audio.h"
 #include "disas/disas.h"
 #include "sysemu/balloon.h"
@@ -4611,13 +4612,15 @@  void host_net_remove_completion(ReadLineState *rs, int nb_args, const char *str)
 static void vm_completion(ReadLineState *rs, const char *str)
 {
     size_t len;
-    BlockDriverState *bs = NULL;
+    BlockDriverState *bs;
+    BlockBackend *blk = NULL;
 
     len = strlen(str);
     readline_set_completion_index(rs, len);
-    while ((bs = bdrv_next(bs))) {
+    while ((blk = blk_next_inserted(blk)) != NULL) {
         SnapshotInfoList *snapshots, *snapshot;
 
+        bs = blk_bs(blk);
         if (!bdrv_can_snapshot(bs)) {
             continue;
         }
@@ -4664,7 +4667,7 @@  static void monitor_find_completion_by_table(Monitor *mon,
     int i;
     const char *ptype, *str, *name;
     const mon_cmd_t *cmd;
-    BlockDriverState *bs;
+    BlockBackend *blk = NULL;
 
     if (nb_args <= 1) {
         /* command completion */
@@ -4717,8 +4720,8 @@  static void monitor_find_completion_by_table(Monitor *mon,
         case 'B':
             /* block device name completion */
             readline_set_completion_index(mon->rs, strlen(str));
-            for (bs = bdrv_next(NULL); bs; bs = bdrv_next(bs)) {
-                name = bdrv_get_device_name(bs);
+            while ((blk = blk_next(blk)) != NULL) {
+                name = blk_name(blk);
                 if (str[0] == '\0' ||
                     !strncmp(name, str, strlen(str))) {
                     readline_add_completion(mon->rs, name);
diff --git a/qemu-char.c b/qemu-char.c
index 98d4342..4d3fb60 100644
--- a/qemu-char.c
+++ b/qemu-char.c
@@ -24,6 +24,7 @@ 
 #include "qemu-common.h"
 #include "monitor/monitor.h"
 #include "sysemu/sysemu.h"
+#include "sysemu/block-backend.h"
 #include "qemu/timer.h"
 #include "sysemu/char.h"
 #include "hw/usb.h"
@@ -523,7 +524,7 @@  static int mux_proc_byte(CharDriverState *chr, MuxDriver *d, int ch)
                  break;
             }
         case 's':
-            bdrv_commit_all();
+            blk_commit_all();
             break;
         case 'b':
             qemu_chr_be_event(chr, CHR_EVENT_BREAK);
diff --git a/qemu-io.c b/qemu-io.c
index ffbe0f1..6970dfc 100644
--- a/qemu-io.c
+++ b/qemu-io.c
@@ -474,7 +474,7 @@  int main(int argc, char **argv)
     /*
      * Make sure all outstanding requests complete before the program exits.
      */
-    bdrv_drain_all();
+    blk_drain_all();
 
     blk_unref(qemuio_blk, NULL);
     g_free(readline_state);
diff --git a/qmp.c b/qmp.c
index d414118..9402555 100644
--- a/qmp.c
+++ b/qmp.c
@@ -151,8 +151,7 @@  SpiceInfo *qmp_query_spice(Error **errp)
 
 void qmp_cont(Error **errp)
 {
-    BlockBackend *blk;
-    BlockDriverState *bs;
+    BlockBackend *blk = NULL;
 
     if (runstate_needs_reset()) {
         error_setg(errp, "Resetting the Virtual Machine is required");
@@ -161,14 +160,13 @@  void qmp_cont(Error **errp)
         return;
     }
 
-    for (blk = blk_next(NULL); blk; blk = blk_next(blk)) {
+    while ((blk = blk_next(blk)) != NULL) {
         blk_iostatus_reset(blk);
     }
-    for (bs = bdrv_next(NULL); bs; bs = bdrv_next(bs)) {
-        if (bdrv_key_required(bs)) {
-            error_set(errp, QERR_DEVICE_ENCRYPTED,
-                      bdrv_get_device_name(bs),
-                      bdrv_get_encrypted_filename(bs));
+    while ((blk = blk_next_inserted(blk)) != NULL) {
+        if (bdrv_key_required(blk_bs(blk))) {
+            error_set(errp, QERR_DEVICE_ENCRYPTED, blk_name(blk),
+                      bdrv_get_encrypted_filename(blk_bs(blk)));
             return;
         }
     }
diff --git a/savevm.c b/savevm.c
index 08ec678..ec4c2df 100644
--- a/savevm.c
+++ b/savevm.c
@@ -30,6 +30,7 @@ 
 #include "net/net.h"
 #include "monitor/monitor.h"
 #include "sysemu/sysemu.h"
+#include "sysemu/block-backend.h"
 #include "qemu/timer.h"
 #include "audio/audio.h"
 #include "migration/migration.h"
@@ -1001,10 +1002,10 @@  out:
 
 static BlockDriverState *find_vmstate_bs(void)
 {
-    BlockDriverState *bs = NULL;
-    while ((bs = bdrv_next(bs))) {
-        if (bdrv_can_snapshot(bs)) {
-            return bs;
+    BlockBackend *blk = NULL;
+    while ((blk = blk_next_inserted(blk)) != NULL) {
+        if (bdrv_can_snapshot(blk_bs(blk))) {
+            return blk_bs(blk);
         }
     }
     return NULL;
@@ -1016,11 +1017,13 @@  static BlockDriverState *find_vmstate_bs(void)
 static int del_existing_snapshots(Monitor *mon, const char *name)
 {
     BlockDriverState *bs;
+    BlockBackend *blk = NULL;
     QEMUSnapshotInfo sn1, *snapshot = &sn1;
     Error *err = NULL;
 
-    bs = NULL;
-    while ((bs = bdrv_next(bs))) {
+    while ((blk = blk_next_inserted(blk)) != NULL) {
+        bs = blk_bs(blk);
+
         if (bdrv_can_snapshot(bs) &&
             bdrv_snapshot_find(bs, snapshot, name) >= 0) {
             bdrv_snapshot_delete_by_id_or_name(bs, name, &err);
@@ -1042,6 +1045,7 @@  static int del_existing_snapshots(Monitor *mon, const char *name)
 void do_savevm(Monitor *mon, const QDict *qdict)
 {
     BlockDriverState *bs, *bs1;
+    BlockBackend *blk = NULL;
     QEMUSnapshotInfo sn1, *sn = &sn1, old_sn1, *old_sn = &old_sn1;
     int ret;
     QEMUFile *f;
@@ -1052,16 +1056,14 @@  void do_savevm(Monitor *mon, const QDict *qdict)
     const char *name = qdict_get_try_str(qdict, "name");
 
     /* Verify if there is a device that doesn't support snapshots and is writable */
-    bs = NULL;
-    while ((bs = bdrv_next(bs))) {
-
-        if (!bdrv_is_inserted(bs) || bdrv_is_read_only(bs)) {
+    while ((blk = blk_next_inserted(blk)) != NULL) {
+        if (blk_is_read_only(blk)) {
             continue;
         }
 
-        if (!bdrv_can_snapshot(bs)) {
+        if (!bdrv_can_snapshot(blk_bs(blk))) {
             monitor_printf(mon, "Device '%s' is writable but does not support snapshots.\n",
-                               bdrv_get_device_name(bs));
+                           blk_name(blk));
             return;
         }
     }
@@ -1118,15 +1120,17 @@  void do_savevm(Monitor *mon, const QDict *qdict)
 
     /* create the snapshots */
 
-    bs1 = NULL;
-    while ((bs1 = bdrv_next(bs1))) {
+    blk = NULL;
+    while ((blk = blk_next_inserted(blk)) != NULL) {
+        bs1 = blk_bs(blk);
+
         if (bdrv_can_snapshot(bs1)) {
             /* Write VM state size only to the image that contains the state */
             sn->vm_state_size = (bs == bs1 ? vm_state_size : 0);
             ret = bdrv_snapshot_create(bs1, sn);
             if (ret < 0) {
                 monitor_printf(mon, "Error while creating snapshot on '%s'\n",
-                               bdrv_get_device_name(bs1));
+                               blk_name(blk));
             }
         }
     }
@@ -1165,6 +1169,7 @@  void qmp_xen_save_devices_state(const char *filename, Error **errp)
 
 int load_vmstate(const char *name)
 {
+    BlockBackend *blk;
     BlockDriverState *bs, *bs_vm_state;
     QEMUSnapshotInfo sn;
     QEMUFile *f;
@@ -1188,12 +1193,12 @@  int load_vmstate(const char *name)
 
     /* Verify if there is any device that doesn't support snapshots and is
     writable and check if the requested snapshot is available too. */
-    bs = NULL;
-    while ((bs = bdrv_next(bs))) {
-
-        if (!bdrv_is_inserted(bs) || bdrv_is_read_only(bs)) {
+    blk = NULL;
+    while ((blk = blk_next_inserted(blk)) != NULL) {
+        if (blk_is_read_only(blk)) {
             continue;
         }
+        bs = blk_bs(blk);
 
         if (!bdrv_can_snapshot(bs)) {
             error_report("Device '%s' is writable but does not support snapshots.",
@@ -1210,10 +1215,12 @@  int load_vmstate(const char *name)
     }
 
     /* Flush all IO requests so they don't interfere with the new state.  */
-    bdrv_drain_all();
+    blk_drain_all();
+
+    blk = NULL;
+    while ((blk = blk_next_inserted(blk)) != NULL) {
+        bs = blk_bs(blk);
 
-    bs = NULL;
-    while ((bs = bdrv_next(bs))) {
         if (bdrv_can_snapshot(bs)) {
             ret = bdrv_snapshot_goto(bs, name);
             if (ret < 0) {
@@ -1246,6 +1253,7 @@  int load_vmstate(const char *name)
 void do_delvm(Monitor *mon, const QDict *qdict)
 {
     BlockDriverState *bs;
+    BlockBackend *blk = NULL;
     Error *err;
     const char *name = qdict_get_str(qdict, "name");
 
@@ -1254,8 +1262,9 @@  void do_delvm(Monitor *mon, const QDict *qdict)
         return;
     }
 
-    bs = NULL;
-    while ((bs = bdrv_next(bs))) {
+    while ((blk = blk_next_inserted(blk)) != NULL) {
+        bs = blk_bs(blk);
+
         if (bdrv_can_snapshot(bs)) {
             err = NULL;
             bdrv_snapshot_delete_by_id_or_name(bs, name, &err);
@@ -1263,7 +1272,7 @@  void do_delvm(Monitor *mon, const QDict *qdict)
                 monitor_printf(mon,
                                "Error while deleting snapshot on device '%s':"
                                " %s\n",
-                               bdrv_get_device_name(bs),
+                               blk_name(blk),
                                error_get_pretty(err));
                 error_free(err);
             }
@@ -1274,6 +1283,7 @@  void do_delvm(Monitor *mon, const QDict *qdict)
 void do_info_snapshots(Monitor *mon, const QDict *qdict)
 {
     BlockDriverState *bs, *bs1;
+    BlockBackend *blk;
     QEMUSnapshotInfo *sn_tab, *sn, s, *sn_info = &s;
     int nb_sns, i, ret, available;
     int total;
@@ -1301,9 +1311,11 @@  void do_info_snapshots(Monitor *mon, const QDict *qdict)
     for (i = 0; i < nb_sns; i++) {
         sn = &sn_tab[i];
         available = 1;
-        bs1 = NULL;
+        blk = NULL;
+
+        while ((blk = blk_next_inserted(blk)) != NULL) {
+            bs1 = blk_bs(blk);
 
-        while ((bs1 = bdrv_next(bs1))) {
             if (bdrv_can_snapshot(bs1) && bs1 != bs) {
                 ret = bdrv_snapshot_find(bs1, sn_info, sn->id_str);
                 if (ret < 0) {
diff --git a/xen-mapcache.c b/xen-mapcache.c
index 8cefd0c..1a98a69 100644
--- a/xen-mapcache.c
+++ b/xen-mapcache.c
@@ -14,6 +14,7 @@ 
 
 #include "hw/xen/xen_backend.h"
 #include "sysemu/blockdev.h"
+#include "sysemu/block-backend.h"
 #include "qemu/bitmap.h"
 
 #include <xen/hvm/params.h>
@@ -421,7 +422,7 @@  void xen_invalidate_map_cache(void)
     MapCacheRev *reventry;
 
     /* Flush pending AIO before destroying the mapcache */
-    bdrv_drain_all();
+    blk_drain_all();
 
     mapcache_lock();