diff options
author | Vladimir Sementsov-Ogievskiy | 2021-04-21 09:58:58 +0200 |
---|---|---|
committer | Max Reitz | 2021-05-14 16:14:10 +0200 |
commit | 9c785cd714b3c368503ba3aed4266a77056cae29 (patch) | |
tree | 2f1978b1bc246ff0dc57e48f71acbcdb496f1d47 /block | |
parent | monitor: hmp_qemu_io: acquire aio contex, fix crash (diff) | |
download | qemu-9c785cd714b3c368503ba3aed4266a77056cae29.tar.gz qemu-9c785cd714b3c368503ba3aed4266a77056cae29.tar.xz qemu-9c785cd714b3c368503ba3aed4266a77056cae29.zip |
mirror: stop cancelling in-flight requests on non-force cancel in READY
If mirror is READY than cancel operation is not discarding the whole
result of the operation, but instead it's a documented way get a
point-in-time snapshot of source disk.
So, we should not cancel any requests if mirror is READ and
force=false. Let's fix that case.
Note, that bug that we have before this commit is not critical, as the
only .bdrv_cancel_in_flight implementation is nbd_cancel_in_flight()
and it cancels only requests waiting for reconnection, so it should be
rare case.
Fixes: 521ff8b779b11c394dbdc43f02e158dd99df308a
Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
Message-Id: <20210421075858.40197-1-vsementsov@virtuozzo.com>
Signed-off-by: Max Reitz <mreitz@redhat.com>
Diffstat (limited to 'block')
-rw-r--r-- | block/backup.c | 2 | ||||
-rw-r--r-- | block/mirror.c | 6 |
2 files changed, 5 insertions, 3 deletions
diff --git a/block/backup.c b/block/backup.c index 6cf2f974aa..bd3614ce70 100644 --- a/block/backup.c +++ b/block/backup.c @@ -331,7 +331,7 @@ static void coroutine_fn backup_set_speed(BlockJob *job, int64_t speed) } } -static void backup_cancel(Job *job) +static void backup_cancel(Job *job, bool force) { BackupBlockJob *s = container_of(job, BackupBlockJob, common.job); diff --git a/block/mirror.c b/block/mirror.c index 840b8e8c15..019f6deaa5 100644 --- a/block/mirror.c +++ b/block/mirror.c @@ -1178,12 +1178,14 @@ static bool mirror_drained_poll(BlockJob *job) return !!s->in_flight; } -static void mirror_cancel(Job *job) +static void mirror_cancel(Job *job, bool force) { MirrorBlockJob *s = container_of(job, MirrorBlockJob, common.job); BlockDriverState *target = blk_bs(s->target); - bdrv_cancel_in_flight(target); + if (force || !job_is_ready(job)) { + bdrv_cancel_in_flight(target); + } } static const BlockJobDriver mirror_job_driver = { |