[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[PULL 21/27] block/mirror: determine copy_to_target only once
From: |
Kevin Wolf |
Subject: |
[PULL 21/27] block/mirror: determine copy_to_target only once |
Date: |
Tue, 31 Oct 2023 19:59:12 +0100 |
From: Fiona Ebner <f.ebner@proxmox.com>
In preparation to allow changing the copy_mode via QMP. When running
in an iothread, it could be that copy_mode is changed from the main
thread in between reading copy_mode in bdrv_mirror_top_pwritev() and
reading copy_mode in bdrv_mirror_top_do_write(), so they might end up
disagreeing about whether copy_to_target is true or false. Avoid that
scenario by determining copy_to_target only once and passing it to
bdrv_mirror_top_do_write() as an argument.
Signed-off-by: Fiona Ebner <f.ebner@proxmox.com>
Reviewed-by: Vladimir Sementsov-Ogievskiy <vsementsov@yandex-team.ru>
Message-ID: <20231031135431.393137-5-f.ebner@proxmox.com>
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
---
block/mirror.c | 41 ++++++++++++++++++-----------------------
1 file changed, 18 insertions(+), 23 deletions(-)
diff --git a/block/mirror.c b/block/mirror.c
index 914d723446..31da1526eb 100644
--- a/block/mirror.c
+++ b/block/mirror.c
@@ -1463,21 +1463,21 @@ bdrv_mirror_top_preadv(BlockDriverState *bs, int64_t
offset, int64_t bytes,
return bdrv_co_preadv(bs->backing, offset, bytes, qiov, flags);
}
+static bool should_copy_to_target(MirrorBDSOpaque *s)
+{
+ return s->job && s->job->ret >= 0 &&
+ !job_is_cancelled(&s->job->common.job) &&
+ s->job->copy_mode == MIRROR_COPY_MODE_WRITE_BLOCKING;
+}
+
static int coroutine_fn GRAPH_RDLOCK
bdrv_mirror_top_do_write(BlockDriverState *bs, MirrorMethod method,
- uint64_t offset, uint64_t bytes, QEMUIOVector *qiov,
- int flags)
+ bool copy_to_target, uint64_t offset, uint64_t bytes,
+ QEMUIOVector *qiov, int flags)
{
MirrorOp *op = NULL;
MirrorBDSOpaque *s = bs->opaque;
int ret = 0;
- bool copy_to_target = false;
-
- if (s->job) {
- copy_to_target = s->job->ret >= 0 &&
- !job_is_cancelled(&s->job->common.job) &&
- s->job->copy_mode == MIRROR_COPY_MODE_WRITE_BLOCKING;
- }
if (copy_to_target) {
op = active_write_prepare(s->job, offset, bytes);
@@ -1524,17 +1524,10 @@ static int coroutine_fn GRAPH_RDLOCK
bdrv_mirror_top_pwritev(BlockDriverState *bs, int64_t offset, int64_t bytes,
QEMUIOVector *qiov, BdrvRequestFlags flags)
{
- MirrorBDSOpaque *s = bs->opaque;
QEMUIOVector bounce_qiov;
void *bounce_buf;
int ret = 0;
- bool copy_to_target = false;
-
- if (s->job) {
- copy_to_target = s->job->ret >= 0 &&
- !job_is_cancelled(&s->job->common.job) &&
- s->job->copy_mode == MIRROR_COPY_MODE_WRITE_BLOCKING;
- }
+ bool copy_to_target = should_copy_to_target(bs->opaque);
if (copy_to_target) {
/* The guest might concurrently modify the data to write; but
@@ -1551,8 +1544,8 @@ bdrv_mirror_top_pwritev(BlockDriverState *bs, int64_t
offset, int64_t bytes,
flags &= ~BDRV_REQ_REGISTERED_BUF;
}
- ret = bdrv_mirror_top_do_write(bs, MIRROR_METHOD_COPY, offset, bytes, qiov,
- flags);
+ ret = bdrv_mirror_top_do_write(bs, MIRROR_METHOD_COPY, copy_to_target,
+ offset, bytes, qiov, flags);
if (copy_to_target) {
qemu_iovec_destroy(&bounce_qiov);
@@ -1575,15 +1568,17 @@ static int coroutine_fn GRAPH_RDLOCK
bdrv_mirror_top_pwrite_zeroes(BlockDriverState *bs, int64_t offset,
int64_t bytes, BdrvRequestFlags flags)
{
- return bdrv_mirror_top_do_write(bs, MIRROR_METHOD_ZERO, offset, bytes,
NULL,
- flags);
+ bool copy_to_target = should_copy_to_target(bs->opaque);
+ return bdrv_mirror_top_do_write(bs, MIRROR_METHOD_ZERO, copy_to_target,
+ offset, bytes, NULL, flags);
}
static int coroutine_fn GRAPH_RDLOCK
bdrv_mirror_top_pdiscard(BlockDriverState *bs, int64_t offset, int64_t bytes)
{
- return bdrv_mirror_top_do_write(bs, MIRROR_METHOD_DISCARD, offset, bytes,
- NULL, 0);
+ bool copy_to_target = should_copy_to_target(bs->opaque);
+ return bdrv_mirror_top_do_write(bs, MIRROR_METHOD_DISCARD, copy_to_target,
+ offset, bytes, NULL, 0);
}
static void bdrv_mirror_top_refresh_filename(BlockDriverState *bs)
--
2.41.0
- [PULL 00/27] Block layer patches, Kevin Wolf, 2023/10/31
- [PULL 01/27] qemu-img: rebase: stop when reaching EOF of old backing file, Kevin Wolf, 2023/10/31
- [PULL 02/27] qemu-iotests: 024: add rebasing test case for overlay_size > backing_size, Kevin Wolf, 2023/10/31
- [PULL 03/27] qemu-img: rebase: use backing files' BlockBackend for buffer alignment, Kevin Wolf, 2023/10/31
- [PULL 04/27] qemu-img: add chunk size parameter to compare_buffers(), Kevin Wolf, 2023/10/31
- [PULL 07/27] qemu-img: add compression option to rebase subcommand, Kevin Wolf, 2023/10/31
- [PULL 05/27] qemu-img: rebase: avoid unnecessary COW operations, Kevin Wolf, 2023/10/31
- [PULL 06/27] iotests/{024, 271}: add testcases for qemu-img rebase, Kevin Wolf, 2023/10/31
- [PULL 16/27] virtio: use defer_call() in virtio_irqfd_notify(), Kevin Wolf, 2023/10/31
- [PULL 15/27] util/defer-call: move defer_call() to util/, Kevin Wolf, 2023/10/31
- [PULL 21/27] block/mirror: determine copy_to_target only once,
Kevin Wolf <=
- [PULL 19/27] block/mirror: set actively_synced even after the job is ready, Kevin Wolf, 2023/10/31
- [PULL 20/27] block/mirror: move dirty bitmap to filter, Kevin Wolf, 2023/10/31
- [PULL 17/27] virtio-blk: remove batch notification BH, Kevin Wolf, 2023/10/31
- [PULL 13/27] blockdev: mirror: avoid potential deadlock when using iothread, Kevin Wolf, 2023/10/31
- [PULL 18/27] blockjob: introduce block-job-change QMP command, Kevin Wolf, 2023/10/31
- [PULL 09/27] block: Fix locking in media change monitor commands, Kevin Wolf, 2023/10/31
- [PULL 11/27] blockjob: drop AioContext lock before calling bdrv_graph_wrlock(), Kevin Wolf, 2023/10/31
- [PULL 25/27] blockjob: query driver-specific info via a new 'query' driver method, Kevin Wolf, 2023/10/31
- [PULL 12/27] block: avoid potential deadlock during bdrv_graph_wrlock() in bdrv_close(), Kevin Wolf, 2023/10/31
- [PULL 14/27] block: rename blk_io_plug_call() API to defer_call(), Kevin Wolf, 2023/10/31