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 <[email protected]> > Reviewed-by: Eric Blake <[email protected]> > --- > 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);
>
signature.asc
Description: OpenPGP digital signature
