Blame SOURCES/kvm-block-add-BDRV_REQ_SERIALISING-flag.patch

383d26
From 0ea414a81a3e1372257a54c8756a643b91ae773a Mon Sep 17 00:00:00 2001
383d26
From: John Snow <jsnow@redhat.com>
383d26
Date: Wed, 18 Jul 2018 22:54:57 +0200
383d26
Subject: [PATCH 72/89] block: add BDRV_REQ_SERIALISING flag
383d26
383d26
RH-Author: John Snow <jsnow@redhat.com>
383d26
Message-id: <20180718225511.14878-22-jsnow@redhat.com>
383d26
Patchwork-id: 81421
383d26
O-Subject: [RHEL-7.6 qemu-kvm-rhev PATCH 21/35] block: add BDRV_REQ_SERIALISING flag
383d26
Bugzilla: 1207657
383d26
RH-Acked-by: Eric Blake <eblake@redhat.com>
383d26
RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
383d26
RH-Acked-by: Fam Zheng <famz@redhat.com>
383d26
383d26
From: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
383d26
383d26
Serialized writes should be used in copy-on-write of backup(sync=none)
383d26
for image fleecing scheme.
383d26
383d26
We need to change an assert in bdrv_aligned_pwritev, added in
383d26
28de2dcd88de. The assert may fail now, because call to
383d26
wait_serialising_requests here may become first call to it for this
383d26
request with serializing flag set. It occurs if the request is aligned
383d26
(otherwise, we should already set serializing flag before calling
383d26
bdrv_aligned_pwritev and correspondingly waited for all intersecting
383d26
requests). However, for aligned requests, we should not care about
383d26
outdating of previously read data, as there no such data. Therefore,
383d26
let's just update an assert to not care about aligned requests.
383d26
383d26
Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
383d26
Reviewed-by: Fam Zheng <famz@redhat.com>
383d26
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
383d26
(cherry picked from commit 09d2f948462f4979d18f573a0734d1daae8e67a9)
383d26
Signed-off-by: John Snow <jsnow@redhat.com>
383d26
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
383d26
---
383d26
 block/io.c            | 28 +++++++++++++++++++++++++++-
383d26
 include/block/block.h | 14 +++++++++++++-
383d26
 2 files changed, 40 insertions(+), 2 deletions(-)
383d26
383d26
diff --git a/block/io.c b/block/io.c
383d26
index 2d04289..bb617de 100644
383d26
--- a/block/io.c
383d26
+++ b/block/io.c
383d26
@@ -535,6 +535,18 @@ static void mark_request_serialising(BdrvTrackedRequest *req, uint64_t align)
383d26
     req->overlap_bytes = MAX(req->overlap_bytes, overlap_bytes);
383d26
 }
383d26
 
383d26
+static bool is_request_serialising_and_aligned(BdrvTrackedRequest *req)
383d26
+{
383d26
+    /*
383d26
+     * If the request is serialising, overlap_offset and overlap_bytes are set,
383d26
+     * so we can check if the request is aligned. Otherwise, don't care and
383d26
+     * return false.
383d26
+     */
383d26
+
383d26
+    return req->serialising && (req->offset == req->overlap_offset) &&
383d26
+           (req->bytes == req->overlap_bytes);
383d26
+}
383d26
+
383d26
 /**
383d26
  * Round a region to cluster boundaries
383d26
  */
383d26
@@ -1206,6 +1218,9 @@ static int coroutine_fn bdrv_aligned_preadv(BdrvChild *child,
383d26
         mark_request_serialising(req, bdrv_get_cluster_size(bs));
383d26
     }
383d26
 
383d26
+    /* BDRV_REQ_SERIALISING is only for write operation */
383d26
+    assert(!(flags & BDRV_REQ_SERIALISING));
383d26
+
383d26
     if (!(flags & BDRV_REQ_NO_SERIALISING)) {
383d26
         wait_serialising_requests(req);
383d26
     }
383d26
@@ -1507,8 +1522,14 @@ static int coroutine_fn bdrv_aligned_pwritev(BdrvChild *child,
383d26
 
383d26
     /* BDRV_REQ_NO_SERIALISING is only for read operation */
383d26
     assert(!(flags & BDRV_REQ_NO_SERIALISING));
383d26
+
383d26
+    if (flags & BDRV_REQ_SERIALISING) {
383d26
+        mark_request_serialising(req, bdrv_get_cluster_size(bs));
383d26
+    }
383d26
+
383d26
     waited = wait_serialising_requests(req);
383d26
-    assert(!waited || !req->serialising);
383d26
+    assert(!waited || !req->serialising ||
383d26
+           is_request_serialising_and_aligned(req));
383d26
     assert(req->overlap_offset <= offset);
383d26
     assert(offset + bytes <= req->overlap_offset + req->overlap_bytes);
383d26
     if (flags & BDRV_REQ_WRITE_UNCHANGED) {
383d26
@@ -2881,6 +2902,8 @@ static int coroutine_fn bdrv_co_copy_range_internal(
383d26
         tracked_request_begin(&req, src->bs, src_offset, bytes,
383d26
                               BDRV_TRACKED_READ);
383d26
 
383d26
+        /* BDRV_REQ_SERIALISING is only for write operation */
383d26
+        assert(!(read_flags & BDRV_REQ_SERIALISING));
383d26
         if (!(read_flags & BDRV_REQ_NO_SERIALISING)) {
383d26
             wait_serialising_requests(&req;;
383d26
         }
383d26
@@ -2900,6 +2923,9 @@ static int coroutine_fn bdrv_co_copy_range_internal(
383d26
 
383d26
         /* BDRV_REQ_NO_SERIALISING is only for read operation */
383d26
         assert(!(write_flags & BDRV_REQ_NO_SERIALISING));
383d26
+        if (write_flags & BDRV_REQ_SERIALISING) {
383d26
+            mark_request_serialising(&req, bdrv_get_cluster_size(dst->bs));
383d26
+        }
383d26
         wait_serialising_requests(&req;;
383d26
 
383d26
         ret = dst->bs->drv->bdrv_co_copy_range_to(dst->bs,
383d26
diff --git a/include/block/block.h b/include/block/block.h
383d26
index 409db21..8f87eea 100644
383d26
--- a/include/block/block.h
383d26
+++ b/include/block/block.h
383d26
@@ -70,8 +70,20 @@ typedef enum {
383d26
      * content. */
383d26
     BDRV_REQ_WRITE_UNCHANGED    = 0x40,
383d26
 
383d26
+    /*
383d26
+     * BDRV_REQ_SERIALISING forces request serialisation for writes.
383d26
+     * It is used to ensure that writes to the backing file of a backup process
383d26
+     * target cannot race with a read of the backup target that defers to the
383d26
+     * backing file.
383d26
+     *
383d26
+     * Note, that BDRV_REQ_SERIALISING is _not_ opposite in meaning to
383d26
+     * BDRV_REQ_NO_SERIALISING. A more descriptive name for the latter might be
383d26
+     * _DO_NOT_WAIT_FOR_SERIALISING, except that is too long.
383d26
+     */
383d26
+    BDRV_REQ_SERIALISING        = 0x80,
383d26
+
383d26
     /* Mask of valid flags */
383d26
-    BDRV_REQ_MASK               = 0x7f,
383d26
+    BDRV_REQ_MASK               = 0xff,
383d26
 } BdrvRequestFlags;
383d26
 
383d26
 typedef struct BlockSizes {
383d26
-- 
383d26
1.8.3.1
383d26