block: Propagate .drained_begin/end callbacks
When draining intermediate nodes (i.e. nodes that aren't the root node for at least one of their parents; with node references, the user can always configure the graph to create this situation), we need to propagate the .drained_begin/end callbacks all the way up to the root for the drain to be effective. Signed-off-by: Kevin Wolf <kwolf@redhat.com> Reviewed-by: Eric Blake <eblake@redhat.com> Reviewed-by: Fam Zheng <famz@redhat.com>
This commit is contained in:
parent
36fe13317b
commit
20018e12cf
20
block.c
20
block.c
@ -659,6 +659,18 @@ int bdrv_parse_cache_mode(const char *mode, int *flags, bool *writethrough)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void bdrv_child_cb_drained_begin(BdrvChild *child)
|
||||||
|
{
|
||||||
|
BlockDriverState *bs = child->opaque;
|
||||||
|
bdrv_drained_begin(bs);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void bdrv_child_cb_drained_end(BdrvChild *child)
|
||||||
|
{
|
||||||
|
BlockDriverState *bs = child->opaque;
|
||||||
|
bdrv_drained_end(bs);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Returns the options and flags that a temporary snapshot should get, based on
|
* Returns the options and flags that a temporary snapshot should get, based on
|
||||||
* the originally requested flags (the originally requested image will have
|
* the originally requested flags (the originally requested image will have
|
||||||
@ -705,6 +717,8 @@ static void bdrv_inherited_options(int *child_flags, QDict *child_options,
|
|||||||
|
|
||||||
const BdrvChildRole child_file = {
|
const BdrvChildRole child_file = {
|
||||||
.inherit_options = bdrv_inherited_options,
|
.inherit_options = bdrv_inherited_options,
|
||||||
|
.drained_begin = bdrv_child_cb_drained_begin,
|
||||||
|
.drained_end = bdrv_child_cb_drained_end,
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -723,6 +737,8 @@ static void bdrv_inherited_fmt_options(int *child_flags, QDict *child_options,
|
|||||||
|
|
||||||
const BdrvChildRole child_format = {
|
const BdrvChildRole child_format = {
|
||||||
.inherit_options = bdrv_inherited_fmt_options,
|
.inherit_options = bdrv_inherited_fmt_options,
|
||||||
|
.drained_begin = bdrv_child_cb_drained_begin,
|
||||||
|
.drained_end = bdrv_child_cb_drained_end,
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -750,6 +766,8 @@ static void bdrv_backing_options(int *child_flags, QDict *child_options,
|
|||||||
|
|
||||||
static const BdrvChildRole child_backing = {
|
static const BdrvChildRole child_backing = {
|
||||||
.inherit_options = bdrv_backing_options,
|
.inherit_options = bdrv_backing_options,
|
||||||
|
.drained_begin = bdrv_child_cb_drained_begin,
|
||||||
|
.drained_end = bdrv_child_cb_drained_end,
|
||||||
};
|
};
|
||||||
|
|
||||||
static int bdrv_open_flags(BlockDriverState *bs, int flags)
|
static int bdrv_open_flags(BlockDriverState *bs, int flags)
|
||||||
@ -1195,7 +1213,7 @@ BdrvChild *bdrv_attach_child(BlockDriverState *parent_bs,
|
|||||||
const BdrvChildRole *child_role)
|
const BdrvChildRole *child_role)
|
||||||
{
|
{
|
||||||
BdrvChild *child = bdrv_root_attach_child(child_bs, child_name, child_role,
|
BdrvChild *child = bdrv_root_attach_child(child_bs, child_name, child_role,
|
||||||
NULL);
|
parent_bs);
|
||||||
QLIST_INSERT_HEAD(&parent_bs->children, child, next);
|
QLIST_INSERT_HEAD(&parent_bs->children, child, next);
|
||||||
return child;
|
return child;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user