|
|
ae23c9 |
From 426d98dc12ef863627d90890278e6de92a81446f Mon Sep 17 00:00:00 2001
|
|
|
ae23c9 |
From: Kevin Wolf <kwolf@redhat.com>
|
|
|
ae23c9 |
Date: Tue, 26 Jun 2018 09:48:23 +0200
|
|
|
ae23c9 |
Subject: [PATCH 115/268] job: Move completion and cancellation to Job
|
|
|
ae23c9 |
|
|
|
ae23c9 |
RH-Author: Kevin Wolf <kwolf@redhat.com>
|
|
|
ae23c9 |
Message-id: <20180626094856.6924-41-kwolf@redhat.com>
|
|
|
ae23c9 |
Patchwork-id: 81116
|
|
|
ae23c9 |
O-Subject: [RHV-7.6 qemu-kvm-rhev PATCH v2 40/73] job: Move completion and cancellation to Job
|
|
|
ae23c9 |
Bugzilla: 1513543
|
|
|
ae23c9 |
RH-Acked-by: Jeffrey Cody <jcody@redhat.com>
|
|
|
ae23c9 |
RH-Acked-by: Max Reitz <mreitz@redhat.com>
|
|
|
ae23c9 |
RH-Acked-by: Fam Zheng <famz@redhat.com>
|
|
|
ae23c9 |
|
|
|
ae23c9 |
This moves the top-level job completion and cancellation functions from
|
|
|
ae23c9 |
BlockJob to Job.
|
|
|
ae23c9 |
|
|
|
ae23c9 |
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
|
|
|
ae23c9 |
(cherry picked from commit 3d70ff53b6bf90d9eec6f97024ec9895f6799d9e)
|
|
|
ae23c9 |
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
|
|
|
ae23c9 |
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
|
|
|
ae23c9 |
---
|
|
|
ae23c9 |
block.c | 4 ++-
|
|
|
ae23c9 |
block/backup.c | 3 +-
|
|
|
ae23c9 |
block/commit.c | 6 ++--
|
|
|
ae23c9 |
block/mirror.c | 6 ++--
|
|
|
ae23c9 |
block/replication.c | 4 +--
|
|
|
ae23c9 |
block/stream.c | 2 +-
|
|
|
ae23c9 |
block/trace-events | 3 --
|
|
|
ae23c9 |
blockdev.c | 8 ++---
|
|
|
ae23c9 |
blockjob.c | 76 ---------------------------------------
|
|
|
ae23c9 |
include/block/blockjob.h | 55 -----------------------------
|
|
|
ae23c9 |
include/block/blockjob_int.h | 18 ----------
|
|
|
ae23c9 |
include/qemu/job.h | 68 +++++++++++++++++++++++++++++------
|
|
|
ae23c9 |
job.c | 84 +++++++++++++++++++++++++++++++++++++++-----
|
|
|
ae23c9 |
qemu-img.c | 2 +-
|
|
|
ae23c9 |
tests/test-bdrv-drain.c | 5 ++-
|
|
|
ae23c9 |
tests/test-blockjob-txn.c | 14 ++++----
|
|
|
ae23c9 |
tests/test-blockjob.c | 21 ++++++-----
|
|
|
ae23c9 |
trace-events | 1 +
|
|
|
ae23c9 |
18 files changed, 171 insertions(+), 209 deletions(-)
|
|
|
ae23c9 |
|
|
|
ae23c9 |
diff --git a/block.c b/block.c
|
|
|
ae23c9 |
index d991a09..a83787f 100644
|
|
|
ae23c9 |
--- a/block.c
|
|
|
ae23c9 |
+++ b/block.c
|
|
|
ae23c9 |
@@ -3374,7 +3374,9 @@ static void bdrv_close(BlockDriverState *bs)
|
|
|
ae23c9 |
|
|
|
ae23c9 |
void bdrv_close_all(void)
|
|
|
ae23c9 |
{
|
|
|
ae23c9 |
- block_job_cancel_sync_all();
|
|
|
ae23c9 |
+ /* TODO We do want to cancel all jobs instead of just block jobs on
|
|
|
ae23c9 |
+ * shutdown, but bdrv_close_all() isn't the right place any more. */
|
|
|
ae23c9 |
+ job_cancel_sync_all();
|
|
|
ae23c9 |
nbd_export_close_all();
|
|
|
ae23c9 |
|
|
|
ae23c9 |
/* Drop references from requests still in flight, such as canceled block
|
|
|
ae23c9 |
diff --git a/block/backup.c b/block/backup.c
|
|
|
ae23c9 |
index 6172f90..b13f91d 100644
|
|
|
ae23c9 |
--- a/block/backup.c
|
|
|
ae23c9 |
+++ b/block/backup.c
|
|
|
ae23c9 |
@@ -319,10 +319,9 @@ typedef struct {
|
|
|
ae23c9 |
|
|
|
ae23c9 |
static void backup_complete(Job *job, void *opaque)
|
|
|
ae23c9 |
{
|
|
|
ae23c9 |
- BlockJob *bjob = container_of(job, BlockJob, job);
|
|
|
ae23c9 |
BackupCompleteData *data = opaque;
|
|
|
ae23c9 |
|
|
|
ae23c9 |
- block_job_completed(bjob, data->ret);
|
|
|
ae23c9 |
+ job_completed(job, data->ret);
|
|
|
ae23c9 |
g_free(data);
|
|
|
ae23c9 |
}
|
|
|
ae23c9 |
|
|
|
ae23c9 |
diff --git a/block/commit.c b/block/commit.c
|
|
|
ae23c9 |
index 40d97a3..b0a847e 100644
|
|
|
ae23c9 |
--- a/block/commit.c
|
|
|
ae23c9 |
+++ b/block/commit.c
|
|
|
ae23c9 |
@@ -112,12 +112,12 @@ static void commit_complete(Job *job, void *opaque)
|
|
|
ae23c9 |
blk_unref(s->top);
|
|
|
ae23c9 |
|
|
|
ae23c9 |
/* If there is more than one reference to the job (e.g. if called from
|
|
|
ae23c9 |
- * job_finish_sync()), block_job_completed() won't free it and therefore
|
|
|
ae23c9 |
- * the blockers on the intermediate nodes remain. This would cause
|
|
|
ae23c9 |
+ * job_finish_sync()), job_completed() won't free it and therefore the
|
|
|
ae23c9 |
+ * blockers on the intermediate nodes remain. This would cause
|
|
|
ae23c9 |
* bdrv_set_backing_hd() to fail. */
|
|
|
ae23c9 |
block_job_remove_all_bdrv(bjob);
|
|
|
ae23c9 |
|
|
|
ae23c9 |
- block_job_completed(&s->common, ret);
|
|
|
ae23c9 |
+ job_completed(job, ret);
|
|
|
ae23c9 |
g_free(data);
|
|
|
ae23c9 |
|
|
|
ae23c9 |
/* If bdrv_drop_intermediate() didn't already do that, remove the commit
|
|
|
ae23c9 |
diff --git a/block/mirror.c b/block/mirror.c
|
|
|
ae23c9 |
index 656237a..c63cf7c 100644
|
|
|
ae23c9 |
--- a/block/mirror.c
|
|
|
ae23c9 |
+++ b/block/mirror.c
|
|
|
ae23c9 |
@@ -498,7 +498,7 @@ static void mirror_exit(Job *job, void *opaque)
|
|
|
ae23c9 |
bdrv_release_dirty_bitmap(src, s->dirty_bitmap);
|
|
|
ae23c9 |
|
|
|
ae23c9 |
/* Make sure that the source BDS doesn't go away before we called
|
|
|
ae23c9 |
- * block_job_completed(). */
|
|
|
ae23c9 |
+ * job_completed(). */
|
|
|
ae23c9 |
bdrv_ref(src);
|
|
|
ae23c9 |
bdrv_ref(mirror_top_bs);
|
|
|
ae23c9 |
bdrv_ref(target_bs);
|
|
|
ae23c9 |
@@ -581,7 +581,7 @@ static void mirror_exit(Job *job, void *opaque)
|
|
|
ae23c9 |
blk_set_perm(bjob->blk, 0, BLK_PERM_ALL, &error_abort);
|
|
|
ae23c9 |
blk_insert_bs(bjob->blk, mirror_top_bs, &error_abort);
|
|
|
ae23c9 |
|
|
|
ae23c9 |
- block_job_completed(&s->common, data->ret);
|
|
|
ae23c9 |
+ job_completed(job, data->ret);
|
|
|
ae23c9 |
|
|
|
ae23c9 |
g_free(data);
|
|
|
ae23c9 |
bdrv_drained_end(src);
|
|
|
ae23c9 |
@@ -954,7 +954,7 @@ static void mirror_complete(Job *job, Error **errp)
|
|
|
ae23c9 |
}
|
|
|
ae23c9 |
|
|
|
ae23c9 |
s->should_complete = true;
|
|
|
ae23c9 |
- block_job_enter(&s->common);
|
|
|
ae23c9 |
+ job_enter(job);
|
|
|
ae23c9 |
}
|
|
|
ae23c9 |
|
|
|
ae23c9 |
static void mirror_pause(Job *job)
|
|
|
ae23c9 |
diff --git a/block/replication.c b/block/replication.c
|
|
|
ae23c9 |
index 8241400..f3b2839 100644
|
|
|
ae23c9 |
--- a/block/replication.c
|
|
|
ae23c9 |
+++ b/block/replication.c
|
|
|
ae23c9 |
@@ -145,7 +145,7 @@ static void replication_close(BlockDriverState *bs)
|
|
|
ae23c9 |
replication_stop(s->rs, false, NULL);
|
|
|
ae23c9 |
}
|
|
|
ae23c9 |
if (s->stage == BLOCK_REPLICATION_FAILOVER) {
|
|
|
ae23c9 |
- block_job_cancel_sync(s->active_disk->bs->job);
|
|
|
ae23c9 |
+ job_cancel_sync(&s->active_disk->bs->job->job);
|
|
|
ae23c9 |
}
|
|
|
ae23c9 |
|
|
|
ae23c9 |
if (s->mode == REPLICATION_MODE_SECONDARY) {
|
|
|
ae23c9 |
@@ -679,7 +679,7 @@ static void replication_stop(ReplicationState *rs, bool failover, Error **errp)
|
|
|
ae23c9 |
* disk, secondary disk in backup_job_completed().
|
|
|
ae23c9 |
*/
|
|
|
ae23c9 |
if (s->secondary_disk->bs->job) {
|
|
|
ae23c9 |
- block_job_cancel_sync(s->secondary_disk->bs->job);
|
|
|
ae23c9 |
+ job_cancel_sync(&s->secondary_disk->bs->job->job);
|
|
|
ae23c9 |
}
|
|
|
ae23c9 |
|
|
|
ae23c9 |
if (!failover) {
|
|
|
ae23c9 |
diff --git a/block/stream.c b/block/stream.c
|
|
|
ae23c9 |
index b996278..8546c41 100644
|
|
|
ae23c9 |
--- a/block/stream.c
|
|
|
ae23c9 |
+++ b/block/stream.c
|
|
|
ae23c9 |
@@ -93,7 +93,7 @@ out:
|
|
|
ae23c9 |
}
|
|
|
ae23c9 |
|
|
|
ae23c9 |
g_free(s->backing_file_str);
|
|
|
ae23c9 |
- block_job_completed(&s->common, data->ret);
|
|
|
ae23c9 |
+ job_completed(job, data->ret);
|
|
|
ae23c9 |
g_free(data);
|
|
|
ae23c9 |
}
|
|
|
ae23c9 |
|
|
|
ae23c9 |
diff --git a/block/trace-events b/block/trace-events
|
|
|
ae23c9 |
index 93b9279..2d59b53 100644
|
|
|
ae23c9 |
--- a/block/trace-events
|
|
|
ae23c9 |
+++ b/block/trace-events
|
|
|
ae23c9 |
@@ -4,9 +4,6 @@
|
|
|
ae23c9 |
bdrv_open_common(void *bs, const char *filename, int flags, const char *format_name) "bs %p filename \"%s\" flags 0x%x format_name \"%s\""
|
|
|
ae23c9 |
bdrv_lock_medium(void *bs, bool locked) "bs %p locked %d"
|
|
|
ae23c9 |
|
|
|
ae23c9 |
-# blockjob.c
|
|
|
ae23c9 |
-block_job_completed(void *job, int ret, int jret) "job %p ret %d corrected ret %d"
|
|
|
ae23c9 |
-
|
|
|
ae23c9 |
# block/block-backend.c
|
|
|
ae23c9 |
blk_co_preadv(void *blk, void *bs, int64_t offset, unsigned int bytes, int flags) "blk %p bs %p offset %"PRId64" bytes %u flags 0x%x"
|
|
|
ae23c9 |
blk_co_pwritev(void *blk, void *bs, int64_t offset, unsigned int bytes, int flags) "blk %p bs %p offset %"PRId64" bytes %u flags 0x%x"
|
|
|
ae23c9 |
diff --git a/blockdev.c b/blockdev.c
|
|
|
ae23c9 |
index 9aa2e79..c768e68 100644
|
|
|
ae23c9 |
--- a/blockdev.c
|
|
|
ae23c9 |
+++ b/blockdev.c
|
|
|
ae23c9 |
@@ -151,7 +151,7 @@ void blockdev_mark_auto_del(BlockBackend *blk)
|
|
|
ae23c9 |
aio_context_acquire(aio_context);
|
|
|
ae23c9 |
|
|
|
ae23c9 |
if (bs->job) {
|
|
|
ae23c9 |
- block_job_cancel(bs->job, false);
|
|
|
ae23c9 |
+ job_cancel(&bs->job->job, false);
|
|
|
ae23c9 |
}
|
|
|
ae23c9 |
|
|
|
ae23c9 |
aio_context_release(aio_context);
|
|
|
ae23c9 |
@@ -1926,7 +1926,7 @@ static void drive_backup_abort(BlkActionState *common)
|
|
|
ae23c9 |
aio_context = bdrv_get_aio_context(state->bs);
|
|
|
ae23c9 |
aio_context_acquire(aio_context);
|
|
|
ae23c9 |
|
|
|
ae23c9 |
- block_job_cancel_sync(state->job);
|
|
|
ae23c9 |
+ job_cancel_sync(&state->job->job);
|
|
|
ae23c9 |
|
|
|
ae23c9 |
aio_context_release(aio_context);
|
|
|
ae23c9 |
}
|
|
|
ae23c9 |
@@ -2024,7 +2024,7 @@ static void blockdev_backup_abort(BlkActionState *common)
|
|
|
ae23c9 |
aio_context = bdrv_get_aio_context(state->bs);
|
|
|
ae23c9 |
aio_context_acquire(aio_context);
|
|
|
ae23c9 |
|
|
|
ae23c9 |
- block_job_cancel_sync(state->job);
|
|
|
ae23c9 |
+ job_cancel_sync(&state->job->job);
|
|
|
ae23c9 |
|
|
|
ae23c9 |
aio_context_release(aio_context);
|
|
|
ae23c9 |
}
|
|
|
ae23c9 |
@@ -3852,7 +3852,7 @@ void qmp_block_job_cancel(const char *device,
|
|
|
ae23c9 |
}
|
|
|
ae23c9 |
|
|
|
ae23c9 |
trace_qmp_block_job_cancel(job);
|
|
|
ae23c9 |
- block_job_user_cancel(job, force, errp);
|
|
|
ae23c9 |
+ job_user_cancel(&job->job, force, errp);
|
|
|
ae23c9 |
out:
|
|
|
ae23c9 |
aio_context_release(aio_context);
|
|
|
ae23c9 |
}
|
|
|
ae23c9 |
diff --git a/blockjob.c b/blockjob.c
|
|
|
ae23c9 |
index 14b21c8..438baa1 100644
|
|
|
ae23c9 |
--- a/blockjob.c
|
|
|
ae23c9 |
+++ b/blockjob.c
|
|
|
ae23c9 |
@@ -255,63 +255,6 @@ void block_job_dismiss(BlockJob **jobptr, Error **errp)
|
|
|
ae23c9 |
*jobptr = NULL;
|
|
|
ae23c9 |
}
|
|
|
ae23c9 |
|
|
|
ae23c9 |
-void block_job_cancel(BlockJob *job, bool force)
|
|
|
ae23c9 |
-{
|
|
|
ae23c9 |
- if (job->job.status == JOB_STATUS_CONCLUDED) {
|
|
|
ae23c9 |
- job_do_dismiss(&job->job);
|
|
|
ae23c9 |
- return;
|
|
|
ae23c9 |
- }
|
|
|
ae23c9 |
- job_cancel_async(&job->job, force);
|
|
|
ae23c9 |
- if (!job_started(&job->job)) {
|
|
|
ae23c9 |
- block_job_completed(job, -ECANCELED);
|
|
|
ae23c9 |
- } else if (job->job.deferred_to_main_loop) {
|
|
|
ae23c9 |
- job_completed_txn_abort(&job->job);
|
|
|
ae23c9 |
- } else {
|
|
|
ae23c9 |
- block_job_enter(job);
|
|
|
ae23c9 |
- }
|
|
|
ae23c9 |
-}
|
|
|
ae23c9 |
-
|
|
|
ae23c9 |
-void block_job_user_cancel(BlockJob *job, bool force, Error **errp)
|
|
|
ae23c9 |
-{
|
|
|
ae23c9 |
- if (job_apply_verb(&job->job, JOB_VERB_CANCEL, errp)) {
|
|
|
ae23c9 |
- return;
|
|
|
ae23c9 |
- }
|
|
|
ae23c9 |
- block_job_cancel(job, force);
|
|
|
ae23c9 |
-}
|
|
|
ae23c9 |
-
|
|
|
ae23c9 |
-/* A wrapper around block_job_cancel() taking an Error ** parameter so it may be
|
|
|
ae23c9 |
- * used with job_finish_sync() without the need for (rather nasty) function
|
|
|
ae23c9 |
- * pointer casts there. */
|
|
|
ae23c9 |
-static void block_job_cancel_err(Job *job, Error **errp)
|
|
|
ae23c9 |
-{
|
|
|
ae23c9 |
- BlockJob *bjob = container_of(job, BlockJob, job);
|
|
|
ae23c9 |
- assert(is_block_job(job));
|
|
|
ae23c9 |
- block_job_cancel(bjob, false);
|
|
|
ae23c9 |
-}
|
|
|
ae23c9 |
-
|
|
|
ae23c9 |
-int block_job_cancel_sync(BlockJob *job)
|
|
|
ae23c9 |
-{
|
|
|
ae23c9 |
- return job_finish_sync(&job->job, &block_job_cancel_err, NULL);
|
|
|
ae23c9 |
-}
|
|
|
ae23c9 |
-
|
|
|
ae23c9 |
-void block_job_cancel_sync_all(void)
|
|
|
ae23c9 |
-{
|
|
|
ae23c9 |
- BlockJob *job;
|
|
|
ae23c9 |
- AioContext *aio_context;
|
|
|
ae23c9 |
-
|
|
|
ae23c9 |
- while ((job = block_job_next(NULL))) {
|
|
|
ae23c9 |
- aio_context = blk_get_aio_context(job->blk);
|
|
|
ae23c9 |
- aio_context_acquire(aio_context);
|
|
|
ae23c9 |
- block_job_cancel_sync(job);
|
|
|
ae23c9 |
- aio_context_release(aio_context);
|
|
|
ae23c9 |
- }
|
|
|
ae23c9 |
-}
|
|
|
ae23c9 |
-
|
|
|
ae23c9 |
-int block_job_complete_sync(BlockJob *job, Error **errp)
|
|
|
ae23c9 |
-{
|
|
|
ae23c9 |
- return job_finish_sync(&job->job, job_complete, errp);
|
|
|
ae23c9 |
-}
|
|
|
ae23c9 |
-
|
|
|
ae23c9 |
void block_job_progress_update(BlockJob *job, uint64_t done)
|
|
|
ae23c9 |
{
|
|
|
ae23c9 |
job->offset += done;
|
|
|
ae23c9 |
@@ -488,25 +431,6 @@ void *block_job_create(const char *job_id, const BlockJobDriver *driver,
|
|
|
ae23c9 |
return job;
|
|
|
ae23c9 |
}
|
|
|
ae23c9 |
|
|
|
ae23c9 |
-void block_job_completed(BlockJob *job, int ret)
|
|
|
ae23c9 |
-{
|
|
|
ae23c9 |
- assert(job && job->job.txn && !job_is_completed(&job->job));
|
|
|
ae23c9 |
- assert(blk_bs(job->blk)->job == job);
|
|
|
ae23c9 |
- job->job.ret = ret;
|
|
|
ae23c9 |
- job_update_rc(&job->job);
|
|
|
ae23c9 |
- trace_block_job_completed(job, ret, job->job.ret);
|
|
|
ae23c9 |
- if (job->job.ret) {
|
|
|
ae23c9 |
- job_completed_txn_abort(&job->job);
|
|
|
ae23c9 |
- } else {
|
|
|
ae23c9 |
- job_completed_txn_success(&job->job);
|
|
|
ae23c9 |
- }
|
|
|
ae23c9 |
-}
|
|
|
ae23c9 |
-
|
|
|
ae23c9 |
-void block_job_enter(BlockJob *job)
|
|
|
ae23c9 |
-{
|
|
|
ae23c9 |
- job_enter_cond(&job->job, NULL);
|
|
|
ae23c9 |
-}
|
|
|
ae23c9 |
-
|
|
|
ae23c9 |
void block_job_yield(BlockJob *job)
|
|
|
ae23c9 |
{
|
|
|
ae23c9 |
assert(job->job.busy);
|
|
|
ae23c9 |
diff --git a/include/block/blockjob.h b/include/block/blockjob.h
|
|
|
ae23c9 |
index 09e6bb4..e9ed7b8 100644
|
|
|
ae23c9 |
--- a/include/block/blockjob.h
|
|
|
ae23c9 |
+++ b/include/block/blockjob.h
|
|
|
ae23c9 |
@@ -141,15 +141,6 @@ void block_job_remove_all_bdrv(BlockJob *job);
|
|
|
ae23c9 |
void block_job_set_speed(BlockJob *job, int64_t speed, Error **errp);
|
|
|
ae23c9 |
|
|
|
ae23c9 |
/**
|
|
|
ae23c9 |
- * block_job_cancel:
|
|
|
ae23c9 |
- * @job: The job to be canceled.
|
|
|
ae23c9 |
- * @force: Quit a job without waiting for data to be in sync.
|
|
|
ae23c9 |
- *
|
|
|
ae23c9 |
- * Asynchronously cancel the specified job.
|
|
|
ae23c9 |
- */
|
|
|
ae23c9 |
-void block_job_cancel(BlockJob *job, bool force);
|
|
|
ae23c9 |
-
|
|
|
ae23c9 |
-/**
|
|
|
ae23c9 |
* block_job_dismiss:
|
|
|
ae23c9 |
* @job: The job to be dismissed.
|
|
|
ae23c9 |
* @errp: Error object.
|
|
|
ae23c9 |
@@ -186,52 +177,6 @@ void block_job_progress_set_remaining(BlockJob *job, uint64_t remaining);
|
|
|
ae23c9 |
BlockJobInfo *block_job_query(BlockJob *job, Error **errp);
|
|
|
ae23c9 |
|
|
|
ae23c9 |
/**
|
|
|
ae23c9 |
- * block_job_user_cancel:
|
|
|
ae23c9 |
- * @job: The job to be cancelled.
|
|
|
ae23c9 |
- * @force: Quit a job without waiting for data to be in sync.
|
|
|
ae23c9 |
- *
|
|
|
ae23c9 |
- * Cancels the specified job, but may refuse to do so if the
|
|
|
ae23c9 |
- * operation isn't currently meaningful.
|
|
|
ae23c9 |
- */
|
|
|
ae23c9 |
-void block_job_user_cancel(BlockJob *job, bool force, Error **errp);
|
|
|
ae23c9 |
-
|
|
|
ae23c9 |
-/**
|
|
|
ae23c9 |
- * block_job_cancel_sync:
|
|
|
ae23c9 |
- * @job: The job to be canceled.
|
|
|
ae23c9 |
- *
|
|
|
ae23c9 |
- * Synchronously cancel the job. The completion callback is called
|
|
|
ae23c9 |
- * before the function returns. The job may actually complete
|
|
|
ae23c9 |
- * instead of canceling itself; the circumstances under which this
|
|
|
ae23c9 |
- * happens depend on the kind of job that is active.
|
|
|
ae23c9 |
- *
|
|
|
ae23c9 |
- * Returns the return value from the job if the job actually completed
|
|
|
ae23c9 |
- * during the call, or -ECANCELED if it was canceled.
|
|
|
ae23c9 |
- */
|
|
|
ae23c9 |
-int block_job_cancel_sync(BlockJob *job);
|
|
|
ae23c9 |
-
|
|
|
ae23c9 |
-/**
|
|
|
ae23c9 |
- * block_job_cancel_sync_all:
|
|
|
ae23c9 |
- *
|
|
|
ae23c9 |
- * Synchronously cancels all jobs using block_job_cancel_sync().
|
|
|
ae23c9 |
- */
|
|
|
ae23c9 |
-void block_job_cancel_sync_all(void);
|
|
|
ae23c9 |
-
|
|
|
ae23c9 |
-/**
|
|
|
ae23c9 |
- * block_job_complete_sync:
|
|
|
ae23c9 |
- * @job: The job to be completed.
|
|
|
ae23c9 |
- * @errp: Error object which may be set by block_job_complete(); this is not
|
|
|
ae23c9 |
- * necessarily set on every error, the job return value has to be
|
|
|
ae23c9 |
- * checked as well.
|
|
|
ae23c9 |
- *
|
|
|
ae23c9 |
- * Synchronously complete the job. The completion callback is called before the
|
|
|
ae23c9 |
- * function returns, unless it is NULL (which is permissible when using this
|
|
|
ae23c9 |
- * function).
|
|
|
ae23c9 |
- *
|
|
|
ae23c9 |
- * Returns the return value from the job.
|
|
|
ae23c9 |
- */
|
|
|
ae23c9 |
-int block_job_complete_sync(BlockJob *job, Error **errp);
|
|
|
ae23c9 |
-
|
|
|
ae23c9 |
-/**
|
|
|
ae23c9 |
* block_job_iostatus_reset:
|
|
|
ae23c9 |
* @job: The job whose I/O status should be reset.
|
|
|
ae23c9 |
*
|
|
|
ae23c9 |
diff --git a/include/block/blockjob_int.h b/include/block/blockjob_int.h
|
|
|
ae23c9 |
index 29a2802..7df07b2 100644
|
|
|
ae23c9 |
--- a/include/block/blockjob_int.h
|
|
|
ae23c9 |
+++ b/include/block/blockjob_int.h
|
|
|
ae23c9 |
@@ -124,24 +124,6 @@ void block_job_yield(BlockJob *job);
|
|
|
ae23c9 |
int64_t block_job_ratelimit_get_delay(BlockJob *job, uint64_t n);
|
|
|
ae23c9 |
|
|
|
ae23c9 |
/**
|
|
|
ae23c9 |
- * block_job_completed:
|
|
|
ae23c9 |
- * @job: The job being completed.
|
|
|
ae23c9 |
- * @ret: The status code.
|
|
|
ae23c9 |
- *
|
|
|
ae23c9 |
- * Call the completion function that was registered at creation time, and
|
|
|
ae23c9 |
- * free @job.
|
|
|
ae23c9 |
- */
|
|
|
ae23c9 |
-void block_job_completed(BlockJob *job, int ret);
|
|
|
ae23c9 |
-
|
|
|
ae23c9 |
-/**
|
|
|
ae23c9 |
- * block_job_enter:
|
|
|
ae23c9 |
- * @job: The job to enter.
|
|
|
ae23c9 |
- *
|
|
|
ae23c9 |
- * Continue the specified job by entering the coroutine.
|
|
|
ae23c9 |
- */
|
|
|
ae23c9 |
-void block_job_enter(BlockJob *job);
|
|
|
ae23c9 |
-
|
|
|
ae23c9 |
-/**
|
|
|
ae23c9 |
* block_job_event_ready:
|
|
|
ae23c9 |
* @job: The job which is now ready to be completed.
|
|
|
ae23c9 |
*
|
|
|
ae23c9 |
diff --git a/include/qemu/job.h b/include/qemu/job.h
|
|
|
ae23c9 |
index 39d74ab..bbe1b0c 100644
|
|
|
ae23c9 |
--- a/include/qemu/job.h
|
|
|
ae23c9 |
+++ b/include/qemu/job.h
|
|
|
ae23c9 |
@@ -74,8 +74,8 @@ typedef struct Job {
|
|
|
ae23c9 |
|
|
|
ae23c9 |
/**
|
|
|
ae23c9 |
* Set to false by the job while the coroutine has yielded and may be
|
|
|
ae23c9 |
- * re-entered by block_job_enter(). There may still be I/O or event loop
|
|
|
ae23c9 |
- * activity pending. Accessed under block_job_mutex (in blockjob.c).
|
|
|
ae23c9 |
+ * re-entered by job_enter(). There may still be I/O or event loop activity
|
|
|
ae23c9 |
+ * pending. Accessed under block_job_mutex (in blockjob.c).
|
|
|
ae23c9 |
*/
|
|
|
ae23c9 |
bool busy;
|
|
|
ae23c9 |
|
|
|
ae23c9 |
@@ -114,7 +114,7 @@ typedef struct Job {
|
|
|
ae23c9 |
/** True if this job should automatically dismiss itself */
|
|
|
ae23c9 |
bool auto_dismiss;
|
|
|
ae23c9 |
|
|
|
ae23c9 |
- /** ret code passed to block_job_completed. */
|
|
|
ae23c9 |
+ /** ret code passed to job_completed. */
|
|
|
ae23c9 |
int ret;
|
|
|
ae23c9 |
|
|
|
ae23c9 |
/** The completion function that will be called when the job completes. */
|
|
|
ae23c9 |
@@ -266,8 +266,8 @@ void job_txn_unref(JobTxn *txn);
|
|
|
ae23c9 |
* @job: Job to add to the transaction
|
|
|
ae23c9 |
*
|
|
|
ae23c9 |
* Add @job to the transaction. The @job must not already be in a transaction.
|
|
|
ae23c9 |
- * The caller must call either job_txn_unref() or block_job_completed() to
|
|
|
ae23c9 |
- * release the reference that is automatically grabbed here.
|
|
|
ae23c9 |
+ * The caller must call either job_txn_unref() or job_completed() to release
|
|
|
ae23c9 |
+ * the reference that is automatically grabbed here.
|
|
|
ae23c9 |
*
|
|
|
ae23c9 |
* If @txn is NULL, the function does nothing.
|
|
|
ae23c9 |
*/
|
|
|
ae23c9 |
@@ -416,8 +416,59 @@ int job_apply_verb(Job *job, JobVerb verb, Error **errp);
|
|
|
ae23c9 |
/** The @job could not be started, free it. */
|
|
|
ae23c9 |
void job_early_fail(Job *job);
|
|
|
ae23c9 |
|
|
|
ae23c9 |
+/**
|
|
|
ae23c9 |
+ * @job: The job being completed.
|
|
|
ae23c9 |
+ * @ret: The status code.
|
|
|
ae23c9 |
+ *
|
|
|
ae23c9 |
+ * Marks @job as completed. If @ret is non-zero, the job transaction it is part
|
|
|
ae23c9 |
+ * of is aborted. If @ret is zero, the job moves into the WAITING state. If it
|
|
|
ae23c9 |
+ * is the last job to complete in its transaction, all jobs in the transaction
|
|
|
ae23c9 |
+ * move from WAITING to PENDING.
|
|
|
ae23c9 |
+ */
|
|
|
ae23c9 |
+void job_completed(Job *job, int ret);
|
|
|
ae23c9 |
+
|
|
|
ae23c9 |
/** Asynchronously complete the specified @job. */
|
|
|
ae23c9 |
-void job_complete(Job *job, Error **errp);;
|
|
|
ae23c9 |
+void job_complete(Job *job, Error **errp);
|
|
|
ae23c9 |
+
|
|
|
ae23c9 |
+/**
|
|
|
ae23c9 |
+ * Asynchronously cancel the specified @job. If @force is true, the job should
|
|
|
ae23c9 |
+ * be cancelled immediately without waiting for a consistent state.
|
|
|
ae23c9 |
+ */
|
|
|
ae23c9 |
+void job_cancel(Job *job, bool force);
|
|
|
ae23c9 |
+
|
|
|
ae23c9 |
+/**
|
|
|
ae23c9 |
+ * Cancels the specified job like job_cancel(), but may refuse to do so if the
|
|
|
ae23c9 |
+ * operation isn't meaningful in the current state of the job.
|
|
|
ae23c9 |
+ */
|
|
|
ae23c9 |
+void job_user_cancel(Job *job, bool force, Error **errp);
|
|
|
ae23c9 |
+
|
|
|
ae23c9 |
+/**
|
|
|
ae23c9 |
+ * Synchronously cancel the @job. The completion callback is called
|
|
|
ae23c9 |
+ * before the function returns. The job may actually complete
|
|
|
ae23c9 |
+ * instead of canceling itself; the circumstances under which this
|
|
|
ae23c9 |
+ * happens depend on the kind of job that is active.
|
|
|
ae23c9 |
+ *
|
|
|
ae23c9 |
+ * Returns the return value from the job if the job actually completed
|
|
|
ae23c9 |
+ * during the call, or -ECANCELED if it was canceled.
|
|
|
ae23c9 |
+ */
|
|
|
ae23c9 |
+int job_cancel_sync(Job *job);
|
|
|
ae23c9 |
+
|
|
|
ae23c9 |
+/** Synchronously cancels all jobs using job_cancel_sync(). */
|
|
|
ae23c9 |
+void job_cancel_sync_all(void);
|
|
|
ae23c9 |
+
|
|
|
ae23c9 |
+/**
|
|
|
ae23c9 |
+ * @job: The job to be completed.
|
|
|
ae23c9 |
+ * @errp: Error object which may be set by job_complete(); this is not
|
|
|
ae23c9 |
+ * necessarily set on every error, the job return value has to be
|
|
|
ae23c9 |
+ * checked as well.
|
|
|
ae23c9 |
+ *
|
|
|
ae23c9 |
+ * Synchronously complete the job. The completion callback is called before the
|
|
|
ae23c9 |
+ * function returns, unless it is NULL (which is permissible when using this
|
|
|
ae23c9 |
+ * function).
|
|
|
ae23c9 |
+ *
|
|
|
ae23c9 |
+ * Returns the return value from the job.
|
|
|
ae23c9 |
+ */
|
|
|
ae23c9 |
+int job_complete_sync(Job *job, Error **errp);
|
|
|
ae23c9 |
|
|
|
ae23c9 |
/**
|
|
|
ae23c9 |
* For a @job that has finished its work and is pending awaiting explicit
|
|
|
ae23c9 |
@@ -459,11 +510,6 @@ int job_finish_sync(Job *job, void (*finish)(Job *, Error **errp), Error **errp)
|
|
|
ae23c9 |
void job_state_transition(Job *job, JobStatus s1);
|
|
|
ae23c9 |
void coroutine_fn job_do_yield(Job *job, uint64_t ns);
|
|
|
ae23c9 |
bool job_should_pause(Job *job);
|
|
|
ae23c9 |
-bool job_started(Job *job);
|
|
|
ae23c9 |
void job_do_dismiss(Job *job);
|
|
|
ae23c9 |
-void job_update_rc(Job *job);
|
|
|
ae23c9 |
-void job_cancel_async(Job *job, bool force);
|
|
|
ae23c9 |
-void job_completed_txn_abort(Job *job);
|
|
|
ae23c9 |
-void job_completed_txn_success(Job *job);
|
|
|
ae23c9 |
|
|
|
ae23c9 |
#endif
|
|
|
ae23c9 |
diff --git a/job.c b/job.c
|
|
|
ae23c9 |
index 4f6fd73..2e453f6 100644
|
|
|
ae23c9 |
--- a/job.c
|
|
|
ae23c9 |
+++ b/job.c
|
|
|
ae23c9 |
@@ -221,7 +221,7 @@ bool job_is_completed(Job *job)
|
|
|
ae23c9 |
return false;
|
|
|
ae23c9 |
}
|
|
|
ae23c9 |
|
|
|
ae23c9 |
-bool job_started(Job *job)
|
|
|
ae23c9 |
+static bool job_started(Job *job)
|
|
|
ae23c9 |
{
|
|
|
ae23c9 |
return job->co;
|
|
|
ae23c9 |
}
|
|
|
ae23c9 |
@@ -391,10 +391,10 @@ void job_enter(Job *job)
|
|
|
ae23c9 |
}
|
|
|
ae23c9 |
|
|
|
ae23c9 |
/* Yield, and schedule a timer to reenter the coroutine after @ns nanoseconds.
|
|
|
ae23c9 |
- * Reentering the job coroutine with block_job_enter() before the timer has
|
|
|
ae23c9 |
- * expired is allowed and cancels the timer.
|
|
|
ae23c9 |
+ * Reentering the job coroutine with job_enter() before the timer has expired
|
|
|
ae23c9 |
+ * is allowed and cancels the timer.
|
|
|
ae23c9 |
*
|
|
|
ae23c9 |
- * If @ns is (uint64_t) -1, no timer is scheduled and block_job_enter() must be
|
|
|
ae23c9 |
+ * If @ns is (uint64_t) -1, no timer is scheduled and job_enter() must be
|
|
|
ae23c9 |
* called explicitly. */
|
|
|
ae23c9 |
void coroutine_fn job_do_yield(Job *job, uint64_t ns)
|
|
|
ae23c9 |
{
|
|
|
ae23c9 |
@@ -579,7 +579,7 @@ static void job_conclude(Job *job)
|
|
|
ae23c9 |
}
|
|
|
ae23c9 |
}
|
|
|
ae23c9 |
|
|
|
ae23c9 |
-void job_update_rc(Job *job)
|
|
|
ae23c9 |
+static void job_update_rc(Job *job)
|
|
|
ae23c9 |
{
|
|
|
ae23c9 |
if (!job->ret && job_is_cancelled(job)) {
|
|
|
ae23c9 |
job->ret = -ECANCELED;
|
|
|
ae23c9 |
@@ -644,7 +644,7 @@ static int job_finalize_single(Job *job)
|
|
|
ae23c9 |
return 0;
|
|
|
ae23c9 |
}
|
|
|
ae23c9 |
|
|
|
ae23c9 |
-void job_cancel_async(Job *job, bool force)
|
|
|
ae23c9 |
+static void job_cancel_async(Job *job, bool force)
|
|
|
ae23c9 |
{
|
|
|
ae23c9 |
if (job->user_paused) {
|
|
|
ae23c9 |
/* Do not call job_enter here, the caller will handle it. */
|
|
|
ae23c9 |
@@ -660,7 +660,7 @@ void job_cancel_async(Job *job, bool force)
|
|
|
ae23c9 |
job->force_cancel |= force;
|
|
|
ae23c9 |
}
|
|
|
ae23c9 |
|
|
|
ae23c9 |
-void job_completed_txn_abort(Job *job)
|
|
|
ae23c9 |
+static void job_completed_txn_abort(Job *job)
|
|
|
ae23c9 |
{
|
|
|
ae23c9 |
AioContext *ctx;
|
|
|
ae23c9 |
JobTxn *txn = job->txn;
|
|
|
ae23c9 |
@@ -748,7 +748,7 @@ static int job_transition_to_pending(Job *job)
|
|
|
ae23c9 |
return 0;
|
|
|
ae23c9 |
}
|
|
|
ae23c9 |
|
|
|
ae23c9 |
-void job_completed_txn_success(Job *job)
|
|
|
ae23c9 |
+static void job_completed_txn_success(Job *job)
|
|
|
ae23c9 |
{
|
|
|
ae23c9 |
JobTxn *txn = job->txn;
|
|
|
ae23c9 |
Job *other_job;
|
|
|
ae23c9 |
@@ -774,6 +774,74 @@ void job_completed_txn_success(Job *job)
|
|
|
ae23c9 |
}
|
|
|
ae23c9 |
}
|
|
|
ae23c9 |
|
|
|
ae23c9 |
+void job_completed(Job *job, int ret)
|
|
|
ae23c9 |
+{
|
|
|
ae23c9 |
+ assert(job && job->txn && !job_is_completed(job));
|
|
|
ae23c9 |
+ job->ret = ret;
|
|
|
ae23c9 |
+ job_update_rc(job);
|
|
|
ae23c9 |
+ trace_job_completed(job, ret, job->ret);
|
|
|
ae23c9 |
+ if (job->ret) {
|
|
|
ae23c9 |
+ job_completed_txn_abort(job);
|
|
|
ae23c9 |
+ } else {
|
|
|
ae23c9 |
+ job_completed_txn_success(job);
|
|
|
ae23c9 |
+ }
|
|
|
ae23c9 |
+}
|
|
|
ae23c9 |
+
|
|
|
ae23c9 |
+void job_cancel(Job *job, bool force)
|
|
|
ae23c9 |
+{
|
|
|
ae23c9 |
+ if (job->status == JOB_STATUS_CONCLUDED) {
|
|
|
ae23c9 |
+ job_do_dismiss(job);
|
|
|
ae23c9 |
+ return;
|
|
|
ae23c9 |
+ }
|
|
|
ae23c9 |
+ job_cancel_async(job, force);
|
|
|
ae23c9 |
+ if (!job_started(job)) {
|
|
|
ae23c9 |
+ job_completed(job, -ECANCELED);
|
|
|
ae23c9 |
+ } else if (job->deferred_to_main_loop) {
|
|
|
ae23c9 |
+ job_completed_txn_abort(job);
|
|
|
ae23c9 |
+ } else {
|
|
|
ae23c9 |
+ job_enter(job);
|
|
|
ae23c9 |
+ }
|
|
|
ae23c9 |
+}
|
|
|
ae23c9 |
+
|
|
|
ae23c9 |
+void job_user_cancel(Job *job, bool force, Error **errp)
|
|
|
ae23c9 |
+{
|
|
|
ae23c9 |
+ if (job_apply_verb(job, JOB_VERB_CANCEL, errp)) {
|
|
|
ae23c9 |
+ return;
|
|
|
ae23c9 |
+ }
|
|
|
ae23c9 |
+ job_cancel(job, force);
|
|
|
ae23c9 |
+}
|
|
|
ae23c9 |
+
|
|
|
ae23c9 |
+/* A wrapper around job_cancel() taking an Error ** parameter so it may be
|
|
|
ae23c9 |
+ * used with job_finish_sync() without the need for (rather nasty) function
|
|
|
ae23c9 |
+ * pointer casts there. */
|
|
|
ae23c9 |
+static void job_cancel_err(Job *job, Error **errp)
|
|
|
ae23c9 |
+{
|
|
|
ae23c9 |
+ job_cancel(job, false);
|
|
|
ae23c9 |
+}
|
|
|
ae23c9 |
+
|
|
|
ae23c9 |
+int job_cancel_sync(Job *job)
|
|
|
ae23c9 |
+{
|
|
|
ae23c9 |
+ return job_finish_sync(job, &job_cancel_err, NULL);
|
|
|
ae23c9 |
+}
|
|
|
ae23c9 |
+
|
|
|
ae23c9 |
+void job_cancel_sync_all(void)
|
|
|
ae23c9 |
+{
|
|
|
ae23c9 |
+ Job *job;
|
|
|
ae23c9 |
+ AioContext *aio_context;
|
|
|
ae23c9 |
+
|
|
|
ae23c9 |
+ while ((job = job_next(NULL))) {
|
|
|
ae23c9 |
+ aio_context = job->aio_context;
|
|
|
ae23c9 |
+ aio_context_acquire(aio_context);
|
|
|
ae23c9 |
+ job_cancel_sync(job);
|
|
|
ae23c9 |
+ aio_context_release(aio_context);
|
|
|
ae23c9 |
+ }
|
|
|
ae23c9 |
+}
|
|
|
ae23c9 |
+
|
|
|
ae23c9 |
+int job_complete_sync(Job *job, Error **errp)
|
|
|
ae23c9 |
+{
|
|
|
ae23c9 |
+ return job_finish_sync(job, job_complete, errp);
|
|
|
ae23c9 |
+}
|
|
|
ae23c9 |
+
|
|
|
ae23c9 |
void job_complete(Job *job, Error **errp)
|
|
|
ae23c9 |
{
|
|
|
ae23c9 |
/* Should not be reachable via external interface for internal jobs */
|
|
|
ae23c9 |
diff --git a/qemu-img.c b/qemu-img.c
|
|
|
ae23c9 |
index 91b3151..734ea94 100644
|
|
|
ae23c9 |
--- a/qemu-img.c
|
|
|
ae23c9 |
+++ b/qemu-img.c
|
|
|
ae23c9 |
@@ -881,7 +881,7 @@ static void run_block_job(BlockJob *job, Error **errp)
|
|
|
ae23c9 |
} while (!job->ready && !job_is_completed(&job->job));
|
|
|
ae23c9 |
|
|
|
ae23c9 |
if (!job_is_completed(&job->job)) {
|
|
|
ae23c9 |
- ret = block_job_complete_sync(job, errp);
|
|
|
ae23c9 |
+ ret = job_complete_sync(&job->job, errp);
|
|
|
ae23c9 |
} else {
|
|
|
ae23c9 |
ret = job->job.ret;
|
|
|
ae23c9 |
}
|
|
|
ae23c9 |
diff --git a/tests/test-bdrv-drain.c b/tests/test-bdrv-drain.c
|
|
|
ae23c9 |
index b428aac..3600ffd 100644
|
|
|
ae23c9 |
--- a/tests/test-bdrv-drain.c
|
|
|
ae23c9 |
+++ b/tests/test-bdrv-drain.c
|
|
|
ae23c9 |
@@ -498,8 +498,7 @@ typedef struct TestBlockJob {
|
|
|
ae23c9 |
|
|
|
ae23c9 |
static void test_job_completed(Job *job, void *opaque)
|
|
|
ae23c9 |
{
|
|
|
ae23c9 |
- BlockJob *bjob = container_of(job, BlockJob, job);
|
|
|
ae23c9 |
- block_job_completed(bjob, 0);
|
|
|
ae23c9 |
+ job_completed(job, 0);
|
|
|
ae23c9 |
}
|
|
|
ae23c9 |
|
|
|
ae23c9 |
static void coroutine_fn test_job_start(void *opaque)
|
|
|
ae23c9 |
@@ -593,7 +592,7 @@ static void test_blockjob_common(enum drain_type drain_type)
|
|
|
ae23c9 |
g_assert_false(job->job.paused);
|
|
|
ae23c9 |
g_assert_false(job->job.busy); /* We're in job_sleep_ns() */
|
|
|
ae23c9 |
|
|
|
ae23c9 |
- ret = block_job_complete_sync(job, &error_abort);
|
|
|
ae23c9 |
+ ret = job_complete_sync(&job->job, &error_abort);
|
|
|
ae23c9 |
g_assert_cmpint(ret, ==, 0);
|
|
|
ae23c9 |
|
|
|
ae23c9 |
blk_unref(blk_src);
|
|
|
ae23c9 |
diff --git a/tests/test-blockjob-txn.c b/tests/test-blockjob-txn.c
|
|
|
ae23c9 |
index 6ee31d5..34ee179 100644
|
|
|
ae23c9 |
--- a/tests/test-blockjob-txn.c
|
|
|
ae23c9 |
+++ b/tests/test-blockjob-txn.c
|
|
|
ae23c9 |
@@ -34,7 +34,7 @@ static void test_block_job_complete(Job *job, void *opaque)
|
|
|
ae23c9 |
rc = -ECANCELED;
|
|
|
ae23c9 |
}
|
|
|
ae23c9 |
|
|
|
ae23c9 |
- block_job_completed(bjob, rc);
|
|
|
ae23c9 |
+ job_completed(job, rc);
|
|
|
ae23c9 |
bdrv_unref(bs);
|
|
|
ae23c9 |
}
|
|
|
ae23c9 |
|
|
|
ae23c9 |
@@ -130,7 +130,7 @@ static void test_single_job(int expected)
|
|
|
ae23c9 |
job_start(&job->job);
|
|
|
ae23c9 |
|
|
|
ae23c9 |
if (expected == -ECANCELED) {
|
|
|
ae23c9 |
- block_job_cancel(job, false);
|
|
|
ae23c9 |
+ job_cancel(&job->job, false);
|
|
|
ae23c9 |
}
|
|
|
ae23c9 |
|
|
|
ae23c9 |
while (result == -EINPROGRESS) {
|
|
|
ae23c9 |
@@ -176,10 +176,10 @@ static void test_pair_jobs(int expected1, int expected2)
|
|
|
ae23c9 |
job_txn_unref(txn);
|
|
|
ae23c9 |
|
|
|
ae23c9 |
if (expected1 == -ECANCELED) {
|
|
|
ae23c9 |
- block_job_cancel(job1, false);
|
|
|
ae23c9 |
+ job_cancel(&job1->job, false);
|
|
|
ae23c9 |
}
|
|
|
ae23c9 |
if (expected2 == -ECANCELED) {
|
|
|
ae23c9 |
- block_job_cancel(job2, false);
|
|
|
ae23c9 |
+ job_cancel(&job2->job, false);
|
|
|
ae23c9 |
}
|
|
|
ae23c9 |
|
|
|
ae23c9 |
while (result1 == -EINPROGRESS || result2 == -EINPROGRESS) {
|
|
|
ae23c9 |
@@ -232,13 +232,13 @@ static void test_pair_jobs_fail_cancel_race(void)
|
|
|
ae23c9 |
job_start(&job1->job);
|
|
|
ae23c9 |
job_start(&job2->job);
|
|
|
ae23c9 |
|
|
|
ae23c9 |
- block_job_cancel(job1, false);
|
|
|
ae23c9 |
+ job_cancel(&job1->job, false);
|
|
|
ae23c9 |
|
|
|
ae23c9 |
/* Now make job2 finish before the main loop kicks jobs. This simulates
|
|
|
ae23c9 |
* the race between a pending kick and another job completing.
|
|
|
ae23c9 |
*/
|
|
|
ae23c9 |
- block_job_enter(job2);
|
|
|
ae23c9 |
- block_job_enter(job2);
|
|
|
ae23c9 |
+ job_enter(&job2->job);
|
|
|
ae23c9 |
+ job_enter(&job2->job);
|
|
|
ae23c9 |
|
|
|
ae23c9 |
while (result1 == -EINPROGRESS || result2 == -EINPROGRESS) {
|
|
|
ae23c9 |
aio_poll(qemu_get_aio_context(), true);
|
|
|
ae23c9 |
diff --git a/tests/test-blockjob.c b/tests/test-blockjob.c
|
|
|
ae23c9 |
index 1e052c2..46a7873 100644
|
|
|
ae23c9 |
--- a/tests/test-blockjob.c
|
|
|
ae23c9 |
+++ b/tests/test-blockjob.c
|
|
|
ae23c9 |
@@ -165,10 +165,9 @@ typedef struct CancelJob {
|
|
|
ae23c9 |
|
|
|
ae23c9 |
static void cancel_job_completed(Job *job, void *opaque)
|
|
|
ae23c9 |
{
|
|
|
ae23c9 |
- BlockJob *bjob = container_of(job, BlockJob, job);
|
|
|
ae23c9 |
CancelJob *s = opaque;
|
|
|
ae23c9 |
s->completed = true;
|
|
|
ae23c9 |
- block_job_completed(bjob, 0);
|
|
|
ae23c9 |
+ job_completed(job, 0);
|
|
|
ae23c9 |
}
|
|
|
ae23c9 |
|
|
|
ae23c9 |
static void cancel_job_complete(Job *job, Error **errp)
|
|
|
ae23c9 |
@@ -232,7 +231,7 @@ static void cancel_common(CancelJob *s)
|
|
|
ae23c9 |
BlockBackend *blk = s->blk;
|
|
|
ae23c9 |
JobStatus sts = job->job.status;
|
|
|
ae23c9 |
|
|
|
ae23c9 |
- block_job_cancel_sync(job);
|
|
|
ae23c9 |
+ job_cancel_sync(&job->job);
|
|
|
ae23c9 |
if (sts != JOB_STATUS_CREATED && sts != JOB_STATUS_CONCLUDED) {
|
|
|
ae23c9 |
BlockJob *dummy = job;
|
|
|
ae23c9 |
block_job_dismiss(&dummy, &error_abort);
|
|
|
ae23c9 |
@@ -275,7 +274,7 @@ static void test_cancel_paused(void)
|
|
|
ae23c9 |
assert(job->job.status == JOB_STATUS_RUNNING);
|
|
|
ae23c9 |
|
|
|
ae23c9 |
job_user_pause(&job->job, &error_abort);
|
|
|
ae23c9 |
- block_job_enter(job);
|
|
|
ae23c9 |
+ job_enter(&job->job);
|
|
|
ae23c9 |
assert(job->job.status == JOB_STATUS_PAUSED);
|
|
|
ae23c9 |
|
|
|
ae23c9 |
cancel_common(s);
|
|
|
ae23c9 |
@@ -292,7 +291,7 @@ static void test_cancel_ready(void)
|
|
|
ae23c9 |
assert(job->job.status == JOB_STATUS_RUNNING);
|
|
|
ae23c9 |
|
|
|
ae23c9 |
s->should_converge = true;
|
|
|
ae23c9 |
- block_job_enter(job);
|
|
|
ae23c9 |
+ job_enter(&job->job);
|
|
|
ae23c9 |
assert(job->job.status == JOB_STATUS_READY);
|
|
|
ae23c9 |
|
|
|
ae23c9 |
cancel_common(s);
|
|
|
ae23c9 |
@@ -309,11 +308,11 @@ static void test_cancel_standby(void)
|
|
|
ae23c9 |
assert(job->job.status == JOB_STATUS_RUNNING);
|
|
|
ae23c9 |
|
|
|
ae23c9 |
s->should_converge = true;
|
|
|
ae23c9 |
- block_job_enter(job);
|
|
|
ae23c9 |
+ job_enter(&job->job);
|
|
|
ae23c9 |
assert(job->job.status == JOB_STATUS_READY);
|
|
|
ae23c9 |
|
|
|
ae23c9 |
job_user_pause(&job->job, &error_abort);
|
|
|
ae23c9 |
- block_job_enter(job);
|
|
|
ae23c9 |
+ job_enter(&job->job);
|
|
|
ae23c9 |
assert(job->job.status == JOB_STATUS_STANDBY);
|
|
|
ae23c9 |
|
|
|
ae23c9 |
cancel_common(s);
|
|
|
ae23c9 |
@@ -330,11 +329,11 @@ static void test_cancel_pending(void)
|
|
|
ae23c9 |
assert(job->job.status == JOB_STATUS_RUNNING);
|
|
|
ae23c9 |
|
|
|
ae23c9 |
s->should_converge = true;
|
|
|
ae23c9 |
- block_job_enter(job);
|
|
|
ae23c9 |
+ job_enter(&job->job);
|
|
|
ae23c9 |
assert(job->job.status == JOB_STATUS_READY);
|
|
|
ae23c9 |
|
|
|
ae23c9 |
job_complete(&job->job, &error_abort);
|
|
|
ae23c9 |
- block_job_enter(job);
|
|
|
ae23c9 |
+ job_enter(&job->job);
|
|
|
ae23c9 |
while (!s->completed) {
|
|
|
ae23c9 |
aio_poll(qemu_get_aio_context(), true);
|
|
|
ae23c9 |
}
|
|
|
ae23c9 |
@@ -354,11 +353,11 @@ static void test_cancel_concluded(void)
|
|
|
ae23c9 |
assert(job->job.status == JOB_STATUS_RUNNING);
|
|
|
ae23c9 |
|
|
|
ae23c9 |
s->should_converge = true;
|
|
|
ae23c9 |
- block_job_enter(job);
|
|
|
ae23c9 |
+ job_enter(&job->job);
|
|
|
ae23c9 |
assert(job->job.status == JOB_STATUS_READY);
|
|
|
ae23c9 |
|
|
|
ae23c9 |
job_complete(&job->job, &error_abort);
|
|
|
ae23c9 |
- block_job_enter(job);
|
|
|
ae23c9 |
+ job_enter(&job->job);
|
|
|
ae23c9 |
while (!s->completed) {
|
|
|
ae23c9 |
aio_poll(qemu_get_aio_context(), true);
|
|
|
ae23c9 |
}
|
|
|
ae23c9 |
diff --git a/trace-events b/trace-events
|
|
|
ae23c9 |
index 2507e13..ef7579a 100644
|
|
|
ae23c9 |
--- a/trace-events
|
|
|
ae23c9 |
+++ b/trace-events
|
|
|
ae23c9 |
@@ -107,6 +107,7 @@ gdbstub_err_checksum_incorrect(uint8_t expected, uint8_t got) "got command packe
|
|
|
ae23c9 |
# job.c
|
|
|
ae23c9 |
job_state_transition(void *job, int ret, const char *legal, const char *s0, const char *s1) "job %p (ret: %d) attempting %s transition (%s-->%s)"
|
|
|
ae23c9 |
job_apply_verb(void *job, const char *state, const char *verb, const char *legal) "job %p in state %s; applying verb %s (%s)"
|
|
|
ae23c9 |
+job_completed(void *job, int ret, int jret) "job %p ret %d corrected ret %d"
|
|
|
ae23c9 |
|
|
|
ae23c9 |
### Guest events, keep at bottom
|
|
|
ae23c9 |
|
|
|
ae23c9 |
--
|
|
|
ae23c9 |
1.8.3.1
|
|
|
ae23c9 |
|