[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