qemu-block
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Qemu-block] [PATCH v4 13/13] block/mirror: Block "device IO" during


From: Paolo Bonzini
Subject: Re: [Qemu-block] [PATCH v4 13/13] block/mirror: Block "device IO" during mirror exit
Date: Tue, 19 May 2015 10:04:51 +0200
User-agent: Mozilla/5.0 (X11; Linux x86_64; rv:31.0) Gecko/20100101 Thunderbird/31.5.0

On 19/05/2015 13:49, Fam Zheng wrote:
> When block job mirror is finished, the source and target is synced. But
> we call bdrv_swap() later in main loop bh. If the guest write before
> that, target will not get the new data.

This is too late.  As a rule, the blocker must be established before
calling bdrv_drain, and removed on the next yield (in this case, before
the assignment to last_pause_ns).

Paolo

> Reported-by: Wen Congyang <address@hidden>
> Signed-off-by: Fam Zheng <address@hidden>
> ---
>  block/mirror.c | 8 +++++++-
>  1 file changed, 7 insertions(+), 1 deletion(-)
> 
> diff --git a/block/mirror.c b/block/mirror.c
> index 58f391a..d96403b 100644
> --- a/block/mirror.c
> +++ b/block/mirror.c
> @@ -320,6 +320,8 @@ static void mirror_drain(MirrorBlockJob *s)
>  
>  typedef struct {
>      int ret;
> +    /* Use to pause device IO during mirror exit */
> +    Error *blocker;
>  } MirrorExitData;
>  
>  static void mirror_exit(BlockJob *job, void *opaque)
> @@ -328,6 +330,8 @@ static void mirror_exit(BlockJob *job, void *opaque)
>      MirrorExitData *data = opaque;
>      AioContext *replace_aio_context = NULL;
>  
> +    bdrv_op_unblock(s->common.bs, BLOCK_OP_TYPE_DEVICE_IO, data->blocker);
> +    error_free(data->blocker);
>      if (s->to_replace) {
>          replace_aio_context = bdrv_get_aio_context(s->to_replace);
>          aio_context_acquire(replace_aio_context);
> @@ -563,8 +567,10 @@ immediate_exit:
>      bdrv_release_dirty_bitmap(bs, s->dirty_bitmap);
>      bdrv_iostatus_disable(s->target);
>  
> -    data = g_malloc(sizeof(*data));
> +    data = g_malloc0(sizeof(*data));
>      data->ret = ret;
> +    error_setg(&data->blocker, "mirror job exiting");
> +    bdrv_op_block(bs, BLOCK_OP_TYPE_DEVICE_IO, data->blocker);
>      block_job_defer_to_main_loop(&s->common, mirror_exit, data);
>  }
>  
> 



reply via email to

[Prev in Thread] Current Thread [Next in Thread]