26ba25
From ba0f4624b12b27820e7e59b5e2a6a84f9736533d Mon Sep 17 00:00:00 2001
26ba25
From: Kevin Wolf <kwolf@redhat.com>
26ba25
Date: Tue, 26 Jun 2018 09:48:18 +0200
26ba25
Subject: [PATCH 110/268] job: Add job_drain()
26ba25
26ba25
RH-Author: Kevin Wolf <kwolf@redhat.com>
26ba25
Message-id: <20180626094856.6924-36-kwolf@redhat.com>
26ba25
Patchwork-id: 81119
26ba25
O-Subject: [RHV-7.6 qemu-kvm-rhev PATCH v2 35/73] job: Add job_drain()
26ba25
Bugzilla: 1513543
26ba25
RH-Acked-by: Jeffrey Cody <jcody@redhat.com>
26ba25
RH-Acked-by: Max Reitz <mreitz@redhat.com>
26ba25
RH-Acked-by: Fam Zheng <famz@redhat.com>
26ba25
26ba25
block_job_drain() contains a blk_drain() call which cannot be moved to
26ba25
Job, so add a new JobDriver callback JobDriver.drain which has a common
26ba25
implementation for all BlockJobs. In addition to this we keep the
26ba25
existing BlockJobDriver.drain callback that is called by the common
26ba25
drain implementation for all block jobs.
26ba25
26ba25
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
26ba25
Reviewed-by: Max Reitz <mreitz@redhat.com>
26ba25
(cherry picked from commit b69f777dd9ba992fdd35828a90eefcd88c0ec332)
26ba25
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
26ba25
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
26ba25
---
26ba25
 block/backup.c               |  1 +
26ba25
 block/commit.c               |  1 +
26ba25
 block/mirror.c               |  2 ++
26ba25
 block/stream.c               |  1 +
26ba25
 blockjob.c                   | 20 ++++++++++----------
26ba25
 include/block/blockjob_int.h | 12 ++++++++++++
26ba25
 include/qemu/job.h           | 13 +++++++++++++
26ba25
 job.c                        | 11 +++++++++++
26ba25
 tests/test-bdrv-drain.c      |  1 +
26ba25
 tests/test-blockjob-txn.c    |  1 +
26ba25
 tests/test-blockjob.c        |  2 ++
26ba25
 11 files changed, 55 insertions(+), 10 deletions(-)
26ba25
26ba25
diff --git a/block/backup.c b/block/backup.c
26ba25
index bd31282..ca7d990 100644
26ba25
--- a/block/backup.c
26ba25
+++ b/block/backup.c
26ba25
@@ -529,6 +529,7 @@ static const BlockJobDriver backup_job_driver = {
26ba25
         .job_type               = JOB_TYPE_BACKUP,
26ba25
         .free                   = block_job_free,
26ba25
         .user_resume            = block_job_user_resume,
26ba25
+        .drain                  = block_job_drain,
26ba25
         .start                  = backup_run,
26ba25
         .commit                 = backup_commit,
26ba25
         .abort                  = backup_abort,
26ba25
diff --git a/block/commit.c b/block/commit.c
26ba25
index e53b2d7..02a8af9 100644
26ba25
--- a/block/commit.c
26ba25
+++ b/block/commit.c
26ba25
@@ -221,6 +221,7 @@ static const BlockJobDriver commit_job_driver = {
26ba25
         .job_type      = JOB_TYPE_COMMIT,
26ba25
         .free          = block_job_free,
26ba25
         .user_resume   = block_job_user_resume,
26ba25
+        .drain         = block_job_drain,
26ba25
         .start         = commit_run,
26ba25
     },
26ba25
 };
26ba25
diff --git a/block/mirror.c b/block/mirror.c
26ba25
index c3951d1..a579bd8 100644
26ba25
--- a/block/mirror.c
26ba25
+++ b/block/mirror.c
26ba25
@@ -992,6 +992,7 @@ static const BlockJobDriver mirror_job_driver = {
26ba25
         .job_type               = JOB_TYPE_MIRROR,
26ba25
         .free                   = block_job_free,
26ba25
         .user_resume            = block_job_user_resume,
26ba25
+        .drain                  = block_job_drain,
26ba25
         .start                  = mirror_run,
26ba25
         .pause                  = mirror_pause,
26ba25
     },
26ba25
@@ -1006,6 +1007,7 @@ static const BlockJobDriver commit_active_job_driver = {
26ba25
         .job_type               = JOB_TYPE_COMMIT,
26ba25
         .free                   = block_job_free,
26ba25
         .user_resume            = block_job_user_resume,
26ba25
+        .drain                  = block_job_drain,
26ba25
         .start                  = mirror_run,
26ba25
         .pause                  = mirror_pause,
26ba25
     },
26ba25
diff --git a/block/stream.c b/block/stream.c
26ba25
index eee0253..b996278 100644
26ba25
--- a/block/stream.c
26ba25
+++ b/block/stream.c
26ba25
@@ -215,6 +215,7 @@ static const BlockJobDriver stream_job_driver = {
26ba25
         .free          = block_job_free,
26ba25
         .start         = stream_run,
26ba25
         .user_resume   = block_job_user_resume,
26ba25
+        .drain         = block_job_drain,
26ba25
     },
26ba25
 };
26ba25
 
26ba25
diff --git a/blockjob.c b/blockjob.c
26ba25
index 4cac367..63e1669 100644
26ba25
--- a/blockjob.c
26ba25
+++ b/blockjob.c
26ba25
@@ -169,14 +169,13 @@ static void block_job_attached_aio_context(AioContext *new_context,
26ba25
     job_resume(&job->job);
26ba25
 }
26ba25
 
26ba25
-static void block_job_drain(BlockJob *job)
26ba25
+void block_job_drain(Job *job)
26ba25
 {
26ba25
-    /* If job is !job->job.busy this kicks it into the next pause point. */
26ba25
-    block_job_enter(job);
26ba25
+    BlockJob *bjob = container_of(job, BlockJob, job);
26ba25
 
26ba25
-    blk_drain(job->blk);
26ba25
-    if (job->driver->drain) {
26ba25
-        job->driver->drain(job);
26ba25
+    blk_drain(bjob->blk);
26ba25
+    if (bjob->driver->drain) {
26ba25
+        bjob->driver->drain(bjob);
26ba25
     }
26ba25
 }
26ba25
 
26ba25
@@ -190,7 +189,7 @@ static void block_job_detach_aio_context(void *opaque)
26ba25
     job_pause(&job->job);
26ba25
 
26ba25
     while (!job->job.paused && !job_is_completed(&job->job)) {
26ba25
-        block_job_drain(job);
26ba25
+        job_drain(&job->job);
26ba25
     }
26ba25
 
26ba25
     job->job.aio_context = NULL;
26ba25
@@ -327,11 +326,11 @@ static int block_job_finish_sync(BlockJob *job,
26ba25
         job_unref(&job->job);
26ba25
         return -EBUSY;
26ba25
     }
26ba25
-    /* block_job_drain calls block_job_enter, and it should be enough to
26ba25
-     * induce progress until the job completes or moves to the main thread.
26ba25
+    /* job_drain calls job_enter, and it should be enough to induce progress
26ba25
+     * until the job completes or moves to the main thread.
26ba25
     */
26ba25
     while (!job->job.deferred_to_main_loop && !job_is_completed(&job->job)) {
26ba25
-        block_job_drain(job);
26ba25
+        job_drain(&job->job);
26ba25
     }
26ba25
     while (!job_is_completed(&job->job)) {
26ba25
         aio_poll(qemu_get_aio_context(), true);
26ba25
@@ -713,6 +712,7 @@ void *block_job_create(const char *job_id, const BlockJobDriver *driver,
26ba25
     assert(is_block_job(&job->job));
26ba25
     assert(job->job.driver->free == &block_job_free);
26ba25
     assert(job->job.driver->user_resume == &block_job_user_resume);
26ba25
+    assert(job->job.driver->drain == &block_job_drain);
26ba25
 
26ba25
     job->driver        = driver;
26ba25
     job->blk           = blk;
26ba25
diff --git a/include/block/blockjob_int.h b/include/block/blockjob_int.h
26ba25
index bf2b762..38fe22d 100644
26ba25
--- a/include/block/blockjob_int.h
26ba25
+++ b/include/block/blockjob_int.h
26ba25
@@ -65,6 +65,10 @@ struct BlockJobDriver {
26ba25
      * If the callback is not NULL, it will be invoked when the job has to be
26ba25
      * synchronously cancelled or completed; it should drain BlockDriverStates
26ba25
      * as required to ensure progress.
26ba25
+     *
26ba25
+     * Block jobs must use the default implementation for job_driver.drain,
26ba25
+     * which will in turn call this callback after doing generic block job
26ba25
+     * stuff.
26ba25
      */
26ba25
     void (*drain)(BlockJob *job);
26ba25
 };
26ba25
@@ -112,6 +116,14 @@ void block_job_free(Job *job);
26ba25
 void block_job_user_resume(Job *job);
26ba25
 
26ba25
 /**
26ba25
+ * block_job_drain:
26ba25
+ * Callback to be used for JobDriver.drain in all block jobs. Drains the main
26ba25
+ * block node associated with the block jobs and calls BlockJobDriver.drain for
26ba25
+ * job-specific actions.
26ba25
+ */
26ba25
+void block_job_drain(Job *job);
26ba25
+
26ba25
+/**
26ba25
  * block_job_yield:
26ba25
  * @job: The job that calls the function.
26ba25
  *
26ba25
diff --git a/include/qemu/job.h b/include/qemu/job.h
26ba25
index 2648c74..aebc195 100644
26ba25
--- a/include/qemu/job.h
26ba25
+++ b/include/qemu/job.h
26ba25
@@ -167,6 +167,13 @@ struct JobDriver {
26ba25
      */
26ba25
     void (*user_resume)(Job *job);
26ba25
 
26ba25
+    /*
26ba25
+     * If the callback is not NULL, it will be invoked when the job has to be
26ba25
+     * synchronously cancelled or completed; it should drain any activities
26ba25
+     * as required to ensure progress.
26ba25
+     */
26ba25
+    void (*drain)(Job *job);
26ba25
+
26ba25
     /**
26ba25
      * If the callback is not NULL, it will be invoked when all the jobs
26ba25
      * belonging to the same transaction complete; or upon this job's
26ba25
@@ -325,6 +332,12 @@ bool job_user_paused(Job *job);
26ba25
  */
26ba25
 void job_user_resume(Job *job, Error **errp);
26ba25
 
26ba25
+/*
26ba25
+ * Drain any activities as required to ensure progress. This can be called in a
26ba25
+ * loop to synchronously complete a job.
26ba25
+ */
26ba25
+void job_drain(Job *job);
26ba25
+
26ba25
 /**
26ba25
  * Get the next element from the list of block jobs after @job, or the
26ba25
  * first one if @job is %NULL.
26ba25
diff --git a/job.c b/job.c
26ba25
index 64b64da..3772a35 100644
26ba25
--- a/job.c
26ba25
+++ b/job.c
26ba25
@@ -367,6 +367,17 @@ void coroutine_fn job_sleep_ns(Job *job, int64_t ns)
26ba25
     job_pause_point(job);
26ba25
 }
26ba25
 
26ba25
+void job_drain(Job *job)
26ba25
+{
26ba25
+    /* If job is !busy this kicks it into the next pause point. */
26ba25
+    job_enter(job);
26ba25
+
26ba25
+    if (job->driver->drain) {
26ba25
+        job->driver->drain(job);
26ba25
+    }
26ba25
+}
26ba25
+
26ba25
+
26ba25
 /**
26ba25
  * All jobs must allow a pause point before entering their job proper. This
26ba25
  * ensures that jobs can be paused prior to being started, then resumed later.
26ba25
diff --git a/tests/test-bdrv-drain.c b/tests/test-bdrv-drain.c
26ba25
index c993512..58ea566 100644
26ba25
--- a/tests/test-bdrv-drain.c
26ba25
+++ b/tests/test-bdrv-drain.c
26ba25
@@ -525,6 +525,7 @@ BlockJobDriver test_job_driver = {
26ba25
         .instance_size  = sizeof(TestBlockJob),
26ba25
         .free           = block_job_free,
26ba25
         .user_resume    = block_job_user_resume,
26ba25
+        .drain          = block_job_drain,
26ba25
         .start          = test_job_start,
26ba25
     },
26ba25
     .complete       = test_job_complete,
26ba25
diff --git a/tests/test-blockjob-txn.c b/tests/test-blockjob-txn.c
26ba25
index 60e9fa2..1572f8d 100644
26ba25
--- a/tests/test-blockjob-txn.c
26ba25
+++ b/tests/test-blockjob-txn.c
26ba25
@@ -79,6 +79,7 @@ static const BlockJobDriver test_block_job_driver = {
26ba25
         .instance_size = sizeof(TestBlockJob),
26ba25
         .free          = block_job_free,
26ba25
         .user_resume   = block_job_user_resume,
26ba25
+        .drain         = block_job_drain,
26ba25
         .start         = test_block_job_run,
26ba25
     },
26ba25
 };
26ba25
diff --git a/tests/test-blockjob.c b/tests/test-blockjob.c
26ba25
index 1fe6803..592a136 100644
26ba25
--- a/tests/test-blockjob.c
26ba25
+++ b/tests/test-blockjob.c
26ba25
@@ -21,6 +21,7 @@ static const BlockJobDriver test_block_job_driver = {
26ba25
         .instance_size = sizeof(BlockJob),
26ba25
         .free          = block_job_free,
26ba25
         .user_resume   = block_job_user_resume,
26ba25
+        .drain         = block_job_drain,
26ba25
     },
26ba25
 };
26ba25
 
26ba25
@@ -201,6 +202,7 @@ static const BlockJobDriver test_cancel_driver = {
26ba25
         .instance_size = sizeof(CancelJob),
26ba25
         .free          = block_job_free,
26ba25
         .user_resume   = block_job_user_resume,
26ba25
+        .drain         = block_job_drain,
26ba25
         .start         = cancel_job_start,
26ba25
     },
26ba25
     .complete      = cancel_job_complete,
26ba25
-- 
26ba25
1.8.3.1
26ba25