From nobody Tue Feb 10 13:36:54 2026 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; 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=pass(p=none dis=none) header.from=yandex-team.ru ARC-Seal: i=1; a=rsa-sha256; t=1683731306; cv=none; d=zohomail.com; s=zohoarc; b=aa60mkXaFU6wYN3O8Ug77IiH5QwBYLcBGQ+WF8CzCjDbKx5+sw+IapE549NQLei7FfdEAUxOJFJ9fjX7hiZIJq8BVjZgi9jyEAtgvKZ7sblc8mqA6kbvprHinsbm/P0ZCD5tBiGg5kAyB9Xuose6vlS5s+YVPLM4CCzvzV1k4qM= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1683731306; h=Content-Transfer-Encoding:Cc:Date:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:To; bh=uvC/9tJikHQto5fPs1uuzEh6Moc77wBMQshr3GgWtRU=; b=OIU0yVtW//Lti7E5Px9wrtfywbW0XRa/2k4UXaAg4NI/Vth9njRrNqEFvyiowkJ3LN32bEgjjs4oC8WwxqcFQTdCGl9GPUw8l3MK+HTQw/c1OlfArVlca20IwftRMJE65I71lUZ2BZ4qPDZeaY/JVohKgBEz3tuPRqSKwkuXH4c= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; 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=pass header.from= (p=none dis=none) Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 16837313063271003.6124449332922; Wed, 10 May 2023 08:08:26 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1pwlPP-0006v9-CN; Wed, 10 May 2023 11:07:15 -0400 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 1pwlPE-0006sH-Ve; Wed, 10 May 2023 11:07:05 -0400 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 1pwlP0-0001To-By; Wed, 10 May 2023 11:07:04 -0400 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:a884:0:640:947b:0]) by forwardcorp1c.mail.yandex.net (Yandex) with ESMTP id EF54B5EC48; Wed, 10 May 2023 18:06:41 +0300 (MSK) Received: from vsementsov-nix.yandex-team.ru (unknown [2a02:6b8:b081:2::1:11]) by mail-nwsmtp-smtp-corp-main-44.iva.yp-c.yandex.net (smtpcorp/Yandex) with ESMTPSA id P6XgPR0OpqM0-mLvyswwE; Wed, 10 May 2023 18:06:40 +0300 X-Yandex-Fwd: 1 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yandex-team.ru; s=default; t=1683731200; bh=uvC/9tJikHQto5fPs1uuzEh6Moc77wBMQshr3GgWtRU=; h=Message-Id:Date:In-Reply-To:Cc:Subject:References:To:From; b=Taapu9TS9GV0qVSSt9O8TQ/AmR7C46VFynXpPEoKwgK52Gdg1+GD17eLE13l+QMPx XwNKZS0v+LQS+58IwqzQtzYlCpAV/UeiSS+xiphFnGia5uEPAnWeodbDEnipLSB6NQ hcMEj3KcjYChirdgcbgOuE1c4EDU7C5mTe5D5qGQ= Authentication-Results: mail-nwsmtp-smtp-corp-main-44.iva.yp-c.yandex.net; dkim=pass header.i=@yandex-team.ru From: Vladimir Sementsov-Ogievskiy To: qemu-block@nongnu.org Cc: qemu-devel@nongnu.org, kwolf@redhat.com, hreitz@redhat.com, vsementsov@yandex-team.ru, den@openvz.org, alexander.ivanov@virtuozzo.com Subject: [PATCH v9 6/6] blockdev: qmp_transaction: drop extra generic layer Date: Wed, 10 May 2023 18:06:24 +0300 Message-Id: <20230510150624.310640-7-vsementsov@yandex-team.ru> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20230510150624.310640-1-vsementsov@yandex-team.ru> References: <20230510150624.310640-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: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, SPF_HELO_NONE=0.001, SPF_PASS=-0.001, T_SCC_BODY_TEXT_LINE=-0.01 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-ZohoMail-DKIM: pass (identity @yandex-team.ru) X-ZM-MESSAGEID: 1683731308697100007 Content-Type: text/plain; charset="utf-8" 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 | 266 +++++++++++++++++------------------------------------ 1 file changed, 85 insertions(+), 181 deletions(-) diff --git a/blockdev.c b/blockdev.c index 10003bdc52..75f7e209a9 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; @@ -1383,7 +1331,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; @@ -1398,8 +1345,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; @@ -1412,9 +1359,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 @@ -1648,7 +1593,6 @@ static void external_snapshot_clean(void *opaque) } =20 typedef struct DriveBackupState { - BlkActionState common; BlockDriverState *bs; BlockJob *job; } DriveBackupState; @@ -1668,11 +1612,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; @@ -1688,9 +1632,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; } @@ -1810,7 +1751,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); @@ -1859,7 +1800,6 @@ static void drive_backup_clean(void *opaque) } =20 typedef struct BlockdevBackupState { - BlkActionState common; BlockDriverState *bs; BlockJob *job; } BlockdevBackupState; @@ -1873,11 +1813,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; @@ -1886,9 +1826,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; @@ -1919,7 +1856,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); } @@ -1965,11 +1902,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 @@ -1979,17 +1914,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, @@ -2022,16 +1954,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, @@ -2069,16 +1998,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, @@ -2110,16 +2036,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, @@ -2151,17 +2074,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); @@ -2175,16 +2094,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); @@ -2215,13 +2131,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 @@ -2230,62 +2144,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 @@ -2336,21 +2254,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