From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from [140.186.70.92] (port=53501 helo=eggs.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1OZ04v-0006SW-DF for qemu-devel@nongnu.org; Wed, 14 Jul 2010 07:24:42 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.69) (envelope-from ) id 1OZ04u-0001SE-19 for qemu-devel@nongnu.org; Wed, 14 Jul 2010 07:24:41 -0400 Received: from mx1.redhat.com ([209.132.183.28]:45856) by eggs.gnu.org with esmtp (Exim 4.69) (envelope-from ) id 1OZ04t-0001S5-NS for qemu-devel@nongnu.org; Wed, 14 Jul 2010 07:24:39 -0400 From: Kevin Wolf Date: Wed, 14 Jul 2010 13:24:05 +0200 Message-Id: <1279106653-24351-7-git-send-email-kwolf@redhat.com> In-Reply-To: <1279106653-24351-1-git-send-email-kwolf@redhat.com> References: <1279106653-24351-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] [STABLE][PATCH 06/14] 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: aurelien@aurel32.net Cc: kwolf@redhat.com, qemu-devel@nongnu.org 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 (cherry picked from commit f21dc3a4652eeb82117d7d55d975278fe1444b26) Conflicts: block/vdi.c Signed-off-by: Kevin Wolf --- block/vdi.c | 18 +++++++++++++++--- 1 files changed, 15 insertions(+), 3 deletions(-) diff --git a/block/vdi.c b/block/vdi.c index 45aa81c..64bf66f 100644 --- a/block/vdi.c +++ b/block/vdi.c @@ -399,6 +399,15 @@ static int vdi_open(BlockDriverState *bs, const char= *filename, 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); @@ -417,9 +426,9 @@ static int vdi_open(BlockDriverState *bs, const char = *filename, int flags) } 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 !=3D + } else if (header.disk_size > (uint64_t)header.blocks_in_image * header.block_size) { - logout("unexpected block number %u B\n", header.blocks_in_image)= ; + 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"); @@ -831,7 +840,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.7.1.1