qemu-devel
[Top][All Lists]
Advanced

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

Re: [Qemu-devel] [PATCH v3 1/6] mirror: Do zero write on target if secto


From: Paolo Bonzini
Subject: Re: [Qemu-devel] [PATCH v3 1/6] mirror: Do zero write on target if sectors not allocated
Date: Thu, 14 May 2015 12:30:46 +0200
User-agent: Mozilla/5.0 (X11; Linux x86_64; rv:31.0) Gecko/20100101 Thunderbird/31.5.0


On 12/05/2015 13:48, Fam Zheng wrote:
> +    if (!bdrv_is_allocated_above(source, NULL, sector_num,
> +                                 nb_sectors, &pnum)) {
> +        op->nb_sectors = pnum;
> +        if (s->source_may_unmap) {

Can you avoid this check by introducing bdrv_get_block_status_above?  Then:

- if BDRV_ZERO, you use bdrv_aio_write_zeroes

- if BDRV_ALLOCATED, you use bdrv_aio_readv

- else you use bdrv_aio_discard

> +            /*
> +             * Source unallocated sectors have zero data. We can't discard
> +             * target even if s->target_may_unmap, because the discard
> +             * granularity may be different.
> +             */
> +            bdrv_aio_write_zeroes(s->target, sector_num, op->nb_sectors,
> +                                  s->target_may_unmap ? BDRV_REQ_MAY_UNMAP : 
> 0,

You can set the flag unconditionally.  But it's probably better to make
this a drive-mirror argument instead of checking the target's
BlockDriverInfo.

Paolo

> +                                  mirror_write_complete,
> +                                  op);
> +        } else {
> +            /*
> +             * Source has irrelevant data in unmapped sectors, it's safe to
> +             * discard target.
> +             * */
> +            bdrv_aio_discard(s->target, sector_num, op->nb_sectors,
> +                             mirror_write_complete, op);
> +        }
> +    } else {
> +        bdrv_aio_readv(source, sector_num, &op->qiov, nb_sectors,
> +                       mirror_read_complete, op);
> +    }
>      return delay_ns;
>  }
>  
> @@ -399,6 +428,22 @@ static void coroutine_fn mirror_run(void *opaque)
>      length = DIV_ROUND_UP(s->bdev_length, s->granularity);
>      s->in_flight_bitmap = bitmap_new(length);
>  
> +    ret = bdrv_get_info(bs, &bdi);
> +    if (ret < 0) {
> +        /* Safe side. */
> +        s->source_may_unmap = true;
> +    } else {
> +        s->source_may_unmap = bdi.can_write_zeroes_with_unmap;
> +    }
> +
> +    ret = bdrv_get_info(s->target, &bdi);
> +    if (ret < 0) {
> +        /* Safe side. */
> +        s->target_may_unmap = false;
> +    } else {
> +        s->target_may_unmap = bdi.can_write_zeroes_with_unmap;
> +    }
> +



reply via email to

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