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