aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStefan Weil <stefan@kiwi.(none)>2013-02-07 20:26:52 +0100
committerAnthony Liguori <aliguori@us.ibm.com>2013-02-11 08:14:41 -0600
commitf880defbb06708d30a38ce9f2667067626acdd38 (patch)
tree2a9ba716053aab8888be44b39e4fc2678a403f2e
parent2c5a7f20112615ce13a3434ab90bee1ed8d44ebd (diff)
block/vpc: Fix size calculation
The size calculated from the CHS values is not the real image (disk) size, but usually a smaller value. This is caused by rounding effects. Only older operating systems use CHS. Such guests won't be able to use the whole disk. All modern operating systems use the real size. This patch fixes https://bugs.launchpad.net/qemu/+bug/1105670/. Signed-off-by: Stefan Weil <sw@weilnetz.de> Message-id: 1360265212-22037-1-git-send-email-sw@weilnetz.de Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
-rw-r--r--block/vpc.c14
1 files changed, 9 insertions, 5 deletions
diff --git a/block/vpc.c b/block/vpc.c
index 82229ef5a0..b4ff5646a2 100644
--- a/block/vpc.c
+++ b/block/vpc.c
@@ -34,6 +34,8 @@
#define HEADER_SIZE 512
+#define VHD_SECTOR_SIZE 512
+
//#define CACHE
enum vhd_type {
@@ -204,11 +206,13 @@ static int vpc_open(BlockDriverState *bs, int flags)
/* Write 'checksum' back to footer, or else will leave it with zero. */
footer->checksum = be32_to_cpu(checksum);
- // The visible size of a image in Virtual PC depends on the geometry
- // rather than on the size stored in the footer (the size in the footer
- // is too large usually)
- bs->total_sectors = (int64_t)
- be16_to_cpu(footer->cyls) * footer->heads * footer->secs_per_cyl;
+ /* The visible size of a image in Virtual PC depends on the guest:
+ * QEMU and other emulators report the real size (here in sectors).
+ * All modern operating systems use this real size.
+ * Very old operating systems use CHS values to calculate the total size.
+ * This calculated size is usually smaller than the real size.
+ */
+ bs->total_sectors = be64_to_cpu(footer->size) / VHD_SECTOR_SIZE;
/* Allow a maximum disk size of approximately 2 TB */
if (bs->total_sectors >= 65535LL * 255 * 255) {