Commit 738301e1 authored by Kevin Wolf's avatar Kevin Wolf
Browse files

file-posix: Support BDRV_REQ_NO_FALLBACK for zero writes



We know that the kernel implements a slow fallback code path for
BLKZEROOUT, so if BDRV_REQ_NO_FALLBACK is given, we shouldn't call it.
The other operations we call in the context of .bdrv_co_pwrite_zeroes
should usually be quick, so no modification should be needed for them.
If we ever notice that there are additional problematic cases, we can
still make these conditional as well.

Signed-off-by: default avatarKevin Wolf <kwolf@redhat.com>
Acked-by: default avatarEric Blake <eblake@redhat.com>
parent 80f5c33f
Loading
Loading
Loading
Loading
+16 −8
Original line number Diff line number Diff line
@@ -652,7 +652,7 @@ static int raw_open_common(BlockDriverState *bs, QDict *options,
    }
#endif

    bs->supported_zero_flags = BDRV_REQ_MAY_UNMAP;
    bs->supported_zero_flags = BDRV_REQ_MAY_UNMAP | BDRV_REQ_NO_FALLBACK;
    ret = 0;
fail:
    if (filename && (bdrv_flags & BDRV_O_TEMPORARY)) {
@@ -1500,6 +1500,10 @@ static ssize_t handle_aiocb_write_zeroes_block(RawPosixAIOData *aiocb)
    }

#ifdef BLKZEROOUT
    /* The BLKZEROOUT implementation in the kernel doesn't set
     * BLKDEV_ZERO_NOFALLBACK, so we can't call this if we have to avoid slow
     * fallbacks. */
    if (!(aiocb->aio_type & QEMU_AIO_NO_FALLBACK)) {
        do {
            uint64_t range[2] = { aiocb->aio_offset, aiocb->aio_nbytes };
            if (ioctl(aiocb->aio_fildes, BLKZEROOUT, range) == 0) {
@@ -1508,6 +1512,7 @@ static ssize_t handle_aiocb_write_zeroes_block(RawPosixAIOData *aiocb)
        } while (errno == EINTR);

        ret = translate_err(-errno);
    }
#endif

    if (ret == -ENOTSUP) {
@@ -2659,6 +2664,9 @@ raw_do_pwrite_zeroes(BlockDriverState *bs, int64_t offset, int bytes,
    if (blkdev) {
        acb.aio_type |= QEMU_AIO_BLKDEV;
    }
    if (flags & BDRV_REQ_NO_FALLBACK) {
        acb.aio_type |= QEMU_AIO_NO_FALLBACK;
    }

    if (flags & BDRV_REQ_MAY_UNMAP) {
        acb.aio_type |= QEMU_AIO_DISCARD;
+1 −0
Original line number Diff line number Diff line
@@ -40,6 +40,7 @@
/* AIO flags */
#define QEMU_AIO_MISALIGNED   0x1000
#define QEMU_AIO_BLKDEV       0x2000
#define QEMU_AIO_NO_FALLBACK  0x4000


/* linux-aio.c - Linux native implementation */