26ba25
From 98c027dc5d49edb499749092d647edd620ca7d68 Mon Sep 17 00:00:00 2001
26ba25
From: John Snow <jsnow@redhat.com>
26ba25
Date: Tue, 25 Sep 2018 22:34:12 +0100
26ba25
Subject: [PATCH 09/28] jobs: utilize job_exit shim
26ba25
26ba25
RH-Author: John Snow <jsnow@redhat.com>
26ba25
Message-id: <20180925223431.24791-7-jsnow@redhat.com>
26ba25
Patchwork-id: 82267
26ba25
O-Subject: [RHEL8/rhel qemu-kvm PATCH 06/25] jobs: utilize job_exit shim
26ba25
Bugzilla: 1632939
26ba25
RH-Acked-by: Jeffrey Cody <jcody@redhat.com>
26ba25
RH-Acked-by: Max Reitz <mreitz@redhat.com>
26ba25
RH-Acked-by: Kevin Wolf <kwolf@redhat.com>
26ba25
26ba25
Utilize the job_exit shim by not calling job_defer_to_main_loop, and
26ba25
where applicable, converting the deferred callback into the job_exit
26ba25
callback.
26ba25
26ba25
This converts backup, stream, create, and the unit tests all at once.
26ba25
Most of these jobs do not see any changes to the order in which they
26ba25
clean up their resources, except the test-blockjob-txn test, which
26ba25
now puts down its bs before job_completed is called.
26ba25
26ba25
This is safe for the same reason the reordering in the mirror job is
26ba25
safe, because job_completed no longer runs under two locks, making
26ba25
the unref safe even if it causes a flush.
26ba25
26ba25
Signed-off-by: John Snow <jsnow@redhat.com>
26ba25
Reviewed-by: Max Reitz <mreitz@redhat.com>
26ba25
Message-id: 20180830015734.19765-7-jsnow@redhat.com
26ba25
Signed-off-by: Max Reitz <mreitz@redhat.com>
26ba25
(cherry picked from commit eb23654dbe43b549ea2a9ebff9d8edf544d34a73)
26ba25
Signed-off-by: John Snow <jsnow@redhat.com>
26ba25
Signed-off-by: Danilo C. L. de Paula <ddepaula@redhat.com>
26ba25
---
26ba25
 block/backup.c            | 16 ----------------
26ba25
 block/create.c            | 14 +++-----------
26ba25
 block/stream.c            | 22 +++++++---------------
26ba25
 tests/test-bdrv-drain.c   |  6 ------
26ba25
 tests/test-blockjob-txn.c | 11 ++---------
26ba25
 tests/test-blockjob.c     | 10 ++++------
26ba25
 6 files changed, 16 insertions(+), 63 deletions(-)
26ba25
26ba25
diff --git a/block/backup.c b/block/backup.c
26ba25
index a5bf699..08a5b74 100644
26ba25
--- a/block/backup.c
26ba25
+++ b/block/backup.c
26ba25
@@ -380,18 +380,6 @@ static BlockErrorAction backup_error_action(BackupBlockJob *job,
26ba25
     }
26ba25
 }
26ba25
 
26ba25
-typedef struct {
26ba25
-    int ret;
26ba25
-} BackupCompleteData;
26ba25
-
26ba25
-static void backup_complete(Job *job, void *opaque)
26ba25
-{
26ba25
-    BackupCompleteData *data = opaque;
26ba25
-
26ba25
-    job_completed(job, data->ret);
26ba25
-    g_free(data);
26ba25
-}
26ba25
-
26ba25
 static bool coroutine_fn yield_and_check(BackupBlockJob *job)
26ba25
 {
26ba25
     uint64_t delay_ns;
26ba25
@@ -483,7 +471,6 @@ static void backup_incremental_init_copy_bitmap(BackupBlockJob *job)
26ba25
 static int coroutine_fn backup_run(Job *opaque_job, Error **errp)
26ba25
 {
26ba25
     BackupBlockJob *job = container_of(opaque_job, BackupBlockJob, common.job);
26ba25
-    BackupCompleteData *data;
26ba25
     BlockDriverState *bs = blk_bs(job->common.blk);
26ba25
     int64_t offset, nb_clusters;
26ba25
     int ret = 0;
26ba25
@@ -584,9 +571,6 @@ static int coroutine_fn backup_run(Job *opaque_job, Error **errp)
26ba25
     qemu_co_rwlock_unlock(&job->flush_rwlock);
26ba25
     hbitmap_free(job->copy_bitmap);
26ba25
 
26ba25
-    data = g_malloc(sizeof(*data));
26ba25
-    data->ret = ret;
26ba25
-    job_defer_to_main_loop(&job->common.job, backup_complete, data);
26ba25
     return ret;
26ba25
 }
26ba25
 
26ba25
diff --git a/block/create.c b/block/create.c
26ba25
index 26a385c..9534121 100644
26ba25
--- a/block/create.c
26ba25
+++ b/block/create.c
26ba25
@@ -34,28 +34,20 @@ typedef struct BlockdevCreateJob {
26ba25
     Job common;
26ba25
     BlockDriver *drv;
26ba25
     BlockdevCreateOptions *opts;
26ba25
-    int ret;
26ba25
 } BlockdevCreateJob;
26ba25
 
26ba25
-static void blockdev_create_complete(Job *job, void *opaque)
26ba25
-{
26ba25
-    BlockdevCreateJob *s = container_of(job, BlockdevCreateJob, common);
26ba25
-
26ba25
-    job_completed(job, s->ret);
26ba25
-}
26ba25
-
26ba25
 static int coroutine_fn blockdev_create_run(Job *job, Error **errp)
26ba25
 {
26ba25
     BlockdevCreateJob *s = container_of(job, BlockdevCreateJob, common);
26ba25
+    int ret;
26ba25
 
26ba25
     job_progress_set_remaining(&s->common, 1);
26ba25
-    s->ret = s->drv->bdrv_co_create(s->opts, errp);
26ba25
+    ret = s->drv->bdrv_co_create(s->opts, errp);
26ba25
     job_progress_update(&s->common, 1);
26ba25
 
26ba25
     qapi_free_BlockdevCreateOptions(s->opts);
26ba25
-    job_defer_to_main_loop(&s->common, blockdev_create_complete, NULL);
26ba25
 
26ba25
-    return s->ret;
26ba25
+    return ret;
26ba25
 }
26ba25
 
26ba25
 static const JobDriver blockdev_create_job_driver = {
26ba25
diff --git a/block/stream.c b/block/stream.c
26ba25
index 26a7753..67e1e72 100644
26ba25
--- a/block/stream.c
26ba25
+++ b/block/stream.c
26ba25
@@ -54,20 +54,16 @@ static int coroutine_fn stream_populate(BlockBackend *blk,
26ba25
     return blk_co_preadv(blk, offset, qiov.size, &qiov, BDRV_REQ_COPY_ON_READ);
26ba25
 }
26ba25
 
26ba25
-typedef struct {
26ba25
-    int ret;
26ba25
-} StreamCompleteData;
26ba25
-
26ba25
-static void stream_complete(Job *job, void *opaque)
26ba25
+static void stream_exit(Job *job)
26ba25
 {
26ba25
     StreamBlockJob *s = container_of(job, StreamBlockJob, common.job);
26ba25
     BlockJob *bjob = &s->common;
26ba25
-    StreamCompleteData *data = opaque;
26ba25
     BlockDriverState *bs = blk_bs(bjob->blk);
26ba25
     BlockDriverState *base = s->base;
26ba25
     Error *local_err = NULL;
26ba25
+    int ret = job->ret;
26ba25
 
26ba25
-    if (!job_is_cancelled(job) && bs->backing && data->ret == 0) {
26ba25
+    if (!job_is_cancelled(job) && bs->backing && ret == 0) {
26ba25
         const char *base_id = NULL, *base_fmt = NULL;
26ba25
         if (base) {
26ba25
             base_id = s->backing_file_str;
26ba25
@@ -75,11 +71,11 @@ static void stream_complete(Job *job, void *opaque)
26ba25
                 base_fmt = base->drv->format_name;
26ba25
             }
26ba25
         }
26ba25
-        data->ret = bdrv_change_backing_file(bs, base_id, base_fmt);
26ba25
+        ret = bdrv_change_backing_file(bs, base_id, base_fmt);
26ba25
         bdrv_set_backing_hd(bs, base, &local_err);
26ba25
         if (local_err) {
26ba25
             error_report_err(local_err);
26ba25
-            data->ret = -EPERM;
26ba25
+            ret = -EPERM;
26ba25
             goto out;
26ba25
         }
26ba25
     }
26ba25
@@ -93,14 +89,12 @@ out:
26ba25
     }
26ba25
 
26ba25
     g_free(s->backing_file_str);
26ba25
-    job_completed(job, data->ret);
26ba25
-    g_free(data);
26ba25
+    job->ret = ret;
26ba25
 }
26ba25
 
26ba25
 static int coroutine_fn stream_run(Job *job, Error **errp)
26ba25
 {
26ba25
     StreamBlockJob *s = container_of(job, StreamBlockJob, common.job);
26ba25
-    StreamCompleteData *data;
26ba25
     BlockBackend *blk = s->common.blk;
26ba25
     BlockDriverState *bs = blk_bs(blk);
26ba25
     BlockDriverState *base = s->base;
26ba25
@@ -203,9 +197,6 @@ static int coroutine_fn stream_run(Job *job, Error **errp)
26ba25
 
26ba25
 out:
26ba25
     /* Modify backing chain and close BDSes in main loop */
26ba25
-    data = g_malloc(sizeof(*data));
26ba25
-    data->ret = ret;
26ba25
-    job_defer_to_main_loop(&s->common.job, stream_complete, data);
26ba25
     return ret;
26ba25
 }
26ba25
 
26ba25
@@ -215,6 +206,7 @@ static const BlockJobDriver stream_job_driver = {
26ba25
         .job_type      = JOB_TYPE_STREAM,
26ba25
         .free          = block_job_free,
26ba25
         .run           = stream_run,
26ba25
+        .exit          = stream_exit,
26ba25
         .user_resume   = block_job_user_resume,
26ba25
         .drain         = block_job_drain,
26ba25
     },
26ba25
diff --git a/tests/test-bdrv-drain.c b/tests/test-bdrv-drain.c
26ba25
index 8937894..403446e 100644
26ba25
--- a/tests/test-bdrv-drain.c
26ba25
+++ b/tests/test-bdrv-drain.c
26ba25
@@ -496,11 +496,6 @@ typedef struct TestBlockJob {
26ba25
     bool should_complete;
26ba25
 } TestBlockJob;
26ba25
 
26ba25
-static void test_job_completed(Job *job, void *opaque)
26ba25
-{
26ba25
-    job_completed(job, 0);
26ba25
-}
26ba25
-
26ba25
 static int coroutine_fn test_job_run(Job *job, Error **errp)
26ba25
 {
26ba25
     TestBlockJob *s = container_of(job, TestBlockJob, common.job);
26ba25
@@ -510,7 +505,6 @@ static int coroutine_fn test_job_run(Job *job, Error **errp)
26ba25
         job_sleep_ns(&s->common.job, 100000);
26ba25
     }
26ba25
 
26ba25
-    job_defer_to_main_loop(&s->common.job, test_job_completed, NULL);
26ba25
     return 0;
26ba25
 }
26ba25
 
26ba25
diff --git a/tests/test-blockjob-txn.c b/tests/test-blockjob-txn.c
26ba25
index 82cedee..ef29f35 100644
26ba25
--- a/tests/test-blockjob-txn.c
26ba25
+++ b/tests/test-blockjob-txn.c
26ba25
@@ -24,17 +24,11 @@ typedef struct {
26ba25
     int *result;
26ba25
 } TestBlockJob;
26ba25
 
26ba25
-static void test_block_job_complete(Job *job, void *opaque)
26ba25
+static void test_block_job_exit(Job *job)
26ba25
 {
26ba25
     BlockJob *bjob = container_of(job, BlockJob, job);
26ba25
     BlockDriverState *bs = blk_bs(bjob->blk);
26ba25
-    int rc = (intptr_t)opaque;
26ba25
 
26ba25
-    if (job_is_cancelled(job)) {
26ba25
-        rc = -ECANCELED;
26ba25
-    }
26ba25
-
26ba25
-    job_completed(job, rc);
26ba25
     bdrv_unref(bs);
26ba25
 }
26ba25
 
26ba25
@@ -54,8 +48,6 @@ static int coroutine_fn test_block_job_run(Job *job, Error **errp)
26ba25
         }
26ba25
     }
26ba25
 
26ba25
-    job_defer_to_main_loop(job, test_block_job_complete,
26ba25
-                           (void *)(intptr_t)s->rc);
26ba25
     return s->rc;
26ba25
 }
26ba25
 
26ba25
@@ -81,6 +73,7 @@ static const BlockJobDriver test_block_job_driver = {
26ba25
         .user_resume   = block_job_user_resume,
26ba25
         .drain         = block_job_drain,
26ba25
         .run           = test_block_job_run,
26ba25
+        .exit          = test_block_job_exit,
26ba25
     },
26ba25
 };
26ba25
 
26ba25
diff --git a/tests/test-blockjob.c b/tests/test-blockjob.c
26ba25
index 408a226..ad4a65b 100644
26ba25
--- a/tests/test-blockjob.c
26ba25
+++ b/tests/test-blockjob.c
26ba25
@@ -163,11 +163,10 @@ typedef struct CancelJob {
26ba25
     bool completed;
26ba25
 } CancelJob;
26ba25
 
26ba25
-static void cancel_job_completed(Job *job, void *opaque)
26ba25
+static void cancel_job_exit(Job *job)
26ba25
 {
26ba25
-    CancelJob *s = opaque;
26ba25
+    CancelJob *s = container_of(job, CancelJob, common.job);
26ba25
     s->completed = true;
26ba25
-    job_completed(job, 0);
26ba25
 }
26ba25
 
26ba25
 static void cancel_job_complete(Job *job, Error **errp)
26ba25
@@ -182,7 +181,7 @@ static int coroutine_fn cancel_job_run(Job *job, Error **errp)
26ba25
 
26ba25
     while (!s->should_complete) {
26ba25
         if (job_is_cancelled(&s->common.job)) {
26ba25
-            goto defer;
26ba25
+            return 0;
26ba25
         }
26ba25
 
26ba25
         if (!job_is_ready(&s->common.job) && s->should_converge) {
26ba25
@@ -192,8 +191,6 @@ static int coroutine_fn cancel_job_run(Job *job, Error **errp)
26ba25
         job_sleep_ns(&s->common.job, 100000);
26ba25
     }
26ba25
 
26ba25
- defer:
26ba25
-    job_defer_to_main_loop(&s->common.job, cancel_job_completed, s);
26ba25
     return 0;
26ba25
 }
26ba25
 
26ba25
@@ -204,6 +201,7 @@ static const BlockJobDriver test_cancel_driver = {
26ba25
         .user_resume   = block_job_user_resume,
26ba25
         .drain         = block_job_drain,
26ba25
         .run           = cancel_job_run,
26ba25
+        .exit          = cancel_job_exit,
26ba25
         .complete      = cancel_job_complete,
26ba25
     },
26ba25
 };
26ba25
-- 
26ba25
1.8.3.1
26ba25