Skip to content

Commit

Permalink
file-posix: Support BDRV_REQ_NO_FALLBACK for zero writes
Browse files Browse the repository at this point in the history
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: Kevin Wolf <kwolf@redhat.com>
Acked-by: Eric Blake <eblake@redhat.com>
  • Loading branch information
kevmw committed Mar 26, 2019
1 parent 80f5c33 commit 738301e
Show file tree
Hide file tree
Showing 2 changed files with 17 additions and 8 deletions.
24 changes: 16 additions & 8 deletions block/file-posix.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)) {
Expand Down Expand Up @@ -1500,14 +1500,19 @@ static ssize_t handle_aiocb_write_zeroes_block(RawPosixAIOData *aiocb)
}

#ifdef BLKZEROOUT
do {
uint64_t range[2] = { aiocb->aio_offset, aiocb->aio_nbytes };
if (ioctl(aiocb->aio_fildes, BLKZEROOUT, range) == 0) {
return 0;
}
} while (errno == EINTR);
/* 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) {
return 0;
}
} while (errno == EINTR);

ret = translate_err(-errno);
ret = translate_err(-errno);
}
#endif

if (ret == -ENOTSUP) {
Expand Down Expand Up @@ -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;
Expand Down
1 change: 1 addition & 0 deletions include/block/raw-aio.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 */
Expand Down

0 comments on commit 738301e

Please sign in to comment.