[PULL,3/7] block: Add BDRV_REQ_NO_FALLBACK
diff mbox series

Message ID 20190326155157.3719-4-kwolf@redhat.com
State New
Headers show
Series
  • [PULL,1/7] iotests: add 248: test resume mirror after auto pause on ENOSPC
Related show

Commit Message

Kevin Wolf March 26, 2019, 3:51 p.m. UTC
For qemu-img convert, we want an operation that zeroes out the whole
image if this can be done efficiently, but that returns an error
otherwise so we don't write explicit zeroes and immediately overwrite
them with the real data, potentially doubling the amount of data to be
written.

Signed-off-by: Kevin Wolf <kwolf@redhat.com>
Acked-by: Eric Blake <eblake@redhat.com>
---
 include/block/block.h |  7 ++++++-
 block/io.c            | 12 +++++++++++-
 2 files changed, 17 insertions(+), 2 deletions(-)

Patch
diff mbox series

diff --git a/include/block/block.h b/include/block/block.h
index e452988b66..c7a26199aa 100644
--- a/include/block/block.h
+++ b/include/block/block.h
@@ -83,8 +83,13 @@  typedef enum {
      */
     BDRV_REQ_SERIALISING        = 0x80,
 
+    /* Execute the request only if the operation can be offloaded or otherwise
+     * be executed efficiently, but return an error instead of using a slow
+     * fallback. */
+    BDRV_REQ_NO_FALLBACK        = 0x100,
+
     /* Mask of valid flags */
-    BDRV_REQ_MASK               = 0xff,
+    BDRV_REQ_MASK               = 0x1ff,
 } BdrvRequestFlags;
 
 typedef struct BlockSizes {
diff --git a/block/io.c b/block/io.c
index 952372c2bb..dfc153b8d8 100644
--- a/block/io.c
+++ b/block/io.c
@@ -1015,6 +1015,7 @@  static int coroutine_fn bdrv_driver_preadv(BlockDriverState *bs,
     unsigned int nb_sectors;
 
     assert(!(flags & ~BDRV_REQ_MASK));
+    assert(!(flags & BDRV_REQ_NO_FALLBACK));
 
     if (!drv) {
         return -ENOMEDIUM;
@@ -1061,6 +1062,7 @@  static int coroutine_fn bdrv_driver_pwritev(BlockDriverState *bs,
     int ret;
 
     assert(!(flags & ~BDRV_REQ_MASK));
+    assert(!(flags & BDRV_REQ_NO_FALLBACK));
 
     if (!drv) {
         return -ENOMEDIUM;
@@ -1467,6 +1469,10 @@  static int coroutine_fn bdrv_co_do_pwrite_zeroes(BlockDriverState *bs,
         return -ENOMEDIUM;
     }
 
+    if ((flags & ~bs->supported_zero_flags) & BDRV_REQ_NO_FALLBACK) {
+        return -ENOTSUP;
+    }
+
     assert(alignment % bs->bl.request_alignment == 0);
     head = offset % alignment;
     tail = (offset + bytes) % alignment;
@@ -1510,7 +1516,7 @@  static int coroutine_fn bdrv_co_do_pwrite_zeroes(BlockDriverState *bs,
             assert(!bs->supported_zero_flags);
         }
 
-        if (ret == -ENOTSUP) {
+        if (ret == -ENOTSUP && !(flags & BDRV_REQ_NO_FALLBACK)) {
             /* Fall back to bounce buffer if write zeroes is unsupported */
             BdrvRequestFlags write_flags = flags & ~BDRV_REQ_ZERO_WRITE;
 
@@ -2949,6 +2955,10 @@  static int coroutine_fn bdrv_co_copy_range_internal(
     BdrvTrackedRequest req;
     int ret;
 
+    /* TODO We can support BDRV_REQ_NO_FALLBACK here */
+    assert(!(read_flags & BDRV_REQ_NO_FALLBACK));
+    assert(!(write_flags & BDRV_REQ_NO_FALLBACK));
+
     if (!dst || !dst->bs) {
         return -ENOMEDIUM;
     }