From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from [140.186.70.92] (port=41433 helo=eggs.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1OCyQa-0000hZ-Mk for qemu-devel@nongnu.org; Fri, 14 May 2010 13:12:05 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.69) (envelope-from ) id 1OCyQX-0001y5-46 for qemu-devel@nongnu.org; Fri, 14 May 2010 13:12:00 -0400 Received: from mx1.redhat.com ([209.132.183.28]:30683) by eggs.gnu.org with esmtp (Exim 4.69) (envelope-from ) id 1OCyQW-0001xv-PV for qemu-devel@nongnu.org; Fri, 14 May 2010 13:11:57 -0400 From: Kevin Wolf Date: Fri, 14 May 2010 19:10:52 +0200 Message-Id: <1273857055-26715-19-git-send-email-kwolf@redhat.com> In-Reply-To: <1273857055-26715-1-git-send-email-kwolf@redhat.com> References: <1273857055-26715-1-git-send-email-kwolf@redhat.com> MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: quoted-printable Subject: [Qemu-devel] [PATCH 18/21] block/vdi: Fix image opening and creation for odd disk sizes List-Id: qemu-devel.nongnu.org List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: anthony@codemonkey.ws Cc: kwolf@redhat.com, qemu-devel@nongnu.org From: Stefan Weil The fix is based on a patch from Kevin Wolf. Here his comment: "The number of blocks needs to be rounded up to cover all of the virtual = hard disk. Without this fix, we can't even open our own images if their size i= s not a multiple of the block size." While Kevin's patch addressed vdi_create, my modification also fixes vdi_open which now accepts images with odd disk sizes. v3: Don't allow reading of disk images with too large disk sizes. Neither VBoxManage nor old versions of qemu-img read such images. This change requires rounding of odd disk sizes before we do the checks. Cc: Kevin Wolf Cc: Fran=C3=A7ois Revol Signed-off-by: Stefan Weil Signed-off-by: Kevin Wolf --- block/vdi.c | 23 ++++++++++++++++------- 1 files changed, 16 insertions(+), 7 deletions(-) diff --git a/block/vdi.c b/block/vdi.c index 3ea4103..ee8cc7b 100644 --- a/block/vdi.c +++ b/block/vdi.c @@ -393,6 +393,15 @@ static int vdi_open(BlockDriverState *bs, int flags) vdi_header_print(&header); #endif =20 + if (header.disk_size % SECTOR_SIZE !=3D 0) { + /* 'VBoxManage convertfromraw' can create images with odd disk s= izes. + We accept them but round the disk size to the next multiple o= f + SECTOR_SIZE. */ + logout("odd disk size %" PRIu64 " B, round up\n", header.disk_si= ze); + header.disk_size +=3D SECTOR_SIZE - 1; + header.disk_size &=3D ~(SECTOR_SIZE - 1); + } + if (header.version !=3D VDI_VERSION_1_1) { logout("unsupported version %u.%u\n", header.version >> 16, header.version & 0xffff); @@ -405,18 +414,15 @@ static int vdi_open(BlockDriverState *bs, int flags= ) /* We only support data blocks which start on a sector boundary.= */ logout("unsupported data offset 0x%x B\n", header.offset_data); goto fail; - } else if (header.disk_size % SECTOR_SIZE !=3D 0) { - logout("unsupported disk size %" PRIu64 " B\n", header.disk_size= ); - goto fail; } else if (header.sector_size !=3D SECTOR_SIZE) { logout("unsupported sector size %u B\n", header.sector_size); goto fail; } else if (header.block_size !=3D 1 * MiB) { logout("unsupported block size %u B\n", header.block_size); goto fail; - } else if ((header.disk_size + header.block_size - 1) / header.block= _size !=3D - (uint64_t)header.blocks_in_image) { - logout("unexpected block number %u B\n", header.blocks_in_image)= ; + } else if (header.disk_size > + (uint64_t)header.blocks_in_image * header.block_size) { + logout("unsupported disk size %" PRIu64 " B\n", header.disk_size= ); goto fail; } else if (!uuid_is_null(header.uuid_link)) { logout("link uuid !=3D 0, unsupported\n"); @@ -829,7 +835,10 @@ static int vdi_create(const char *filename, QEMUOpti= onParameter *options) return -errno; } =20 - blocks =3D bytes / block_size; + /* We need enough blocks to store the given disk size, + so always round up. */ + blocks =3D (bytes + block_size - 1) / block_size; + bmap_size =3D blocks * sizeof(uint32_t); bmap_size =3D ((bmap_size + SECTOR_SIZE - 1) & ~(SECTOR_SIZE -1)); =20 --=20 1.6.6.1