From: Fam Zheng <famz@redhat.com>
To: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
Cc: qemu-devel@nongnu.org, qemu-block@nongnu.org, pl@kamp.de,
pbonzini@redhat.com, ronniesahlberg@gmail.com,
stefanha@redhat.com, mreitz@redhat.com, kwolf@redhat.com,
jcody@redhat.com, jsnow@redhat.com, den@openvz.org
Subject: Re: [Qemu-devel] [PATCH v5 3/4] block: add BDRV_REQ_SERIALISING flag
Date: Tue, 10 Jul 2018 10:51:02 +0800 [thread overview]
Message-ID: <20180710025101.GH17581@lemon.usersys.redhat.com> (raw)
In-Reply-To: <20180709163719.87107-4-vsementsov@virtuozzo.com>
On Mon, 07/09 19:37, Vladimir Sementsov-Ogievskiy wrote:
> Serialized writes should be used in copy-on-write of backup(sync=none)
> for image fleecing scheme.
>
> We need to change an assert in bdrv_aligned_pwritev, added in
> 28de2dcd88de. The assert may fail now, because call to
> wait_serialising_requests here may become first call to it for this
> request with serializing flag set.
> It occurs if the request is aligned
> (otherwise, we should already set serializing flag before calling
> bdrv_aligned_pwritev and correspondingly waited for all intersecting
> requests). However, for aligned requests, we should not care about
> outdating of previously read data, as there no such data. Therefore,
> let's just update an assert to not care about aligned requests.
>
> Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
> ---
> include/block/block.h | 13 ++++++++++++-
> block/io.c | 26 +++++++++++++++++++++++++-
> 2 files changed, 37 insertions(+), 2 deletions(-)
>
> diff --git a/include/block/block.h b/include/block/block.h
> index 57a96d4988..6623d15432 100644
> --- a/include/block/block.h
> +++ b/include/block/block.h
> @@ -69,8 +69,19 @@ typedef enum {
> * content. */
> BDRV_REQ_WRITE_UNCHANGED = 0x40,
>
> + /* BDRV_REQ_SERIALISING forces request serialisation for writes.
> + * It is used to ensure that writes to the backing file of a backup process
> + * target cannot race with a read of the backup target that defers to the
> + * backing file.
> + *
> + * Note, that BDRV_REQ_SERIALISING is _not_ opposite in meaning to
> + * BDRV_REQ_NO_SERIALISING. A more descriptive name for the latter might be
> + * _DO_NOT_WAIT_FOR_SERIALISING, except that is too long.
> + */
> + BDRV_REQ_SERIALISING = 0x80,
> +
> /* Mask of valid flags */
> - BDRV_REQ_MASK = 0x7f,
> + BDRV_REQ_MASK = 0xff,
> } BdrvRequestFlags;
>
> typedef struct BlockSizes {
> diff --git a/block/io.c b/block/io.c
> index 5d5651ad84..102cb0e1ba 100644
> --- a/block/io.c
> +++ b/block/io.c
> @@ -623,6 +623,16 @@ static void mark_request_serialising(BdrvTrackedRequest *req, uint64_t align)
> req->overlap_bytes = MAX(req->overlap_bytes, overlap_bytes);
> }
>
> +static bool is_request_serialising_and_aligned(BdrvTrackedRequest *req)
> +{
> + /* if request is serialising, overlap_offset and overlap_bytes are set, so
> + * we can check is request aligned. Otherwise don't care and return false
"if the request is aligned".
> + */
> +
> + return req->serialising && (req->offset == req->overlap_offset) &&
> + (req->bytes == req->overlap_bytes);
> +}
> +
> /**
> * Round a region to cluster boundaries
> */
> @@ -1291,6 +1301,9 @@ static int coroutine_fn bdrv_aligned_preadv(BdrvChild *child,
> mark_request_serialising(req, bdrv_get_cluster_size(bs));
> }
>
> + /* BDRV_REQ_SERIALISING is only for write operation */
> + assert(!(flags & BDRV_REQ_SERIALISING));
> +
> if (!(flags & BDRV_REQ_NO_SERIALISING)) {
> wait_serialising_requests(req);
> }
> @@ -1574,8 +1587,14 @@ static int coroutine_fn bdrv_aligned_pwritev(BdrvChild *child,
>
> /* BDRV_REQ_NO_SERIALISING is only for read operation */
> assert(!(flags & BDRV_REQ_NO_SERIALISING));
> +
> + if (flags & BDRV_REQ_SERIALISING) {
> + mark_request_serialising(req, bdrv_get_cluster_size(bs));
> + }
> +
> waited = wait_serialising_requests(req);
> - assert(!waited || !req->serialising);
> + assert(!waited || !req->serialising ||
> + is_request_serialising_and_aligned(req));
Note to myself: what can happen is when we have a CoR request in flight which
was marked serialising, this aligned write overlaps with it. In this case, we
will wait (waited == true), and req->serialising == true as set by
BDRV_REQ_SERIALISING. (Previously we must have called
wait_serialising_requests() in bdrv_co_pwritev() or bdrv_co_do_zero_pwritev()
before reaching here, if req->serialising, in which case no wait should happen.)
> assert(req->overlap_offset <= offset);
> assert(offset + bytes <= req->overlap_offset + req->overlap_bytes);
> if (flags & BDRV_REQ_WRITE_UNCHANGED) {
> @@ -2929,6 +2948,8 @@ static int coroutine_fn bdrv_co_copy_range_internal(
> tracked_request_begin(&req, src->bs, src_offset, bytes,
> BDRV_TRACKED_READ);
>
> + /* BDRV_REQ_SERIALISING is only for write operation */
> + assert(!(read_flags & BDRV_REQ_SERIALISING));
> if (!(read_flags & BDRV_REQ_NO_SERIALISING)) {
> wait_serialising_requests(&req);
> }
> @@ -2948,6 +2969,9 @@ static int coroutine_fn bdrv_co_copy_range_internal(
>
> /* BDRV_REQ_NO_SERIALISING is only for read operation */
> assert(!(write_flags & BDRV_REQ_NO_SERIALISING));
> + if (write_flags & BDRV_REQ_SERIALISING) {
> + mark_request_serialising(&req, bdrv_get_cluster_size(dst->bs));
> + }
> wait_serialising_requests(&req);
>
> ret = dst->bs->drv->bdrv_co_copy_range_to(dst->bs,
> --
> 2.11.1
>
Reviewed-by: Fam Zheng <famz@redhat.com>
Fam
next prev parent reply other threads:[~2018-07-10 2:51 UTC|newest]
Thread overview: 10+ messages / expand[flat|nested] mbox.gz Atom feed top
2018-07-09 16:37 [Qemu-devel] [PATCH v5 0/4] fix image fleecing Vladimir Sementsov-Ogievskiy
2018-07-09 16:37 ` [Qemu-devel] [PATCH v5 1/4] block/io: fix copy_range Vladimir Sementsov-Ogievskiy
2018-07-10 1:49 ` Fam Zheng
2018-07-09 16:37 ` [Qemu-devel] [PATCH v5 2/4] block: split flags in copy_range Vladimir Sementsov-Ogievskiy
2018-07-10 1:52 ` Fam Zheng
2018-07-09 16:37 ` [Qemu-devel] [PATCH v5 3/4] block: add BDRV_REQ_SERIALISING flag Vladimir Sementsov-Ogievskiy
2018-07-10 2:51 ` Fam Zheng [this message]
2018-07-09 16:37 ` [Qemu-devel] [PATCH v5 4/4] block/backup: fix fleecing scheme: use serialized writes Vladimir Sementsov-Ogievskiy
2018-07-10 2:57 ` Fam Zheng
2018-07-10 11:13 ` [Qemu-devel] [PATCH v5 0/4] fix image fleecing Kevin Wolf
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20180710025101.GH17581@lemon.usersys.redhat.com \
--to=famz@redhat.com \
--cc=den@openvz.org \
--cc=jcody@redhat.com \
--cc=jsnow@redhat.com \
--cc=kwolf@redhat.com \
--cc=mreitz@redhat.com \
--cc=pbonzini@redhat.com \
--cc=pl@kamp.de \
--cc=qemu-block@nongnu.org \
--cc=qemu-devel@nongnu.org \
--cc=ronniesahlberg@gmail.com \
--cc=stefanha@redhat.com \
--cc=vsementsov@virtuozzo.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).