On 2018-01-18 18:49, Anton Nefedov wrote:
> The idea is that ALLOCATE requests may overlap with other requests.
> Reuse the existing block layer infrastructure for serialising requests.
> Use the following approach:
>   - mark ALLOCATE serialising, so subsequent requests to the area wait
>   - ALLOCATE request itself must never wait if another request is in flight
>     already. Return EAGAIN, let the caller reconsider.
> 
> Signed-off-by: Anton Nefedov <anton.nefe...@virtuozzo.com>
> Reviewed-by: Eric Blake <ebl...@redhat.com>
> ---
>  block/io.c | 27 +++++++++++++++++++--------
>  1 file changed, 19 insertions(+), 8 deletions(-)

The basic principle looks good to me.

> diff --git a/block/io.c b/block/io.c
> index cf2f84c..4b0d34f 100644
> --- a/block/io.c
> +++ b/block/io.c

[...]

> @@ -1717,7 +1728,7 @@ int coroutine_fn bdrv_co_pwritev(BdrvChild *child,
>          struct iovec head_iov;
>  
>          mark_request_serialising(&req, align);
> -        wait_serialising_requests(&req);
> +        wait_serialising_requests(&req, false);

What if someone calls bdrv_co_pwritev() with BDRV_REQ_ZERO_WRITE |
BDRV_REQ_ALLOCATE?  Then this should do exactly the same as
bdrv_co_do_zero_pwritev(), which it currently does not -- besides this
serialization, this includes returning -ENOTSUP if there is a head or
tail to write.

Max

>  
>          head_buf = qemu_blockalign(bs, align);
>          head_iov = (struct iovec) {
> @@ -1758,7 +1769,7 @@ int coroutine_fn bdrv_co_pwritev(BdrvChild *child,
>          bool waited;
>  
>          mark_request_serialising(&req, align);
> -        waited = wait_serialising_requests(&req);
> +        waited = wait_serialising_requests(&req, false);
>          assert(!waited || !use_local_qiov);
>  
>          tail_buf = qemu_blockalign(bs, align);
> 


Attachment: signature.asc
Description: OpenPGP digital signature

Reply via email to