From nobody Mon Feb 9 16:36:25 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=1682078108; cv=none; d=zohomail.com; s=zohoarc; b=eYrIP0EqmsKT3qjyzm2IQyzZixFPV8mcCRTvPE/rv4npAknGp+4ZtcMcTlyR1rwuUpQA6O/dOLeZTZkwmJi5k5iGnXp+gD/dzxmdezGTHmLWzt0wM3vFk7G2PSLN6Ozrvp2AaBbwaOb7OLTbsk/ANlkpJzxJPSkwLR40h8FJD08= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1682078108; 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=zzGDHoq70eJc8ePfBI1i2glNUAtITItIkhjL960g/U0=; b=ZfA/4L/hz7nkMlkqmlZvti9/zgoYODuIXsoSfy4vQCZH3q/dy/Ajla9U9eJEiKdrs30wDrac8VE8rzFDCEG2sXq12vZ4yhp+USyrXlkAfEKFIx5/dLOBi355fyK2N2hldNpXHvaKircmwjHfFgaLv0sea7Dsfft/aNd24F9fR78= 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 1682078108787714.7665213098155; Fri, 21 Apr 2023 04:55:08 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1pppKz-0006VM-Ot; Fri, 21 Apr 2023 07:54:01 -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 1pppKu-0006SF-Ix; Fri, 21 Apr 2023 07:53:57 -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 1pppKr-0003wX-A1; Fri, 21 Apr 2023 07:53:56 -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:7f29:0:640:9a2b:0]) by forwardcorp1c.mail.yandex.net (Yandex) with ESMTP id 6D96760139; Fri, 21 Apr 2023 14:53:43 +0300 (MSK) Received: from vsementsov-nix.yandex.net (unknown [2a02:6b8:b081:8816::1:4]) by mail-nwsmtp-smtp-corp-main-44.iva.yp-c.yandex.net (smtpcorp/Yandex) with ESMTPSA id SrdkeT1Ona60-2tmVvt8V; Fri, 21 Apr 2023 14:53:42 +0300 X-Yandex-Fwd: 1 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yandex-team.ru; s=default; t=1682078022; bh=zzGDHoq70eJc8ePfBI1i2glNUAtITItIkhjL960g/U0=; h=Message-Id:Date:In-Reply-To:Cc:Subject:References:To:From; b=ZLq/+Mw+9nO0daiVdMqqc/wiZ422Szb4xs1HcvwPMZ1IGnp827oZGV7PIZd/7zbK9 eM9NNytQR79RaZDhHt3Hlozt3vnxl9YqTkiLAI75+DNkW5DGaN5LVj2w0hryfvSYon P3xNRH3AQOxp5qWWqb0ZfYllqWHQl50W2CQ3mnzY= 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, hreitz@redhat.com, kwolf@redhat.com, den@openvz.org, alexander.ivanov@virtuozzo.com, Vladimir Sementsov-Ogievskiy Subject: [PATCH v8 5/5] blockdev: qmp_transaction: drop extra generic layer Date: Fri, 21 Apr 2023 14:53:27 +0300 Message-Id: <20230421115327.907104-6-vsementsov@yandex-team.ru> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20230421115327.907104-1-vsementsov@yandex-team.ru> References: <20230421115327.907104-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: 1682078109772100005 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 | 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