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

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