[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-block] [PATCH v2 06/12] block: Deep-clear inherits_from
From: |
Max Reitz |
Subject: |
[Qemu-block] [PATCH v2 06/12] block: Deep-clear inherits_from |
Date: |
Wed, 3 Jul 2019 19:28:07 +0200 |
BDS.inherits_from does not always point to an immediate parent node.
When launching a block job with a filter node, for example, the node
directly below the filter will not point to the filter, but keep its old
pointee (above the filter).
If that pointee goes away while the job is still running, the node's
inherits_from will not be updated and thus point to garbage. To fix
this, bdrv_unref_child() has to check not only the parent node's
immediate children for nodes whose inherits_from needs to be cleared,
but its whole subtree.
Signed-off-by: Max Reitz <address@hidden>
---
block.c | 34 ++++++++++++++++++++++++----------
1 file changed, 24 insertions(+), 10 deletions(-)
diff --git a/block.c b/block.c
index 1fc9e709ad..5f5a06eb7d 100644
--- a/block.c
+++ b/block.c
@@ -2493,18 +2493,20 @@ void bdrv_root_unref_child(BdrvChild *child)
bdrv_unref(child_bs);
}
-void bdrv_unref_child(BlockDriverState *parent, BdrvChild *child)
+/**
+ * Clear all inherits_from pointers from children and grandchildren of
+ * @root that point to @root, where necessary.
+ */
+static void bdrv_unset_inherits_from(BlockDriverState *root, BdrvChild *child)
{
- if (child == NULL) {
- return;
- }
-
- if (child->bs->inherits_from == parent) {
- BdrvChild *c;
+ BdrvChild *c;
- /* Remove inherits_from only when the last reference between parent and
- * child->bs goes away. */
- QLIST_FOREACH(c, &parent->children, next) {
+ if (child->bs->inherits_from == root) {
+ /*
+ * Remove inherits_from only when the last reference between root and
+ * child->bs goes away.
+ */
+ QLIST_FOREACH(c, &root->children, next) {
if (c != child && c->bs == child->bs) {
break;
}
@@ -2514,6 +2516,18 @@ void bdrv_unref_child(BlockDriverState *parent,
BdrvChild *child)
}
}
+ QLIST_FOREACH(c, &child->bs->children, next) {
+ bdrv_unset_inherits_from(root, c);
+ }
+}
+
+void bdrv_unref_child(BlockDriverState *parent, BdrvChild *child)
+{
+ if (child == NULL) {
+ return;
+ }
+
+ bdrv_unset_inherits_from(parent, child);
bdrv_root_unref_child(child);
}
--
2.21.0
- Re: [Qemu-block] [PATCH v2 04/12] block: Keep subtree drained in drop_intermediate, (continued)
- [Qemu-block] [PATCH v2 11/12] iotests: Add read-only test case to 030, Max Reitz, 2019/07/03
- [Qemu-block] [PATCH v2 02/12] block/stream: Fix error path, Max Reitz, 2019/07/03
- [Qemu-block] [PATCH v2 12/12] iotests: Add test for concurrent stream/commit, Max Reitz, 2019/07/03
- [Qemu-block] [PATCH v2 07/12] iotests: Fix throttling in 030, Max Reitz, 2019/07/03
- [Qemu-block] [PATCH v2 05/12] block: Reduce (un)drains when replacing a child, Max Reitz, 2019/07/03
- [Qemu-block] [PATCH v2 09/12] iotests: Add @use_log to VM.run_job(), Max Reitz, 2019/07/03
- [Qemu-block] [PATCH v2 08/12] iotests: Compare error messages in 030, Max Reitz, 2019/07/03
- [Qemu-block] [PATCH v2 03/12] block/stream: Swap backing file change order, Max Reitz, 2019/07/03
- [Qemu-block] [PATCH v2 06/12] block: Deep-clear inherits_from,
Max Reitz <=
[Qemu-block] [PATCH v2 10/12] iotests: Add new case to 030, Max Reitz, 2019/07/03
Re: [Qemu-block] [PATCH v2 00/12] block: Fixes for concurrent block jobs, Max Reitz, 2019/07/10
Re: [Qemu-block] [PATCH v2 00/12] block: Fixes for concurrent block jobs, Max Reitz, 2019/07/15