[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [PULL 05/11] block: Deep-clear inherits_from
From: |
Max Reitz |
Subject: |
[Qemu-devel] [PULL 05/11] block: Deep-clear inherits_from |
Date: |
Mon, 15 Jul 2019 16:28:59 +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>
Message-id: address@hidden
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 6565192b91..29e931e217 100644
--- a/block.c
+++ b/block.c
@@ -2472,18 +2472,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;
}
@@ -2493,6 +2495,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
- [Qemu-devel] [PULL 00/11] Block patches for rc1, Max Reitz, 2019/07/15
- [Qemu-devel] [PULL 01/11] nvme: Set number of queues later in nvme_init(), Max Reitz, 2019/07/15
- [Qemu-devel] [PULL 02/11] block: Add BDS.never_freeze, Max Reitz, 2019/07/15
- [Qemu-devel] [PULL 03/11] block/stream: Fix error path, Max Reitz, 2019/07/15
- [Qemu-devel] [PULL 04/11] block/stream: Swap backing file change order, Max Reitz, 2019/07/15
- [Qemu-devel] [PULL 05/11] block: Deep-clear inherits_from,
Max Reitz <=
- [Qemu-devel] [PULL 06/11] iotests: Fix throttling in 030, Max Reitz, 2019/07/15
- [Qemu-devel] [PULL 07/11] iotests: Compare error messages in 030, Max Reitz, 2019/07/15
- [Qemu-devel] [PULL 08/11] iotests: Add @use_log to VM.run_job(), Max Reitz, 2019/07/15
- [Qemu-devel] [PULL 09/11] iotests: Add new case to 030, Max Reitz, 2019/07/15
- [Qemu-devel] [PULL 10/11] iotests: Add read-only test case to 030, Max Reitz, 2019/07/15
- [Qemu-devel] [PULL 11/11] gluster: fix .bdrv_reopen_prepare when backing file is a JSON object, Max Reitz, 2019/07/15
- Re: [Qemu-devel] [PULL 00/11] Block patches for rc1, Peter Maydell, 2019/07/15