From nobody Fri Nov 14 00:48:48 2025 Delivered-To: importer@patchew.org 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; 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=virtuozzo.com ARC-Seal: i=1; a=rsa-sha256; t=1583480498; cv=none; d=zohomail.com; s=zohoarc; b=HhvynZDc075RzoUyUzpSM1gQaxu8/qiTJoXz8YiZSs8j4O4hiZ29o7SLyNxGrbvPE9vndWzeD1BemnyIogL4xL6K8gNDs1x+wlOB37ZBM79RZrtGgIo3Na8zWQ+C9vLs9QLLWY6HJ4J6+ttAh/DDx/Zo91BK+OxxcBNrvr1BoCQ= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1583480498; h=Content-Type: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=0CgiwzpIJkPZJZZH1JbjyX/5+6jCsjAJvZQ2R1iladE=; b=ZpuPMLl6JCzyFdYYVB2ojW9/CuJ28z2sjBYLuV3nAbhPLV7a8tyIA7BTx0xPtq3ij1mKnPq+HlywPiIAMxLVoo/i5roLS43+Rzk/jz82djctQOKWQtt5qhcYovvVGFq3Bv7DM3Kxc9pPtxUPt2pAqhdwL/p1XM4MhA3dJo30t+E= ARC-Authentication-Results: i=1; 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 header.from= (p=none dis=none) header.from= Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1583480498321133.38076481183123; Thu, 5 Mar 2020 23:41:38 -0800 (PST) Received: from localhost ([::1]:60518 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1jA7c1-0002YL-78 for importer@patchew.org; Fri, 06 Mar 2020 02:41:37 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]:46366) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1jA7ZJ-000585-0k for qemu-devel@nongnu.org; Fri, 06 Mar 2020 02:38:50 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1jA7ZG-0008P1-Vy for qemu-devel@nongnu.org; Fri, 06 Mar 2020 02:38:48 -0500 Received: from relay.sw.ru ([185.231.240.75]:37988) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1jA7ZC-0007ws-Hl; Fri, 06 Mar 2020 02:38:42 -0500 Received: from vovaso.qa.sw.ru ([10.94.3.0] helo=kvm.qa.sw.ru) by relay.sw.ru with esmtp (Exim 4.92.3) (envelope-from ) id 1jA7Z8-0002Qu-SB; Fri, 06 Mar 2020 10:38:38 +0300 From: Vladimir Sementsov-Ogievskiy To: qemu-block@nongnu.org Subject: [PATCH v3 9/9] block/block-copy: hide structure definitions Date: Fri, 6 Mar 2020 10:38:31 +0300 Message-Id: <20200306073831.7737-10-vsementsov@virtuozzo.com> X-Mailer: git-send-email 2.21.0 In-Reply-To: <20200306073831.7737-1-vsementsov@virtuozzo.com> References: <20200306073831.7737-1-vsementsov@virtuozzo.com> MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable X-detected-operating-system: by eggs.gnu.org: GNU/Linux 3.x [fuzzy] X-Received-From: 185.231.240.75 X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: kwolf@redhat.com, vsementsov@virtuozzo.com, qemu-devel@nongnu.org, mreitz@redhat.com, andrey.shinkevich@virtuozzo.com, jsnow@redhat.com Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" Hide structure definitions and add explicit API instead, to keep an eye on the scope of the shared fields. Signed-off-by: Vladimir Sementsov-Ogievskiy Reviewed-by: Andrey Shinkevich Reviewed-by: Max Reitz --- include/block/block-copy.h | 52 +++---------------------------- block/backup-top.c | 6 ++-- block/backup.c | 25 +++++++-------- block/block-copy.c | 63 ++++++++++++++++++++++++++++++++++++-- 4 files changed, 82 insertions(+), 64 deletions(-) diff --git a/include/block/block-copy.h b/include/block/block-copy.h index c46b382cc6..9718c241c9 100644 --- a/include/block/block-copy.h +++ b/include/block/block-copy.h @@ -18,56 +18,9 @@ #include "block/block.h" #include "qemu/co-shared-resource.h" =20 -typedef struct BlockCopyInFlightReq { - int64_t offset; - int64_t bytes; - QLIST_ENTRY(BlockCopyInFlightReq) list; - CoQueue wait_queue; /* coroutines blocked on this request */ -} BlockCopyInFlightReq; - typedef void (*ProgressBytesCallbackFunc)(int64_t bytes, void *opaque); typedef void (*ProgressResetCallbackFunc)(void *opaque); -typedef struct BlockCopyState { - /* - * BdrvChild objects are not owned or managed by block-copy. They are - * provided by block-copy user and user is responsible for appropriate - * permissions on these children. - */ - BdrvChild *source; - BdrvChild *target; - BdrvDirtyBitmap *copy_bitmap; - int64_t in_flight_bytes; - int64_t cluster_size; - bool use_copy_range; - int64_t copy_size; - uint64_t len; - QLIST_HEAD(, BlockCopyInFlightReq) inflight_reqs; - - BdrvRequestFlags write_flags; - - /* - * skip_unallocated: - * - * Used by sync=3Dtop jobs, which first scan the source node for unall= ocated - * areas and clear them in the copy_bitmap. During this process, the = bitmap - * is thus not fully initialized: It may still have bits set for areas= that - * are unallocated and should actually not be copied. - * - * This is indicated by skip_unallocated. - * - * In this case, block_copy() will query the source=E2=80=99s allocati= on status, - * skip unallocated regions, clear them in the copy_bitmap, and invoke - * block_copy_reset_unallocated() every time it does. - */ - bool skip_unallocated; - - ProgressMeter *progress; - /* progress_bytes_callback: called when some copying progress is done.= */ - ProgressBytesCallbackFunc progress_bytes_callback; - void *progress_opaque; - - SharedResource *mem; -} BlockCopyState; +typedef struct BlockCopyState BlockCopyState; =20 BlockCopyState *block_copy_state_new(BdrvChild *source, BdrvChild *target, int64_t cluster_size, @@ -89,4 +42,7 @@ int64_t block_copy_reset_unallocated(BlockCopyState *s, int coroutine_fn block_copy(BlockCopyState *s, int64_t offset, int64_t byt= es, bool *error_is_read); =20 +BdrvDirtyBitmap *block_copy_dirty_bitmap(BlockCopyState *s); +void block_copy_set_skip_unallocated(BlockCopyState *s, bool skip); + #endif /* BLOCK_COPY_H */ diff --git a/block/backup-top.c b/block/backup-top.c index 1bfb360bd3..3b50c06e2c 100644 --- a/block/backup-top.c +++ b/block/backup-top.c @@ -38,6 +38,7 @@ typedef struct BDRVBackupTopState { BlockCopyState *bcs; BdrvChild *target; bool active; + int64_t cluster_size; } BDRVBackupTopState; =20 static coroutine_fn int backup_top_co_preadv( @@ -57,8 +58,8 @@ static coroutine_fn int backup_top_cbw(BlockDriverState *= bs, uint64_t offset, return 0; } =20 - off =3D QEMU_ALIGN_DOWN(offset, s->bcs->cluster_size); - end =3D QEMU_ALIGN_UP(offset + bytes, s->bcs->cluster_size); + off =3D QEMU_ALIGN_DOWN(offset, s->cluster_size); + end =3D QEMU_ALIGN_UP(offset + bytes, s->cluster_size); =20 return block_copy(s->bcs, off, end - off, NULL); } @@ -238,6 +239,7 @@ BlockDriverState *bdrv_backup_top_append(BlockDriverSta= te *source, goto fail; } =20 + state->cluster_size =3D cluster_size; state->bcs =3D block_copy_state_new(top->backing, state->target, cluster_size, write_flags, &local_er= r); if (local_err) { diff --git a/block/backup.c b/block/backup.c index 8694e0394b..7430ca5883 100644 --- a/block/backup.c +++ b/block/backup.c @@ -102,7 +102,7 @@ static void backup_cleanup_sync_bitmap(BackupBlockJob *= job, int ret) =20 if (ret < 0 && job->bitmap_mode =3D=3D BITMAP_SYNC_MODE_ALWAYS) { /* If we failed and synced, merge in the bits we didn't copy: */ - bdrv_dirty_bitmap_merge_internal(bm, job->bcs->copy_bitmap, + bdrv_dirty_bitmap_merge_internal(bm, block_copy_dirty_bitmap(job->= bcs), NULL, true); } } @@ -145,7 +145,8 @@ void backup_do_checkpoint(BlockJob *job, Error **errp) return; } =20 - bdrv_set_dirty_bitmap(backup_job->bcs->copy_bitmap, 0, backup_job->len= ); + bdrv_set_dirty_bitmap(block_copy_dirty_bitmap(backup_job->bcs), 0, + backup_job->len); } =20 static BlockErrorAction backup_error_action(BackupBlockJob *job, @@ -190,7 +191,7 @@ static int coroutine_fn backup_loop(BackupBlockJob *job) BdrvDirtyBitmapIter *bdbi; int ret =3D 0; =20 - bdbi =3D bdrv_dirty_iter_new(job->bcs->copy_bitmap); + bdbi =3D bdrv_dirty_iter_new(block_copy_dirty_bitmap(job->bcs)); while ((offset =3D bdrv_dirty_iter_next(bdbi)) !=3D -1) { do { if (yield_and_check(job)) { @@ -210,14 +211,14 @@ static int coroutine_fn backup_loop(BackupBlockJob *j= ob) return ret; } =20 -static void backup_init_copy_bitmap(BackupBlockJob *job) +static void backup_init_bcs_bitmap(BackupBlockJob *job) { bool ret; uint64_t estimate; + BdrvDirtyBitmap *bcs_bitmap =3D block_copy_dirty_bitmap(job->bcs); =20 if (job->sync_mode =3D=3D MIRROR_SYNC_MODE_BITMAP) { - ret =3D bdrv_dirty_bitmap_merge_internal(job->bcs->copy_bitmap, - job->sync_bitmap, + ret =3D bdrv_dirty_bitmap_merge_internal(bcs_bitmap, job->sync_bit= map, NULL, true); assert(ret); } else { @@ -226,12 +227,12 @@ static void backup_init_copy_bitmap(BackupBlockJob *j= ob) * We can't hog the coroutine to initialize this thoroughly. * Set a flag and resume work when we are able to yield safely. */ - job->bcs->skip_unallocated =3D true; + block_copy_set_skip_unallocated(job->bcs, true); } - bdrv_set_dirty_bitmap(job->bcs->copy_bitmap, 0, job->len); + bdrv_set_dirty_bitmap(bcs_bitmap, 0, job->len); } =20 - estimate =3D bdrv_get_dirty_count(job->bcs->copy_bitmap); + estimate =3D bdrv_get_dirty_count(bcs_bitmap); job_progress_set_remaining(&job->common.job, estimate); } =20 @@ -240,7 +241,7 @@ static int coroutine_fn backup_run(Job *job, Error **er= rp) BackupBlockJob *s =3D container_of(job, BackupBlockJob, common.job); int ret =3D 0; =20 - backup_init_copy_bitmap(s); + backup_init_bcs_bitmap(s); =20 if (s->sync_mode =3D=3D MIRROR_SYNC_MODE_TOP) { int64_t offset =3D 0; @@ -259,12 +260,12 @@ static int coroutine_fn backup_run(Job *job, Error **= errp) =20 offset +=3D count; } - s->bcs->skip_unallocated =3D false; + block_copy_set_skip_unallocated(s->bcs, false); } =20 if (s->sync_mode =3D=3D MIRROR_SYNC_MODE_NONE) { /* - * All bits are set in copy_bitmap to allow any cluster to be copi= ed. + * All bits are set in bcs bitmap to allow any cluster to be copie= d. * This does not actually require them to be copied. */ while (!job_is_cancelled(job)) { diff --git a/block/block-copy.c b/block/block-copy.c index d66b8eb691..a2d8579ca0 100644 --- a/block/block-copy.c +++ b/block/block-copy.c @@ -24,9 +24,58 @@ #define BLOCK_COPY_MAX_BUFFER (1 * MiB) #define BLOCK_COPY_MAX_MEM (128 * MiB) =20 +typedef struct BlockCopyInFlightReq { + int64_t offset; + int64_t bytes; + QLIST_ENTRY(BlockCopyInFlightReq) list; + CoQueue wait_queue; /* coroutines blocked on this request */ +} BlockCopyInFlightReq; + +typedef struct BlockCopyState { + /* + * BdrvChild objects are not owned or managed by block-copy. They are + * provided by block-copy user and user is responsible for appropriate + * permissions on these children. + */ + BdrvChild *source; + BdrvChild *target; + BdrvDirtyBitmap *copy_bitmap; + int64_t in_flight_bytes; + int64_t cluster_size; + bool use_copy_range; + int64_t copy_size; + uint64_t len; + QLIST_HEAD(, BlockCopyInFlightReq) inflight_reqs; + + BdrvRequestFlags write_flags; + + /* + * skip_unallocated: + * + * Used by sync=3Dtop jobs, which first scan the source node for unall= ocated + * areas and clear them in the copy_bitmap. During this process, the = bitmap + * is thus not fully initialized: It may still have bits set for areas= that + * are unallocated and should actually not be copied. + * + * This is indicated by skip_unallocated. + * + * In this case, block_copy() will query the source=E2=80=99s allocati= on status, + * skip unallocated regions, clear them in the copy_bitmap, and invoke + * block_copy_reset_unallocated() every time it does. + */ + bool skip_unallocated; + + ProgressMeter *progress; + /* progress_bytes_callback: called when some copying progress is done.= */ + ProgressBytesCallbackFunc progress_bytes_callback; + void *progress_opaque; + + SharedResource *mem; +} BlockCopyState; + static BlockCopyInFlightReq *find_conflicting_inflight_req(BlockCopyState = *s, - int64_t offset, - int64_t bytes) + int64_t offset, + int64_t bytes) { BlockCopyInFlightReq *req; =20 @@ -516,3 +565,13 @@ int coroutine_fn block_copy(BlockCopyState *s, int64_t= offset, int64_t bytes, =20 return ret; } + +BdrvDirtyBitmap *block_copy_dirty_bitmap(BlockCopyState *s) +{ + return s->copy_bitmap; +} + +void block_copy_set_skip_unallocated(BlockCopyState *s, bool skip) +{ + s->skip_unallocated =3D skip; +} --=20 2.21.0