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