Skip to content

Commit

Permalink
block: Inactivate parents before children
Browse files Browse the repository at this point in the history
The proper order for inactivating block nodes is that first the parents
get inactivated and then the children. If we do things in this order, we
can assert that we didn't accidentally leave a parent activated when one
of its child nodes is inactive.

Signed-off-by: Kevin Wolf <[email protected]>
Reviewed-by: Eric Blake <[email protected]>
  • Loading branch information
kevmw committed May 11, 2017
1 parent cfa1a57 commit 38701b6
Showing 1 changed file with 18 additions and 7 deletions.
25 changes: 18 additions & 7 deletions block.c
Original file line number Diff line number Diff line change
Expand Up @@ -762,6 +762,13 @@ static void bdrv_child_cb_drained_end(BdrvChild *child)
bdrv_drained_end(bs);
}

static int bdrv_child_cb_inactivate(BdrvChild *child)
{
BlockDriverState *bs = child->opaque;
assert(bs->open_flags & BDRV_O_INACTIVE);
return 0;
}

/*
* Returns the options and flags that a temporary snapshot should get, based on
* the originally requested flags (the originally requested image will have
Expand Down Expand Up @@ -822,6 +829,7 @@ const BdrvChildRole child_file = {
.inherit_options = bdrv_inherited_options,
.drained_begin = bdrv_child_cb_drained_begin,
.drained_end = bdrv_child_cb_drained_end,
.inactivate = bdrv_child_cb_inactivate,
};

/*
Expand All @@ -843,6 +851,7 @@ const BdrvChildRole child_format = {
.inherit_options = bdrv_inherited_fmt_options,
.drained_begin = bdrv_child_cb_drained_begin,
.drained_end = bdrv_child_cb_drained_end,
.inactivate = bdrv_child_cb_inactivate,
};

static void bdrv_backing_attach(BdrvChild *c)
Expand Down Expand Up @@ -928,6 +937,7 @@ const BdrvChildRole child_backing = {
.inherit_options = bdrv_backing_options,
.drained_begin = bdrv_child_cb_drained_begin,
.drained_end = bdrv_child_cb_drained_end,
.inactivate = bdrv_child_cb_inactivate,
};

static int bdrv_open_flags(BlockDriverState *bs, int flags)
Expand Down Expand Up @@ -4029,13 +4039,6 @@ static int bdrv_inactivate_recurse(BlockDriverState *bs,
}
}

QLIST_FOREACH(child, &bs->children, next) {
ret = bdrv_inactivate_recurse(child->bs, setting_flag);
if (ret < 0) {
return ret;
}
}

if (setting_flag) {
bs->open_flags |= BDRV_O_INACTIVE;

Expand All @@ -4049,6 +4052,14 @@ static int bdrv_inactivate_recurse(BlockDriverState *bs,
}
}
}

QLIST_FOREACH(child, &bs->children, next) {
ret = bdrv_inactivate_recurse(child->bs, setting_flag);
if (ret < 0) {
return ret;
}
}

return 0;
}

Expand Down

0 comments on commit 38701b6

Please sign in to comment.