|
|
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 |
|