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>
This commit is contained in:
parent
aec81049c2
commit
a6490ec9d5
16
block.c
16
block.c
@ -6959,7 +6959,8 @@ bdrv_has_bds_parent(BlockDriverState *bs, bool only_active)
|
|||||||
return false;
|
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;
|
BdrvChild *child, *parent;
|
||||||
int ret;
|
int ret;
|
||||||
@ -6977,7 +6978,14 @@ static int GRAPH_RDLOCK bdrv_inactivate_recurse(BlockDriverState *bs)
|
|||||||
return 0;
|
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 */
|
/* Inactivate this node */
|
||||||
if (bs->drv->bdrv_inactivate) {
|
if (bs->drv->bdrv_inactivate) {
|
||||||
@ -7014,7 +7022,7 @@ static int GRAPH_RDLOCK bdrv_inactivate_recurse(BlockDriverState *bs)
|
|||||||
|
|
||||||
/* Recursively inactivate children */
|
/* Recursively inactivate children */
|
||||||
QLIST_FOREACH(child, &bs->children, next) {
|
QLIST_FOREACH(child, &bs->children, next) {
|
||||||
ret = bdrv_inactivate_recurse(child->bs);
|
ret = bdrv_inactivate_recurse(child->bs, false);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
@ -7039,7 +7047,7 @@ int bdrv_inactivate_all(void)
|
|||||||
if (bdrv_has_bds_parent(bs, false)) {
|
if (bdrv_has_bds_parent(bs, false)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
ret = bdrv_inactivate_recurse(bs);
|
ret = bdrv_inactivate_recurse(bs, true);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
bdrv_next_cleanup(&it);
|
bdrv_next_cleanup(&it);
|
||||||
break;
|
break;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user