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

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