aboutsummaryrefslogtreecommitdiff
path: root/blockjob.c
diff options
context:
space:
mode:
authorKevin Wolf <kwolf@redhat.com>2019-05-06 19:18:03 +0200
committerKevin Wolf <kwolf@redhat.com>2019-05-20 17:08:56 +0200
commit9ff7f0df8757c1c6ca582935c27db377a1eaeb22 (patch)
tree1b3aefe5b5f0b9090dab28ce173d12e687bf34c6 /blockjob.c
parent980b0f943aad9240f276d7e48e2cf92ae4eb61ca (diff)
blockjob: Propagate AioContext change to all job nodes
Block jobs require that all of the nodes the job is using are in the same AioContext. Therefore all BdrvChild objects of the job propagate .(can_)set_aio_context to all other job nodes, so that the switch is checked and performed consistently even if both nodes are in different subtrees. Signed-off-by: Kevin Wolf <kwolf@redhat.com>
Diffstat (limited to 'blockjob.c')
-rw-r--r--blockjob.c34
1 files changed, 34 insertions, 0 deletions
diff --git a/blockjob.c b/blockjob.c
index 730101d282..24e6093a9c 100644
--- a/blockjob.c
+++ b/blockjob.c
@@ -183,11 +183,44 @@ static void child_job_drained_end(BdrvChild *c)
job_resume(&job->job);
}
+static bool child_job_can_set_aio_ctx(BdrvChild *c, AioContext *ctx,
+ GSList **ignore, Error **errp)
+{
+ BlockJob *job = c->opaque;
+ GSList *l;
+
+ for (l = job->nodes; l; l = l->next) {
+ BdrvChild *sibling = l->data;
+ if (!bdrv_child_can_set_aio_context(sibling, ctx, ignore, errp)) {
+ return false;
+ }
+ }
+ return true;
+}
+
+static void child_job_set_aio_ctx(BdrvChild *c, AioContext *ctx,
+ GSList **ignore)
+{
+ BlockJob *job = c->opaque;
+ GSList *l;
+
+ for (l = job->nodes; l; l = l->next) {
+ BdrvChild *sibling = l->data;
+ if (g_slist_find(*ignore, sibling)) {
+ continue;
+ }
+ *ignore = g_slist_prepend(*ignore, sibling);
+ bdrv_set_aio_context_ignore(sibling->bs, ctx, ignore);
+ }
+}
+
static const BdrvChildRole child_job = {
.get_parent_desc = child_job_get_parent_desc,
.drained_begin = child_job_drained_begin,
.drained_poll = child_job_drained_poll,
.drained_end = child_job_drained_end,
+ .can_set_aio_ctx = child_job_can_set_aio_ctx,
+ .set_aio_ctx = child_job_set_aio_ctx,
.stay_at_node = true,
};
@@ -440,6 +473,7 @@ void *block_job_create(const char *job_id, const BlockJobDriver *driver,
blk_add_aio_context_notifier(blk, block_job_attached_aio_context,
block_job_detach_aio_context, job);
+ blk_set_allow_aio_context_change(blk, true);
/* Only set speed when necessary to avoid NotSupported error */
if (speed != 0) {