Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 30 Aug 1996 22:06:17 +0200 (SAT)
From:      Robert Nordier <rnordier@iafrica.com>
To:        terry@lambert.org (Terry Lambert)
Cc:        hackers@freebsd.org
Subject:   Re: Determining disk type & size
Message-ID:  <199608302006.WAA00985@eac.iafrica.com>
In-Reply-To: <199608291704.KAA28904@phaeton.artisoft.com> from "Terry Lambert" at Aug 29, 96 10:04:29 am

next in thread | previous in thread | raw e-mail | index | archive | help
Terry Lambert wrote:
 
> > Unfortunately, DOS makes an absolute distinction between hard and
> > floppy disks in its mount code, to the extent of having entirely
> > separate routines.  These deal differently with boot sector
> > recognition; validation to determine whether the boot sector BPB
> > is to be trusted; and even the loading of FS parameters from a
> > valid boot sector BPB.
> 
> Try building a hard disk partition exactly a floppy disk size large;
> if you can get your sector translation to allow it, I think you will
> be very surprised.

I'll try this over the weekend.  If the underlying implication is
that FS parameter determination is primarily size-based, though,
I just can't reconcile this with the underlying code.

I had to go to all the trouble of doing a lengthy disassembly of the
relevant sections of io.sys from both MS-DOS 6.22 and Windows 95,
mostly because the DOS handling of the boot sector is really counter-
intuitive, and just not what anyone would reasonably expect from
documentation or data structures.

In a sense, it can be misleading to think of the boot sector BPB
as a kind of primitive superblock.  MS-DOS FS routines are actually
completely ignorant of the BPB as a disk-based structure.  The boot
sector is simply "reserved" and the FS begins with the FAT.

The BPB is for device driver use only; and the driver itself is
absolutely responsible for deciding on all aspects of a given FS
layout.  DOS simply accepts a BPB from the driver as a _fait
accompli_.

The most elegant proof of this is the case of RAM disks, which may
lack a boot sector altogether.  As long as the driver can come up
a BPB on request, it is free to store the BPB values where it
chooses.

The MS-DOS default block device driver contains two distinct Build
BPB routines.  BPBs for hard drives partitions are built during
io.sys initialization, as a step in locating and validating DOS
partitions.  BPBs for floppy drives are built at DOS request,
typically following a negative/neutral media check result.

The io.sys routines are completely distinct, and don't share common
routines even to the extent usual in assembly language coding.
And the logic just differs.

So, from a vfatfs_mount perspective, the question really becomes:
"Looking at this boot sector, what (unit type of what) DOS device
driver am I pretending to be?"  Because of its own hierarchical
chaos, DOS does argue strongly for access to information that should
be hidden from code that seeks to duplicate its behavior.

The boot sector BPB simply isn't a context-free structure.  That
said, I'd guess a drive type could generally be inferred with
acceptable accuracy from size + partition information, if necessary.

> I think the main distinction is "is there a partition table on this
> ting, or isn't there?"... the actual fact that you only allow partition
> tables on hard disks is irrelevant.
> 
> I have a hard time with any fix that doesn't use the partition type
> hints: "this logical device is a child of the 'DOS partitioning'
> logigical-to-physical device, therefore itis a hard disk".  Mostly
> this is a problem because I don't want to distinguish floppy disks
> on anything other than the fact that they are removable media.

To derive FS parameters, I'd even want to distinguish the recording
technology, if possible.  (I was reminded this morning of DOS-format
MOs).  Still, deductions could possibly be made on indirect evidence.

> The controls you put in to prevent DOS parititioning of anything but
> raw devices which are not floppy-disk-sized is entire independent, I
> think, of the FS implementation itself.  Internally, the FS might be
> expected to get information about its host device.  If you want to
> get into implementation details, the logical-to-physical device mapping
> probably depends upon this: the "file system" "mount" of a DOS partition
> to export an Extended DOS partition device, for instance, can be though
> of in terms of FS stacking, and nothing else.
>
> The problem with implementing it exactly this way (yet, anyway) comes
> from the fact that there is no well-defined "bottom end" interface
> common to all file systems (again: yet).
> 
> So the mount code may call a device ioctl() on the device to ask about
> geometry, and have a table of allowable mount options on that basis.
> I don't think one of the hints could be, legally, "is floppy disk",
> without damaging the ability to later abstract media "arrival" and
> "departure" events.  In the *absolute* worst case, consider the floppy
> disk attached via PCMCIA interface to a laptop.

No point in messing things up solely on account of DOS support.

> > Of course, one could ignore the whole issue, but this does mean
> > there are (theoretically) a very great many DOS boot sectors that
> > would be incompatible.  And with the prevalence of boot sector
> > viruses in the DOS world, there are potentially some practical
> > implications also.
> 
> I think they are all required to be taken care of in the "what kind
> of logical device is allowed to host me" -- one below the level of
> the implementation, and no deeper.
> 
> Floppy devices, in this case, will always be raw, and raw devices will
> only be legal if they are the size of a floppy.
> 
> The only possible failure case, then would be the raw non-floppy device
> which only holds up to 2.88M (can you build a floppy DOS FS in 2.88M?).

Non-floppy DOS FS, rather?  Yes.  DOS considers any partition >= 64
sectors as suitable for an FS.  So (theoretically, anyway) even 160K
could go either way.

> The application of disklabels and/or DOS partitioning should use an
> ioctl() by root to the host driver to invoke the "format" routine for
> the logical driver.  The interface abstracts the actual implementation,
> and therefore we end up with a single control program that can operate
> on all types of partitioning mechanisms -- the holy grail of an install
> without futzing with 3 or more partitioning-type programs is achieved,
> and the "write disklabel" and "slice" and "partition" confusion all go
> away.  Open the directory containing the slices on the devfs, and ioctl
> it to manipulate the slices themselves -- assuming the things are not
> mounted.

Sounds great.

> > I also just don't like the idea that it is possible to produce
> > (maliciously) an almost endless supply of different disks that
> > MS-DOS has no trouble with, but the vfatfs would choke on or corrupt.
> 
> The MS-DOS "has no trouble" in the examles you have given so far,
> because it refuses the media.

Actually no.  The problem is that it errs too much in the other
direction: even to the extent of laboriously identifying brain-
damaged formats by version number, and patching in correct values.

Those are not of major practical importance, probably.  But a
hard/floppy distinction (even if vfatfs must deduce this itself)
is critical.  For about half the BPB values, it is a matter of

   mov AL,byte ptr [BX.BPB.RootDirEntries]   ;Floppy disk
   mov AX,[BX.BPB.RootDirEntries]            ;Hard disk

for instance.

> Consider that the logical drivers perform bounds checking on the
> write requests through them, and we are now saved from the current
> DOS FS, which trashes the partition following it, in writing out
> the number of clusters it things should be there.  It is the fact
> that the raw device is being accessed directly, and the bounds
> checking is in the flawed FS operating from flawed data that causes
> the corruption of the next FS on the device.

I'm not sure this actually is the msdosfs problem, but if it _could_
be a problem, it's certainly worthwhile.

> Saving the disk image from corruption within the legal bounds -- well,
> that's another problem.  It means restricting what device the FS will
> allow itself to mount.  We already have to distiguish raw+size for
> FS layout policy anyway (as you pointed out).
> 
> > I'd even settle for ignoring disk type in the FS, but there's also
> > an fsck utility that needs to be able to diagnose this stuff.
> 
> The fsck wants to be an invokable procedure in the VFSOPS array,
> actually.  This allows it to suspen operations, flush buffers, and
> perform a check successfully, even when the thing is mounted.

I hadn't thought of fsck integrated into the FS, but it sounds
reasonable.

> The allowable corruption semantics in a framework that supports
> soft updates is much smaller, easily put into the mount code, actually,
> for FFS (it means making sure the cylinder group offsets are valid,
> nothing more).

I like the soft updates concept.  But the VFAT fsck also has to work
on a FS which may already have been corrupted by something other than
itself (eg. someone's data floppy -- err, 1440K raw device, I mean :).
So it just has to expect the worst.

> Checking the DOSFS external to the DOSFS itself is probably best done
> at a partition level in any case --  at the same level mounts are done,
> and at the same level which fsck for FFS happens now.
> 
> Since the check is by device, it can apply the same "rawness" criteria
> to the devices as the FS applies.  Ideally, this would be shared code,
> and the call interface to retrieve the information would be abstracted
> to hide the kernel space/user space nature.  I don't think the "hey!
> this hard disk is a floppy!" problem is really a big fsck problem in
> any case -- the corruption will be evident and unrecoverable if this
> (or the reverse) ever happens, anyway.

I was thinking more in terms of preempting an attempt to use a disk
format the vfatfs itself couldn't handle.  I was assuming a userland
fsck, which could remove the responsibility for making a drive type
distinction from the FS itself, by ensuring BPBs were "drive type
insensitive" as a sort of preen function.  (A full FFS fsck-style
preen would probably try user patience, anyway, since there is no
"clean" flag.)

--
Robert Nordier



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?199608302006.WAA00985>