qemu-devel
[Top][All Lists]
Advanced

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

[Qemu-devel] [PATCH 08/34] block: Add list of children to BlockDriverSta


From: Kevin Wolf
Subject: [Qemu-devel] [PATCH 08/34] block: Add list of children to BlockDriverState
Date: Fri, 8 May 2015 19:21:40 +0200

This allows iterating over all children of a given BDS, not only
including bs->file and bs->backing_hd, but also driver-specific
ones like VMDK extents or Quorum children.

Signed-off-by: Kevin Wolf <address@hidden>
---
 block.c                   | 27 +++++++++++++++++++++++++++
 include/block/block_int.h |  8 ++++++++
 2 files changed, 35 insertions(+)

diff --git a/block.c b/block.c
index c4f0fb4..59f54ed 100644
--- a/block.c
+++ b/block.c
@@ -1301,6 +1301,19 @@ out:
     return ret;
 }
 
+static void bdrv_attach_child(BlockDriverState *parent_bs,
+                              BlockDriverState *child_bs,
+                              const BdrvChildRole *child_role)
+{
+    BdrvChild *child = g_new(BdrvChild, 1);
+    *child = (BdrvChild) {
+        .bs     = child_bs,
+        .role   = child_role,
+    };
+
+    QLIST_INSERT_HEAD(&parent_bs->children, child, next);
+}
+
 /*
  * Opens a disk image (raw, qcow2, vmdk, ...)
  *
@@ -1353,6 +1366,9 @@ static int bdrv_open_inherit(BlockDriverState **pbs, 
const char *filename,
             return -ENODEV;
         }
         bdrv_ref(bs);
+        if (child_role) {
+            bdrv_attach_child(parent, bs, child_role);
+        }
         *pbs = bs;
         return 0;
     }
@@ -1495,6 +1511,10 @@ static int bdrv_open_inherit(BlockDriverState **pbs, 
const char *filename,
         goto close_and_fail;
     }
 
+    if (child_role) {
+        bdrv_attach_child(parent, bs, child_role);
+    }
+
     QDECREF(options);
     *pbs = bs;
     return 0;
@@ -1789,6 +1809,12 @@ void bdrv_close(BlockDriverState *bs)
     notifier_list_notify(&bs->close_notifiers, bs);
 
     if (bs->drv) {
+        BdrvChild *child, *next;
+
+        QLIST_FOREACH_SAFE(child, &bs->children, next, next) {
+            g_free(child);
+        }
+
         if (bs->backing_hd) {
             BlockDriverState *backing_hd = bs->backing_hd;
             bdrv_set_backing_hd(bs, NULL);
@@ -1999,6 +2025,7 @@ void bdrv_append(BlockDriverState *bs_new, 
BlockDriverState *bs_top)
     /* The contents of 'tmp' will become bs_top, as we are
      * swapping bs_new and bs_top contents. */
     bdrv_set_backing_hd(bs_top, bs_new);
+    bdrv_attach_child(bs_top, bs_new, &child_backing);
 }
 
 static void bdrv_delete(BlockDriverState *bs)
diff --git a/include/block/block_int.h b/include/block/block_int.h
index eb01ea2..12c7fb3 100644
--- a/include/block/block_int.h
+++ b/include/block/block_int.h
@@ -334,6 +334,12 @@ struct BdrvChildRole {
 extern const BdrvChildRole child_file;
 extern const BdrvChildRole child_format;
 
+typedef struct BdrvChild {
+    BlockDriverState *bs;
+    const BdrvChildRole *role;
+    QLIST_ENTRY(BdrvChild) next;
+} BdrvChild;
+
 /*
  * Note: the function bdrv_append() copies and swaps contents of
  * BlockDriverStates, so if you add new fields to this struct, please
@@ -428,6 +434,8 @@ struct BlockDriverState {
     /* long-running background operation */
     BlockJob *job;
 
+    QLIST_HEAD(, BdrvChild) children;
+
     QDict *options;
     BlockdevDetectZeroesOptions detect_zeroes;
 
-- 
1.8.3.1




reply via email to

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