From nobody Tue May 14 23:52:36 2024 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail(p=none dis=none) header.from=yandex-team.ru Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1676994734624158.04418033081333; Tue, 21 Feb 2023 07:52:14 -0800 (PST) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1pUUvf-0002hU-MK; Tue, 21 Feb 2023 10:51:44 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1pUUvI-0001yr-Sm; Tue, 21 Feb 2023 10:51:27 -0500 Received: from forwardcorp1c.mail.yandex.net ([2a02:6b8:c03:500:1:45:d181:df01]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1pUUv8-0004Ur-Ql; Tue, 21 Feb 2023 10:51:20 -0500 Received: from mail-nwsmtp-smtp-corp-main-44.iva.yp-c.yandex.net (mail-nwsmtp-smtp-corp-main-44.iva.yp-c.yandex.net [IPv6:2a02:6b8:c0c:8923:0:640:c717:0]) by forwardcorp1c.mail.yandex.net (Yandex) with ESMTP id 872DC5F52C; Tue, 21 Feb 2023 18:51:01 +0300 (MSK) Received: from vsementsov-win.yandex-team.ru (unknown [2a02:6b8:b081:b584::1:19]) by mail-nwsmtp-smtp-corp-main-44.iva.yp-c.yandex.net (smtpcorp/Yandex) with ESMTPSA id rosEB10KmeA0-NmJU1x3E; Tue, 21 Feb 2023 18:50:59 +0300 X-Yandex-Fwd: 1 Authentication-Results: mail-nwsmtp-smtp-corp-main-44.iva.yp-c.yandex.net; dkim=pass From: Vladimir Sementsov-Ogievskiy To: qemu-block@nongnu.org Cc: qemu-devel@nongnu.org, hreitz@redhat.com, kwolf@redhat.com, alexander.ivanov@virtuozzo.com, den@openvz.org, vsementsov@yandex-team.ru, Vladimir Sementsov-Ogievskiy Subject: [PATCH v7 1/5] blockdev: refactor transaction to use Transaction API Date: Tue, 21 Feb 2023 18:50:47 +0300 Message-Id: <20230221155051.746312-2-vsementsov@yandex-team.ru> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20230221155051.746312-1-vsementsov@yandex-team.ru> References: <20230221155051.746312-1-vsementsov@yandex-team.ru> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: pass client-ip=2a02:6b8:c03:500:1:45:d181:df01; envelope-from=vsementsov@yandex-team.ru; helo=forwardcorp1c.mail.yandex.net X-Spam_score_int: -18 X-Spam_score: -1.9 X-Spam_bar: - X-Spam_report: (-1.9 / 5.0 requ) BAYES_00=-1.9, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZM-MESSAGEID: 1676994736923100007 Content-Type: text/plain; charset="utf-8" From: Vladimir Sementsov-Ogievskiy We are going to add more block-graph modifying transaction actions, and block-graph modifying functions are already based on Transaction API. Next, we'll need to separately update permissions after several graph-modifying actions, and this would be simple with help of Transaction API. So, now let's just transform what we have into new-style transaction actions. Signed-off-by: Vladimir Sementsov-Ogievskiy --- blockdev.c | 317 +++++++++++++++++++++++++++++++---------------------- 1 file changed, 186 insertions(+), 131 deletions(-) diff --git a/blockdev.c b/blockdev.c index d7b5c18f0a..293f6a958e 100644 --- a/blockdev.c +++ b/blockdev.c @@ -1200,10 +1200,7 @@ typedef struct BlkActionState BlkActionState; */ typedef struct BlkActionOps { size_t instance_size; - void (*prepare)(BlkActionState *common, Error **errp); - void (*commit)(BlkActionState *common); - void (*abort)(BlkActionState *common); - void (*clean)(BlkActionState *common); + void (*action)(BlkActionState *common, Transaction *tran, Error **errp= ); } BlkActionOps; =20 /** @@ -1235,6 +1232,12 @@ typedef struct InternalSnapshotState { bool created; } InternalSnapshotState; =20 +static void internal_snapshot_abort(void *opaque); +static void internal_snapshot_clean(void *opaque); +TransactionActionDrv internal_snapshot_drv =3D { + .abort =3D internal_snapshot_abort, + .clean =3D internal_snapshot_clean, +}; =20 static int action_check_completion_mode(BlkActionState *s, Error **errp) { @@ -1249,8 +1252,8 @@ static int action_check_completion_mode(BlkActionStat= e *s, Error **errp) return 0; } =20 -static void internal_snapshot_prepare(BlkActionState *common, - Error **errp) +static void internal_snapshot_action(BlkActionState *common, + Transaction *tran, Error **errp) { Error *local_err =3D NULL; const char *device; @@ -1269,6 +1272,8 @@ static void internal_snapshot_prepare(BlkActionState = *common, internal =3D common->action->u.blockdev_snapshot_internal_sync.data; state =3D DO_UPCAST(InternalSnapshotState, common, common); =20 + tran_add(tran, &internal_snapshot_drv, state); + /* 1. parse input */ device =3D internal->device; name =3D internal->name; @@ -1353,10 +1358,9 @@ out: aio_context_release(aio_context); } =20 -static void internal_snapshot_abort(BlkActionState *common) +static void internal_snapshot_abort(void *opaque) { - InternalSnapshotState *state =3D - DO_UPCAST(InternalSnapshotState, common, comm= on); + InternalSnapshotState *state =3D opaque; BlockDriverState *bs =3D state->bs; QEMUSnapshotInfo *sn =3D &state->sn; AioContext *aio_context; @@ -1380,10 +1384,9 @@ static void internal_snapshot_abort(BlkActionState *= common) aio_context_release(aio_context); } =20 -static void internal_snapshot_clean(BlkActionState *common) +static void internal_snapshot_clean(void *opaque) { - InternalSnapshotState *state =3D DO_UPCAST(InternalSnapshotState, - common, common); + InternalSnapshotState *state =3D opaque; AioContext *aio_context; =20 if (!state->bs) { @@ -1396,6 +1399,8 @@ static void internal_snapshot_clean(BlkActionState *c= ommon) bdrv_drained_end(state->bs); =20 aio_context_release(aio_context); + + g_free(state); } =20 /* external snapshot private data */ @@ -1406,8 +1411,17 @@ typedef struct ExternalSnapshotState { bool overlay_appended; } ExternalSnapshotState; =20 -static void external_snapshot_prepare(BlkActionState *common, - Error **errp) +static void external_snapshot_commit(void *opaque); +static void external_snapshot_abort(void *opaque); +static void external_snapshot_clean(void *opaque); +TransactionActionDrv external_snapshot_drv =3D { + .commit =3D external_snapshot_commit, + .abort =3D external_snapshot_abort, + .clean =3D external_snapshot_clean, +}; + +static void external_snapshot_action(BlkActionState *common, Transaction *= tran, + Error **errp) { int ret; int flags =3D 0; @@ -1426,6 +1440,8 @@ static void external_snapshot_prepare(BlkActionState = *common, AioContext *aio_context; uint64_t perm, shared; =20 + tran_add(tran, &external_snapshot_drv, state); + /* 'blockdev-snapshot' and 'blockdev-snapshot-sync' have similar * purpose but a different set of parameters */ switch (action->type) { @@ -1578,10 +1594,9 @@ out: aio_context_release(aio_context); } =20 -static void external_snapshot_commit(BlkActionState *common) +static void external_snapshot_commit(void *opaque) { - ExternalSnapshotState *state =3D - DO_UPCAST(ExternalSnapshotState, common, comm= on); + ExternalSnapshotState *state =3D opaque; AioContext *aio_context; =20 aio_context =3D bdrv_get_aio_context(state->old_bs); @@ -1597,10 +1612,9 @@ static void external_snapshot_commit(BlkActionState = *common) aio_context_release(aio_context); } =20 -static void external_snapshot_abort(BlkActionState *common) +static void external_snapshot_abort(void *opaque) { - ExternalSnapshotState *state =3D - DO_UPCAST(ExternalSnapshotState, common, comm= on); + ExternalSnapshotState *state =3D opaque; if (state->new_bs) { if (state->overlay_appended) { AioContext *aio_context; @@ -1640,10 +1654,9 @@ static void external_snapshot_abort(BlkActionState *= common) } } =20 -static void external_snapshot_clean(BlkActionState *common) +static void external_snapshot_clean(void *opaque) { - ExternalSnapshotState *state =3D - DO_UPCAST(ExternalSnapshotState, common, comm= on); + ExternalSnapshotState *state =3D opaque; AioContext *aio_context; =20 if (!state->old_bs) { @@ -1657,6 +1670,8 @@ static void external_snapshot_clean(BlkActionState *c= ommon) bdrv_unref(state->new_bs); =20 aio_context_release(aio_context); + + g_free(state); } =20 typedef struct DriveBackupState { @@ -1671,7 +1686,17 @@ static BlockJob *do_backup_common(BackupCommon *back= up, AioContext *aio_context, JobTxn *txn, Error **errp); =20 -static void drive_backup_prepare(BlkActionState *common, Error **errp) +static void drive_backup_commit(void *opaque); +static void drive_backup_abort(void *opaque); +static void drive_backup_clean(void *opaque); +TransactionActionDrv drive_backup_drv =3D { + .commit =3D drive_backup_commit, + .abort =3D drive_backup_abort, + .clean =3D drive_backup_clean, +}; + +static void drive_backup_action(BlkActionState *common, Transaction *tran, + Error **errp) { DriveBackupState *state =3D DO_UPCAST(DriveBackupState, common, common= ); DriveBackup *backup; @@ -1688,6 +1713,8 @@ static void drive_backup_prepare(BlkActionState *comm= on, Error **errp) bool set_backing_hd =3D false; int ret; =20 + tran_add(tran, &drive_backup_drv, state); + assert(common->action->type =3D=3D TRANSACTION_ACTION_KIND_DRIVE_BACKU= P); backup =3D common->action->u.drive_backup.data; =20 @@ -1818,9 +1845,9 @@ out: aio_context_release(aio_context); } =20 -static void drive_backup_commit(BlkActionState *common) +static void drive_backup_commit(void *opaque) { - DriveBackupState *state =3D DO_UPCAST(DriveBackupState, common, common= ); + DriveBackupState *state =3D opaque; AioContext *aio_context; =20 aio_context =3D bdrv_get_aio_context(state->bs); @@ -1832,18 +1859,18 @@ static void drive_backup_commit(BlkActionState *com= mon) aio_context_release(aio_context); } =20 -static void drive_backup_abort(BlkActionState *common) +static void drive_backup_abort(void *opaque) { - DriveBackupState *state =3D DO_UPCAST(DriveBackupState, common, common= ); + DriveBackupState *state =3D opaque; =20 if (state->job) { job_cancel_sync(&state->job->job, true); } } =20 -static void drive_backup_clean(BlkActionState *common) +static void drive_backup_clean(void *opaque) { - DriveBackupState *state =3D DO_UPCAST(DriveBackupState, common, common= ); + DriveBackupState *state =3D opaque; AioContext *aio_context; =20 if (!state->bs) { @@ -1856,6 +1883,8 @@ static void drive_backup_clean(BlkActionState *common) bdrv_drained_end(state->bs); =20 aio_context_release(aio_context); + + g_free(state); } =20 typedef struct BlockdevBackupState { @@ -1864,7 +1893,17 @@ typedef struct BlockdevBackupState { BlockJob *job; } BlockdevBackupState; =20 -static void blockdev_backup_prepare(BlkActionState *common, Error **errp) +static void blockdev_backup_commit(void *opaque); +static void blockdev_backup_abort(void *opaque); +static void blockdev_backup_clean(void *opaque); +TransactionActionDrv blockdev_backup_drv =3D { + .commit =3D blockdev_backup_commit, + .abort =3D blockdev_backup_abort, + .clean =3D blockdev_backup_clean, +}; + +static void blockdev_backup_action(BlkActionState *common, Transaction *tr= an, + Error **errp) { BlockdevBackupState *state =3D DO_UPCAST(BlockdevBackupState, common, = common); BlockdevBackup *backup; @@ -1874,6 +1913,8 @@ static void blockdev_backup_prepare(BlkActionState *c= ommon, Error **errp) AioContext *old_context; int ret; =20 + tran_add(tran, &blockdev_backup_drv, state); + assert(common->action->type =3D=3D TRANSACTION_ACTION_KIND_BLOCKDEV_BA= CKUP); backup =3D common->action->u.blockdev_backup.data; =20 @@ -1912,9 +1953,9 @@ static void blockdev_backup_prepare(BlkActionState *c= ommon, Error **errp) aio_context_release(aio_context); } =20 -static void blockdev_backup_commit(BlkActionState *common) +static void blockdev_backup_commit(void *opaque) { - BlockdevBackupState *state =3D DO_UPCAST(BlockdevBackupState, common, = common); + BlockdevBackupState *state =3D opaque; AioContext *aio_context; =20 aio_context =3D bdrv_get_aio_context(state->bs); @@ -1926,18 +1967,18 @@ static void blockdev_backup_commit(BlkActionState *= common) aio_context_release(aio_context); } =20 -static void blockdev_backup_abort(BlkActionState *common) +static void blockdev_backup_abort(void *opaque) { - BlockdevBackupState *state =3D DO_UPCAST(BlockdevBackupState, common, = common); + BlockdevBackupState *state =3D opaque; =20 if (state->job) { job_cancel_sync(&state->job->job, true); } } =20 -static void blockdev_backup_clean(BlkActionState *common) +static void blockdev_backup_clean(void *opaque) { - BlockdevBackupState *state =3D DO_UPCAST(BlockdevBackupState, common, = common); + BlockdevBackupState *state =3D opaque; AioContext *aio_context; =20 if (!state->bs) { @@ -1950,6 +1991,8 @@ static void blockdev_backup_clean(BlkActionState *com= mon) bdrv_drained_end(state->bs); =20 aio_context_release(aio_context); + + g_free(state); } =20 typedef struct BlockDirtyBitmapState { @@ -1961,14 +2004,22 @@ typedef struct BlockDirtyBitmapState { bool was_enabled; } BlockDirtyBitmapState; =20 -static void block_dirty_bitmap_add_prepare(BlkActionState *common, - Error **errp) +static void block_dirty_bitmap_add_abort(void *opaque); +TransactionActionDrv block_dirty_bitmap_add_drv =3D { + .abort =3D block_dirty_bitmap_add_abort, + .clean =3D g_free, +}; + +static void block_dirty_bitmap_add_action(BlkActionState *common, + Transaction *tran, Error **errp) { Error *local_err =3D NULL; BlockDirtyBitmapAdd *action; BlockDirtyBitmapState *state =3D DO_UPCAST(BlockDirtyBitmapState, common, common); =20 + tran_add(tran, &block_dirty_bitmap_add_drv, state); + if (action_check_completion_mode(common, errp) < 0) { return; } @@ -1988,13 +2039,12 @@ static void block_dirty_bitmap_add_prepare(BlkActio= nState *common, } } =20 -static void block_dirty_bitmap_add_abort(BlkActionState *common) +static void block_dirty_bitmap_add_abort(void *opaque) { BlockDirtyBitmapAdd *action; - BlockDirtyBitmapState *state =3D DO_UPCAST(BlockDirtyBitmapState, - common, common); + BlockDirtyBitmapState *state =3D opaque; =20 - action =3D common->action->u.block_dirty_bitmap_add.data; + action =3D state->common.action->u.block_dirty_bitmap_add.data; /* Should not be able to fail: IF the bitmap was added via .prepare(), * then the node reference and bitmap name must have been valid. */ @@ -2003,13 +2053,23 @@ static void block_dirty_bitmap_add_abort(BlkActionS= tate *common) } } =20 -static void block_dirty_bitmap_clear_prepare(BlkActionState *common, - Error **errp) +static void block_dirty_bitmap_restore(void *opaque); +static void block_dirty_bitmap_free_backup(void *opaque); +TransactionActionDrv block_dirty_bitmap_clear_drv =3D { + .abort =3D block_dirty_bitmap_restore, + .commit =3D block_dirty_bitmap_free_backup, + .clean =3D g_free, +}; + +static void block_dirty_bitmap_clear_action(BlkActionState *common, + Transaction *tran, Error **err= p) { BlockDirtyBitmapState *state =3D DO_UPCAST(BlockDirtyBitmapState, common, common); BlockDirtyBitmap *action; =20 + tran_add(tran, &block_dirty_bitmap_clear_drv, state); + if (action_check_completion_mode(common, errp) < 0) { return; } @@ -2030,31 +2090,37 @@ static void block_dirty_bitmap_clear_prepare(BlkAct= ionState *common, bdrv_clear_dirty_bitmap(state->bitmap, &state->backup); } =20 -static void block_dirty_bitmap_restore(BlkActionState *common) +static void block_dirty_bitmap_restore(void *opaque) { - BlockDirtyBitmapState *state =3D DO_UPCAST(BlockDirtyBitmapState, - common, common); + BlockDirtyBitmapState *state =3D opaque; =20 if (state->backup) { bdrv_restore_dirty_bitmap(state->bitmap, state->backup); } } =20 -static void block_dirty_bitmap_free_backup(BlkActionState *common) +static void block_dirty_bitmap_free_backup(void *opaque) { - BlockDirtyBitmapState *state =3D DO_UPCAST(BlockDirtyBitmapState, - common, common); + BlockDirtyBitmapState *state =3D opaque; =20 hbitmap_free(state->backup); } =20 -static void block_dirty_bitmap_enable_prepare(BlkActionState *common, - Error **errp) +static void block_dirty_bitmap_enable_abort(void *opaque); +TransactionActionDrv block_dirty_bitmap_enable_drv =3D { + .abort =3D block_dirty_bitmap_enable_abort, + .clean =3D g_free, +}; + +static void block_dirty_bitmap_enable_action(BlkActionState *common, + Transaction *tran, Error **er= rp) { BlockDirtyBitmap *action; BlockDirtyBitmapState *state =3D DO_UPCAST(BlockDirtyBitmapState, common, common); =20 + tran_add(tran, &block_dirty_bitmap_enable_drv, state); + if (action_check_completion_mode(common, errp) < 0) { return; } @@ -2076,23 +2142,30 @@ static void block_dirty_bitmap_enable_prepare(BlkAc= tionState *common, bdrv_enable_dirty_bitmap(state->bitmap); } =20 -static void block_dirty_bitmap_enable_abort(BlkActionState *common) +static void block_dirty_bitmap_enable_abort(void *opaque) { - BlockDirtyBitmapState *state =3D DO_UPCAST(BlockDirtyBitmapState, - common, common); + BlockDirtyBitmapState *state =3D opaque; =20 if (!state->was_enabled) { bdrv_disable_dirty_bitmap(state->bitmap); } } =20 -static void block_dirty_bitmap_disable_prepare(BlkActionState *common, - Error **errp) +static void block_dirty_bitmap_disable_abort(void *opaque); +TransactionActionDrv block_dirty_bitmap_disable_drv =3D { + .abort =3D block_dirty_bitmap_disable_abort, + .clean =3D g_free, +}; + +static void block_dirty_bitmap_disable_action(BlkActionState *common, + Transaction *tran, Error **e= rrp) { BlockDirtyBitmap *action; BlockDirtyBitmapState *state =3D DO_UPCAST(BlockDirtyBitmapState, common, common); =20 + tran_add(tran, &block_dirty_bitmap_disable_drv, state); + if (action_check_completion_mode(common, errp) < 0) { return; } @@ -2114,23 +2187,30 @@ static void block_dirty_bitmap_disable_prepare(BlkA= ctionState *common, bdrv_disable_dirty_bitmap(state->bitmap); } =20 -static void block_dirty_bitmap_disable_abort(BlkActionState *common) +static void block_dirty_bitmap_disable_abort(void *opaque) { - BlockDirtyBitmapState *state =3D DO_UPCAST(BlockDirtyBitmapState, - common, common); + BlockDirtyBitmapState *state =3D opaque; =20 if (state->was_enabled) { bdrv_enable_dirty_bitmap(state->bitmap); } } =20 -static void block_dirty_bitmap_merge_prepare(BlkActionState *common, - Error **errp) +TransactionActionDrv block_dirty_bitmap_merge_drv =3D { + .commit =3D block_dirty_bitmap_free_backup, + .abort =3D block_dirty_bitmap_restore, + .clean =3D g_free, +}; + +static void block_dirty_bitmap_merge_action(BlkActionState *common, + Transaction *tran, Error **err= p) { BlockDirtyBitmapMerge *action; BlockDirtyBitmapState *state =3D DO_UPCAST(BlockDirtyBitmapState, common, common); =20 + tran_add(tran, &block_dirty_bitmap_merge_drv, state); + if (action_check_completion_mode(common, errp) < 0) { return; } @@ -2142,13 +2222,23 @@ static void block_dirty_bitmap_merge_prepare(BlkAct= ionState *common, errp); } =20 -static void block_dirty_bitmap_remove_prepare(BlkActionState *common, - Error **errp) +static void block_dirty_bitmap_remove_commit(void *opaque); +static void block_dirty_bitmap_remove_abort(void *opaque); +TransactionActionDrv block_dirty_bitmap_remove_drv =3D { + .commit =3D block_dirty_bitmap_remove_commit, + .abort =3D block_dirty_bitmap_remove_abort, + .clean =3D g_free, +}; + +static void block_dirty_bitmap_remove_action(BlkActionState *common, + Transaction *tran, Error **er= rp) { BlockDirtyBitmap *action; BlockDirtyBitmapState *state =3D DO_UPCAST(BlockDirtyBitmapState, common, common); =20 + tran_add(tran, &block_dirty_bitmap_remove_drv, state); + if (action_check_completion_mode(common, errp) < 0) { return; } @@ -2163,10 +2253,9 @@ static void block_dirty_bitmap_remove_prepare(BlkAct= ionState *common, } } =20 -static void block_dirty_bitmap_remove_abort(BlkActionState *common) +static void block_dirty_bitmap_remove_abort(void *opaque) { - BlockDirtyBitmapState *state =3D DO_UPCAST(BlockDirtyBitmapState, - common, common); + BlockDirtyBitmapState *state =3D opaque; =20 if (state->bitmap) { bdrv_dirty_bitmap_skip_store(state->bitmap, false); @@ -2174,21 +2263,28 @@ static void block_dirty_bitmap_remove_abort(BlkActi= onState *common) } } =20 -static void block_dirty_bitmap_remove_commit(BlkActionState *common) +static void block_dirty_bitmap_remove_commit(void *opaque) { - BlockDirtyBitmapState *state =3D DO_UPCAST(BlockDirtyBitmapState, - common, common); + BlockDirtyBitmapState *state =3D opaque; =20 bdrv_dirty_bitmap_set_busy(state->bitmap, false); bdrv_release_dirty_bitmap(state->bitmap); } =20 -static void abort_prepare(BlkActionState *common, Error **errp) +static void abort_commit(void *opaque); +TransactionActionDrv abort_drv =3D { + .commit =3D abort_commit, + .clean =3D g_free, +}; + +static void abort_action(BlkActionState *common, Transaction *tran, + Error **errp) { + tran_add(tran, &abort_drv, common); error_setg(errp, "Transaction aborted using Abort action"); } =20 -static void abort_commit(BlkActionState *common) +static void abort_commit(void *opaque) { g_assert_not_reached(); /* this action never succeeds */ } @@ -2196,75 +2292,51 @@ static void abort_commit(BlkActionState *common) static const BlkActionOps actions[] =3D { [TRANSACTION_ACTION_KIND_BLOCKDEV_SNAPSHOT] =3D { .instance_size =3D sizeof(ExternalSnapshotState), - .prepare =3D external_snapshot_prepare, - .commit =3D external_snapshot_commit, - .abort =3D external_snapshot_abort, - .clean =3D external_snapshot_clean, + .action =3D external_snapshot_action, }, [TRANSACTION_ACTION_KIND_BLOCKDEV_SNAPSHOT_SYNC] =3D { .instance_size =3D sizeof(ExternalSnapshotState), - .prepare =3D external_snapshot_prepare, - .commit =3D external_snapshot_commit, - .abort =3D external_snapshot_abort, - .clean =3D external_snapshot_clean, + .action =3D external_snapshot_action, }, [TRANSACTION_ACTION_KIND_DRIVE_BACKUP] =3D { .instance_size =3D sizeof(DriveBackupState), - .prepare =3D drive_backup_prepare, - .commit =3D drive_backup_commit, - .abort =3D drive_backup_abort, - .clean =3D drive_backup_clean, + .action =3D drive_backup_action, }, [TRANSACTION_ACTION_KIND_BLOCKDEV_BACKUP] =3D { .instance_size =3D sizeof(BlockdevBackupState), - .prepare =3D blockdev_backup_prepare, - .commit =3D blockdev_backup_commit, - .abort =3D blockdev_backup_abort, - .clean =3D blockdev_backup_clean, + .action =3D blockdev_backup_action, }, [TRANSACTION_ACTION_KIND_ABORT] =3D { .instance_size =3D sizeof(BlkActionState), - .prepare =3D abort_prepare, - .commit =3D abort_commit, + .action =3D abort_action, }, [TRANSACTION_ACTION_KIND_BLOCKDEV_SNAPSHOT_INTERNAL_SYNC] =3D { .instance_size =3D sizeof(InternalSnapshotState), - .prepare =3D internal_snapshot_prepare, - .abort =3D internal_snapshot_abort, - .clean =3D internal_snapshot_clean, + .action =3D internal_snapshot_action, }, [TRANSACTION_ACTION_KIND_BLOCK_DIRTY_BITMAP_ADD] =3D { .instance_size =3D sizeof(BlockDirtyBitmapState), - .prepare =3D block_dirty_bitmap_add_prepare, - .abort =3D block_dirty_bitmap_add_abort, + .action =3D block_dirty_bitmap_add_action, }, [TRANSACTION_ACTION_KIND_BLOCK_DIRTY_BITMAP_CLEAR] =3D { .instance_size =3D sizeof(BlockDirtyBitmapState), - .prepare =3D block_dirty_bitmap_clear_prepare, - .commit =3D block_dirty_bitmap_free_backup, - .abort =3D block_dirty_bitmap_restore, + .action =3D block_dirty_bitmap_clear_action, }, [TRANSACTION_ACTION_KIND_BLOCK_DIRTY_BITMAP_ENABLE] =3D { .instance_size =3D sizeof(BlockDirtyBitmapState), - .prepare =3D block_dirty_bitmap_enable_prepare, - .abort =3D block_dirty_bitmap_enable_abort, + .action =3D block_dirty_bitmap_enable_action, }, [TRANSACTION_ACTION_KIND_BLOCK_DIRTY_BITMAP_DISABLE] =3D { .instance_size =3D sizeof(BlockDirtyBitmapState), - .prepare =3D block_dirty_bitmap_disable_prepare, - .abort =3D block_dirty_bitmap_disable_abort, + .action =3D block_dirty_bitmap_disable_action, }, [TRANSACTION_ACTION_KIND_BLOCK_DIRTY_BITMAP_MERGE] =3D { .instance_size =3D sizeof(BlockDirtyBitmapState), - .prepare =3D block_dirty_bitmap_merge_prepare, - .commit =3D block_dirty_bitmap_free_backup, - .abort =3D block_dirty_bitmap_restore, + .action =3D block_dirty_bitmap_merge_action, }, [TRANSACTION_ACTION_KIND_BLOCK_DIRTY_BITMAP_REMOVE] =3D { .instance_size =3D sizeof(BlockDirtyBitmapState), - .prepare =3D block_dirty_bitmap_remove_prepare, - .commit =3D block_dirty_bitmap_remove_commit, - .abort =3D block_dirty_bitmap_remove_abort, + .action =3D block_dirty_bitmap_remove_action, }, /* Where are transactions for MIRROR, COMMIT and STREAM? * Although these blockjobs use transaction callbacks like the backup = job, @@ -2306,14 +2378,11 @@ void qmp_transaction(TransactionActionList *dev_lis= t, TransactionActionList *dev_entry =3D dev_list; bool has_props =3D !!props; JobTxn *block_job_txn =3D NULL; - BlkActionState *state, *next; Error *local_err =3D NULL; + Transaction *tran =3D tran_new(); =20 GLOBAL_STATE_CODE(); =20 - QTAILQ_HEAD(, BlkActionState) snap_bdrv_states; - QTAILQ_INIT(&snap_bdrv_states); - /* Does this transaction get canceled as a group on failure? * If not, we don't really need to make a JobTxn. */ @@ -2329,6 +2398,7 @@ void qmp_transaction(TransactionActionList *dev_list, while (NULL !=3D dev_entry) { TransactionAction *dev_info =3D NULL; const BlkActionOps *ops; + BlkActionState *state; =20 dev_info =3D dev_entry->value; dev_entry =3D dev_entry->next; @@ -2343,38 +2413,23 @@ void qmp_transaction(TransactionActionList *dev_lis= t, state->action =3D dev_info; state->block_job_txn =3D block_job_txn; state->txn_props =3D props; - QTAILQ_INSERT_TAIL(&snap_bdrv_states, state, entry); =20 - state->ops->prepare(state, &local_err); + state->ops->action(state, tran, &local_err); if (local_err) { error_propagate(errp, local_err); goto delete_and_fail; } } =20 - QTAILQ_FOREACH(state, &snap_bdrv_states, entry) { - if (state->ops->commit) { - state->ops->commit(state); - } - } + tran_commit(tran); =20 /* success */ goto exit; =20 delete_and_fail: /* failure, and it is all-or-none; roll back all operations */ - QTAILQ_FOREACH_REVERSE(state, &snap_bdrv_states, entry) { - if (state->ops->abort) { - state->ops->abort(state); - } - } + tran_abort(tran); exit: - QTAILQ_FOREACH_SAFE(state, &snap_bdrv_states, entry, next) { - if (state->ops->clean) { - state->ops->clean(state); - } - g_free(state); - } if (!has_props) { qapi_free_TransactionProperties(props); } --=20 2.34.1 From nobody Tue May 14 23:52:36 2024 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail(p=none dis=none) header.from=yandex-team.ru Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1676994723756393.9863512408914; Tue, 21 Feb 2023 07:52:03 -0800 (PST) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1pUUvp-00038C-Qu; Tue, 21 Feb 2023 10:51:55 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1pUUvH-0001yX-9S; Tue, 21 Feb 2023 10:51:27 -0500 Received: from forwardcorp1c.mail.yandex.net ([178.154.239.200]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1pUUv8-0004VL-QQ; Tue, 21 Feb 2023 10:51:18 -0500 Received: from mail-nwsmtp-smtp-corp-main-44.iva.yp-c.yandex.net (mail-nwsmtp-smtp-corp-main-44.iva.yp-c.yandex.net [IPv6:2a02:6b8:c0c:8923:0:640:c717:0]) by forwardcorp1c.mail.yandex.net (Yandex) with ESMTP id CC7145F52B; Tue, 21 Feb 2023 18:51:02 +0300 (MSK) Received: from vsementsov-win.yandex-team.ru (unknown [2a02:6b8:b081:b584::1:19]) by mail-nwsmtp-smtp-corp-main-44.iva.yp-c.yandex.net (smtpcorp/Yandex) with ESMTPSA id rosEB10KmeA0-kaZWdvBf; Tue, 21 Feb 2023 18:51:01 +0300 X-Yandex-Fwd: 1 Authentication-Results: mail-nwsmtp-smtp-corp-main-44.iva.yp-c.yandex.net; dkim=pass From: Vladimir Sementsov-Ogievskiy To: qemu-block@nongnu.org Cc: qemu-devel@nongnu.org, hreitz@redhat.com, kwolf@redhat.com, alexander.ivanov@virtuozzo.com, den@openvz.org, vsementsov@yandex-team.ru, Vladimir Sementsov-Ogievskiy Subject: [PATCH v7 2/5] blockdev: transactions: rename some things Date: Tue, 21 Feb 2023 18:50:48 +0300 Message-Id: <20230221155051.746312-3-vsementsov@yandex-team.ru> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20230221155051.746312-1-vsementsov@yandex-team.ru> References: <20230221155051.746312-1-vsementsov@yandex-team.ru> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: pass client-ip=178.154.239.200; envelope-from=vsementsov@yandex-team.ru; helo=forwardcorp1c.mail.yandex.net X-Spam_score_int: -18 X-Spam_score: -1.9 X-Spam_bar: - X-Spam_report: (-1.9 / 5.0 requ) BAYES_00=-1.9, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZM-MESSAGEID: 1676994724444100004 Content-Type: text/plain; charset="utf-8" From: Vladimir Sementsov-Ogievskiy Look at qmp_transaction(): dev_list is not obvious name for list of actions. Let's look at qapi spec, this argument is "actions". Let's follow the common practice of using same argument names in qapi scheme and code. To be honest, rename props to properties for same reason. Next, we have to rename global map of actions, to not conflict with new name for function argument. Rename also dev_entry loop variable accordingly to new name of the list. Signed-off-by: Vladimir Sementsov-Ogievskiy --- blockdev.c | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/blockdev.c b/blockdev.c index 293f6a958e..2174ab2694 100644 --- a/blockdev.c +++ b/blockdev.c @@ -2289,7 +2289,7 @@ static void abort_commit(void *opaque) g_assert_not_reached(); /* this action never succeeds */ } =20 -static const BlkActionOps actions[] =3D { +static const BlkActionOps actions_map[] =3D { [TRANSACTION_ACTION_KIND_BLOCKDEV_SNAPSHOT] =3D { .instance_size =3D sizeof(ExternalSnapshotState), .action =3D external_snapshot_action, @@ -2371,12 +2371,12 @@ static TransactionProperties *get_transaction_prope= rties( * * Always run under BQL. */ -void qmp_transaction(TransactionActionList *dev_list, - struct TransactionProperties *props, +void qmp_transaction(TransactionActionList *actions, + struct TransactionProperties *properties, Error **errp) { - TransactionActionList *dev_entry =3D dev_list; - bool has_props =3D !!props; + TransactionActionList *act =3D actions; + bool has_properties =3D !!properties; JobTxn *block_job_txn =3D NULL; Error *local_err =3D NULL; Transaction *tran =3D tran_new(); @@ -2386,8 +2386,8 @@ void qmp_transaction(TransactionActionList *dev_list, /* Does this transaction get canceled as a group on failure? * If not, we don't really need to make a JobTxn. */ - props =3D get_transaction_properties(props); - if (props->completion_mode !=3D ACTION_COMPLETION_MODE_INDIVIDUAL) { + properties =3D get_transaction_properties(properties); + if (properties->completion_mode !=3D ACTION_COMPLETION_MODE_INDIVIDUAL= ) { block_job_txn =3D job_txn_new(); } =20 @@ -2395,24 +2395,24 @@ void qmp_transaction(TransactionActionList *dev_lis= t, bdrv_drain_all(); =20 /* We don't do anything in this loop that commits us to the operations= */ - while (NULL !=3D dev_entry) { + while (NULL !=3D act) { TransactionAction *dev_info =3D NULL; const BlkActionOps *ops; BlkActionState *state; =20 - dev_info =3D dev_entry->value; - dev_entry =3D dev_entry->next; + dev_info =3D act->value; + act =3D act->next; =20 - assert(dev_info->type < ARRAY_SIZE(actions)); + assert(dev_info->type < ARRAY_SIZE(actions_map)); =20 - ops =3D &actions[dev_info->type]; + ops =3D &actions_map[dev_info->type]; assert(ops->instance_size > 0); =20 state =3D g_malloc0(ops->instance_size); state->ops =3D ops; state->action =3D dev_info; state->block_job_txn =3D block_job_txn; - state->txn_props =3D props; + state->txn_props =3D properties; =20 state->ops->action(state, tran, &local_err); if (local_err) { @@ -2430,8 +2430,8 @@ delete_and_fail: /* failure, and it is all-or-none; roll back all operations */ tran_abort(tran); exit: - if (!has_props) { - qapi_free_TransactionProperties(props); + if (!has_properties) { + qapi_free_TransactionProperties(properties); } job_txn_unref(block_job_txn); } --=20 2.34.1 From nobody Tue May 14 23:52:36 2024 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail(p=none dis=none) header.from=yandex-team.ru Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1676994722450162.11710231010193; Tue, 21 Feb 2023 07:52:02 -0800 (PST) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1pUUve-0002df-KL; Tue, 21 Feb 2023 10:51:42 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1pUUvI-0001ys-Sp; Tue, 21 Feb 2023 10:51:27 -0500 Received: from forwardcorp1b.mail.yandex.net ([2a02:6b8:c02:900:1:45:d181:df01]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1pUUvG-0004Vg-Qx; Tue, 21 Feb 2023 10:51:20 -0500 Received: from mail-nwsmtp-smtp-corp-main-44.iva.yp-c.yandex.net (mail-nwsmtp-smtp-corp-main-44.iva.yp-c.yandex.net [IPv6:2a02:6b8:c0c:8923:0:640:c717:0]) by forwardcorp1b.mail.yandex.net (Yandex) with ESMTP id 1121762111; Tue, 21 Feb 2023 18:51:04 +0300 (MSK) Received: from vsementsov-win.yandex-team.ru (unknown [2a02:6b8:b081:b584::1:19]) by mail-nwsmtp-smtp-corp-main-44.iva.yp-c.yandex.net (smtpcorp/Yandex) with ESMTPSA id rosEB10KmeA0-kjyrYmWU; Tue, 21 Feb 2023 18:51:02 +0300 X-Yandex-Fwd: 1 Authentication-Results: mail-nwsmtp-smtp-corp-main-44.iva.yp-c.yandex.net; dkim=pass From: Vladimir Sementsov-Ogievskiy To: qemu-block@nongnu.org Cc: qemu-devel@nongnu.org, hreitz@redhat.com, kwolf@redhat.com, alexander.ivanov@virtuozzo.com, den@openvz.org, vsementsov@yandex-team.ru, Vladimir Sementsov-Ogievskiy Subject: [PATCH v7 3/5] blockdev: qmp_transaction: refactor loop to classic for Date: Tue, 21 Feb 2023 18:50:49 +0300 Message-Id: <20230221155051.746312-4-vsementsov@yandex-team.ru> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20230221155051.746312-1-vsementsov@yandex-team.ru> References: <20230221155051.746312-1-vsementsov@yandex-team.ru> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: pass client-ip=2a02:6b8:c02:900:1:45:d181:df01; envelope-from=vsementsov@yandex-team.ru; helo=forwardcorp1b.mail.yandex.net X-Spam_score_int: -18 X-Spam_score: -1.9 X-Spam_bar: - X-Spam_report: (-1.9 / 5.0 requ) BAYES_00=-1.9, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZM-MESSAGEID: 1676994724420100003 Content-Type: text/plain; charset="utf-8" From: Vladimir Sementsov-Ogievskiy Signed-off-by: Vladimir Sementsov-Ogievskiy --- blockdev.c | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/blockdev.c b/blockdev.c index 2174ab2694..89c573a094 100644 --- a/blockdev.c +++ b/blockdev.c @@ -2375,7 +2375,7 @@ void qmp_transaction(TransactionActionList *actions, struct TransactionProperties *properties, Error **errp) { - TransactionActionList *act =3D actions; + TransactionActionList *act; bool has_properties =3D !!properties; JobTxn *block_job_txn =3D NULL; Error *local_err =3D NULL; @@ -2395,14 +2395,11 @@ void qmp_transaction(TransactionActionList *actions, bdrv_drain_all(); =20 /* We don't do anything in this loop that commits us to the operations= */ - while (NULL !=3D act) { - TransactionAction *dev_info =3D NULL; + for (act =3D actions; act; act =3D act->next) { + TransactionAction *dev_info =3D act->value; const BlkActionOps *ops; BlkActionState *state; =20 - dev_info =3D act->value; - act =3D act->next; - assert(dev_info->type < ARRAY_SIZE(actions_map)); =20 ops =3D &actions_map[dev_info->type]; --=20 2.34.1 From nobody Tue May 14 23:52:36 2024 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail(p=none dis=none) header.from=yandex-team.ru Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 167699474523958.522459667501835; Tue, 21 Feb 2023 07:52:25 -0800 (PST) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1pUUw7-0003u7-O4; Tue, 21 Feb 2023 10:52:12 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1pUUvJ-0001yu-8j; Tue, 21 Feb 2023 10:51:27 -0500 Received: from forwardcorp1c.mail.yandex.net ([178.154.239.200]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1pUUvG-0004WF-RS; Tue, 21 Feb 2023 10:51:20 -0500 Received: from mail-nwsmtp-smtp-corp-main-44.iva.yp-c.yandex.net (mail-nwsmtp-smtp-corp-main-44.iva.yp-c.yandex.net [IPv6:2a02:6b8:c0c:8923:0:640:c717:0]) by forwardcorp1c.mail.yandex.net (Yandex) with ESMTP id 662DB5F52F; Tue, 21 Feb 2023 18:51:05 +0300 (MSK) Received: from vsementsov-win.yandex-team.ru (unknown [2a02:6b8:b081:b584::1:19]) by mail-nwsmtp-smtp-corp-main-44.iva.yp-c.yandex.net (smtpcorp/Yandex) with ESMTPSA id rosEB10KmeA0-pm3yR1Lt; Tue, 21 Feb 2023 18:51:04 +0300 X-Yandex-Fwd: 1 Authentication-Results: mail-nwsmtp-smtp-corp-main-44.iva.yp-c.yandex.net; dkim=pass From: Vladimir Sementsov-Ogievskiy To: qemu-block@nongnu.org Cc: qemu-devel@nongnu.org, hreitz@redhat.com, kwolf@redhat.com, alexander.ivanov@virtuozzo.com, den@openvz.org, vsementsov@yandex-team.ru, Vladimir Sementsov-Ogievskiy Subject: [PATCH v7 4/5] blockdev: transaction: refactor handling transaction properties Date: Tue, 21 Feb 2023 18:50:50 +0300 Message-Id: <20230221155051.746312-5-vsementsov@yandex-team.ru> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20230221155051.746312-1-vsementsov@yandex-team.ru> References: <20230221155051.746312-1-vsementsov@yandex-team.ru> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: pass client-ip=178.154.239.200; envelope-from=vsementsov@yandex-team.ru; helo=forwardcorp1c.mail.yandex.net X-Spam_score_int: -18 X-Spam_score: -1.9 X-Spam_bar: - X-Spam_report: (-1.9 / 5.0 requ) BAYES_00=-1.9, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZM-MESSAGEID: 1676994746616100001 Content-Type: text/plain; charset="utf-8" From: Vladimir Sementsov-Ogievskiy Only backup supports GROUPED mode. Make this logic more clear. And avoid passing extra thing to each action. Signed-off-by: Vladimir Sementsov-Ogievskiy --- blockdev.c | 92 +++++++++++------------------------------------------- 1 file changed, 19 insertions(+), 73 deletions(-) diff --git a/blockdev.c b/blockdev.c index 89c573a094..edaf7c6601 100644 --- a/blockdev.c +++ b/blockdev.c @@ -1220,7 +1220,6 @@ struct BlkActionState { TransactionAction *action; const BlkActionOps *ops; JobTxn *block_job_txn; - TransactionProperties *txn_props; QTAILQ_ENTRY(BlkActionState) entry; }; =20 @@ -1239,19 +1238,6 @@ TransactionActionDrv internal_snapshot_drv =3D { .clean =3D internal_snapshot_clean, }; =20 -static int action_check_completion_mode(BlkActionState *s, Error **errp) -{ - if (s->txn_props->completion_mode !=3D ACTION_COMPLETION_MODE_INDIVIDU= AL) { - error_setg(errp, - "Action '%s' does not support Transaction property " - "completion-mode =3D %s", - TransactionActionKind_str(s->action->type), - ActionCompletionMode_str(s->txn_props->completion_mode)= ); - return -1; - } - return 0; -} - static void internal_snapshot_action(BlkActionState *common, Transaction *tran, Error **errp) { @@ -1274,15 +1260,9 @@ static void internal_snapshot_action(BlkActionState = *common, =20 tran_add(tran, &internal_snapshot_drv, state); =20 - /* 1. parse input */ device =3D internal->device; name =3D internal->name; =20 - /* 2. check for validation */ - if (action_check_completion_mode(common, errp) < 0) { - return; - } - bs =3D qmp_get_root_bs(device, errp); if (!bs) { return; @@ -1468,9 +1448,6 @@ static void external_snapshot_action(BlkActionState *= common, Transaction *tran, } =20 /* start processing */ - if (action_check_completion_mode(common, errp) < 0) { - return; - } =20 state->old_bs =3D bdrv_lookup_bs(device, node_name, errp); if (!state->old_bs) { @@ -2020,10 +1997,6 @@ static void block_dirty_bitmap_add_action(BlkActionS= tate *common, =20 tran_add(tran, &block_dirty_bitmap_add_drv, state); =20 - if (action_check_completion_mode(common, errp) < 0) { - return; - } - action =3D common->action->u.block_dirty_bitmap_add.data; /* AIO context taken and released within qmp_block_dirty_bitmap_add */ qmp_block_dirty_bitmap_add(action->node, action->name, @@ -2070,10 +2043,6 @@ static void block_dirty_bitmap_clear_action(BlkActio= nState *common, =20 tran_add(tran, &block_dirty_bitmap_clear_drv, state); =20 - if (action_check_completion_mode(common, errp) < 0) { - return; - } - action =3D common->action->u.block_dirty_bitmap_clear.data; state->bitmap =3D block_dirty_bitmap_lookup(action->node, action->name, @@ -2121,10 +2090,6 @@ static void block_dirty_bitmap_enable_action(BlkActi= onState *common, =20 tran_add(tran, &block_dirty_bitmap_enable_drv, state); =20 - if (action_check_completion_mode(common, errp) < 0) { - return; - } - action =3D common->action->u.block_dirty_bitmap_enable.data; state->bitmap =3D block_dirty_bitmap_lookup(action->node, action->name, @@ -2166,10 +2131,6 @@ static void block_dirty_bitmap_disable_action(BlkAct= ionState *common, =20 tran_add(tran, &block_dirty_bitmap_disable_drv, state); =20 - if (action_check_completion_mode(common, errp) < 0) { - return; - } - action =3D common->action->u.block_dirty_bitmap_disable.data; state->bitmap =3D block_dirty_bitmap_lookup(action->node, action->name, @@ -2211,10 +2172,6 @@ static void block_dirty_bitmap_merge_action(BlkActio= nState *common, =20 tran_add(tran, &block_dirty_bitmap_merge_drv, state); =20 - if (action_check_completion_mode(common, errp) < 0) { - return; - } - action =3D common->action->u.block_dirty_bitmap_merge.data; =20 state->bitmap =3D block_dirty_bitmap_merge(action->node, action->targe= t, @@ -2239,10 +2196,6 @@ static void block_dirty_bitmap_remove_action(BlkActi= onState *common, =20 tran_add(tran, &block_dirty_bitmap_remove_drv, state); =20 - if (action_check_completion_mode(common, errp) < 0) { - return; - } - action =3D common->action->u.block_dirty_bitmap_remove.data; =20 state->bitmap =3D block_dirty_bitmap_remove(action->node, action->name, @@ -2346,25 +2299,6 @@ static const BlkActionOps actions_map[] =3D { */ }; =20 -/** - * Allocate a TransactionProperties structure if necessary, and fill - * that structure with desired defaults if they are unset. - */ -static TransactionProperties *get_transaction_properties( - TransactionProperties *props) -{ - if (!props) { - props =3D g_new0(TransactionProperties, 1); - } - - if (!props->has_completion_mode) { - props->has_completion_mode =3D true; - props->completion_mode =3D ACTION_COMPLETION_MODE_INDIVIDUAL; - } - - return props; -} - /* * 'Atomic' group operations. The operations are performed as a set, and = if * any fail then we roll back all operations in the group. @@ -2376,18 +2310,34 @@ void qmp_transaction(TransactionActionList *actions, Error **errp) { TransactionActionList *act; - bool has_properties =3D !!properties; JobTxn *block_job_txn =3D NULL; Error *local_err =3D NULL; Transaction *tran =3D tran_new(); + ActionCompletionMode comp_mode =3D + properties ? properties->completion_mode : + ACTION_COMPLETION_MODE_INDIVIDUAL; =20 GLOBAL_STATE_CODE(); =20 /* Does this transaction get canceled as a group on failure? * If not, we don't really need to make a JobTxn. */ - properties =3D get_transaction_properties(properties); - if (properties->completion_mode !=3D ACTION_COMPLETION_MODE_INDIVIDUAL= ) { + if (comp_mode !=3D ACTION_COMPLETION_MODE_INDIVIDUAL) { + for (act =3D actions; act; act =3D act->next) { + TransactionActionKind type =3D act->value->type; + + if (type !=3D TRANSACTION_ACTION_KIND_BLOCKDEV_BACKUP && + type !=3D TRANSACTION_ACTION_KIND_DRIVE_BACKUP) + { + error_setg(errp, + "Action '%s' does not support Transaction prope= rty " + "completion-mode =3D %s", + TransactionActionKind_str(type), + ActionCompletionMode_str(comp_mode)); + return; + } + } + block_job_txn =3D job_txn_new(); } =20 @@ -2409,7 +2359,6 @@ void qmp_transaction(TransactionActionList *actions, state->ops =3D ops; state->action =3D dev_info; state->block_job_txn =3D block_job_txn; - state->txn_props =3D properties; =20 state->ops->action(state, tran, &local_err); if (local_err) { @@ -2427,9 +2376,6 @@ delete_and_fail: /* failure, and it is all-or-none; roll back all operations */ tran_abort(tran); exit: - if (!has_properties) { - qapi_free_TransactionProperties(properties); - } job_txn_unref(block_job_txn); } =20 --=20 2.34.1 From nobody Tue May 14 23:52:36 2024 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail(p=none dis=none) header.from=yandex-team.ru Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1676994854442785.3718289407939; Tue, 21 Feb 2023 07:54:14 -0800 (PST) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1pUUvl-0002jT-NW; Tue, 21 Feb 2023 10:51:50 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1pUUvQ-00021e-Cj; Tue, 21 Feb 2023 10:51:28 -0500 Received: from forwardcorp1b.mail.yandex.net ([2a02:6b8:c02:900:1:45:d181:df01]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1pUUvK-0004XT-8g; Tue, 21 Feb 2023 10:51:28 -0500 Received: from mail-nwsmtp-smtp-corp-main-44.iva.yp-c.yandex.net (mail-nwsmtp-smtp-corp-main-44.iva.yp-c.yandex.net [IPv6:2a02:6b8:c0c:8923:0:640:c717:0]) by forwardcorp1b.mail.yandex.net (Yandex) with ESMTP id 1AE5B62112; Tue, 21 Feb 2023 18:51:07 +0300 (MSK) Received: from vsementsov-win.yandex-team.ru (unknown [2a02:6b8:b081:b584::1:19]) by mail-nwsmtp-smtp-corp-main-44.iva.yp-c.yandex.net (smtpcorp/Yandex) with ESMTPSA id rosEB10KmeA0-RNmGsj1X; Tue, 21 Feb 2023 18:51:05 +0300 X-Yandex-Fwd: 1 Authentication-Results: mail-nwsmtp-smtp-corp-main-44.iva.yp-c.yandex.net; dkim=pass From: Vladimir Sementsov-Ogievskiy To: qemu-block@nongnu.org Cc: qemu-devel@nongnu.org, hreitz@redhat.com, kwolf@redhat.com, alexander.ivanov@virtuozzo.com, den@openvz.org, vsementsov@yandex-team.ru, Vladimir Sementsov-Ogievskiy Subject: [PATCH v7 5/5] blockdev: qmp_transaction: drop extra generic layer Date: Tue, 21 Feb 2023 18:50:51 +0300 Message-Id: <20230221155051.746312-6-vsementsov@yandex-team.ru> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20230221155051.746312-1-vsementsov@yandex-team.ru> References: <20230221155051.746312-1-vsementsov@yandex-team.ru> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: pass client-ip=2a02:6b8:c02:900:1:45:d181:df01; envelope-from=vsementsov@yandex-team.ru; helo=forwardcorp1b.mail.yandex.net X-Spam_score_int: -18 X-Spam_score: -1.9 X-Spam_bar: - X-Spam_report: (-1.9 / 5.0 requ) BAYES_00=-1.9, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZM-MESSAGEID: 1676994855209100001 Content-Type: text/plain; charset="utf-8" From: Vladimir Sementsov-Ogievskiy Let's simplify things: First, actions generally don't need access to common BlkActionState structure. The only exclusion are backup actions that need block_job_txn. Next, for transaction actions of Transaction API is more native to allocated state structure in the action itself. So, do the following transformation: 1. Let all actions be represented by a function with corresponding structure as arguments. 2. Instead of array-map marshaller, let's make a function, that calls corresponding action directly. 3. BlkActionOps and BlkActionState structures become unused Signed-off-by: Vladimir Sementsov-Ogievskiy --- blockdev.c | 278 +++++++++++++++++------------------------------------ 1 file changed, 89 insertions(+), 189 deletions(-) diff --git a/blockdev.c b/blockdev.c index edaf7c6601..2bfa77e564 100644 --- a/blockdev.c +++ b/blockdev.c @@ -1178,54 +1178,8 @@ out_aio_context: return NULL; } =20 -/* New and old BlockDriverState structs for atomic group operations */ - -typedef struct BlkActionState BlkActionState; - -/** - * BlkActionOps: - * Table of operations that define an Action. - * - * @instance_size: Size of state struct, in bytes. - * @prepare: Prepare the work, must NOT be NULL. - * @commit: Commit the changes, can be NULL. - * @abort: Abort the changes on fail, can be NULL. - * @clean: Clean up resources after all transaction actions have called - * commit() or abort(). Can be NULL. - * - * Only prepare() may fail. In a single transaction, only one of commit() = or - * abort() will be called. clean() will always be called if it is present. - * - * Always run under BQL. - */ -typedef struct BlkActionOps { - size_t instance_size; - void (*action)(BlkActionState *common, Transaction *tran, Error **errp= ); -} BlkActionOps; - -/** - * BlkActionState: - * Describes one Action's state within a Transaction. - * - * @action: QAPI-defined enum identifying which Action to perform. - * @ops: Table of ActionOps this Action can perform. - * @block_job_txn: Transaction which this action belongs to. - * @entry: List membership for all Actions in this Transaction. - * - * This structure must be arranged as first member in a subclassed type, - * assuming that the compiler will also arrange it to the same offsets as = the - * base class. - */ -struct BlkActionState { - TransactionAction *action; - const BlkActionOps *ops; - JobTxn *block_job_txn; - QTAILQ_ENTRY(BlkActionState) entry; -}; - /* internal snapshot private data */ typedef struct InternalSnapshotState { - BlkActionState common; BlockDriverState *bs; QEMUSnapshotInfo sn; bool created; @@ -1238,7 +1192,7 @@ TransactionActionDrv internal_snapshot_drv =3D { .clean =3D internal_snapshot_clean, }; =20 -static void internal_snapshot_action(BlkActionState *common, +static void internal_snapshot_action(BlockdevSnapshotInternal *internal, Transaction *tran, Error **errp) { Error *local_err =3D NULL; @@ -1248,16 +1202,10 @@ static void internal_snapshot_action(BlkActionState= *common, QEMUSnapshotInfo old_sn, *sn; bool ret; int64_t rt; - BlockdevSnapshotInternal *internal; - InternalSnapshotState *state; + InternalSnapshotState *state =3D g_new0(InternalSnapshotState, 1); AioContext *aio_context; int ret1; =20 - g_assert(common->action->type =3D=3D - TRANSACTION_ACTION_KIND_BLOCKDEV_SNAPSHOT_INTERNAL_SYNC); - internal =3D common->action->u.blockdev_snapshot_internal_sync.data; - state =3D DO_UPCAST(InternalSnapshotState, common, common); - tran_add(tran, &internal_snapshot_drv, state); =20 device =3D internal->device; @@ -1385,7 +1333,6 @@ static void internal_snapshot_clean(void *opaque) =20 /* external snapshot private data */ typedef struct ExternalSnapshotState { - BlkActionState common; BlockDriverState *old_bs; BlockDriverState *new_bs; bool overlay_appended; @@ -1400,8 +1347,8 @@ TransactionActionDrv external_snapshot_drv =3D { .clean =3D external_snapshot_clean, }; =20 -static void external_snapshot_action(BlkActionState *common, Transaction *= tran, - Error **errp) +static void external_snapshot_action(TransactionAction *action, + Transaction *tran, Error **errp) { int ret; int flags =3D 0; @@ -1414,9 +1361,7 @@ static void external_snapshot_action(BlkActionState *= common, Transaction *tran, const char *snapshot_ref; /* File name of the new image (for 'blockdev-snapshot-sync') */ const char *new_image_file; - ExternalSnapshotState *state =3D - DO_UPCAST(ExternalSnapshotState, common, comm= on); - TransactionAction *action =3D common->action; + ExternalSnapshotState *state =3D g_new0(ExternalSnapshotState, 1); AioContext *aio_context; uint64_t perm, shared; =20 @@ -1652,7 +1597,6 @@ static void external_snapshot_clean(void *opaque) } =20 typedef struct DriveBackupState { - BlkActionState common; BlockDriverState *bs; BlockJob *job; } DriveBackupState; @@ -1672,11 +1616,11 @@ TransactionActionDrv drive_backup_drv =3D { .clean =3D drive_backup_clean, }; =20 -static void drive_backup_action(BlkActionState *common, Transaction *tran, - Error **errp) +static void drive_backup_action(DriveBackup *backup, + JobTxn *block_job_txn, + Transaction *tran, Error **errp) { - DriveBackupState *state =3D DO_UPCAST(DriveBackupState, common, common= ); - DriveBackup *backup; + DriveBackupState *state =3D g_new0(DriveBackupState, 1); BlockDriverState *bs; BlockDriverState *target_bs; BlockDriverState *source =3D NULL; @@ -1692,9 +1636,6 @@ static void drive_backup_action(BlkActionState *commo= n, Transaction *tran, =20 tran_add(tran, &drive_backup_drv, state); =20 - assert(common->action->type =3D=3D TRANSACTION_ACTION_KIND_DRIVE_BACKU= P); - backup =3D common->action->u.drive_backup.data; - if (!backup->has_mode) { backup->mode =3D NEW_IMAGE_MODE_ABSOLUTE_PATHS; } @@ -1814,7 +1755,7 @@ static void drive_backup_action(BlkActionState *commo= n, Transaction *tran, =20 state->job =3D do_backup_common(qapi_DriveBackup_base(backup), bs, target_bs, aio_context, - common->block_job_txn, errp); + block_job_txn, errp); =20 unref: bdrv_unref(target_bs); @@ -1865,7 +1806,6 @@ static void drive_backup_clean(void *opaque) } =20 typedef struct BlockdevBackupState { - BlkActionState common; BlockDriverState *bs; BlockJob *job; } BlockdevBackupState; @@ -1879,11 +1819,11 @@ TransactionActionDrv blockdev_backup_drv =3D { .clean =3D blockdev_backup_clean, }; =20 -static void blockdev_backup_action(BlkActionState *common, Transaction *tr= an, - Error **errp) +static void blockdev_backup_action(BlockdevBackup *backup, + JobTxn *block_job_txn, + Transaction *tran, Error **errp) { - BlockdevBackupState *state =3D DO_UPCAST(BlockdevBackupState, common, = common); - BlockdevBackup *backup; + BlockdevBackupState *state =3D g_new0(BlockdevBackupState, 1); BlockDriverState *bs; BlockDriverState *target_bs; AioContext *aio_context; @@ -1892,9 +1832,6 @@ static void blockdev_backup_action(BlkActionState *co= mmon, Transaction *tran, =20 tran_add(tran, &blockdev_backup_drv, state); =20 - assert(common->action->type =3D=3D TRANSACTION_ACTION_KIND_BLOCKDEV_BA= CKUP); - backup =3D common->action->u.blockdev_backup.data; - bs =3D bdrv_lookup_bs(backup->device, backup->device, errp); if (!bs) { return; @@ -1925,7 +1862,7 @@ static void blockdev_backup_action(BlkActionState *co= mmon, Transaction *tran, =20 state->job =3D do_backup_common(qapi_BlockdevBackup_base(backup), bs, target_bs, aio_context, - common->block_job_txn, errp); + block_job_txn, errp); =20 aio_context_release(aio_context); } @@ -1973,11 +1910,9 @@ static void blockdev_backup_clean(void *opaque) } =20 typedef struct BlockDirtyBitmapState { - BlkActionState common; BdrvDirtyBitmap *bitmap; BlockDriverState *bs; HBitmap *backup; - bool prepared; bool was_enabled; } BlockDirtyBitmapState; =20 @@ -1987,17 +1922,14 @@ TransactionActionDrv block_dirty_bitmap_add_drv =3D= { .clean =3D g_free, }; =20 -static void block_dirty_bitmap_add_action(BlkActionState *common, +static void block_dirty_bitmap_add_action(BlockDirtyBitmapAdd *action, Transaction *tran, Error **errp) { Error *local_err =3D NULL; - BlockDirtyBitmapAdd *action; - BlockDirtyBitmapState *state =3D DO_UPCAST(BlockDirtyBitmapState, - common, common); + BlockDirtyBitmapState *state =3D g_new0(BlockDirtyBitmapState, 1); =20 tran_add(tran, &block_dirty_bitmap_add_drv, state); =20 - action =3D common->action->u.block_dirty_bitmap_add.data; /* AIO context taken and released within qmp_block_dirty_bitmap_add */ qmp_block_dirty_bitmap_add(action->node, action->name, action->has_granularity, action->granularit= y, @@ -2006,7 +1938,8 @@ static void block_dirty_bitmap_add_action(BlkActionSt= ate *common, &local_err); =20 if (!local_err) { - state->prepared =3D true; + state->bitmap =3D block_dirty_bitmap_lookup(action->node, action->= name, + NULL, &error_abort); } else { error_propagate(errp, local_err); } @@ -2014,15 +1947,10 @@ static void block_dirty_bitmap_add_action(BlkAction= State *common, =20 static void block_dirty_bitmap_add_abort(void *opaque) { - BlockDirtyBitmapAdd *action; BlockDirtyBitmapState *state =3D opaque; =20 - action =3D state->common.action->u.block_dirty_bitmap_add.data; - /* Should not be able to fail: IF the bitmap was added via .prepare(), - * then the node reference and bitmap name must have been valid. - */ - if (state->prepared) { - qmp_block_dirty_bitmap_remove(action->node, action->name, &error_a= bort); + if (state->bitmap) { + bdrv_release_dirty_bitmap(state->bitmap); } } =20 @@ -2034,16 +1962,13 @@ TransactionActionDrv block_dirty_bitmap_clear_drv = =3D { .clean =3D g_free, }; =20 -static void block_dirty_bitmap_clear_action(BlkActionState *common, +static void block_dirty_bitmap_clear_action(BlockDirtyBitmap *action, Transaction *tran, Error **err= p) { - BlockDirtyBitmapState *state =3D DO_UPCAST(BlockDirtyBitmapState, - common, common); - BlockDirtyBitmap *action; + BlockDirtyBitmapState *state =3D g_new0(BlockDirtyBitmapState, 1); =20 tran_add(tran, &block_dirty_bitmap_clear_drv, state); =20 - action =3D common->action->u.block_dirty_bitmap_clear.data; state->bitmap =3D block_dirty_bitmap_lookup(action->node, action->name, &state->bs, @@ -2081,16 +2006,13 @@ TransactionActionDrv block_dirty_bitmap_enable_drv = =3D { .clean =3D g_free, }; =20 -static void block_dirty_bitmap_enable_action(BlkActionState *common, +static void block_dirty_bitmap_enable_action(BlockDirtyBitmap *action, Transaction *tran, Error **er= rp) { - BlockDirtyBitmap *action; - BlockDirtyBitmapState *state =3D DO_UPCAST(BlockDirtyBitmapState, - common, common); + BlockDirtyBitmapState *state =3D g_new0(BlockDirtyBitmapState, 1); =20 tran_add(tran, &block_dirty_bitmap_enable_drv, state); =20 - action =3D common->action->u.block_dirty_bitmap_enable.data; state->bitmap =3D block_dirty_bitmap_lookup(action->node, action->name, NULL, @@ -2122,16 +2044,13 @@ TransactionActionDrv block_dirty_bitmap_disable_drv= =3D { .clean =3D g_free, }; =20 -static void block_dirty_bitmap_disable_action(BlkActionState *common, +static void block_dirty_bitmap_disable_action(BlockDirtyBitmap *action, Transaction *tran, Error **e= rrp) { - BlockDirtyBitmap *action; - BlockDirtyBitmapState *state =3D DO_UPCAST(BlockDirtyBitmapState, - common, common); + BlockDirtyBitmapState *state =3D g_new0(BlockDirtyBitmapState, 1); =20 tran_add(tran, &block_dirty_bitmap_disable_drv, state); =20 - action =3D common->action->u.block_dirty_bitmap_disable.data; state->bitmap =3D block_dirty_bitmap_lookup(action->node, action->name, NULL, @@ -2163,17 +2082,13 @@ TransactionActionDrv block_dirty_bitmap_merge_drv = =3D { .clean =3D g_free, }; =20 -static void block_dirty_bitmap_merge_action(BlkActionState *common, +static void block_dirty_bitmap_merge_action(BlockDirtyBitmapMerge *action, Transaction *tran, Error **err= p) { - BlockDirtyBitmapMerge *action; - BlockDirtyBitmapState *state =3D DO_UPCAST(BlockDirtyBitmapState, - common, common); + BlockDirtyBitmapState *state =3D g_new0(BlockDirtyBitmapState, 1); =20 tran_add(tran, &block_dirty_bitmap_merge_drv, state); =20 - action =3D common->action->u.block_dirty_bitmap_merge.data; - state->bitmap =3D block_dirty_bitmap_merge(action->node, action->targe= t, action->bitmaps, &state->back= up, errp); @@ -2187,16 +2102,13 @@ TransactionActionDrv block_dirty_bitmap_remove_drv = =3D { .clean =3D g_free, }; =20 -static void block_dirty_bitmap_remove_action(BlkActionState *common, +static void block_dirty_bitmap_remove_action(BlockDirtyBitmap *action, Transaction *tran, Error **er= rp) { - BlockDirtyBitmap *action; - BlockDirtyBitmapState *state =3D DO_UPCAST(BlockDirtyBitmapState, - common, common); + BlockDirtyBitmapState *state =3D g_new0(BlockDirtyBitmapState, 1); =20 tran_add(tran, &block_dirty_bitmap_remove_drv, state); =20 - action =3D common->action->u.block_dirty_bitmap_remove.data; =20 state->bitmap =3D block_dirty_bitmap_remove(action->node, action->name, false, &state->bs, errp); @@ -2227,13 +2139,11 @@ static void block_dirty_bitmap_remove_commit(void *= opaque) static void abort_commit(void *opaque); TransactionActionDrv abort_drv =3D { .commit =3D abort_commit, - .clean =3D g_free, }; =20 -static void abort_action(BlkActionState *common, Transaction *tran, - Error **errp) +static void abort_action(Transaction *tran, Error **errp) { - tran_add(tran, &abort_drv, common); + tran_add(tran, &abort_drv, NULL); error_setg(errp, "Transaction aborted using Abort action"); } =20 @@ -2242,62 +2152,66 @@ static void abort_commit(void *opaque) g_assert_not_reached(); /* this action never succeeds */ } =20 -static const BlkActionOps actions_map[] =3D { - [TRANSACTION_ACTION_KIND_BLOCKDEV_SNAPSHOT] =3D { - .instance_size =3D sizeof(ExternalSnapshotState), - .action =3D external_snapshot_action, - }, - [TRANSACTION_ACTION_KIND_BLOCKDEV_SNAPSHOT_SYNC] =3D { - .instance_size =3D sizeof(ExternalSnapshotState), - .action =3D external_snapshot_action, - }, - [TRANSACTION_ACTION_KIND_DRIVE_BACKUP] =3D { - .instance_size =3D sizeof(DriveBackupState), - .action =3D drive_backup_action, - }, - [TRANSACTION_ACTION_KIND_BLOCKDEV_BACKUP] =3D { - .instance_size =3D sizeof(BlockdevBackupState), - .action =3D blockdev_backup_action, - }, - [TRANSACTION_ACTION_KIND_ABORT] =3D { - .instance_size =3D sizeof(BlkActionState), - .action =3D abort_action, - }, - [TRANSACTION_ACTION_KIND_BLOCKDEV_SNAPSHOT_INTERNAL_SYNC] =3D { - .instance_size =3D sizeof(InternalSnapshotState), - .action =3D internal_snapshot_action, - }, - [TRANSACTION_ACTION_KIND_BLOCK_DIRTY_BITMAP_ADD] =3D { - .instance_size =3D sizeof(BlockDirtyBitmapState), - .action =3D block_dirty_bitmap_add_action, - }, - [TRANSACTION_ACTION_KIND_BLOCK_DIRTY_BITMAP_CLEAR] =3D { - .instance_size =3D sizeof(BlockDirtyBitmapState), - .action =3D block_dirty_bitmap_clear_action, - }, - [TRANSACTION_ACTION_KIND_BLOCK_DIRTY_BITMAP_ENABLE] =3D { - .instance_size =3D sizeof(BlockDirtyBitmapState), - .action =3D block_dirty_bitmap_enable_action, - }, - [TRANSACTION_ACTION_KIND_BLOCK_DIRTY_BITMAP_DISABLE] =3D { - .instance_size =3D sizeof(BlockDirtyBitmapState), - .action =3D block_dirty_bitmap_disable_action, - }, - [TRANSACTION_ACTION_KIND_BLOCK_DIRTY_BITMAP_MERGE] =3D { - .instance_size =3D sizeof(BlockDirtyBitmapState), - .action =3D block_dirty_bitmap_merge_action, - }, - [TRANSACTION_ACTION_KIND_BLOCK_DIRTY_BITMAP_REMOVE] =3D { - .instance_size =3D sizeof(BlockDirtyBitmapState), - .action =3D block_dirty_bitmap_remove_action, - }, - /* Where are transactions for MIRROR, COMMIT and STREAM? +static void transaction_action(TransactionAction *act, JobTxn *block_job_t= xn, + Transaction *tran, Error **errp) +{ + switch (act->type) { + case TRANSACTION_ACTION_KIND_BLOCKDEV_SNAPSHOT: + case TRANSACTION_ACTION_KIND_BLOCKDEV_SNAPSHOT_SYNC: + external_snapshot_action(act, tran, errp); + return; + case TRANSACTION_ACTION_KIND_DRIVE_BACKUP: + drive_backup_action(act->u.drive_backup.data, + block_job_txn, tran, errp); + return; + case TRANSACTION_ACTION_KIND_BLOCKDEV_BACKUP: + blockdev_backup_action(act->u.blockdev_backup.data, + block_job_txn, tran, errp); + return; + case TRANSACTION_ACTION_KIND_ABORT: + abort_action(tran, errp); + return; + case TRANSACTION_ACTION_KIND_BLOCKDEV_SNAPSHOT_INTERNAL_SYNC: + internal_snapshot_action(act->u.blockdev_snapshot_internal_sync.da= ta, + tran, errp); + return; + case TRANSACTION_ACTION_KIND_BLOCK_DIRTY_BITMAP_ADD: + block_dirty_bitmap_add_action(act->u.block_dirty_bitmap_add.data, + tran, errp); + return; + case TRANSACTION_ACTION_KIND_BLOCK_DIRTY_BITMAP_CLEAR: + block_dirty_bitmap_clear_action(act->u.block_dirty_bitmap_clear.da= ta, + tran, errp); + return; + case TRANSACTION_ACTION_KIND_BLOCK_DIRTY_BITMAP_ENABLE: + block_dirty_bitmap_enable_action(act->u.block_dirty_bitmap_enable.= data, + tran, errp); + return; + case TRANSACTION_ACTION_KIND_BLOCK_DIRTY_BITMAP_DISABLE: + block_dirty_bitmap_disable_action( + act->u.block_dirty_bitmap_disable.data, tran, errp); + return; + case TRANSACTION_ACTION_KIND_BLOCK_DIRTY_BITMAP_MERGE: + block_dirty_bitmap_merge_action(act->u.block_dirty_bitmap_merge.da= ta, + tran, errp); + return; + case TRANSACTION_ACTION_KIND_BLOCK_DIRTY_BITMAP_REMOVE: + block_dirty_bitmap_remove_action(act->u.block_dirty_bitmap_remove.= data, + tran, errp); + return; + /* + * Where are transactions for MIRROR, COMMIT and STREAM? * Although these blockjobs use transaction callbacks like the backup = job, * these jobs do not necessarily adhere to transaction semantics. * These jobs may not fully undo all of their actions on abort, nor do= they * necessarily work in transactions with more than one job in them. */ -}; + case TRANSACTION_ACTION_KIND__MAX: + default: + g_assert_not_reached(); + }; +} + =20 /* * 'Atomic' group operations. The operations are performed as a set, and = if @@ -2346,21 +2260,7 @@ void qmp_transaction(TransactionActionList *actions, =20 /* We don't do anything in this loop that commits us to the operations= */ for (act =3D actions; act; act =3D act->next) { - TransactionAction *dev_info =3D act->value; - const BlkActionOps *ops; - BlkActionState *state; - - assert(dev_info->type < ARRAY_SIZE(actions_map)); - - ops =3D &actions_map[dev_info->type]; - assert(ops->instance_size > 0); - - state =3D g_malloc0(ops->instance_size); - state->ops =3D ops; - state->action =3D dev_info; - state->block_job_txn =3D block_job_txn; - - state->ops->action(state, tran, &local_err); + transaction_action(act->value, block_job_txn, tran, &local_err); if (local_err) { error_propagate(errp, local_err); goto delete_and_fail; --=20 2.34.1