Commit 9ff7f0df authored by Kevin Wolf's avatar Kevin Wolf
Browse files

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: default avatarKevin Wolf <kwolf@redhat.com>
parent 980b0f94
Loading
Loading
Loading
Loading
+0 −8
Original line number Diff line number Diff line
@@ -300,13 +300,6 @@ static void backup_clean(Job *job)
    s->target = NULL;
}

static void backup_attached_aio_context(BlockJob *job, AioContext *aio_context)
{
    BackupBlockJob *s = container_of(job, BackupBlockJob, common);

    blk_set_aio_context(s->target, aio_context);
}

void backup_do_checkpoint(BlockJob *job, Error **errp)
{
    BackupBlockJob *backup_job = container_of(job, BackupBlockJob, common);
@@ -558,7 +551,6 @@ static const BlockJobDriver backup_job_driver = {
        .abort                  = backup_abort,
        .clean                  = backup_clean,
    },
    .attached_aio_context   = backup_attached_aio_context,
    .drain                  = backup_drain,
};

+1 −9
Original line number Diff line number Diff line
@@ -1142,13 +1142,6 @@ static bool mirror_drained_poll(BlockJob *job)
    return !!s->in_flight;
}

static void mirror_attached_aio_context(BlockJob *job, AioContext *new_context)
{
    MirrorBlockJob *s = container_of(job, MirrorBlockJob, common);

    blk_set_aio_context(s->target, new_context);
}

static void mirror_drain(BlockJob *job)
{
    MirrorBlockJob *s = container_of(job, MirrorBlockJob, common);
@@ -1178,7 +1171,6 @@ static const BlockJobDriver mirror_job_driver = {
        .complete               = mirror_complete,
    },
    .drained_poll           = mirror_drained_poll,
    .attached_aio_context   = mirror_attached_aio_context,
    .drain                  = mirror_drain,
};

@@ -1196,7 +1188,6 @@ static const BlockJobDriver commit_active_job_driver = {
        .complete               = mirror_complete,
    },
    .drained_poll           = mirror_drained_poll,
    .attached_aio_context   = mirror_attached_aio_context,
    .drain                  = mirror_drain,
};

@@ -1612,6 +1603,7 @@ static void mirror_start_job(const char *job_id, BlockDriverState *bs,
         * ensure that. */
        blk_set_force_allow_inactivate(s->target);
    }
    blk_set_allow_aio_context_change(s->target, true);

    s->replaces = g_strdup(replaces);
    s->on_source_error = on_source_error;
+34 −0
Original line number Diff line number Diff line
@@ -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) {