Blame SOURCES/kvm-block-Use-tracked-request-for-truncate.patch

357786
From 309929687960d52f77df69a745bd1c351023febb Mon Sep 17 00:00:00 2001
357786
From: Kevin Wolf <kwolf@redhat.com>
357786
Date: Thu, 12 Jul 2018 14:42:57 +0200
357786
Subject: [PATCH 38/89] block: Use tracked request for truncate
357786
357786
RH-Author: Kevin Wolf <kwolf@redhat.com>
357786
Message-id: <20180712144258.17303-6-kwolf@redhat.com>
357786
Patchwork-id: 81326
357786
O-Subject: [RHV-7.6 qemu-kvm-rhev PATCH 5/6] block: Use tracked request for truncate
357786
Bugzilla: 1595173
357786
RH-Acked-by: Max Reitz <mreitz@redhat.com>
357786
RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
357786
RH-Acked-by: John Snow <jsnow@redhat.com>
357786
357786
When growing an image, block drivers (especially protocol drivers) may
357786
initialise the newly added area. I/O requests to the same area need to
357786
wait for this initialisation to be completed so that data writes don't
357786
get overwritten and reads don't read uninitialised data.
357786
357786
To avoid overhead in the fast I/O path by adding new locking in the
357786
protocol drivers and to restrict the impact to requests that actually
357786
touch the new area, reuse the existing tracked request infrastructure in
357786
block/io.c and mark all discard requests as serialising.
357786
357786
With this change, it is safe for protocol drivers to make
357786
.bdrv_co_truncate actually asynchronous.
357786
357786
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
357786
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
357786
(cherry picked from commit 1bc5f09f2e1b2be8f6f737b8d5352b438fc41492)
357786
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
357786
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
357786
---
357786
 block/io.c                | 25 +++++++++++++++++++++++++
357786
 include/block/block_int.h |  1 +
357786
 2 files changed, 26 insertions(+)
357786
357786
diff --git a/block/io.c b/block/io.c
357786
index 32a82e3..ad8afc0 100644
357786
--- a/block/io.c
357786
+++ b/block/io.c
357786
@@ -2948,6 +2948,8 @@ int coroutine_fn bdrv_co_truncate(BdrvChild *child, int64_t offset,
357786
 {
357786
     BlockDriverState *bs = child->bs;
357786
     BlockDriver *drv = bs->drv;
357786
+    BdrvTrackedRequest req;
357786
+    int64_t old_size, new_bytes;
357786
     int ret;
357786
 
357786
     assert(child->perm & BLK_PERM_RESIZE);
357786
@@ -2962,7 +2964,28 @@ int coroutine_fn bdrv_co_truncate(BdrvChild *child, int64_t offset,
357786
         return -EINVAL;
357786
     }
357786
 
357786
+    old_size = bdrv_getlength(bs);
357786
+    if (old_size < 0) {
357786
+        error_setg_errno(errp, -old_size, "Failed to get old image size");
357786
+        return old_size;
357786
+    }
357786
+
357786
+    if (offset > old_size) {
357786
+        new_bytes = offset - old_size;
357786
+    } else {
357786
+        new_bytes = 0;
357786
+    }
357786
+
357786
     bdrv_inc_in_flight(bs);
357786
+    tracked_request_begin(&req, bs, offset, new_bytes, BDRV_TRACKED_TRUNCATE);
357786
+
357786
+    /* If we are growing the image and potentially using preallocation for the
357786
+     * new area, we need to make sure that no write requests are made to it
357786
+     * concurrently or they might be overwritten by preallocation. */
357786
+    if (new_bytes) {
357786
+        mark_request_serialising(&req, 1);
357786
+        wait_serialising_requests(&req;;
357786
+    }
357786
 
357786
     if (!drv->bdrv_co_truncate) {
357786
         if (bs->file && drv->is_filter) {
357786
@@ -2996,7 +3019,9 @@ int coroutine_fn bdrv_co_truncate(BdrvChild *child, int64_t offset,
357786
     atomic_inc(&bs->write_gen);
357786
 
357786
 out:
357786
+    tracked_request_end(&req;;
357786
     bdrv_dec_in_flight(bs);
357786
+
357786
     return ret;
357786
 }
357786
 
357786
diff --git a/include/block/block_int.h b/include/block/block_int.h
357786
index 6a844ec..27e168f 100644
357786
--- a/include/block/block_int.h
357786
+++ b/include/block/block_int.h
357786
@@ -63,6 +63,7 @@ enum BdrvTrackedRequestType {
357786
     BDRV_TRACKED_READ,
357786
     BDRV_TRACKED_WRITE,
357786
     BDRV_TRACKED_DISCARD,
357786
+    BDRV_TRACKED_TRUNCATE,
357786
 };
357786
 
357786
 typedef struct BdrvTrackedRequest {
357786
-- 
357786
1.8.3.1
357786