qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Qemu-devel] [PATCH 13/21] blockdev: Add list of monitor-owned BlockBack


From: Max Reitz
Subject: [Qemu-devel] [PATCH 13/21] blockdev: Add list of monitor-owned BlockBackends
Date: Mon, 26 Jan 2015 14:27:40 -0500

The monitor does hold references to some BlockBackends so it should have
a list of those BBs; blk_backends is a different list, as it contains
references to all BBs (after a follow-up patch, that is), and that
should not be changed because we do need such a list.

Signed-off-by: Max Reitz <address@hidden>
---
 block/block-backend.c          | 27 ++++++++++++++++++++++++++-
 blockdev.c                     | 14 ++++++++++++++
 include/sysemu/block-backend.h |  2 ++
 3 files changed, 42 insertions(+), 1 deletion(-)

diff --git a/block/block-backend.c b/block/block-backend.c
index f136fc8..c5ca0f4 100644
--- a/block/block-backend.c
+++ b/block/block-backend.c
@@ -28,6 +28,7 @@ struct BlockBackend {
     BlockDriverState *bs;
     DriveInfo *legacy_dinfo;    /* null unless created by drive_new() */
     QTAILQ_ENTRY(BlockBackend) link; /* for blk_backends */
+    QTAILQ_ENTRY(BlockBackend) monitor_link; /* for monitor_block_backends */
 
     void *dev;                  /* attached device model, if any */
     /* TODO change to DeviceState when all users are qdevified */
@@ -67,6 +68,11 @@ static void drive_info_del(DriveInfo *dinfo);
 static QTAILQ_HEAD(, BlockBackend) blk_backends =
     QTAILQ_HEAD_INITIALIZER(blk_backends);
 
+/* All BlockBackends referenced by the monitor and which are iterated through 
by
+ * blk_next() */
+static QTAILQ_HEAD(, BlockBackend) monitor_block_backends =
+    QTAILQ_HEAD_INITIALIZER(monitor_block_backends);
+
 /*
  * Create a new BlockBackend with @name, with a reference count of one.
  * @name must not be null or empty.
@@ -228,7 +234,8 @@ void blk_unref(BlockBackend *blk, Notifier 
*close_all_notifier)
  */
 BlockBackend *blk_next(BlockBackend *blk)
 {
-    return blk ? QTAILQ_NEXT(blk, link) : QTAILQ_FIRST(&blk_backends);
+    return blk ? QTAILQ_NEXT(blk, monitor_link)
+               : QTAILQ_FIRST(&monitor_block_backends);
 }
 
 /*
@@ -247,6 +254,24 @@ BlockBackend *blk_next_inserted(BlockBackend *blk)
 }
 
 /*
+ * Add a BlockBackend into the list of backends referenced by the monitor.
+ * Strictly for use by blockdev.c.
+ */
+void monitor_add_blk(BlockBackend *blk)
+{
+    QTAILQ_INSERT_TAIL(&monitor_block_backends, blk, monitor_link);
+}
+
+/*
+ * Remove a BlockBackend from the list of backends referenced by the monitor.
+ * Strictly for use by blockdev.c.
+ */
+void monitor_remove_blk(BlockBackend *blk)
+{
+    QTAILQ_REMOVE(&monitor_block_backends, blk, monitor_link);
+}
+
+/*
  * 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().
diff --git a/blockdev.c b/blockdev.c
index 22d7ceb..0f965bd 100644
--- a/blockdev.c
+++ b/blockdev.c
@@ -90,6 +90,8 @@ static int if_max_devs[IF_COUNT] = {
 static void monitor_blk_unref_with_can(BlockBackend *blk,
                                        BlockdevCloseAllNotifier *can)
 {
+    BlockBackend *blk1 = NULL;
+
     if (can) {
         assert(can->blk == blk);
     } else {
@@ -101,6 +103,15 @@ static void monitor_blk_unref_with_can(BlockBackend *blk,
         assert(can);
     }
 
+    /* Thanks to do_drive_del() magic, the BlockBackend is not necessarily
+     * listed at this point */
+    while ((blk1 = blk_next(blk1)) != NULL) {
+        if (blk1 == blk) {
+            monitor_remove_blk(blk);
+            break;
+        }
+    }
+
     blk_unref(blk, &can->n);
     QTAILQ_REMOVE(&close_all_notifiers, can, next);
     g_free(can);
@@ -634,6 +645,8 @@ static BlockBackend *blockdev_init(const char *file, QDict 
*bs_opts,
 
     blk_set_on_error(blk, on_read_error, on_write_error);
 
+    monitor_add_blk(blk);
+
 err_no_bs_opts:
     qemu_opts_del(opts);
     return blk;
@@ -2294,6 +2307,7 @@ int do_drive_del(Monitor *mon, const QDict *qdict, 
QObject **ret_data)
      */
     if (blk_get_attached_dev(blk)) {
         blk_hide_on_behalf_of_do_drive_del(blk);
+        monitor_remove_blk(blk);
         /* Further I/O must not pause the guest */
         blk_set_on_error(blk, BLOCKDEV_ON_ERROR_REPORT,
                          BLOCKDEV_ON_ERROR_REPORT);
diff --git a/include/sysemu/block-backend.h b/include/sysemu/block-backend.h
index 73b26ad..1683732 100644
--- a/include/sysemu/block-backend.h
+++ b/include/sysemu/block-backend.h
@@ -75,6 +75,8 @@ BlockBackend *blk_by_name(const char *name);
 bool blk_name_taken(const char *name);
 BlockBackend *blk_next(BlockBackend *blk);
 BlockBackend *blk_next_inserted(BlockBackend *blk);
+void monitor_add_blk(BlockBackend *blk);
+void monitor_remove_blk(BlockBackend *blk);
 
 BlockDriverState *blk_bs(BlockBackend *blk);
 void blk_remove_bs(BlockBackend *blk);
-- 
2.1.0




reply via email to

[Prev in Thread] Current Thread [Next in Thread]