diff mbox series

[v3,1/3] block: implement BDRV_REQ_PREFETCH

Message ID 20190725100550.33801-2-vsementsov@virtuozzo.com
State New
Headers show
Series block: BDRV_REQ_PREFETCH | expand

Commit Message

Vladimir Sementsov-Ogievskiy July 25, 2019, 10:05 a.m. UTC
Do effective copy-on-read request when we don't need data actually. It
will be used for block-stream and NBD_CMD_CACHE.

Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
---
 include/block/block.h |  8 +++++++-
 block/io.c            | 18 ++++++++++++------
 2 files changed, 19 insertions(+), 7 deletions(-)

Comments

Eric Blake July 29, 2019, 9:13 p.m. UTC | #1
On 7/25/19 5:05 AM, Vladimir Sementsov-Ogievskiy wrote:
> Do effective copy-on-read request when we don't need data actually. It
> will be used for block-stream and NBD_CMD_CACHE.
> 
> Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
> ---
>  include/block/block.h |  8 +++++++-
>  block/io.c            | 18 ++++++++++++------
>  2 files changed, 19 insertions(+), 7 deletions(-)
> 
> diff --git a/include/block/block.h b/include/block/block.h
> index 50a07c1c33..73c3fc4daa 100644
> --- a/include/block/block.h
> +++ b/include/block/block.h
> @@ -88,8 +88,14 @@ typedef enum {
>       * fallback. */
>      BDRV_REQ_NO_FALLBACK        = 0x100,
>  
> +    /*
> +     * BDRV_REQ_PREFETCH may be used only together with BDRV_REQ_COPY_ON_READ
> +     * on read request and means that caller don't really need data to be

doesn't

can fix up while staging.


> +++ b/block/io.c
> @@ -1167,7 +1167,8 @@ bdrv_driver_pwritev_compressed(BlockDriverState *bs, uint64_t offset,
>  }
>  
>  static int coroutine_fn bdrv_co_do_copy_on_readv(BdrvChild *child,
> -        int64_t offset, unsigned int bytes, QEMUIOVector *qiov)
> +        int64_t offset, unsigned int bytes, QEMUIOVector *qiov,
> +        int flags)

We're bad about this, but 'int flags' does not play well with the C
language and well-defined behavior when it comes to 1<<31 (bit
operations and unsigned types have guaranteed behavior, bit operations
and negative signed types can cause the compiler to do differently than
you expect).  Not a problem for uses where we don't have 32 flags to OR
together, so I won't change it, so much as point it out for a bigger
task of auditing the entire code base if we are worried.
diff mbox series

Patch

diff --git a/include/block/block.h b/include/block/block.h
index 50a07c1c33..73c3fc4daa 100644
--- a/include/block/block.h
+++ b/include/block/block.h
@@ -88,8 +88,14 @@  typedef enum {
      * fallback. */
     BDRV_REQ_NO_FALLBACK        = 0x100,
 
+    /*
+     * BDRV_REQ_PREFETCH may be used only together with BDRV_REQ_COPY_ON_READ
+     * on read request and means that caller don't really need data to be
+     * written to qiov parameter which may be NULL.
+     */
+    BDRV_REQ_PREFETCH  = 0x200,
     /* Mask of valid flags */
-    BDRV_REQ_MASK               = 0x1ff,
+    BDRV_REQ_MASK               = 0x3ff,
 } BdrvRequestFlags;
 
 typedef struct BlockSizes {
diff --git a/block/io.c b/block/io.c
index 06305c6ea6..9d99858b55 100644
--- a/block/io.c
+++ b/block/io.c
@@ -1167,7 +1167,8 @@  bdrv_driver_pwritev_compressed(BlockDriverState *bs, uint64_t offset,
 }
 
 static int coroutine_fn bdrv_co_do_copy_on_readv(BdrvChild *child,
-        int64_t offset, unsigned int bytes, QEMUIOVector *qiov)
+        int64_t offset, unsigned int bytes, QEMUIOVector *qiov,
+        int flags)
 {
     BlockDriverState *bs = child->bs;
 
@@ -1278,9 +1279,11 @@  static int coroutine_fn bdrv_co_do_copy_on_readv(BdrvChild *child,
                 goto err;
             }
 
-            qemu_iovec_from_buf(qiov, progress, bounce_buffer + skip_bytes,
-                                pnum - skip_bytes);
-        } else {
+            if (!(flags & BDRV_REQ_PREFETCH)) {
+                qemu_iovec_from_buf(qiov, progress, bounce_buffer + skip_bytes,
+                                    pnum - skip_bytes);
+            }
+        } else if (!(flags & BDRV_REQ_PREFETCH)) {
             /* Read directly into the destination */
             qemu_iovec_init(&local_qiov, qiov->niov);
             qemu_iovec_concat(&local_qiov, qiov, progress, pnum - skip_bytes);
@@ -1331,7 +1334,8 @@  static int coroutine_fn bdrv_aligned_preadv(BdrvChild *child,
      * potential fallback support, if we ever implement any read flags
      * to pass through to drivers.  For now, there aren't any
      * passthrough flags.  */
-    assert(!(flags & ~(BDRV_REQ_NO_SERIALISING | BDRV_REQ_COPY_ON_READ)));
+    assert(!(flags & ~(BDRV_REQ_NO_SERIALISING | BDRV_REQ_COPY_ON_READ |
+                       BDRV_REQ_PREFETCH)));
 
     /* Handle Copy on Read and associated serialisation */
     if (flags & BDRV_REQ_COPY_ON_READ) {
@@ -1359,7 +1363,9 @@  static int coroutine_fn bdrv_aligned_preadv(BdrvChild *child,
         }
 
         if (!ret || pnum != bytes) {
-            ret = bdrv_co_do_copy_on_readv(child, offset, bytes, qiov);
+            ret = bdrv_co_do_copy_on_readv(child, offset, bytes, qiov, flags);
+            goto out;
+        } else if (flags & BDRV_REQ_PREFETCH) {
             goto out;
         }
     }