ae23c9
From 7586908f543ae6e8981ed4bc17b60adec3b7456d Mon Sep 17 00:00:00 2001
ae23c9
From: Kevin Wolf <kwolf@redhat.com>
ae23c9
Date: Tue, 26 Jun 2018 09:48:21 +0200
ae23c9
Subject: [PATCH 113/268] job: Switch transactions to JobTxn
ae23c9
ae23c9
RH-Author: Kevin Wolf <kwolf@redhat.com>
ae23c9
Message-id: <20180626094856.6924-39-kwolf@redhat.com>
ae23c9
Patchwork-id: 81086
ae23c9
O-Subject: [RHV-7.6 qemu-kvm-rhev PATCH v2 38/73] job: Switch transactions to JobTxn
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 doesn't actually move any transaction code to Job yet, but it
ae23c9
renames the type for transactions from BlockJobTxn to JobTxn and makes
ae23c9
them contain Jobs rather than BlockJobs
ae23c9
ae23c9
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
ae23c9
Reviewed-by: Max Reitz <mreitz@redhat.com>
ae23c9
(cherry picked from commit 62c9e4162a7bc26a1389e50d17d3b2637028bbc3)
ae23c9
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
ae23c9
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
ae23c9
---
ae23c9
 block/backup.c               |  2 +-
ae23c9
 blockdev.c                   | 14 +++++------
ae23c9
 blockjob.c                   | 60 +++++++++++++++++++++++---------------------
ae23c9
 include/block/block_int.h    |  2 +-
ae23c9
 include/block/blockjob.h     | 11 ++++----
ae23c9
 include/block/blockjob_int.h |  2 +-
ae23c9
 include/qemu/job.h           |  3 +++
ae23c9
 tests/test-blockjob-txn.c    |  8 +++---
ae23c9
 8 files changed, 54 insertions(+), 48 deletions(-)
ae23c9
ae23c9
diff --git a/block/backup.c b/block/backup.c
ae23c9
index ca7d990..6172f90 100644
ae23c9
--- a/block/backup.c
ae23c9
+++ b/block/backup.c
ae23c9
@@ -547,7 +547,7 @@ BlockJob *backup_job_create(const char *job_id, BlockDriverState *bs,
ae23c9
                   BlockdevOnError on_target_error,
ae23c9
                   int creation_flags,
ae23c9
                   BlockCompletionFunc *cb, void *opaque,
ae23c9
-                  BlockJobTxn *txn, Error **errp)
ae23c9
+                  JobTxn *txn, Error **errp)
ae23c9
 {
ae23c9
     int64_t len;
ae23c9
     BlockDriverInfo bdi;
ae23c9
diff --git a/blockdev.c b/blockdev.c
ae23c9
index dd9a080..6efdb30 100644
ae23c9
--- a/blockdev.c
ae23c9
+++ b/blockdev.c
ae23c9
@@ -1447,7 +1447,7 @@ typedef struct BlkActionOps {
ae23c9
 struct BlkActionState {
ae23c9
     TransactionAction *action;
ae23c9
     const BlkActionOps *ops;
ae23c9
-    BlockJobTxn *block_job_txn;
ae23c9
+    JobTxn *block_job_txn;
ae23c9
     TransactionProperties *txn_props;
ae23c9
     QSIMPLEQ_ENTRY(BlkActionState) entry;
ae23c9
 };
ae23c9
@@ -1865,7 +1865,7 @@ typedef struct DriveBackupState {
ae23c9
     BlockJob *job;
ae23c9
 } DriveBackupState;
ae23c9
 
ae23c9
-static BlockJob *do_drive_backup(DriveBackup *backup, BlockJobTxn *txn,
ae23c9
+static BlockJob *do_drive_backup(DriveBackup *backup, JobTxn *txn,
ae23c9
                             Error **errp);
ae23c9
 
ae23c9
 static void drive_backup_prepare(BlkActionState *common, Error **errp)
ae23c9
@@ -1955,7 +1955,7 @@ typedef struct BlockdevBackupState {
ae23c9
     BlockJob *job;
ae23c9
 } BlockdevBackupState;
ae23c9
 
ae23c9
-static BlockJob *do_blockdev_backup(BlockdevBackup *backup, BlockJobTxn *txn,
ae23c9
+static BlockJob *do_blockdev_backup(BlockdevBackup *backup, JobTxn *txn,
ae23c9
                                     Error **errp);
ae23c9
 
ae23c9
 static void blockdev_backup_prepare(BlkActionState *common, Error **errp)
ae23c9
@@ -2244,7 +2244,7 @@ void qmp_transaction(TransactionActionList *dev_list,
ae23c9
                      Error **errp)
ae23c9
 {
ae23c9
     TransactionActionList *dev_entry = dev_list;
ae23c9
-    BlockJobTxn *block_job_txn = NULL;
ae23c9
+    JobTxn *block_job_txn = NULL;
ae23c9
     BlkActionState *state, *next;
ae23c9
     Error *local_err = NULL;
ae23c9
 
ae23c9
@@ -2252,7 +2252,7 @@ void qmp_transaction(TransactionActionList *dev_list,
ae23c9
     QSIMPLEQ_INIT(&snap_bdrv_states);
ae23c9
 
ae23c9
     /* Does this transaction get canceled as a group on failure?
ae23c9
-     * If not, we don't really need to make a BlockJobTxn.
ae23c9
+     * If not, we don't really need to make a JobTxn.
ae23c9
      */
ae23c9
     props = get_transaction_properties(props);
ae23c9
     if (props->completion_mode != ACTION_COMPLETION_MODE_INDIVIDUAL) {
ae23c9
@@ -3265,7 +3265,7 @@ out:
ae23c9
     aio_context_release(aio_context);
ae23c9
 }
ae23c9
 
ae23c9
-static BlockJob *do_drive_backup(DriveBackup *backup, BlockJobTxn *txn,
ae23c9
+static BlockJob *do_drive_backup(DriveBackup *backup, JobTxn *txn,
ae23c9
                                  Error **errp)
ae23c9
 {
ae23c9
     BlockDriverState *bs;
ae23c9
@@ -3435,7 +3435,7 @@ BlockDeviceInfoList *qmp_query_named_block_nodes(Error **errp)
ae23c9
     return bdrv_named_nodes_list(errp);
ae23c9
 }
ae23c9
 
ae23c9
-BlockJob *do_blockdev_backup(BlockdevBackup *backup, BlockJobTxn *txn,
ae23c9
+BlockJob *do_blockdev_backup(BlockdevBackup *backup, JobTxn *txn,
ae23c9
                              Error **errp)
ae23c9
 {
ae23c9
     BlockDriverState *bs;
ae23c9
diff --git a/blockjob.c b/blockjob.c
ae23c9
index 1ed3e9c..bd35c4f 100644
ae23c9
--- a/blockjob.c
ae23c9
+++ b/blockjob.c
ae23c9
@@ -37,13 +37,13 @@
ae23c9
 #include "qemu/timer.h"
ae23c9
 
ae23c9
 /* Transactional group of block jobs */
ae23c9
-struct BlockJobTxn {
ae23c9
+struct JobTxn {
ae23c9
 
ae23c9
     /* Is this txn being cancelled? */
ae23c9
     bool aborting;
ae23c9
 
ae23c9
     /* List of jobs */
ae23c9
-    QLIST_HEAD(, BlockJob) jobs;
ae23c9
+    QLIST_HEAD(, Job) jobs;
ae23c9
 
ae23c9
     /* Reference count */
ae23c9
     int refcnt;
ae23c9
@@ -94,27 +94,27 @@ BlockJob *block_job_get(const char *id)
ae23c9
     }
ae23c9
 }
ae23c9
 
ae23c9
-BlockJobTxn *block_job_txn_new(void)
ae23c9
+JobTxn *block_job_txn_new(void)
ae23c9
 {
ae23c9
-    BlockJobTxn *txn = g_new0(BlockJobTxn, 1);
ae23c9
+    JobTxn *txn = g_new0(JobTxn, 1);
ae23c9
     QLIST_INIT(&txn->jobs);
ae23c9
     txn->refcnt = 1;
ae23c9
     return txn;
ae23c9
 }
ae23c9
 
ae23c9
-static void block_job_txn_ref(BlockJobTxn *txn)
ae23c9
+static void block_job_txn_ref(JobTxn *txn)
ae23c9
 {
ae23c9
     txn->refcnt++;
ae23c9
 }
ae23c9
 
ae23c9
-void block_job_txn_unref(BlockJobTxn *txn)
ae23c9
+void block_job_txn_unref(JobTxn *txn)
ae23c9
 {
ae23c9
     if (txn && --txn->refcnt == 0) {
ae23c9
         g_free(txn);
ae23c9
     }
ae23c9
 }
ae23c9
 
ae23c9
-void block_job_txn_add_job(BlockJobTxn *txn, BlockJob *job)
ae23c9
+void block_job_txn_add_job(JobTxn *txn, BlockJob *job)
ae23c9
 {
ae23c9
     if (!txn) {
ae23c9
         return;
ae23c9
@@ -123,14 +123,14 @@ void block_job_txn_add_job(BlockJobTxn *txn, BlockJob *job)
ae23c9
     assert(!job->txn);
ae23c9
     job->txn = txn;
ae23c9
 
ae23c9
-    QLIST_INSERT_HEAD(&txn->jobs, job, txn_list);
ae23c9
+    QLIST_INSERT_HEAD(&txn->jobs, &job->job, txn_list);
ae23c9
     block_job_txn_ref(txn);
ae23c9
 }
ae23c9
 
ae23c9
 void block_job_txn_del_job(BlockJob *job)
ae23c9
 {
ae23c9
     if (job->txn) {
ae23c9
-        QLIST_REMOVE(job, txn_list);
ae23c9
+        QLIST_REMOVE(&job->job, txn_list);
ae23c9
         block_job_txn_unref(job->txn);
ae23c9
         job->txn = NULL;
ae23c9
     }
ae23c9
@@ -285,18 +285,22 @@ static void job_cancel_async(Job *job, bool force)
ae23c9
     job->force_cancel |= force;
ae23c9
 }
ae23c9
 
ae23c9
-static int block_job_txn_apply(BlockJobTxn *txn, int fn(BlockJob *), bool lock)
ae23c9
+static int block_job_txn_apply(JobTxn *txn, int fn(BlockJob *), bool lock)
ae23c9
 {
ae23c9
     AioContext *ctx;
ae23c9
-    BlockJob *job, *next;
ae23c9
+    Job *job, *next;
ae23c9
+    BlockJob *bjob;
ae23c9
     int rc = 0;
ae23c9
 
ae23c9
     QLIST_FOREACH_SAFE(job, &txn->jobs, txn_list, next) {
ae23c9
+        assert(is_block_job(job));
ae23c9
+        bjob = container_of(job, BlockJob, job);
ae23c9
+
ae23c9
         if (lock) {
ae23c9
-            ctx = blk_get_aio_context(job->blk);
ae23c9
+            ctx = job->aio_context;
ae23c9
             aio_context_acquire(ctx);
ae23c9
         }
ae23c9
-        rc = fn(job);
ae23c9
+        rc = fn(bjob);
ae23c9
         if (lock) {
ae23c9
             aio_context_release(ctx);
ae23c9
         }
ae23c9
@@ -310,8 +314,8 @@ static int block_job_txn_apply(BlockJobTxn *txn, int fn(BlockJob *), bool lock)
ae23c9
 static void block_job_completed_txn_abort(BlockJob *job)
ae23c9
 {
ae23c9
     AioContext *ctx;
ae23c9
-    BlockJobTxn *txn = job->txn;
ae23c9
-    BlockJob *other_job;
ae23c9
+    JobTxn *txn = job->txn;
ae23c9
+    Job *other_job;
ae23c9
 
ae23c9
     if (txn->aborting) {
ae23c9
         /*
ae23c9
@@ -324,7 +328,7 @@ static void block_job_completed_txn_abort(BlockJob *job)
ae23c9
 
ae23c9
     /* We are the first failed job. Cancel other jobs. */
ae23c9
     QLIST_FOREACH(other_job, &txn->jobs, txn_list) {
ae23c9
-        ctx = blk_get_aio_context(other_job->blk);
ae23c9
+        ctx = other_job->aio_context;
ae23c9
         aio_context_acquire(ctx);
ae23c9
     }
ae23c9
 
ae23c9
@@ -332,18 +336,18 @@ static void block_job_completed_txn_abort(BlockJob *job)
ae23c9
      * them; this job, however, may or may not be cancelled, depending
ae23c9
      * on the caller, so leave it. */
ae23c9
     QLIST_FOREACH(other_job, &txn->jobs, txn_list) {
ae23c9
-        if (other_job != job) {
ae23c9
-            job_cancel_async(&other_job->job, false);
ae23c9
+        if (other_job != &job->job) {
ae23c9
+            job_cancel_async(other_job, false);
ae23c9
         }
ae23c9
     }
ae23c9
     while (!QLIST_EMPTY(&txn->jobs)) {
ae23c9
         other_job = QLIST_FIRST(&txn->jobs);
ae23c9
-        ctx = blk_get_aio_context(other_job->blk);
ae23c9
-        if (!job_is_completed(&other_job->job)) {
ae23c9
-            assert(job_is_cancelled(&other_job->job));
ae23c9
-            job_finish_sync(&other_job->job, NULL, NULL);
ae23c9
+        ctx = other_job->aio_context;
ae23c9
+        if (!job_is_completed(other_job)) {
ae23c9
+            assert(job_is_cancelled(other_job));
ae23c9
+            job_finish_sync(other_job, NULL, NULL);
ae23c9
         }
ae23c9
-        job_finalize_single(&other_job->job);
ae23c9
+        job_finalize_single(other_job);
ae23c9
         aio_context_release(ctx);
ae23c9
     }
ae23c9
 
ae23c9
@@ -385,8 +389,8 @@ static int block_job_transition_to_pending(BlockJob *job)
ae23c9
 
ae23c9
 static void block_job_completed_txn_success(BlockJob *job)
ae23c9
 {
ae23c9
-    BlockJobTxn *txn = job->txn;
ae23c9
-    BlockJob *other_job;
ae23c9
+    JobTxn *txn = job->txn;
ae23c9
+    Job *other_job;
ae23c9
 
ae23c9
     job_state_transition(&job->job, JOB_STATUS_WAITING);
ae23c9
 
ae23c9
@@ -395,10 +399,10 @@ static void block_job_completed_txn_success(BlockJob *job)
ae23c9
      * txn.
ae23c9
      */
ae23c9
     QLIST_FOREACH(other_job, &txn->jobs, txn_list) {
ae23c9
-        if (!job_is_completed(&other_job->job)) {
ae23c9
+        if (!job_is_completed(other_job)) {
ae23c9
             return;
ae23c9
         }
ae23c9
-        assert(other_job->job.ret == 0);
ae23c9
+        assert(other_job->ret == 0);
ae23c9
     }
ae23c9
 
ae23c9
     block_job_txn_apply(txn, block_job_transition_to_pending, false);
ae23c9
@@ -628,7 +632,7 @@ static void block_job_event_pending(Notifier *n, void *opaque)
ae23c9
  */
ae23c9
 
ae23c9
 void *block_job_create(const char *job_id, const BlockJobDriver *driver,
ae23c9
-                       BlockJobTxn *txn, BlockDriverState *bs, uint64_t perm,
ae23c9
+                       JobTxn *txn, BlockDriverState *bs, uint64_t perm,
ae23c9
                        uint64_t shared_perm, int64_t speed, int flags,
ae23c9
                        BlockCompletionFunc *cb, void *opaque, Error **errp)
ae23c9
 {
ae23c9
diff --git a/include/block/block_int.h b/include/block/block_int.h
ae23c9
index d913ed1..ad2b852 100644
ae23c9
--- a/include/block/block_int.h
ae23c9
+++ b/include/block/block_int.h
ae23c9
@@ -1018,7 +1018,7 @@ BlockJob *backup_job_create(const char *job_id, BlockDriverState *bs,
ae23c9
                             BlockdevOnError on_target_error,
ae23c9
                             int creation_flags,
ae23c9
                             BlockCompletionFunc *cb, void *opaque,
ae23c9
-                            BlockJobTxn *txn, Error **errp);
ae23c9
+                            JobTxn *txn, Error **errp);
ae23c9
 
ae23c9
 void hmp_drive_add_node(Monitor *mon, const char *optstr);
ae23c9
 
ae23c9
diff --git a/include/block/blockjob.h b/include/block/blockjob.h
ae23c9
index 85ce18a..44df025 100644
ae23c9
--- a/include/block/blockjob.h
ae23c9
+++ b/include/block/blockjob.h
ae23c9
@@ -33,7 +33,7 @@
ae23c9
 #define BLOCK_JOB_SLICE_TIME 100000000ULL /* ns */
ae23c9
 
ae23c9
 typedef struct BlockJobDriver BlockJobDriver;
ae23c9
-typedef struct BlockJobTxn BlockJobTxn;
ae23c9
+typedef struct JobTxn JobTxn;
ae23c9
 
ae23c9
 /**
ae23c9
  * BlockJob:
ae23c9
@@ -85,8 +85,7 @@ typedef struct BlockJob {
ae23c9
     /** BlockDriverStates that are involved in this block job */
ae23c9
     GSList *nodes;
ae23c9
 
ae23c9
-    BlockJobTxn *txn;
ae23c9
-    QLIST_ENTRY(BlockJob) txn_list;
ae23c9
+    JobTxn *txn;
ae23c9
 } BlockJob;
ae23c9
 
ae23c9
 /**
ae23c9
@@ -273,7 +272,7 @@ void block_job_iostatus_reset(BlockJob *job);
ae23c9
  * group.  Jobs wait for each other before completing.  Cancelling one job
ae23c9
  * cancels all jobs in the transaction.
ae23c9
  */
ae23c9
-BlockJobTxn *block_job_txn_new(void);
ae23c9
+JobTxn *block_job_txn_new(void);
ae23c9
 
ae23c9
 /**
ae23c9
  * block_job_txn_unref:
ae23c9
@@ -282,7 +281,7 @@ BlockJobTxn *block_job_txn_new(void);
ae23c9
  * or block_job_txn_new. If it's the last reference to the object, it will be
ae23c9
  * freed.
ae23c9
  */
ae23c9
-void block_job_txn_unref(BlockJobTxn *txn);
ae23c9
+void block_job_txn_unref(JobTxn *txn);
ae23c9
 
ae23c9
 /**
ae23c9
  * block_job_txn_add_job:
ae23c9
@@ -293,7 +292,7 @@ void block_job_txn_unref(BlockJobTxn *txn);
ae23c9
  * The caller must call either block_job_txn_unref() or block_job_completed()
ae23c9
  * to release the reference that is automatically grabbed here.
ae23c9
  */
ae23c9
-void block_job_txn_add_job(BlockJobTxn *txn, BlockJob *job);
ae23c9
+void block_job_txn_add_job(JobTxn *txn, BlockJob *job);
ae23c9
 
ae23c9
 /**
ae23c9
  * block_job_is_internal:
ae23c9
diff --git a/include/block/blockjob_int.h b/include/block/blockjob_int.h
ae23c9
index b8ca7bb..ce66a9b 100644
ae23c9
--- a/include/block/blockjob_int.h
ae23c9
+++ b/include/block/blockjob_int.h
ae23c9
@@ -91,7 +91,7 @@ struct BlockJobDriver {
ae23c9
  * called from a wrapper that is specific to the job type.
ae23c9
  */
ae23c9
 void *block_job_create(const char *job_id, const BlockJobDriver *driver,
ae23c9
-                       BlockJobTxn *txn, BlockDriverState *bs, uint64_t perm,
ae23c9
+                       JobTxn *txn, BlockDriverState *bs, uint64_t perm,
ae23c9
                        uint64_t shared_perm, int64_t speed, int flags,
ae23c9
                        BlockCompletionFunc *cb, void *opaque, Error **errp);
ae23c9
 
ae23c9
diff --git a/include/qemu/job.h b/include/qemu/job.h
ae23c9
index 17e2cec..d4aa7fa 100644
ae23c9
--- a/include/qemu/job.h
ae23c9
+++ b/include/qemu/job.h
ae23c9
@@ -132,6 +132,9 @@ typedef struct Job {
ae23c9
 
ae23c9
     /** Element of the list of jobs */
ae23c9
     QLIST_ENTRY(Job) job_list;
ae23c9
+
ae23c9
+    /** Element of the list of jobs in a job transaction */
ae23c9
+    QLIST_ENTRY(Job) txn_list;
ae23c9
 } Job;
ae23c9
 
ae23c9
 /**
ae23c9
diff --git a/tests/test-blockjob-txn.c b/tests/test-blockjob-txn.c
ae23c9
index 1572f8d..ec5d592 100644
ae23c9
--- a/tests/test-blockjob-txn.c
ae23c9
+++ b/tests/test-blockjob-txn.c
ae23c9
@@ -93,7 +93,7 @@ static const BlockJobDriver test_block_job_driver = {
ae23c9
  */
ae23c9
 static BlockJob *test_block_job_start(unsigned int iterations,
ae23c9
                                       bool use_timer,
ae23c9
-                                      int rc, int *result, BlockJobTxn *txn)
ae23c9
+                                      int rc, int *result, JobTxn *txn)
ae23c9
 {
ae23c9
     BlockDriverState *bs;
ae23c9
     TestBlockJob *s;
ae23c9
@@ -122,7 +122,7 @@ static BlockJob *test_block_job_start(unsigned int iterations,
ae23c9
 static void test_single_job(int expected)
ae23c9
 {
ae23c9
     BlockJob *job;
ae23c9
-    BlockJobTxn *txn;
ae23c9
+    JobTxn *txn;
ae23c9
     int result = -EINPROGRESS;
ae23c9
 
ae23c9
     txn = block_job_txn_new();
ae23c9
@@ -160,7 +160,7 @@ static void test_pair_jobs(int expected1, int expected2)
ae23c9
 {
ae23c9
     BlockJob *job1;
ae23c9
     BlockJob *job2;
ae23c9
-    BlockJobTxn *txn;
ae23c9
+    JobTxn *txn;
ae23c9
     int result1 = -EINPROGRESS;
ae23c9
     int result2 = -EINPROGRESS;
ae23c9
 
ae23c9
@@ -222,7 +222,7 @@ static void test_pair_jobs_fail_cancel_race(void)
ae23c9
 {
ae23c9
     BlockJob *job1;
ae23c9
     BlockJob *job2;
ae23c9
-    BlockJobTxn *txn;
ae23c9
+    JobTxn *txn;
ae23c9
     int result1 = -EINPROGRESS;
ae23c9
     int result2 = -EINPROGRESS;
ae23c9
 
ae23c9
-- 
ae23c9
1.8.3.1
ae23c9