mirror of https://github.com/xemu-project/xemu.git
block-backend: add drained_begin / drained_end ops
Allow block backends to forward drain requests to their devices/users. The initial intended purpose for this patch is to allow BBs to forward requests along to BlockJobs, which will want to pause if their associated BB has entered a drained region. Signed-off-by: John Snow <jsnow@redhat.com> Reviewed-by: Jeff Cody <jcody@redhat.com> Message-id: 20170316212351.13797-3-jsnow@redhat.com Signed-off-by: Jeff Cody <jcody@redhat.com>
This commit is contained in:
parent
e3796a245a
commit
f4d9cc88ee
|
@ -65,6 +65,8 @@ struct BlockBackend {
|
||||||
bool allow_write_beyond_eof;
|
bool allow_write_beyond_eof;
|
||||||
|
|
||||||
NotifierList remove_bs_notifiers, insert_bs_notifiers;
|
NotifierList remove_bs_notifiers, insert_bs_notifiers;
|
||||||
|
|
||||||
|
int quiesce_counter;
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef struct BlockBackendAIOCB {
|
typedef struct BlockBackendAIOCB {
|
||||||
|
@ -699,12 +701,17 @@ void blk_set_dev_ops(BlockBackend *blk, const BlockDevOps *ops,
|
||||||
void *opaque)
|
void *opaque)
|
||||||
{
|
{
|
||||||
/* All drivers that use blk_set_dev_ops() are qdevified and we want to keep
|
/* All drivers that use blk_set_dev_ops() are qdevified and we want to keep
|
||||||
* it that way, so we can assume blk->dev is a DeviceState if blk->dev_ops
|
* it that way, so we can assume blk->dev, if present, is a DeviceState if
|
||||||
* is set. */
|
* blk->dev_ops is set. Non-device users may use dev_ops without device. */
|
||||||
assert(!blk->legacy_dev);
|
assert(!blk->legacy_dev);
|
||||||
|
|
||||||
blk->dev_ops = ops;
|
blk->dev_ops = ops;
|
||||||
blk->dev_opaque = opaque;
|
blk->dev_opaque = opaque;
|
||||||
|
|
||||||
|
/* Are we currently quiesced? Should we enforce this right now? */
|
||||||
|
if (blk->quiesce_counter && ops->drained_begin) {
|
||||||
|
ops->drained_begin(opaque);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -1870,6 +1877,12 @@ static void blk_root_drained_begin(BdrvChild *child)
|
||||||
{
|
{
|
||||||
BlockBackend *blk = child->opaque;
|
BlockBackend *blk = child->opaque;
|
||||||
|
|
||||||
|
if (++blk->quiesce_counter == 1) {
|
||||||
|
if (blk->dev_ops && blk->dev_ops->drained_begin) {
|
||||||
|
blk->dev_ops->drained_begin(blk->dev_opaque);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* Note that blk->root may not be accessible here yet if we are just
|
/* Note that blk->root may not be accessible here yet if we are just
|
||||||
* attaching to a BlockDriverState that is drained. Use child instead. */
|
* attaching to a BlockDriverState that is drained. Use child instead. */
|
||||||
|
|
||||||
|
@ -1881,7 +1894,14 @@ static void blk_root_drained_begin(BdrvChild *child)
|
||||||
static void blk_root_drained_end(BdrvChild *child)
|
static void blk_root_drained_end(BdrvChild *child)
|
||||||
{
|
{
|
||||||
BlockBackend *blk = child->opaque;
|
BlockBackend *blk = child->opaque;
|
||||||
|
assert(blk->quiesce_counter);
|
||||||
|
|
||||||
assert(blk->public.io_limits_disabled);
|
assert(blk->public.io_limits_disabled);
|
||||||
--blk->public.io_limits_disabled;
|
--blk->public.io_limits_disabled;
|
||||||
|
|
||||||
|
if (--blk->quiesce_counter == 0) {
|
||||||
|
if (blk->dev_ops && blk->dev_ops->drained_end) {
|
||||||
|
blk->dev_ops->drained_end(blk->dev_opaque);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -58,6 +58,14 @@ typedef struct BlockDevOps {
|
||||||
* Runs when the size changed (e.g. monitor command block_resize)
|
* Runs when the size changed (e.g. monitor command block_resize)
|
||||||
*/
|
*/
|
||||||
void (*resize_cb)(void *opaque);
|
void (*resize_cb)(void *opaque);
|
||||||
|
/*
|
||||||
|
* Runs when the backend receives a drain request.
|
||||||
|
*/
|
||||||
|
void (*drained_begin)(void *opaque);
|
||||||
|
/*
|
||||||
|
* Runs when the backend's last drain request ends.
|
||||||
|
*/
|
||||||
|
void (*drained_end)(void *opaque);
|
||||||
} BlockDevOps;
|
} BlockDevOps;
|
||||||
|
|
||||||
/* This struct is embedded in (the private) BlockBackend struct and contains
|
/* This struct is embedded in (the private) BlockBackend struct and contains
|
||||||
|
|
Loading…
Reference in New Issue