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

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