From 04c5a9797c3bdf379ffad1f159eccfcdca12475f Mon Sep 17 00:00:00 2001 From: John Snow 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 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 RH-Acked-by: Kevin Wolf RH-Acked-by: Max Reitz 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 Signed-off-by: John Snow Reviewed-by: Eric Blake Message-id: 20190218233154.19303-1-jsnow@redhat.com Signed-off-by: John Snow (cherry picked from commit 0a6c86d024c52b1e66d4f7ec01a3bb8ea2600145) Signed-off-by: John Snow Signed-off-by: Miroslav Rezanina --- 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