yeahuh / rpms / qemu-kvm

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