aboutsummaryrefslogtreecommitdiff
path: root/block/vdi.c
diff options
context:
space:
mode:
authorMax Reitz <mreitz@redhat.com>2014-10-28 11:12:32 +0100
committerMax Reitz <mreitz@redhat.com>2014-11-09 23:39:50 +0100
commitd20418ee514774626ac47a1ad0aa9149c7249cf0 (patch)
tree3f2343113a49320ac9891a33b31e82f6c34091ce /block/vdi.c
parentd21de4d97faaad6ac21011d7bda924f9b2353b7b (diff)
block/vdi: Limit maximum size even futher
The block layer read and write functions do not like requests which are bigger than INT_MAX bytes. Since the VDI bmap is read and written in a single operation, its size is therefore limited accordingly. This reduces the maximum VDI image size supported by QEMU to half of what it currently is (down to approximately 512 TB). The VDI test 084 has to be adapted accordingly. Actually, one could clearly see that it was broken from the "Could not open 'TEST_DIR/t.IMGFMT': Invalid argument" line for an image which was supposed to work just fine. Signed-off-by: Max Reitz <mreitz@redhat.com> Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com> Reviewed-by: Peter Lieven <pl@kamp.de>
Diffstat (limited to 'block/vdi.c')
-rw-r--r--block/vdi.c14
1 files changed, 12 insertions, 2 deletions
diff --git a/block/vdi.c b/block/vdi.c
index e1d211c9f7..39070b75e8 100644
--- a/block/vdi.c
+++ b/block/vdi.c
@@ -120,8 +120,18 @@ typedef unsigned char uuid_t[16];
#define VDI_IS_ALLOCATED(X) ((X) < VDI_DISCARDED)
-/* max blocks in image is (0xffffffff / 4) */
-#define VDI_BLOCKS_IN_IMAGE_MAX 0x3fffffff
+/* The bmap will take up VDI_BLOCKS_IN_IMAGE_MAX * sizeof(uint32_t) bytes; since
+ * the bmap is read and written in a single operation, its size needs to be
+ * limited to INT_MAX; furthermore, when opening an image, the bmap size is
+ * rounded up to be aligned on BDRV_SECTOR_SIZE.
+ * Therefore this should satisfy the following:
+ * VDI_BLOCKS_IN_IMAGE_MAX * sizeof(uint32_t) + BDRV_SECTOR_SIZE == INT_MAX + 1
+ * (INT_MAX + 1 is the first value not representable as an int)
+ * This guarantees that any value below or equal to the constant will, when
+ * multiplied by sizeof(uint32_t) and rounded up to a BDRV_SECTOR_SIZE boundary,
+ * still be below or equal to INT_MAX. */
+#define VDI_BLOCKS_IN_IMAGE_MAX \
+ ((unsigned)((INT_MAX + 1u - BDRV_SECTOR_SIZE) / sizeof(uint32_t)))
#define VDI_DISK_SIZE_MAX ((uint64_t)VDI_BLOCKS_IN_IMAGE_MAX * \
(uint64_t)DEFAULT_CLUSTER_SIZE)