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); >
signature.asc
Description: OpenPGP digital signature