aboutsummaryrefslogtreecommitdiff
path: root/block
diff options
context:
space:
mode:
authorSerge E. Hallyn <serge@hallyn.com>2011-07-25 18:34:35 +0000
committerKevin Wolf <kwolf@redhat.com>2011-08-01 12:10:28 +0200
commitefc8243d00ab4cf4fa05a9be93233cb883b7caa0 (patch)
tree1bc4e76fbcba8e3ae7dac008d79e0f1c13e0fd98 /block
parent49aa46bb4b894ff8bdb0339ee2a5dd3fcfe93ecd (diff)
block/vpc.c: Detect too-large vpc file
VHD files technically can be up to 2Tb, but virtual pc is limited to 127G. Currently qemu-img refused to create vpc files > 127G, but it is failing to return error when converting from a non-vpc VHD file which is >127G. It returns success, but creates a truncated converted image. Also, qemu-img info claims the vpc file is 127G (and clean). This patch detects a too-large vpc file and returns -EFBIG. Without this patch, ============================================================= root@ip-10-38-123-242:~/qemu-fixed# qemu-img info /mnt/140g-dynamic.vhd image: /mnt/140g-dynamic.vhd file format: vpc virtual size: 127G (136899993600 bytes) disk size: 284K root@ip-10-38-123-242:~/qemu-fixed# qemu-img convert -f vpc -O raw /mnt/140g-dynamic.vhd /mnt/y root@ip-10-38-123-242:~/qemu-fixed# echo $? 0 root@ip-10-38-123-242:~/qemu-fixed# qemu-img info /mnt/y image: /mnt/y file format: raw virtual size: 127G (136899993600 bytes) disk size: 0 ============================================================= (The 140G image was truncated with no warning or error.) With the patch, I get: ============================================================= root@ip-10-38-123-242:~/qemu-fixed# ./qemu-img info /mnt/140g-dynamic.vhd qemu-img: Could not open '/mnt/140g-dynamic.vhd': File too large root@ip-10-38-123-242:~/qemu-fixed# ./qemu-img convert -f vpc -O raw /mnt/140g-dynamic.vhd /mnt/y qemu-img: Could not open '/mnt/140g-dynamic.vhd': File too large qemu-img: Could not open '/mnt/140g-dynamic.vhd' ============================================================= See https://bugs.launchpad.net/qemu/+bug/814222 for details. Signed-off-by: Serge Hallyn <serge.hallyn@canonical.com> Signed-off-by: Kevin Wolf <kwolf@redhat.com>
Diffstat (limited to 'block')
-rw-r--r--block/vpc.c8
1 files changed, 7 insertions, 1 deletions
diff --git a/block/vpc.c b/block/vpc.c
index 56865da5bc..fdd5236892 100644
--- a/block/vpc.c
+++ b/block/vpc.c
@@ -156,6 +156,7 @@ static int vpc_open(BlockDriverState *bs, int flags)
struct vhd_dyndisk_header* dyndisk_header;
uint8_t buf[HEADER_SIZE];
uint32_t checksum;
+ int err = -1;
if (bdrv_pread(bs->file, 0, s->footer_buf, HEADER_SIZE) != HEADER_SIZE)
goto fail;
@@ -176,6 +177,11 @@ static int vpc_open(BlockDriverState *bs, int flags)
bs->total_sectors = (int64_t)
be16_to_cpu(footer->cyls) * footer->heads * footer->secs_per_cyl;
+ if (bs->total_sectors >= 65535 * 16 * 255) {
+ err = -EFBIG;
+ goto fail;
+ }
+
if (bdrv_pread(bs->file, be64_to_cpu(footer->data_offset), buf, HEADER_SIZE)
!= HEADER_SIZE)
goto fail;
@@ -222,7 +228,7 @@ static int vpc_open(BlockDriverState *bs, int flags)
return 0;
fail:
- return -1;
+ return err;
}
/*