qemu-devel
[Top][All Lists]
Advanced

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

[PATCH 1/3] block: add BdrvChildClass->pre_detach() and ->post_attach()


From: Stefan Hajnoczi
Subject: [PATCH 1/3] block: add BdrvChildClass->pre_detach() and ->post_attach()
Date: Wed, 4 Jan 2023 17:06:29 -0500

Add callbacks for graph changes and propagate them to the root via
child_of_bds. The purpose is to respond to graph changes.

This commit doesn't do anything on its own since the callbacks aren't
used by BlockBackend's child_root yet. That will be done in the next
commit.

Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
---
 include/block/block_int-common.h |  8 ++++++++
 block.c                          | 34 ++++++++++++++++++++++++++++++++
 2 files changed, 42 insertions(+)

diff --git a/include/block/block_int-common.h b/include/block/block_int-common.h
index c34c525fa6..6cefde5d23 100644
--- a/include/block/block_int-common.h
+++ b/include/block/block_int-common.h
@@ -899,6 +899,14 @@ struct BdrvChildClass {
     void GRAPH_WRLOCK_PTR (*attach)(BdrvChild *child);
     void GRAPH_WRLOCK_PTR (*detach)(BdrvChild *child);
 
+    /*
+     * Notifies the parent that an immediate child or deeper descendant is
+     * about to be detached or has been attached. Use this to monitor graph
+     * changes. to_detach->bs and attached->bs can be NULL.
+     */
+    void (*pre_detach)(BdrvChild *child, BdrvChild *to_detach);
+    void (*post_attach)(BdrvChild *child, BdrvChild *attached);
+
     /*
      * Notifies the parent that the filename of its child has changed (e.g.
      * because the direct child was removed from the backing chain), so that it
diff --git a/block.c b/block.c
index 9c2ac757e4..e472a4b105 100644
--- a/block.c
+++ b/block.c
@@ -1402,6 +1402,30 @@ static void bdrv_inherited_options(BdrvChildRole role, 
bool parent_is_format,
     *child_flags = flags;
 }
 
+static void bdrv_child_cb_pre_detach(BdrvChild *child, BdrvChild *to_detach)
+{
+    BlockDriverState *parent_bs = child->opaque;
+    BdrvChild *grandparent;
+
+    QLIST_FOREACH(grandparent, &parent_bs->parents, next_parent) {
+        if (grandparent->klass->pre_detach) {
+            grandparent->klass->pre_detach(grandparent, to_detach);
+        }
+    }
+}
+
+static void bdrv_child_cb_post_attach(BdrvChild *child, BdrvChild *attached)
+{
+    BlockDriverState *parent_bs = child->opaque;
+    BdrvChild *grandparent;
+
+    QLIST_FOREACH(grandparent, &parent_bs->parents, next_parent) {
+        if (grandparent->klass->post_attach) {
+            grandparent->klass->post_attach(grandparent, attached);
+        }
+    }
+}
+
 static void GRAPH_WRLOCK bdrv_child_cb_attach(BdrvChild *child)
 {
     BlockDriverState *bs = child->opaque;
@@ -1488,6 +1512,8 @@ const BdrvChildClass child_of_bds = {
     .drained_end     = bdrv_child_cb_drained_end,
     .attach          = bdrv_child_cb_attach,
     .detach          = bdrv_child_cb_detach,
+    .pre_detach      = bdrv_child_cb_pre_detach,
+    .post_attach     = bdrv_child_cb_post_attach,
     .inactivate      = bdrv_child_cb_inactivate,
     .change_aio_ctx  = bdrv_child_cb_change_aio_ctx,
     .update_filename = bdrv_child_cb_update_filename,
@@ -2873,6 +2899,10 @@ static void bdrv_replace_child_noperm(BdrvChild *child,
         assert(bdrv_get_aio_context(old_bs) == bdrv_get_aio_context(new_bs));
     }
 
+    if (child->klass->pre_detach) {
+        child->klass->pre_detach(child, child);
+    }
+
     /* TODO Pull this up into the callers to avoid polling here */
     bdrv_graph_wrlock();
     if (old_bs) {
@@ -2892,6 +2922,10 @@ static void bdrv_replace_child_noperm(BdrvChild *child,
     }
     bdrv_graph_wrunlock();
 
+    if (child->klass->post_attach) {
+        child->klass->post_attach(child, child);
+    }
+
     /*
      * If the parent was drained through this BdrvChild previously, but new_bs
      * is not drained, allow requests to come in only after the new node has
-- 
2.39.0




reply via email to

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