Skip to content

Commit

Permalink
blockjob: add .start field
Browse files Browse the repository at this point in the history
Add an explicit start field to specify the entrypoint. We already have
ownership of the coroutine itself AND managing the lifetime of the
coroutine, let's take control of creation of the coroutine, too.

This will allow us to delay creation of the actual coroutine until we
know we'll actually start a BlockJob in block_job_start. This avoids
the sticky question of how to "un-create" a Coroutine that hasn't been
started yet.

Signed-off-by: John Snow <jsnow@redhat.com>
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
Message-id: 1478587839-9834-4-git-send-email-jsnow@redhat.com
Signed-off-by: Jeff Cody <jcody@redhat.com>
  • Loading branch information
jnsnow authored and codyprime committed Nov 15, 2016
1 parent e8a40bf commit a7815a7
Show file tree
Hide file tree
Showing 5 changed files with 23 additions and 15 deletions.
25 changes: 13 additions & 12 deletions block/backup.c
Expand Up @@ -323,17 +323,6 @@ static void backup_drain(BlockJob *job)
}
}

static const BlockJobDriver backup_job_driver = {
.instance_size = sizeof(BackupBlockJob),
.job_type = BLOCK_JOB_TYPE_BACKUP,
.set_speed = backup_set_speed,
.commit = backup_commit,
.abort = backup_abort,
.clean = backup_clean,
.attached_aio_context = backup_attached_aio_context,
.drain = backup_drain,
};

static BlockErrorAction backup_error_action(BackupBlockJob *job,
bool read, int error)
{
Expand Down Expand Up @@ -542,6 +531,18 @@ static void coroutine_fn backup_run(void *opaque)
block_job_defer_to_main_loop(&job->common, backup_complete, data);
}

static const BlockJobDriver backup_job_driver = {
.instance_size = sizeof(BackupBlockJob),
.job_type = BLOCK_JOB_TYPE_BACKUP,
.start = backup_run,
.set_speed = backup_set_speed,
.commit = backup_commit,
.abort = backup_abort,
.clean = backup_clean,
.attached_aio_context = backup_attached_aio_context,
.drain = backup_drain,
};

void backup_start(const char *job_id, BlockDriverState *bs,
BlockDriverState *target, int64_t speed,
MirrorSyncMode sync_mode, BdrvDirtyBitmap *sync_bitmap,
Expand Down Expand Up @@ -653,7 +654,7 @@ void backup_start(const char *job_id, BlockDriverState *bs,

block_job_add_bdrv(&job->common, target);
job->common.len = len;
job->common.co = qemu_coroutine_create(backup_run, job);
job->common.co = qemu_coroutine_create(job->common.driver->start, job);
block_job_txn_add_job(txn, &job->common);
qemu_coroutine_enter(job->common.co);
return;
Expand Down
3 changes: 2 additions & 1 deletion block/commit.c
Expand Up @@ -205,6 +205,7 @@ static const BlockJobDriver commit_job_driver = {
.instance_size = sizeof(CommitBlockJob),
.job_type = BLOCK_JOB_TYPE_COMMIT,
.set_speed = commit_set_speed,
.start = commit_run,
};

void commit_start(const char *job_id, BlockDriverState *bs,
Expand Down Expand Up @@ -288,7 +289,7 @@ void commit_start(const char *job_id, BlockDriverState *bs,
s->backing_file_str = g_strdup(backing_file_str);

s->on_error = on_error;
s->common.co = qemu_coroutine_create(commit_run, s);
s->common.co = qemu_coroutine_create(s->common.driver->start, s);

trace_commit_start(bs, base, top, s, s->common.co);
qemu_coroutine_enter(s->common.co);
Expand Down
4 changes: 3 additions & 1 deletion block/mirror.c
Expand Up @@ -920,6 +920,7 @@ static const BlockJobDriver mirror_job_driver = {
.instance_size = sizeof(MirrorBlockJob),
.job_type = BLOCK_JOB_TYPE_MIRROR,
.set_speed = mirror_set_speed,
.start = mirror_run,
.complete = mirror_complete,
.pause = mirror_pause,
.attached_aio_context = mirror_attached_aio_context,
Expand All @@ -930,6 +931,7 @@ static const BlockJobDriver commit_active_job_driver = {
.instance_size = sizeof(MirrorBlockJob),
.job_type = BLOCK_JOB_TYPE_COMMIT,
.set_speed = mirror_set_speed,
.start = mirror_run,
.complete = mirror_complete,
.pause = mirror_pause,
.attached_aio_context = mirror_attached_aio_context,
Expand Down Expand Up @@ -1007,7 +1009,7 @@ static void mirror_start_job(const char *job_id, BlockDriverState *bs,
}
}

s->common.co = qemu_coroutine_create(mirror_run, s);
s->common.co = qemu_coroutine_create(s->common.driver->start, s);
trace_mirror_start(bs, s, s->common.co, opaque);
qemu_coroutine_enter(s->common.co);
}
Expand Down
3 changes: 2 additions & 1 deletion block/stream.c
Expand Up @@ -218,6 +218,7 @@ static const BlockJobDriver stream_job_driver = {
.instance_size = sizeof(StreamBlockJob),
.job_type = BLOCK_JOB_TYPE_STREAM,
.set_speed = stream_set_speed,
.start = stream_run,
};

void stream_start(const char *job_id, BlockDriverState *bs,
Expand Down Expand Up @@ -254,7 +255,7 @@ void stream_start(const char *job_id, BlockDriverState *bs,
s->bs_flags = orig_bs_flags;

s->on_error = on_error;
s->common.co = qemu_coroutine_create(stream_run, s);
s->common.co = qemu_coroutine_create(s->common.driver->start, s);
trace_stream_start(bs, base, s, s->common.co);
qemu_coroutine_enter(s->common.co);
}
3 changes: 3 additions & 0 deletions include/block/blockjob_int.h
Expand Up @@ -47,6 +47,9 @@ struct BlockJobDriver {
/** Optional callback for job types that need to forward I/O status reset */
void (*iostatus_reset)(BlockJob *job);

/** Mandatory: Entrypoint for the Coroutine. */
CoroutineEntry *start;

/**
* Optional callback for job types whose completion must be triggered
* manually.
Expand Down

0 comments on commit a7815a7

Please sign in to comment.