aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKevin Wolf <kwolf@redhat.com>2025-02-04 22:13:53 +0100
committerKevin Wolf <kwolf@redhat.com>2025-02-06 14:26:51 +0100
commita6490ec9d56b9e95a13918813585a3a9891710bc (patch)
tree01af06965c6ab713aaa9ace8e5c894966bef9089
parentaec81049c2daa8a97b89e59f03733b21ae0f8c2d (diff)
downloadqemu-a6490ec9d56b9e95a13918813585a3a9891710bc.zip
qemu-a6490ec9d56b9e95a13918813585a3a9891710bc.tar.gz
qemu-a6490ec9d56b9e95a13918813585a3a9891710bc.tar.bz2
block: Allow inactivating already inactive nodes
What we wanted to catch with the assertion is cases where the recursion finds that a child was inactive before its parent. This should never happen. But if the user tries to inactivate an image that is already inactive, that's harmless and we don't want to fail the assertion. Signed-off-by: Kevin Wolf <kwolf@redhat.com> Acked-by: Fabiano Rosas <farosas@suse.de> Reviewed-by: Eric Blake <eblake@redhat.com> Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com> Message-ID: <20250204211407.381505-3-kwolf@redhat.com> Signed-off-by: Kevin Wolf <kwolf@redhat.com>
-rw-r--r--block.c16
1 files changed, 12 insertions, 4 deletions
diff --git a/block.c b/block.c
index 9aad958..9458c5e 100644
--- a/block.c
+++ b/block.c
@@ -6959,7 +6959,8 @@ bdrv_has_bds_parent(BlockDriverState *bs, bool only_active)
return false;
}
-static int GRAPH_RDLOCK bdrv_inactivate_recurse(BlockDriverState *bs)
+static int GRAPH_RDLOCK
+bdrv_inactivate_recurse(BlockDriverState *bs, bool top_level)
{
BdrvChild *child, *parent;
int ret;
@@ -6977,7 +6978,14 @@ static int GRAPH_RDLOCK bdrv_inactivate_recurse(BlockDriverState *bs)
return 0;
}
- assert(!(bs->open_flags & BDRV_O_INACTIVE));
+ /*
+ * Inactivating an already inactive node on user request is harmless, but if
+ * a child is already inactive before its parent, that's bad.
+ */
+ if (bs->open_flags & BDRV_O_INACTIVE) {
+ assert(top_level);
+ return 0;
+ }
/* Inactivate this node */
if (bs->drv->bdrv_inactivate) {
@@ -7014,7 +7022,7 @@ static int GRAPH_RDLOCK bdrv_inactivate_recurse(BlockDriverState *bs)
/* Recursively inactivate children */
QLIST_FOREACH(child, &bs->children, next) {
- ret = bdrv_inactivate_recurse(child->bs);
+ ret = bdrv_inactivate_recurse(child->bs, false);
if (ret < 0) {
return ret;
}
@@ -7039,7 +7047,7 @@ int bdrv_inactivate_all(void)
if (bdrv_has_bds_parent(bs, false)) {
continue;
}
- ret = bdrv_inactivate_recurse(bs);
+ ret = bdrv_inactivate_recurse(bs, true);
if (ret < 0) {
bdrv_next_cleanup(&it);
break;