Commit b69f777d authored by Kevin Wolf's avatar Kevin Wolf
Browse files

job: Add job_drain()



block_job_drain() contains a blk_drain() call which cannot be moved to
Job, so add a new JobDriver callback JobDriver.drain which has a common
implementation for all BlockJobs. In addition to this we keep the
existing BlockJobDriver.drain callback that is called by the common
drain implementation for all block jobs.

Signed-off-by: default avatarKevin Wolf <kwolf@redhat.com>
Reviewed-by: default avatarMax Reitz <mreitz@redhat.com>
parent 004e95df
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -529,6 +529,7 @@ static const BlockJobDriver backup_job_driver = {
        .job_type               = JOB_TYPE_BACKUP,
        .free                   = block_job_free,
        .user_resume            = block_job_user_resume,
        .drain                  = block_job_drain,
        .start                  = backup_run,
        .commit                 = backup_commit,
        .abort                  = backup_abort,
+1 −0
Original line number Diff line number Diff line
@@ -221,6 +221,7 @@ static const BlockJobDriver commit_job_driver = {
        .job_type      = JOB_TYPE_COMMIT,
        .free          = block_job_free,
        .user_resume   = block_job_user_resume,
        .drain         = block_job_drain,
        .start         = commit_run,
    },
};
+2 −0
Original line number Diff line number Diff line
@@ -992,6 +992,7 @@ static const BlockJobDriver mirror_job_driver = {
        .job_type               = JOB_TYPE_MIRROR,
        .free                   = block_job_free,
        .user_resume            = block_job_user_resume,
        .drain                  = block_job_drain,
        .start                  = mirror_run,
        .pause                  = mirror_pause,
    },
@@ -1006,6 +1007,7 @@ static const BlockJobDriver commit_active_job_driver = {
        .job_type               = JOB_TYPE_COMMIT,
        .free                   = block_job_free,
        .user_resume            = block_job_user_resume,
        .drain                  = block_job_drain,
        .start                  = mirror_run,
        .pause                  = mirror_pause,
    },
+1 −0
Original line number Diff line number Diff line
@@ -215,6 +215,7 @@ static const BlockJobDriver stream_job_driver = {
        .free          = block_job_free,
        .start         = stream_run,
        .user_resume   = block_job_user_resume,
        .drain         = block_job_drain,
    },
};

+10 −10
Original line number Diff line number Diff line
@@ -169,14 +169,13 @@ static void block_job_attached_aio_context(AioContext *new_context,
    job_resume(&job->job);
}

static void block_job_drain(BlockJob *job)
void block_job_drain(Job *job)
{
    /* If job is !job->job.busy this kicks it into the next pause point. */
    block_job_enter(job);
    BlockJob *bjob = container_of(job, BlockJob, job);

    blk_drain(job->blk);
    if (job->driver->drain) {
        job->driver->drain(job);
    blk_drain(bjob->blk);
    if (bjob->driver->drain) {
        bjob->driver->drain(bjob);
    }
}

@@ -190,7 +189,7 @@ static void block_job_detach_aio_context(void *opaque)
    job_pause(&job->job);

    while (!job->job.paused && !job_is_completed(&job->job)) {
        block_job_drain(job);
        job_drain(&job->job);
    }

    job->job.aio_context = NULL;
@@ -327,11 +326,11 @@ static int block_job_finish_sync(BlockJob *job,
        job_unref(&job->job);
        return -EBUSY;
    }
    /* block_job_drain calls block_job_enter, and it should be enough to
     * induce progress until the job completes or moves to the main thread.
    /* job_drain calls job_enter, and it should be enough to induce progress
     * until the job completes or moves to the main thread.
    */
    while (!job->job.deferred_to_main_loop && !job_is_completed(&job->job)) {
        block_job_drain(job);
        job_drain(&job->job);
    }
    while (!job_is_completed(&job->job)) {
        aio_poll(qemu_get_aio_context(), true);
@@ -713,6 +712,7 @@ void *block_job_create(const char *job_id, const BlockJobDriver *driver,
    assert(is_block_job(&job->job));
    assert(job->job.driver->free == &block_job_free);
    assert(job->job.driver->user_resume == &block_job_user_resume);
    assert(job->job.driver->drain == &block_job_drain);

    job->driver        = driver;
    job->blk           = blk;
Loading