[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [PATCH v3 03/29] vvfat: Do not clobber the user's geometry
From: |
Markus Armbruster |
Subject: |
[Qemu-devel] [PATCH v3 03/29] vvfat: Do not clobber the user's geometry |
Date: |
Tue, 10 Jul 2012 11:12:29 +0200 |
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 <address@hidden>
---
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
- [Qemu-devel] [PATCH v3 00/29] Disk geometry cleanup, Markus Armbruster, 2012/07/10
- [Qemu-devel] [PATCH v3 04/29] qtest: Add hard disk geometry test, Markus Armbruster, 2012/07/10
- [Qemu-devel] [PATCH v3 09/29] hd-geometry: Clean up gratuitous goto in hd_geometry_guess(), Markus Armbruster, 2012/07/10
- [Qemu-devel] [PATCH v3 06/29] hd-geometry: Add tracepoints, Markus Armbruster, 2012/07/10
- [Qemu-devel] [PATCH v3 02/29] vvfat: Fix partition table, Markus Armbruster, 2012/07/10
- [Qemu-devel] [PATCH v3 08/29] hd-geometry: Factor out guess_chs_for_size(), Markus Armbruster, 2012/07/10
- [Qemu-devel] [PATCH v3 01/29] fdc: Move floppy geometry guessing back from block.c, Markus Armbruster, 2012/07/10
- [Qemu-devel] [PATCH v3 11/29] hd-geometry: Cut out block layer translation middleman, Markus Armbruster, 2012/07/10
- [Qemu-devel] [PATCH v3 10/29] hd-geometry: Clean up confusing use of prior translation hint, Markus Armbruster, 2012/07/10
- [Qemu-devel] [PATCH v3 03/29] vvfat: Do not clobber the user's geometry,
Markus Armbruster <=
- [Qemu-devel] [PATCH v3 07/29] hd-geometry: Unnest conditional in hd_geometry_guess(), Markus Armbruster, 2012/07/10
- [Qemu-devel] [PATCH v3 14/29] qdev: Introduce block geometry properties, Markus Armbruster, 2012/07/10
- [Qemu-devel] [PATCH v3 15/29] hd-geometry: Switch to uint32_t to match BlockConf, Markus Armbruster, 2012/07/10
- [Qemu-devel] [PATCH v3 12/29] ide pc: Cut out the block layer geometry middleman, Markus Armbruster, 2012/07/10
- [Qemu-devel] [PATCH v3 21/29] qdev: New property type chs-translation, Markus Armbruster, 2012/07/10
- [Qemu-devel] [PATCH v3 13/29] blockdev: Save geometry in DriveInfo, Markus Armbruster, 2012/07/10
- [Qemu-devel] [PATCH v3 18/29] ide: qdev properties for disk geometry, Markus Armbruster, 2012/07/10
- [Qemu-devel] [PATCH v3 16/29] scsi-hd: qdev properties for disk geometry, Markus Armbruster, 2012/07/10
- [Qemu-devel] [PATCH v3 17/29] virtio-blk: qdev properties for disk geometry, Markus Armbruster, 2012/07/10
- [Qemu-devel] [PATCH v3 19/29] qtest: Cover qdev properties for disk geometry, Markus Armbruster, 2012/07/10