All of lore.kernel.org
 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 v3 03/29] vvfat: Do not clobber the user's geometry
Date: Tue, 10 Jul 2012 11:12:29 +0200	[thread overview]
Message-ID: <1341911575-7306-4-git-send-email-armbru@redhat.com> (raw)
In-Reply-To: <1341911575-7306-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-10  9:13 UTC|newest]

Thread overview: 33+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2012-07-10  9:12 [Qemu-devel] [PATCH v3 00/29] Disk geometry cleanup Markus Armbruster
2012-07-10  9:12 ` [Qemu-devel] [PATCH v3 01/29] fdc: Move floppy geometry guessing back from block.c Markus Armbruster
2012-07-10  9:12 ` [Qemu-devel] [PATCH v3 02/29] vvfat: Fix partition table Markus Armbruster
2012-07-10  9:12 ` Markus Armbruster [this message]
2012-07-10  9:12 ` [Qemu-devel] [PATCH v3 04/29] qtest: Add hard disk geometry test Markus Armbruster
2012-07-10  9:12 ` [Qemu-devel] [PATCH v3 05/29] hd-geometry: Move disk geometry guessing back from block.c Markus Armbruster
2012-07-11 13:54   ` Kevin Wolf
2012-07-11 14:35     ` Markus Armbruster
2012-07-10  9:12 ` [Qemu-devel] [PATCH v3 06/29] hd-geometry: Add tracepoints Markus Armbruster
2012-07-10  9:12 ` [Qemu-devel] [PATCH v3 07/29] hd-geometry: Unnest conditional in hd_geometry_guess() Markus Armbruster
2012-07-10  9:12 ` [Qemu-devel] [PATCH v3 08/29] hd-geometry: Factor out guess_chs_for_size() Markus Armbruster
2012-07-10  9:12 ` [Qemu-devel] [PATCH v3 09/29] hd-geometry: Clean up gratuitous goto in hd_geometry_guess() Markus Armbruster
2012-07-10  9:12 ` [Qemu-devel] [PATCH v3 10/29] hd-geometry: Clean up confusing use of prior translation hint Markus Armbruster
2012-07-10  9:12 ` [Qemu-devel] [PATCH v3 11/29] hd-geometry: Cut out block layer translation middleman Markus Armbruster
2012-07-10  9:12 ` [Qemu-devel] [PATCH v3 12/29] ide pc: Cut out the block layer geometry middleman Markus Armbruster
2012-07-10  9:12 ` [Qemu-devel] [PATCH v3 13/29] blockdev: Save geometry in DriveInfo Markus Armbruster
2012-07-10  9:12 ` [Qemu-devel] [PATCH v3 14/29] qdev: Introduce block geometry properties Markus Armbruster
2012-07-10  9:12 ` [Qemu-devel] [PATCH v3 15/29] hd-geometry: Switch to uint32_t to match BlockConf Markus Armbruster
2012-07-10  9:12 ` [Qemu-devel] [PATCH v3 16/29] scsi-hd: qdev properties for disk geometry Markus Armbruster
2012-07-10  9:12 ` [Qemu-devel] [PATCH v3 17/29] virtio-blk: " Markus Armbruster
2012-07-10  9:12 ` [Qemu-devel] [PATCH v3 18/29] ide: " Markus Armbruster
2012-07-10  9:12 ` [Qemu-devel] [PATCH v3 19/29] qtest: Cover " Markus Armbruster
2012-07-10  9:12 ` [Qemu-devel] [PATCH v3 20/29] qdev: Collect private helpers in one place Markus Armbruster
2012-07-10  9:12 ` [Qemu-devel] [PATCH v3 21/29] qdev: New property type chs-translation Markus Armbruster
2012-07-10  9:12 ` [Qemu-devel] [PATCH v3 22/29] ide: qdev property for BIOS CHS translation Markus Armbruster
2012-07-10  9:12 ` [Qemu-devel] [PATCH v3 23/29] qtest: Cover " Markus Armbruster
2012-07-10  9:12 ` [Qemu-devel] [PATCH v3 24/29] block: Geometry and translation hints are now useless, purge them Markus Armbruster
2012-07-10  9:12 ` [Qemu-devel] [PATCH v3 25/29] ide pc: Put hard disk info into CMOS only for hard disks Markus Armbruster
2012-07-10  9:12 ` [Qemu-devel] [PATCH v3 26/29] qtest: Test we don't put hard disk info into CMOS for a CD-ROM Markus Armbruster
2012-07-10  9:12 ` [Qemu-devel] [PATCH v3 27/29] hd-geometry: Compute BIOS CHS translation in one place Markus Armbruster
2012-07-10  9:12 ` [Qemu-devel] [PATCH v3 28/29] blockdev: Drop redundant CHS validation for if=ide Markus Armbruster
2012-07-10  9:12 ` [Qemu-devel] [PATCH v3 29/29] Relax IDE CHS limits from 16383, 16, 63 to 65535, 16, 255 Markus Armbruster
2012-07-11 15:40 ` [Qemu-devel] [PATCH v3 00/29] Disk geometry cleanup Kevin Wolf

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=1341911575-7306-4-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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.