aboutsummaryrefslogtreecommitdiff
path: root/blockjob.c
diff options
context:
space:
mode:
authorKevin Wolf <kwolf@redhat.com>2018-04-19 17:30:16 +0200
committerKevin Wolf <kwolf@redhat.com>2018-05-23 14:30:50 +0200
commit4ad351819b974d724e926fd23cdd66bec3c9768e (patch)
tree308f62a669a00a138090cb33e329f0232fdd5baf /blockjob.c
parent139a9f020d49e9f863e0d46fd3d0b440dfb3b9d7 (diff)
downloadqemu-4ad351819b974d724e926fd23cdd66bec3c9768e.zip
qemu-4ad351819b974d724e926fd23cdd66bec3c9768e.tar.gz
qemu-4ad351819b974d724e926fd23cdd66bec3c9768e.tar.bz2
job: Move single job finalisation to Job
This moves the finalisation of a single job from BlockJob to Job. Some part of this code depends on job transactions, and job transactions call this code, we introduce some temporary calls from Job functions to BlockJob ones. This will be fixed once transactions move to Job, too. Signed-off-by: Kevin Wolf <kwolf@redhat.com> Reviewed-by: Max Reitz <mreitz@redhat.com>
Diffstat (limited to 'blockjob.c')
-rw-r--r--blockjob.c142
1 files changed, 25 insertions, 117 deletions
diff --git a/blockjob.c b/blockjob.c
index 05d7921..34c57da 100644
--- a/blockjob.c
+++ b/blockjob.c
@@ -127,7 +127,7 @@ void block_job_txn_add_job(BlockJobTxn *txn, BlockJob *job)
block_job_txn_ref(txn);
}
-static void block_job_txn_del_job(BlockJob *job)
+void block_job_txn_del_job(BlockJob *job)
{
if (job->txn) {
QLIST_REMOVE(job, txn_list);
@@ -262,101 +262,12 @@ const BlockJobDriver *block_job_driver(BlockJob *job)
return job->driver;
}
-static void block_job_decommission(BlockJob *job)
-{
- assert(job);
- job->job.busy = false;
- job->job.paused = false;
- job->job.deferred_to_main_loop = true;
- block_job_txn_del_job(job);
- job_state_transition(&job->job, JOB_STATUS_NULL);
- job_unref(&job->job);
-}
-
-static void block_job_do_dismiss(BlockJob *job)
-{
- block_job_decommission(job);
-}
-
-static void block_job_conclude(BlockJob *job)
-{
- job_state_transition(&job->job, JOB_STATUS_CONCLUDED);
- if (job->job.auto_dismiss || !job_started(&job->job)) {
- block_job_do_dismiss(job);
- }
-}
-
-static void block_job_update_rc(BlockJob *job)
-{
- if (!job->ret && job_is_cancelled(&job->job)) {
- job->ret = -ECANCELED;
- }
- if (job->ret) {
- job_state_transition(&job->job, JOB_STATUS_ABORTING);
- }
-}
-
static int block_job_prepare(BlockJob *job)
{
- if (job->ret == 0 && job->driver->prepare) {
- job->ret = job->driver->prepare(job);
- }
- return job->ret;
-}
-
-static void block_job_commit(BlockJob *job)
-{
- assert(!job->ret);
- if (job->driver->commit) {
- job->driver->commit(job);
- }
-}
-
-static void block_job_abort(BlockJob *job)
-{
- assert(job->ret);
- if (job->driver->abort) {
- job->driver->abort(job);
- }
-}
-
-static void block_job_clean(BlockJob *job)
-{
- if (job->driver->clean) {
- job->driver->clean(job);
+ if (job->job.ret == 0 && job->driver->prepare) {
+ job->job.ret = job->driver->prepare(job);
}
-}
-
-static int block_job_finalize_single(BlockJob *job)
-{
- assert(job_is_completed(&job->job));
-
- /* Ensure abort is called for late-transactional failures */
- block_job_update_rc(job);
-
- if (!job->ret) {
- block_job_commit(job);
- } else {
- block_job_abort(job);
- }
- block_job_clean(job);
-
- if (job->cb) {
- job->cb(job->opaque, job->ret);
- }
-
- /* Emit events only if we actually started */
- if (job_started(&job->job)) {
- if (job_is_cancelled(&job->job)) {
- job_event_cancelled(&job->job);
- } else {
- job_event_completed(&job->job);
- }
- }
-
- block_job_txn_del_job(job);
- block_job_conclude(job);
- return 0;
+ return job->job.ret;
}
static void block_job_cancel_async(BlockJob *job, bool force)
@@ -424,8 +335,8 @@ static int block_job_finish_sync(BlockJob *job,
while (!job_is_completed(&job->job)) {
aio_poll(qemu_get_aio_context(), true);
}
- ret = (job_is_cancelled(&job->job) && job->ret == 0)
- ? -ECANCELED : job->ret;
+ ret = (job_is_cancelled(&job->job) && job->job.ret == 0)
+ ? -ECANCELED : job->job.ret;
job_unref(&job->job);
return ret;
}
@@ -466,7 +377,7 @@ static void block_job_completed_txn_abort(BlockJob *job)
assert(job_is_cancelled(&other_job->job));
block_job_finish_sync(other_job, NULL, NULL);
}
- block_job_finalize_single(other_job);
+ job_finalize_single(&other_job->job);
aio_context_release(ctx);
}
@@ -478,6 +389,11 @@ static int block_job_needs_finalize(BlockJob *job)
return !job->job.auto_finalize;
}
+static int block_job_finalize_single(BlockJob *job)
+{
+ return job_finalize_single(&job->job);
+}
+
static void block_job_do_finalize(BlockJob *job)
{
int rc;
@@ -516,7 +432,7 @@ static void block_job_completed_txn_success(BlockJob *job)
if (!job_is_completed(&other_job->job)) {
return;
}
- assert(other_job->ret == 0);
+ assert(other_job->job.ret == 0);
}
block_job_txn_apply(txn, block_job_transition_to_pending, false);
@@ -601,14 +517,14 @@ void block_job_dismiss(BlockJob **jobptr, Error **errp)
return;
}
- block_job_do_dismiss(job);
+ job_do_dismiss(&job->job);
*jobptr = NULL;
}
void block_job_cancel(BlockJob *job, bool force)
{
if (job->job.status == JOB_STATUS_CONCLUDED) {
- block_job_do_dismiss(job);
+ job_do_dismiss(&job->job);
return;
}
block_job_cancel_async(job, force);
@@ -691,8 +607,8 @@ BlockJobInfo *block_job_query(BlockJob *job, Error **errp)
info->status = job->job.status;
info->auto_finalize = job->job.auto_finalize;
info->auto_dismiss = job->job.auto_dismiss;
- info->has_error = job->ret != 0;
- info->error = job->ret ? g_strdup(strerror(-job->ret)) : NULL;
+ info->has_error = job->job.ret != 0;
+ info->error = job->job.ret ? g_strdup(strerror(-job->job.ret)) : NULL;
return info;
}
@@ -729,8 +645,8 @@ static void block_job_event_completed(Notifier *n, void *opaque)
return;
}
- if (job->ret < 0) {
- msg = strerror(-job->ret);
+ if (job->job.ret < 0) {
+ msg = strerror(-job->job.ret);
}
qapi_event_send_block_job_completed(job_type(&job->job),
@@ -787,7 +703,7 @@ void *block_job_create(const char *job_id, const BlockJobDriver *driver,
}
job = job_create(job_id, &driver->job_driver, blk_get_aio_context(blk),
- flags, errp);
+ flags, cb, opaque, errp);
if (job == NULL) {
blk_unref(blk);
return NULL;
@@ -799,8 +715,6 @@ void *block_job_create(const char *job_id, const BlockJobDriver *driver,
job->driver = driver;
job->blk = blk;
- job->cb = cb;
- job->opaque = opaque;
job->finalize_cancelled_notifier.notify = block_job_event_cancelled;
job->finalize_completed_notifier.notify = block_job_event_completed;
@@ -828,7 +742,7 @@ void *block_job_create(const char *job_id, const BlockJobDriver *driver,
block_job_set_speed(job, speed, &local_err);
if (local_err) {
- block_job_early_fail(job);
+ job_early_fail(&job->job);
error_propagate(errp, local_err);
return NULL;
}
@@ -847,20 +761,14 @@ void *block_job_create(const char *job_id, const BlockJobDriver *driver,
return job;
}
-void block_job_early_fail(BlockJob *job)
-{
- assert(job->job.status == JOB_STATUS_CREATED);
- block_job_decommission(job);
-}
-
void block_job_completed(BlockJob *job, int ret)
{
assert(job && job->txn && !job_is_completed(&job->job));
assert(blk_bs(job->blk)->job == job);
- job->ret = ret;
- block_job_update_rc(job);
- trace_block_job_completed(job, ret, job->ret);
- if (job->ret) {
+ job->job.ret = ret;
+ job_update_rc(&job->job);
+ trace_block_job_completed(job, ret, job->job.ret);
+ if (job->job.ret) {
block_job_completed_txn_abort(job);
} else {
block_job_completed_txn_success(job);