diff options
author | Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com> | 2019-10-01 16:14:05 +0300 |
---|---|---|
committer | Max Reitz <mreitz@redhat.com> | 2019-10-10 10:56:18 +0200 |
commit | a6ffe1998cfe1fd3cd83de0a7d1dd16eb514f987 (patch) | |
tree | 2340299ddbb9c799fa5a9d9f0d63bd89551182a2 /block/block-copy.c | |
parent | f2d86ade4da71d1f32ffc5977ea5417c20996919 (diff) |
block/backup: move in-flight requests handling from backup to block-copy
Move synchronization mechanism to block-copy, to be able to use one
block-copy instance from backup job and backup-top filter in parallel.
Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
Message-id: 20191001131409.14202-2-vsementsov@virtuozzo.com
Reviewed-by: Max Reitz <mreitz@redhat.com>
Signed-off-by: Max Reitz <mreitz@redhat.com>
Diffstat (limited to 'block/block-copy.c')
-rw-r--r-- | block/block-copy.c | 43 |
1 files changed, 43 insertions, 0 deletions
diff --git a/block/block-copy.c b/block/block-copy.c index 3fc9152853..61e5ea5f46 100644 --- a/block/block-copy.c +++ b/block/block-copy.c @@ -19,6 +19,41 @@ #include "block/block-copy.h" #include "sysemu/block-backend.h" +static void coroutine_fn block_copy_wait_inflight_reqs(BlockCopyState *s, + int64_t start, + int64_t end) +{ + BlockCopyInFlightReq *req; + bool waited; + + do { + waited = false; + QLIST_FOREACH(req, &s->inflight_reqs, list) { + if (end > req->start_byte && start < req->end_byte) { + qemu_co_queue_wait(&req->wait_queue, NULL); + waited = true; + break; + } + } + } while (waited); +} + +static void block_copy_inflight_req_begin(BlockCopyState *s, + BlockCopyInFlightReq *req, + int64_t start, int64_t end) +{ + req->start_byte = start; + req->end_byte = end; + qemu_co_queue_init(&req->wait_queue); + QLIST_INSERT_HEAD(&s->inflight_reqs, req, list); +} + +static void coroutine_fn block_copy_inflight_req_end(BlockCopyInFlightReq *req) +{ + QLIST_REMOVE(req, list); + qemu_co_queue_restart_all(&req->wait_queue); +} + void block_copy_state_free(BlockCopyState *s) { if (!s) { @@ -79,6 +114,8 @@ BlockCopyState *block_copy_state_new( s->use_copy_range = !(write_flags & BDRV_REQ_WRITE_COMPRESSED) && s->copy_range_size > 0; + QLIST_INIT(&s->inflight_reqs); + /* * We just allow aio context change on our block backends. block_copy() user * (now it's only backup) is responsible for source and target being in same @@ -266,6 +303,7 @@ int coroutine_fn block_copy(BlockCopyState *s, int64_t end = bytes + start; /* bytes */ void *bounce_buffer = NULL; int64_t status_bytes; + BlockCopyInFlightReq req; /* * block_copy() user is responsible for keeping source and target in same @@ -276,6 +314,9 @@ int coroutine_fn block_copy(BlockCopyState *s, assert(QEMU_IS_ALIGNED(start, s->cluster_size)); assert(QEMU_IS_ALIGNED(end, s->cluster_size)); + block_copy_wait_inflight_reqs(s, start, bytes); + block_copy_inflight_req_begin(s, &req, start, end); + while (start < end) { int64_t dirty_end; @@ -329,5 +370,7 @@ int coroutine_fn block_copy(BlockCopyState *s, qemu_vfree(bounce_buffer); } + block_copy_inflight_req_end(&req); + return ret; } |