From 04c5a9797c3bdf379ffad1f159eccfcdca12475f Mon Sep 17 00:00:00 2001
From: John Snow <jsnow@redhat.com>
Date: Wed, 20 Mar 2019 23:55:08 +0100
Subject: [PATCH 046/163] blockdev: acquire aio_context for bitmap add/remove
RH-Author: John Snow <jsnow@redhat.com>
Message-id: <20190320235508.17673-2-jsnow@redhat.com>
Patchwork-id: 85031
O-Subject: [RHEL-7.7 qemu-kvm-rhev PATCH 1/1] blockdev: acquire aio_context for bitmap add/remove
Bugzilla: 1672010
RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
RH-Acked-by: Kevin Wolf <kwolf@redhat.com>
RH-Acked-by: Max Reitz <mreitz@redhat.com>
When bitmaps are persistent, they may incur a disk read or write when bitmaps
are added or removed. For configurations like virtio-dataplane, failing to
acquire this lock will abort QEMU when disk IO occurs.
We used to acquire aio_context as part of the bitmap lookup, so re-introduce
the lock for just the cases that have an IO penalty. Commit 2119882c removed
these locks, and I failed to notice this when we committed fd5ae4cc, so this
has been broken since persistent bitmaps were introduced.
Fixes: https://bugzilla.redhat.com/show_bug.cgi?id=1672010
Reported-By: Aihua Liang <aliang@redhat.com>
Signed-off-by: John Snow <jsnow@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Message-id: 20190218233154.19303-1-jsnow@redhat.com
Signed-off-by: John Snow <jsnow@redhat.com>
(cherry picked from commit 0a6c86d024c52b1e66d4f7ec01a3bb8ea2600145)
Signed-off-by: John Snow <jsnow@redhat.com>
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
---
blockdev.c | 26 ++++++++++++++++++++------
1 file changed, 20 insertions(+), 6 deletions(-)
diff --git a/blockdev.c b/blockdev.c
index 47db9bb..f437896 100644
--- a/blockdev.c
+++ b/blockdev.c
@@ -2973,6 +2973,7 @@ void qmp_block_dirty_bitmap_add(const char *node, const char *name,
{
BlockDriverState *bs;
BdrvDirtyBitmap *bitmap;
+ AioContext *aio_context = NULL;
if (!name || name[0] == '\0') {
error_setg(errp, "Bitmap name cannot be empty");
@@ -3007,15 +3008,17 @@ void qmp_block_dirty_bitmap_add(const char *node, const char *name,
disabled = false;
}
- if (persistent &&
- !bdrv_can_store_new_dirty_bitmap(bs, name, granularity, errp))
- {
- return;
+ if (persistent) {
+ aio_context = bdrv_get_aio_context(bs);
+ aio_context_acquire(aio_context);
+ if (!bdrv_can_store_new_dirty_bitmap(bs, name, granularity, errp)) {
+ goto out;
+ }
}
bitmap = bdrv_create_dirty_bitmap(bs, granularity, name, errp);
if (bitmap == NULL) {
- return;
+ goto out;
}
if (disabled) {
@@ -3023,6 +3026,10 @@ void qmp_block_dirty_bitmap_add(const char *node, const char *name,
}
bdrv_dirty_bitmap_set_persistance(bitmap, persistent);
+ out:
+ if (aio_context) {
+ aio_context_release(aio_context);
+ }
}
void qmp_block_dirty_bitmap_remove(const char *node, const char *name,
@@ -3031,6 +3038,7 @@ void qmp_block_dirty_bitmap_remove(const char *node, const char *name,
BlockDriverState *bs;
BdrvDirtyBitmap *bitmap;
Error *local_err = NULL;
+ AioContext *aio_context = NULL;
bitmap = block_dirty_bitmap_lookup(node, name, &bs, errp);
if (!bitmap || !bs) {
@@ -3045,14 +3053,20 @@ void qmp_block_dirty_bitmap_remove(const char *node, const char *name,
}
if (bdrv_dirty_bitmap_get_persistance(bitmap)) {
+ aio_context = bdrv_get_aio_context(bs);
+ aio_context_acquire(aio_context);
bdrv_remove_persistent_dirty_bitmap(bs, name, &local_err);
if (local_err != NULL) {
error_propagate(errp, local_err);
- return;
+ goto out;
}
}
bdrv_release_dirty_bitmap(bs, bitmap);
+ out:
+ if (aio_context) {
+ aio_context_release(aio_context);
+ }
}
/**
--
1.8.3.1