diff options
author | John Snow | 2017-03-16 22:23:50 +0100 |
---|---|---|
committer | Jeff Cody | 2017-03-22 18:26:27 +0100 |
commit | f4d9cc88ee69a5b04a843424e50f466e36fcad4e (patch) | |
tree | a2d8777a5e230efd54adfadd6020f8a1ab77e5b8 /block | |
parent | blockjob: add block_job_start_shim (diff) | |
download | qemu-f4d9cc88ee69a5b04a843424e50f466e36fcad4e.tar.gz qemu-f4d9cc88ee69a5b04a843424e50f466e36fcad4e.tar.xz qemu-f4d9cc88ee69a5b04a843424e50f466e36fcad4e.zip |
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>
Diffstat (limited to 'block')
-rw-r--r-- | block/block-backend.c | 24 |
1 files changed, 22 insertions, 2 deletions
diff --git a/block/block-backend.c b/block/block-backend.c index 5742c09c2c..0b6377332c 100644 --- a/block/block-backend.c +++ b/block/block-backend.c @@ -65,6 +65,8 @@ struct BlockBackend { bool allow_write_beyond_eof; NotifierList remove_bs_notifiers, insert_bs_notifiers; + + int quiesce_counter; }; typedef struct BlockBackendAIOCB { @@ -699,12 +701,17 @@ void blk_set_dev_ops(BlockBackend *blk, const BlockDevOps *ops, void *opaque) { /* 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 - * is set. */ + * it that way, so we can assume blk->dev, if present, is a DeviceState if + * blk->dev_ops is set. Non-device users may use dev_ops without device. */ assert(!blk->legacy_dev); blk->dev_ops = ops; 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; + 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 * 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) { BlockBackend *blk = child->opaque; + assert(blk->quiesce_counter); assert(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); + } + } } |