Skip to content

Commit 9c60a5d

Browse files
committed
block: Require aligned image size to avoid assertion failure
Unaligned requests will automatically be aligned to bl.request_alignment and we can't extend write requests to access space beyond the end of the image without resizing the image, so if we have the WRITE permission, but not the RESIZE one, it's required that the image size is aligned. Failing to meet this requirement could cause assertion failures like this if RESIZE permissions weren't requested: qemu-img: block/io.c:1910: bdrv_co_write_req_prepare: Assertion `end_sector <= bs->total_sectors || child->perm & BLK_PERM_RESIZE' failed. This was e.g. triggered by qemu-img converting to a target image with 4k request alignment when the image was only aligned to 512 bytes, but not to 4k. Turn this into a graceful error in bdrv_check_perm() so that WRITE without RESIZE can only be taken if the image size is aligned. If a user holds both permissions and drops only RESIZE, the function will return an error, but bdrv_child_try_set_perm() will ignore the failure silently if permissions are only requested to be relaxed and just keep both permissions while returning success. Signed-off-by: Kevin Wolf <[email protected]> Message-Id: <[email protected]> Reviewed-by: Max Reitz <[email protected]> Signed-off-by: Kevin Wolf <[email protected]>
1 parent d047cfa commit 9c60a5d

File tree

1 file changed

+16
-0
lines changed

1 file changed

+16
-0
lines changed

block.c

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2025,6 +2025,22 @@ static int bdrv_check_perm(BlockDriverState *bs, BlockReopenQueue *q,
20252025
return -EPERM;
20262026
}
20272027

2028+
/*
2029+
* Unaligned requests will automatically be aligned to bl.request_alignment
2030+
* and without RESIZE we can't extend requests to write to space beyond the
2031+
* end of the image, so it's required that the image size is aligned.
2032+
*/
2033+
if ((cumulative_perms & (BLK_PERM_WRITE | BLK_PERM_WRITE_UNCHANGED)) &&
2034+
!(cumulative_perms & BLK_PERM_RESIZE))
2035+
{
2036+
if ((bs->total_sectors * BDRV_SECTOR_SIZE) % bs->bl.request_alignment) {
2037+
error_setg(errp, "Cannot get 'write' permission without 'resize': "
2038+
"Image size is not a multiple of request "
2039+
"alignment");
2040+
return -EPERM;
2041+
}
2042+
}
2043+
20282044
/* Check this node */
20292045
if (!drv) {
20302046
return 0;

0 commit comments

Comments
 (0)