From: Andrey Shinkevich <andrey.shinkevich@virtuozzo.com>
To: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>,
qemu-block@nongnu.org
Cc: kwolf@redhat.com, den@openvz.org, jsnow@redhat.com,
qemu-devel@nongnu.org, mreitz@redhat.com
Subject: Re: [PATCH v2 7/7] block/block-copy: hide structure definitions
Date: Thu, 30 Jan 2020 21:58:12 +0300 [thread overview]
Message-ID: <9db878a7-fe50-e8b3-bf6c-e5cc754e4262@virtuozzo.com> (raw)
In-Reply-To: <20191127180840.11937-8-vsementsov@virtuozzo.com>
On 27/11/2019 21:08, Vladimir Sementsov-Ogievskiy wrote:
> 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 <vsementsov@virtuozzo.com>
> ---
> include/block/block-copy.h | 57 +++------------------------------
> block/backup-top.c | 6 ++--
> block/backup.c | 27 ++++++++--------
> block/block-copy.c | 64 ++++++++++++++++++++++++++++++++++++++
> 4 files changed, 86 insertions(+), 68 deletions(-)
>
> diff --git a/include/block/block-copy.h b/include/block/block-copy.h
> index d96b097267..753fa663ac 100644
> --- a/include/block/block-copy.h
> +++ b/include/block/block-copy.h
> @@ -18,61 +18,9 @@
> #include "block/block.h"
> #include "qemu/co-shared-resource.h"
>
> -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 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=top jobs, which first scan the source node for unallocated
> - * 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’s allocation status,
> - * skip unallocated regions, clear them in the copy_bitmap, and invoke
> - * block_copy_reset_unallocated() every time it does.
> - */
> - bool skip_unallocated;
> -
> - /* progress_bytes_callback: called when some copying progress is done. */
> - ProgressBytesCallbackFunc progress_bytes_callback;
> -
> - /*
> - * progress_reset_callback: called when some bytes reset from copy_bitmap
> - * (see @skip_unallocated above). The callee is assumed to recalculate how
> - * many bytes remain based on the dirty bit count of copy_bitmap.
> - */
> - ProgressResetCallbackFunc progress_reset_callback;
> - void *progress_opaque;
> -
> - SharedResource *mem;
> -} BlockCopyState;
> +typedef struct BlockCopyState BlockCopyState;
>
> BlockCopyState *block_copy_state_new(BdrvChild *source, BdrvChild *target,
> int64_t cluster_size,
> @@ -93,4 +41,7 @@ int64_t block_copy_reset_unallocated(BlockCopyState *s,
> int coroutine_fn block_copy(BlockCopyState *s, int64_t start, uint64_t bytes,
> bool *error_is_read);
>
> +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 7cdb1f8eba..1026628b57 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;
>
> static coroutine_fn int backup_top_co_preadv(
> @@ -51,8 +52,8 @@ static coroutine_fn int backup_top_cbw(BlockDriverState *bs, uint64_t offset,
> uint64_t bytes)
> {
> BDRVBackupTopState *s = bs->opaque;
> - uint64_t end = QEMU_ALIGN_UP(offset + bytes, s->bcs->cluster_size);
> - uint64_t off = QEMU_ALIGN_DOWN(offset, s->bcs->cluster_size);
> + uint64_t end = QEMU_ALIGN_UP(offset + bytes, s->cluster_size);
> + uint64_t off = QEMU_ALIGN_DOWN(offset, s->cluster_size);
>
> return block_copy(s->bcs, off, end - off, NULL);
> }
> @@ -227,6 +228,7 @@ BlockDriverState *bdrv_backup_top_append(BlockDriverState *source,
> goto failed_after_append;
> }
>
> + state->cluster_size = cluster_size;
> state->bcs = block_copy_state_new(top->backing, state->target,
> cluster_size, write_flags, &local_err);
> if (local_err) {
> diff --git a/block/backup.c b/block/backup.c
> index cf62b1a38c..acab0d08da 100644
> --- a/block/backup.c
> +++ b/block/backup.c
> @@ -48,6 +48,7 @@ typedef struct BackupBlockJob {
> int64_t cluster_size;
>
> BlockCopyState *bcs;
> + BdrvDirtyBitmap *bcs_bitmap;
> } BackupBlockJob;
>
> static const BlockJobDriver backup_job_driver;
> @@ -63,7 +64,7 @@ static void backup_progress_bytes_callback(int64_t bytes, void *opaque)
> static void backup_progress_reset_callback(void *opaque)
> {
> BackupBlockJob *s = opaque;
> - uint64_t estimate = bdrv_get_dirty_count(s->bcs->copy_bitmap);
> + uint64_t estimate = bdrv_get_dirty_count(s->bcs_bitmap);
>
> job_progress_set_remaining(&s->common.job, estimate);
> }
> @@ -111,8 +112,7 @@ static void backup_cleanup_sync_bitmap(BackupBlockJob *job, int ret)
>
> if (ret < 0 && job->bitmap_mode == 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,
> - NULL, true);
> + bdrv_dirty_bitmap_merge_internal(bm, job->bcs_bitmap, NULL, true);
> }
> }
>
> @@ -151,7 +151,7 @@ void backup_do_checkpoint(BlockJob *job, Error **errp)
> return;
> }
>
> - bdrv_set_dirty_bitmap(backup_job->bcs->copy_bitmap, 0, backup_job->len);
> + bdrv_set_dirty_bitmap(backup_job->bcs_bitmap, 0, backup_job->len);
> }
>
> static BlockErrorAction backup_error_action(BackupBlockJob *job,
> @@ -196,7 +196,7 @@ static int coroutine_fn backup_loop(BackupBlockJob *job)
> BdrvDirtyBitmapIter *bdbi;
> int ret = 0;
>
> - bdbi = bdrv_dirty_iter_new(job->bcs->copy_bitmap);
> + bdbi = bdrv_dirty_iter_new(job->bcs_bitmap);
> while ((offset = bdrv_dirty_iter_next(bdbi)) != -1) {
> do {
> if (yield_and_check(job)) {
> @@ -216,13 +216,13 @@ static int coroutine_fn backup_loop(BackupBlockJob *job)
> return ret;
> }
>
> -static void backup_init_copy_bitmap(BackupBlockJob *job)
> +static void backup_init_bcs_bitmap(BackupBlockJob *job)
> {
> bool ret;
> uint64_t estimate;
>
> if (job->sync_mode == MIRROR_SYNC_MODE_BITMAP) {
> - ret = bdrv_dirty_bitmap_merge_internal(job->bcs->copy_bitmap,
> + ret = bdrv_dirty_bitmap_merge_internal(job->bcs_bitmap,
> job->sync_bitmap,
> NULL, true);
> assert(ret);
> @@ -232,12 +232,12 @@ static void backup_init_copy_bitmap(BackupBlockJob *job)
> * 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 = true;
> + block_copy_set_skip_unallocated(job->bcs, true);
> }
> - bdrv_set_dirty_bitmap(job->bcs->copy_bitmap, 0, job->len);
> + bdrv_set_dirty_bitmap(job->bcs_bitmap, 0, job->len);
> }
>
> - estimate = bdrv_get_dirty_count(job->bcs->copy_bitmap);
> + estimate = bdrv_get_dirty_count(job->bcs_bitmap);
> job_progress_set_remaining(&job->common.job, estimate);
> }
>
> @@ -246,7 +246,7 @@ static int coroutine_fn backup_run(Job *job, Error **errp)
> BackupBlockJob *s = container_of(job, BackupBlockJob, common.job);
> int ret = 0;
>
> - backup_init_copy_bitmap(s);
> + backup_init_bcs_bitmap(s);
>
> if (s->sync_mode == MIRROR_SYNC_MODE_TOP) {
> int64_t offset = 0;
> @@ -265,12 +265,12 @@ static int coroutine_fn backup_run(Job *job, Error **errp)
>
> offset += count;
> }
> - s->bcs->skip_unallocated = false;
> + block_copy_set_skip_unallocated(s->bcs, false);
> }
>
> if (s->sync_mode == MIRROR_SYNC_MODE_NONE) {
> /*
> - * All bits are set in copy_bitmap to allow any cluster to be copied.
> + * All bits are set in bcs_bitmap to allow any cluster to be copied.
> * This does not actually require them to be copied.
> */
> while (!job_is_cancelled(job)) {
> @@ -458,6 +458,7 @@ BlockJob *backup_job_create(const char *job_id, BlockDriverState *bs,
> job->sync_bitmap = sync_bitmap;
> job->bitmap_mode = bitmap_mode;
> job->bcs = bcs;
> + job->bcs_bitmap = block_copy_dirty_bitmap(bcs);
> job->cluster_size = cluster_size;
> job->len = len;
>
> diff --git a/block/block-copy.c b/block/block-copy.c
> index aca44b13fb..7e14e86a2d 100644
> --- a/block/block-copy.c
> +++ b/block/block-copy.c
> @@ -24,6 +24,60 @@
> #define BLOCK_COPY_MAX_BUFFER (1 * MiB)
> #define BLOCK_COPY_MAX_MEM (128 * MiB)
>
> +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 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=top jobs, which first scan the source node for unallocated
> + * 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’s allocation status,
> + * skip unallocated regions, clear them in the copy_bitmap, and invoke
> + * block_copy_reset_unallocated() every time it does.
> + */
> + bool skip_unallocated;
> +
> + /* progress_bytes_callback: called when some copying progress is done. */
> + ProgressBytesCallbackFunc progress_bytes_callback;
> +
> + /*
> + * progress_reset_callback: called when some bytes reset from copy_bitmap
> + * (see @skip_unallocated above). The callee is assumed to recalculate how
> + * many bytes remain based on the dirty bit count of copy_bitmap.
> + */
> + ProgressResetCallbackFunc progress_reset_callback;
> + void *progress_opaque;
> +
> + SharedResource *mem;
> +} BlockCopyState;
> +
> static BlockCopyInFlightReq *block_copy_find_inflight_req(BlockCopyState *s,
> int64_t offset,
> int64_t bytes)
> @@ -492,3 +546,13 @@ int coroutine_fn block_copy(BlockCopyState *s, int64_t start, uint64_t bytes,
>
> return 0;
> }
> +
> +BdrvDirtyBitmap *block_copy_dirty_bitmap(BlockCopyState *s)
> +{
> + return s->copy_bitmap;
> +}
> +
> +void block_copy_set_skip_unallocated(BlockCopyState *s, bool skip)
> +{
> + s->skip_unallocated = skip;
> +}
>
The idea of API is OK but we have got the duplicated members in the
nested structures.
Reviewed-by: Andrey Shinkevich <andrey.shinkevich@virtuozzo.com>
--
With the best regards,
Andrey Shinkevich
next prev parent reply other threads:[~2020-01-30 18:59 UTC|newest]
Thread overview: 40+ messages / expand[flat|nested] mbox.gz Atom feed top
2019-11-27 18:08 [PATCH v2 for-5.0 0/7] block-copy improvements: part I Vladimir Sementsov-Ogievskiy
2019-11-27 18:08 ` [PATCH v2 1/7] block/block-copy: specialcase first copy_range request Vladimir Sementsov-Ogievskiy
2020-01-29 7:38 ` Andrey Shinkevich
2020-02-07 17:28 ` Max Reitz
2020-02-08 12:32 ` Vladimir Sementsov-Ogievskiy
2019-11-27 18:08 ` [PATCH v2 2/7] block/block-copy: use block_status Vladimir Sementsov-Ogievskiy
2020-01-29 9:12 ` Andrey Shinkevich
2020-02-07 17:46 ` Max Reitz
2020-02-08 12:25 ` Vladimir Sementsov-Ogievskiy
2020-02-17 11:48 ` Max Reitz
2019-11-27 18:08 ` [PATCH v2 3/7] block/block-copy: factor out block_copy_find_inflight_req Vladimir Sementsov-Ogievskiy
2020-01-29 9:25 ` Andrey Shinkevich
2020-02-07 17:50 ` Max Reitz
2019-11-27 18:08 ` [PATCH v2 4/7] block/block-copy: refactor interfaces to use bytes instead of end Vladimir Sementsov-Ogievskiy
2020-01-29 17:12 ` Andrey Shinkevich
2020-02-05 11:36 ` Vladimir Sementsov-Ogievskiy
2020-02-07 18:01 ` Max Reitz
2020-02-08 12:55 ` Vladimir Sementsov-Ogievskiy
2019-11-27 18:08 ` [PATCH v2 5/7] block/block-copy: rename start to offset in interfaces Vladimir Sementsov-Ogievskiy
2020-01-29 17:37 ` Andrey Shinkevich
2020-02-07 18:04 ` Max Reitz
2019-11-27 18:08 ` [PATCH v2 6/7] block/block-copy: reduce intersecting request lock Vladimir Sementsov-Ogievskiy
2020-01-29 20:05 ` Andrey Shinkevich
2020-01-30 13:45 ` Vladimir Sementsov-Ogievskiy
2020-01-30 16:24 ` Andrey Shinkevich
2020-01-30 17:09 ` Vladimir Sementsov-Ogievskiy
2020-01-30 18:00 ` Andrey Shinkevich
2020-01-30 15:53 ` Andrey Shinkevich
2020-01-30 16:05 ` Vladimir Sementsov-Ogievskiy
2020-02-17 13:38 ` Max Reitz
2020-02-20 7:21 ` Vladimir Sementsov-Ogievskiy
2020-02-20 9:10 ` Max Reitz
2019-11-27 18:08 ` [PATCH v2 7/7] block/block-copy: hide structure definitions Vladimir Sementsov-Ogievskiy
2020-01-30 18:58 ` Andrey Shinkevich [this message]
2020-02-17 14:04 ` Max Reitz
2020-02-20 7:26 ` Vladimir Sementsov-Ogievskiy
2019-12-19 9:01 ` [PATCH v2 for-5.0 0/7] block-copy improvements: part I Vladimir Sementsov-Ogievskiy
2020-01-20 9:09 ` Vladimir Sementsov-Ogievskiy
2020-02-07 18:05 ` Max Reitz
2020-02-08 10:28 ` Vladimir Sementsov-Ogievskiy
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=9db878a7-fe50-e8b3-bf6c-e5cc754e4262@virtuozzo.com \
--to=andrey.shinkevich@virtuozzo.com \
--cc=den@openvz.org \
--cc=jsnow@redhat.com \
--cc=kwolf@redhat.com \
--cc=mreitz@redhat.com \
--cc=qemu-block@nongnu.org \
--cc=qemu-devel@nongnu.org \
--cc=vsementsov@virtuozzo.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).