[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [PATCH v2 08/20] block/block-copy: add block_copy_cancel
From: |
Max Reitz |
Subject: |
Re: [PATCH v2 08/20] block/block-copy: add block_copy_cancel |
Date: |
Wed, 22 Jul 2020 13:28:25 +0200 |
User-agent: |
Mozilla/5.0 (X11; Linux x86_64; rv:68.0) Gecko/20100101 Thunderbird/68.10.0 |
On 01.06.20 20:11, Vladimir Sementsov-Ogievskiy wrote:
> Add function to cancel running async block-copy call. It will be used
> in backup.
>
> Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
> ---
> include/block/block-copy.h | 7 +++++++
> block/block-copy.c | 22 +++++++++++++++++++---
> 2 files changed, 26 insertions(+), 3 deletions(-)
>
> diff --git a/include/block/block-copy.h b/include/block/block-copy.h
> index d40e691123..370a194d3c 100644
> --- a/include/block/block-copy.h
> +++ b/include/block/block-copy.h
> @@ -67,6 +67,13 @@ BlockCopyCallState *block_copy_async(BlockCopyState *s,
> void block_copy_set_speed(BlockCopyState *s, BlockCopyCallState *call_state,
> uint64_t speed);
>
> +/*
> + * Cancel running block-copy call.
> + * Cancel leaves block-copy state valid: dirty bits are correct and you may
> use
> + * cancel + <run block_copy with same parameters> to emulate pause/resume.
> + */
> +void block_copy_cancel(BlockCopyCallState *call_state);
> +
> BdrvDirtyBitmap *block_copy_dirty_bitmap(BlockCopyState *s);
> void block_copy_set_skip_unallocated(BlockCopyState *s, bool skip);
>
> diff --git a/block/block-copy.c b/block/block-copy.c
> index 851d9c8aaf..b551feb6c2 100644
> --- a/block/block-copy.c
> +++ b/block/block-copy.c
> @@ -44,6 +44,8 @@ typedef struct BlockCopyCallState {
> bool failed;
> bool finished;
> QemuCoSleepState *sleep_state;
> + bool cancelled;
> + Coroutine *canceller;
>
> /* OUT parameters */
> bool error_is_read;
> @@ -582,7 +584,7 @@ block_copy_dirty_clusters(BlockCopyCallState *call_state)
> assert(QEMU_IS_ALIGNED(offset, s->cluster_size));
> assert(QEMU_IS_ALIGNED(bytes, s->cluster_size));
>
> - while (bytes && aio_task_pool_status(aio) == 0) {
> + while (bytes && aio_task_pool_status(aio) == 0 &&
> !call_state->cancelled) {
> BlockCopyTask *task;
> int64_t status_bytes;
>
> @@ -693,7 +695,7 @@ static int coroutine_fn
> block_copy_common(BlockCopyCallState *call_state)
> do {
> ret = block_copy_dirty_clusters(call_state);
>
> - if (ret == 0) {
> + if (ret == 0 && !call_state->cancelled) {
> ret = block_copy_wait_one(call_state->s, call_state->offset,
> call_state->bytes);
> }
> @@ -707,13 +709,18 @@ static int coroutine_fn
> block_copy_common(BlockCopyCallState *call_state)
> * 2. We have waited for some intersecting block-copy request
> * It may have failed and produced new dirty bits.
> */
> - } while (ret > 0);
> + } while (ret > 0 && !call_state->cancelled);
Would it be cleaner if block_copy_dirty_cluster() just returned
-ECANCELED? Or would that pose a problem for its callers or the async
callback?
> if (call_state->cb) {
> call_state->cb(ret, call_state->error_is_read,
> call_state->s->progress_opaque);
> }
>
> + if (call_state->canceller) {
> + aio_co_wake(call_state->canceller);
> + call_state->canceller = NULL;
> + }
> +
> call_state->finished = true;
>
> return ret;
signature.asc
Description: OpenPGP digital signature
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- Re: [PATCH v2 08/20] block/block-copy: add block_copy_cancel,
Max Reitz <=