Skip to content

Commit

Permalink
block-backend: add drained_begin / drained_end ops
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
jnsnow authored and codyprime committed Mar 22, 2017
1 parent e3796a2 commit f4d9cc8
Show file tree
Hide file tree
Showing 2 changed files with 30 additions and 2 deletions.
24 changes: 22 additions & 2 deletions block/block-backend.c
Expand Up @@ -65,6 +65,8 @@ struct BlockBackend {
bool allow_write_beyond_eof;

NotifierList remove_bs_notifiers, insert_bs_notifiers;

int quiesce_counter;
};

typedef struct BlockBackendAIOCB {
Expand Down Expand Up @@ -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);
}
}

/*
Expand Down Expand Up @@ -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. */

Expand All @@ -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);
}
}
}
8 changes: 8 additions & 0 deletions include/sysemu/block-backend.h
Expand Up @@ -58,6 +58,14 @@ typedef struct BlockDevOps {
* Runs when the size changed (e.g. monitor command block_resize)
*/
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;

/* This struct is embedded in (the private) BlockBackend struct and contains
Expand Down

0 comments on commit f4d9cc8

Please sign in to comment.