qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
From: Markus Armbruster <armbru@redhat.com>
To: qemu-devel@nongnu.org
Cc: kwolf@redhat.com, blauwirbel@gmail.com,
	stefanha@linux.vnet.ibm.com, pbonzini@redhat.com
Subject: [Qemu-devel] [PATCH 04/32] vvfat: Do not clobber the user's geometry
Date: Fri,  6 Jul 2012 08:57:42 +0200	[thread overview]
Message-ID: <1341557890-17464-5-git-send-email-armbru@redhat.com> (raw)
In-Reply-To: <1341557890-17464-1-git-send-email-armbru@redhat.com>

vvfat creates a virtual VFAT filesystem with a certain logical
geometry that depends on its options.  It sets the "geometry hint" to
this geometry.  It is the only block driver to do this.

The geometry hint is about about *physical* geometry, and used only by
certain hard disk device models.

vvfat's hint is normally invisible for device models, because
bdrv_open() puts a raw format on top of vvfat's fat protocol.  That
raw format is where drive_init() puts the user's geometry (if any),
and where the device model gets it from.

Nobody complained, because the default physical geometry is the same
as vvfat's logical geometry:

    opts        LCHS        def. PCHS
                1024,16,63  same
    :32:        1024,16,63  same
    :16:        1024,16,63  same
    :12:          64,16,63  same

Except when you specify :floppy:

    opts        LCHS        def. PCHS
       :floppy:   80, 2,36  5,16,63
    :32:floppy:   80, 2,36  5,16,63
    :16:floppy:   80, 2,36  5,16,63
    :12:floppy:   80, 2,18  2,16,63

Silly thing to do for use with a hard disk.

However, the "raw" format can be suppressed by adding an
redundant-looking "format=vvfat" to "file=fat:FOO".  Then, vvfat's
hint clobbers the user's geometry, i.e. -drive options cyls, heads,
secs get silently ignored.  Don't do that.

No change without format=vvfat.  With it, the user's hard disk
geometry (-drive options cyls, heads, secs) is now obeyed, and the
default hard disk geometry with :floppy: now matches the one without
format=vvfat.

Signed-off-by: Markus Armbruster <armbru@redhat.com>
---
 block/vvfat.c |   52 ++++++++++++++++++++++++++++------------------------
 1 files changed, 28 insertions(+), 24 deletions(-)

diff --git a/block/vvfat.c b/block/vvfat.c
index e2b83a2..07d637b 100644
--- a/block/vvfat.c
+++ b/block/vvfat.c
@@ -359,11 +359,12 @@ typedef struct BDRVVVFATState {
  * if the position is outside the specified geometry, fill maximum value for CHS
  * and return 1 to signal overflow.
  */
-static int sector2CHS(BlockDriverState* bs, mbr_chs_t * chs, int spos){
+static int sector2CHS(mbr_chs_t *chs, int spos, int cyls, int heads, int secs)
+{
     int head,sector;
-    sector   = spos % (bs->secs);  spos/= bs->secs;
-    head     = spos % (bs->heads); spos/= bs->heads;
-    if(spos >= bs->cyls){
+    sector   = spos % secs;  spos /= secs;
+    head     = spos % heads; spos /= heads;
+    if (spos >= cyls) {
         /* Overflow,
         it happens if 32bit sector positions are used, while CHS is only 24bit.
         Windows/Dos is said to take 1023/255/63 as nonrepresentable CHS */
@@ -378,7 +379,7 @@ static int sector2CHS(BlockDriverState* bs, mbr_chs_t * chs, int spos){
     return 0;
 }
 
-static void init_mbr(BDRVVVFATState* s)
+static void init_mbr(BDRVVVFATState *s, int cyls, int heads, int secs)
 {
     /* TODO: if the files mbr.img and bootsect.img exist, use them */
     mbr_t* real_mbr=(mbr_t*)s->first_sectors;
@@ -393,8 +394,10 @@ static void init_mbr(BDRVVVFATState* s)
     partition->attributes=0x80; /* bootable */
 
     /* LBA is used when partition is outside the CHS geometry */
-    lba = sector2CHS(s->bs, &partition->start_CHS, s->first_sectors_number-1);
-    lba |= sector2CHS(s->bs, &partition->end_CHS, s->bs->total_sectors - 1);
+    lba  = sector2CHS(&partition->start_CHS, s->first_sectors_number - 1,
+                     cyls, heads, secs);
+    lba |= sector2CHS(&partition->end_CHS,   s->bs->total_sectors - 1,
+                     cyls, heads, secs);
 
     /*LBA partitions are identified only by start/length_sector_long not by CHS*/
     partition->start_sector_long  = cpu_to_le32(s->first_sectors_number - 1);
@@ -831,7 +834,7 @@ static inline off_t cluster2sector(BDRVVVFATState* s, uint32_t cluster_num)
 }
 
 static int init_directories(BDRVVVFATState* s,
-	const char* dirname)
+                            const char *dirname, int heads, int secs)
 {
     bootsector_t* bootsector;
     mapping_t* mapping;
@@ -958,8 +961,8 @@ static int init_directories(BDRVVVFATState* s,
     bootsector->media_type=(s->first_sectors_number>1?0xf8:0xf0); /* media descriptor (f8=hd, f0=3.5 fd)*/
     s->fat.pointer[0] = bootsector->media_type;
     bootsector->sectors_per_fat=cpu_to_le16(s->sectors_per_fat);
-    bootsector->sectors_per_track=cpu_to_le16(s->bs->secs);
-    bootsector->number_of_heads=cpu_to_le16(s->bs->heads);
+    bootsector->sectors_per_track = cpu_to_le16(secs);
+    bootsector->number_of_heads = cpu_to_le16(heads);
     bootsector->hidden_sectors=cpu_to_le32(s->first_sectors_number==1?0:0x3f);
     bootsector->total_sectors=cpu_to_le32(s->sector_count>0xffff?s->sector_count:0);
 
@@ -992,7 +995,7 @@ static void vvfat_rebind(BlockDriverState *bs)
 static int vvfat_open(BlockDriverState *bs, const char* dirname, int flags)
 {
     BDRVVVFATState *s = bs->opaque;
-    int i;
+    int i, cyls, heads, secs;
 
 #ifdef DEBUG
     vvv = s;
@@ -1034,24 +1037,28 @@ DLOG(if (stderr == NULL) {
 	/* 1.44MB or 2.88MB floppy.  2.88MB can be FAT12 (default) or FAT16. */
 	if (!s->fat_type) {
 	    s->fat_type = 12;
-	    bs->secs = 36;
+            secs = 36;
 	    s->sectors_per_cluster=2;
 	} else {
-	    bs->secs=(s->fat_type == 12 ? 18 : 36);
+            secs = s->fat_type == 12 ? 18 : 36;
 	    s->sectors_per_cluster=1;
 	}
 	s->first_sectors_number = 1;
-	bs->cyls=80; bs->heads=2;
+        cyls = 80;
+        heads = 2;
     } else {
 	/* 32MB or 504MB disk*/
 	if (!s->fat_type) {
 	    s->fat_type = 16;
 	}
-	bs->cyls=(s->fat_type == 12 ? 64 : 1024);
-	bs->heads=16; bs->secs=63;
+        cyls = s->fat_type == 12 ? 64 : 1024;
+        heads = 16;
+        secs = 63;
     }
+    fprintf(stderr, "vvfat %s chs %d,%d,%d\n",
+            dirname, cyls, heads, secs);
 
-    s->sector_count=bs->cyls*bs->heads*bs->secs-(s->first_sectors_number-1);
+    s->sector_count = cyls * heads * secs - (s->first_sectors_number - 1);
 
     if (strstr(dirname, ":rw:")) {
 	if (enable_write_target(s))
@@ -1067,19 +1074,16 @@ DLOG(if (stderr == NULL) {
     else
 	dirname += i+1;
 
-    bs->total_sectors=bs->cyls*bs->heads*bs->secs;
+    bs->total_sectors = cyls * heads * secs;
 
-    if(init_directories(s, dirname))
+    if (init_directories(s, dirname, heads, secs)) {
 	return -1;
+    }
 
     s->sector_count = s->faked_sectors + s->sectors_per_cluster*s->cluster_count;
 
     if(s->first_sectors_number==0x40)
-	init_mbr(s);
-    else {
-        /* MS-DOS does not like to know about CHS (?). */
-	bs->heads = bs->cyls = bs->secs = 0;
-    }
+        init_mbr(s, cyls, heads, secs);
 
     //    assert(is_consistent(s));
     qemu_co_mutex_init(&s->lock);
-- 
1.7.6.5

  parent reply	other threads:[~2012-07-06  6:58 UTC|newest]

Thread overview: 42+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2012-07-06  6:57 [Qemu-devel] [PATCH 00/32] Disk geometry cleanup Markus Armbruster
2012-07-06  6:57 ` [Qemu-devel] [PATCH 01/32] fdc: Drop broken code for user-defined floppy geometry Markus Armbruster
2012-07-06  6:57 ` [Qemu-devel] [PATCH 02/32] fdc: Move floppy geometry guessing back from block.c Markus Armbruster
2012-07-06  6:57 ` [Qemu-devel] [PATCH 03/32] vvfat: Fix partition table Markus Armbruster
2012-07-06  6:57 ` Markus Armbruster [this message]
2012-07-06  6:57 ` [Qemu-devel] [PATCH 05/32] qtest: Tidy up temporary files properly Markus Armbruster
2012-07-07  7:39   ` Blue Swirl
2012-07-09  7:56     ` Markus Armbruster
2012-07-09  9:09       ` Kevin Wolf
2012-07-06  6:57 ` [Qemu-devel] [PATCH 06/32] qtest: Add hard disk geometry test Markus Armbruster
2012-07-06  6:57 ` [Qemu-devel] [PATCH 07/32] block: Factor bdrv_read_unthrottled() out of guess_disk_lchs() Markus Armbruster
2012-07-06  6:57 ` [Qemu-devel] [PATCH 08/32] hd-geometry: Move disk geometry guessing back from block.c Markus Armbruster
2012-07-06  6:57 ` [Qemu-devel] [PATCH 09/32] hd-geometry: Add tracepoints Markus Armbruster
2012-07-06  6:57 ` [Qemu-devel] [PATCH 10/32] hd-geometry: Unnest conditional in hd_geometry_guess() Markus Armbruster
2012-07-06  6:57 ` [Qemu-devel] [PATCH 11/32] hd-geometry: Factor out guess_chs_for_size() Markus Armbruster
2012-07-06  6:57 ` [Qemu-devel] [PATCH 12/32] hd-geometry: Clean up gratuitous goto in hd_geometry_guess() Markus Armbruster
2012-07-06  6:57 ` [Qemu-devel] [PATCH 13/32] hd-geometry: Clean up confusing use of prior translation hint Markus Armbruster
2012-07-06  6:57 ` [Qemu-devel] [PATCH 14/32] hd-geometry: Cut out block layer translation middleman Markus Armbruster
2012-07-06  6:57 ` [Qemu-devel] [PATCH 15/32] ide pc: Cut out the block layer geometry middleman Markus Armbruster
2012-07-06  6:57 ` [Qemu-devel] [PATCH 16/32] blockdev: Save geometry in DriveInfo Markus Armbruster
2012-07-06  6:57 ` [Qemu-devel] [PATCH 17/32] qdev: Introduce block geometry properties Markus Armbruster
2012-07-06  6:57 ` [Qemu-devel] [PATCH 18/32] hd-geometry: Switch to uint32_t to match BlockConf Markus Armbruster
2012-07-06  6:57 ` [Qemu-devel] [PATCH 19/32] scsi-hd: qdev properties for disk geometry Markus Armbruster
2012-07-06  6:57 ` [Qemu-devel] [PATCH 20/32] virtio-blk: " Markus Armbruster
2012-07-06  6:57 ` [Qemu-devel] [PATCH 21/32] ide: " Markus Armbruster
2012-07-06  6:58 ` [Qemu-devel] [PATCH 22/32] qtest: Cover " Markus Armbruster
2012-07-06  6:58 ` [Qemu-devel] [PATCH 23/32] qdev: Collect private helpers in one place Markus Armbruster
2012-07-06  6:58 ` [Qemu-devel] [PATCH 24/32] qdev: New property type chs-translation Markus Armbruster
2012-07-06  6:58 ` [Qemu-devel] [PATCH 25/32] ide: qdev property for BIOS CHS translation Markus Armbruster
2012-07-06  6:58 ` [Qemu-devel] [PATCH 26/32] qtest: Cover " Markus Armbruster
2012-07-06  6:58 ` [Qemu-devel] [PATCH 27/32] block: Geometry and translation hints are now useless, purge them Markus Armbruster
2012-07-06  6:58 ` [Qemu-devel] [PATCH 28/32] ide pc: Put hard disk info into CMOS only for hard disks Markus Armbruster
2012-07-06  6:58 ` [Qemu-devel] [PATCH 29/32] qtest: Test we don't put hard disk info into CMOS for a CD-ROM Markus Armbruster
2012-07-06  6:58 ` [Qemu-devel] [PATCH 30/32] hd-geometry: Compute BIOS CHS translation in one place Markus Armbruster
2012-07-06  6:58 ` [Qemu-devel] [PATCH 31/32] blockdev: Drop redundant CHS validation for if=ide Markus Armbruster
2012-07-06  6:58 ` [Qemu-devel] [PATCH 32/32] Relax IDE CHS limits from 16383, 16, 63 to 65535, 16, 255 Markus Armbruster
2012-07-06  7:28 ` [Qemu-devel] [PATCH 00/32] Disk geometry cleanup Markus Armbruster
     [not found] <1340984094-5451-1-git-send-email-armbru@redhat.com>
     [not found] ` <1340984094-5451-5-git-send-email-armbru@redhat.com>
2012-07-04 15:23   ` [Qemu-devel] [PATCH 04/32] vvfat: Do not clobber the user's geometry Kevin Wolf
2012-07-04 16:25     ` Paolo Bonzini
2012-07-05  7:06       ` Kevin Wolf
2012-07-05  9:16         ` Markus Armbruster
2012-07-05 11:13     ` Markus Armbruster

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1341557890-17464-5-git-send-email-armbru@redhat.com \
    --to=armbru@redhat.com \
    --cc=blauwirbel@gmail.com \
    --cc=kwolf@redhat.com \
    --cc=pbonzini@redhat.com \
    --cc=qemu-devel@nongnu.org \
    --cc=stefanha@linux.vnet.ibm.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).