yeahuh / rpms / qemu-kvm

Forked from rpms/qemu-kvm 2 years ago
Clone

Blame SOURCES/kvm-block-Require-aligned-image-size-to-avoid-assertion-.patch

8fced6
From e191ab6358b656764374ff1b3c7224a744dc902a Mon Sep 17 00:00:00 2001
8fced6
From: Kevin Wolf <kwolf@redhat.com>
8fced6
Date: Tue, 26 Jan 2021 17:21:02 -0500
8fced6
Subject: [PATCH 7/9] block: Require aligned image size to avoid assertion
8fced6
 failure
8fced6
8fced6
RH-Author: Kevin Wolf <kwolf@redhat.com>
8fced6
Message-id: <20210126172103.136060-2-kwolf@redhat.com>
8fced6
Patchwork-id: 100786
8fced6
O-Subject: [RHEL-8.4.0 qemu-kvm PATCH 1/2] block: Require aligned image size to avoid assertion failure
8fced6
Bugzilla: 1834281
8fced6
RH-Acked-by: Markus Armbruster <armbru@redhat.com>
8fced6
RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
8fced6
RH-Acked-by: Max Reitz <mreitz@redhat.com>
8fced6
8fced6
Unaligned requests will automatically be aligned to bl.request_alignment
8fced6
and we can't extend write requests to access space beyond the end of the
8fced6
image without resizing the image, so if we have the WRITE permission,
8fced6
but not the RESIZE one, it's required that the image size is aligned.
8fced6
8fced6
Failing to meet this requirement could cause assertion failures like
8fced6
this if RESIZE permissions weren't requested:
8fced6
8fced6
qemu-img: block/io.c:1910: bdrv_co_write_req_prepare: Assertion `end_sector <= bs->total_sectors || child->perm & BLK_PERM_RESIZE' failed.
8fced6
8fced6
This was e.g. triggered by qemu-img converting to a target image with 4k
8fced6
request alignment when the image was only aligned to 512 bytes, but not
8fced6
to 4k.
8fced6
8fced6
Turn this into a graceful error in bdrv_check_perm() so that WRITE
8fced6
without RESIZE can only be taken if the image size is aligned. If a user
8fced6
holds both permissions and drops only RESIZE, the function will return
8fced6
an error, but bdrv_child_try_set_perm() will ignore the failure silently
8fced6
if permissions are only requested to be relaxed and just keep both
8fced6
permissions while returning success.
8fced6
8fced6
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
8fced6
Message-Id: <20200716142601.111237-2-kwolf@redhat.com>
8fced6
Reviewed-by: Max Reitz <mreitz@redhat.com>
8fced6
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
8fced6
(cherry picked from commit 9c60a5d1978e6dcf85c0e01b50e6f7f54ca09104)
8fced6
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
8fced6
Signed-off-by: Jon Maloy <jmaloy.redhat.com>
8fced6
---
8fced6
 block.c | 16 ++++++++++++++++
8fced6
 1 file changed, 16 insertions(+)
8fced6
8fced6
diff --git a/block.c b/block.c
8fced6
index 57740d312e..e9579ddf84 100644
8fced6
--- a/block.c
8fced6
+++ b/block.c
8fced6
@@ -2009,6 +2009,22 @@ static int bdrv_check_perm(BlockDriverState *bs, BlockReopenQueue *q,
8fced6
         return -EPERM;
8fced6
     }
8fced6
 
8fced6
+    /*
8fced6
+     * Unaligned requests will automatically be aligned to bl.request_alignment
8fced6
+     * and without RESIZE we can't extend requests to write to space beyond the
8fced6
+     * end of the image, so it's required that the image size is aligned.
8fced6
+     */
8fced6
+    if ((cumulative_perms & (BLK_PERM_WRITE | BLK_PERM_WRITE_UNCHANGED)) &&
8fced6
+        !(cumulative_perms & BLK_PERM_RESIZE))
8fced6
+    {
8fced6
+        if ((bs->total_sectors * BDRV_SECTOR_SIZE) % bs->bl.request_alignment) {
8fced6
+            error_setg(errp, "Cannot get 'write' permission without 'resize': "
8fced6
+                             "Image size is not a multiple of request "
8fced6
+                             "alignment");
8fced6
+            return -EPERM;
8fced6
+        }
8fced6
+    }
8fced6
+
8fced6
     /* Check this node */
8fced6
     if (!drv) {
8fced6
         return 0;
8fced6
-- 
8fced6
2.18.2
8fced6