[RFC] mount can figure out fstype automatically
Bruce Evans
bde at zeta.org.au
Thu Jul 13 11:03:35 UTC 2006
On Tue, 11 Jul 2006, Robert Watson wrote:
> In both FreeBSD and Darwin, I've noticed that the kernel msdosfs code is
> excessively permissive as to what it considers a FAT file system. This is
> presumably necessary due to the enourmous diversity of FAT file systems
> floating around, but it makes it a little too easy to cause msdos to trip
> over layouts that violate its layout assumptions. :-) FAT is much more
> reliably detected by looking at the partition type it lives in than by
> looking at the bytes that appear inside the partition, I believe.
Um, most msdosfs file systems are on floppies so they don't even have a
partition.
Msdosfs can be very reliably detected from the bpb provided the bpb isn't
uncleared garbage left from a previous file system, but the checks aren't
very cocomplete and people keep relaxing them. In the old version that
I use, the checks are mainly:
% #ifndef MSDOSFS_NOCHECKSIG
% if (bsp->bs50.bsBootSectSig0 != BOOTSIG0
% || bsp->bs50.bsBootSectSig1 != BOOTSIG1) {
% error = EINVAL;
% goto error_exit;
% }
% #endif
Was relaxed.
% [... a few too many assignments before checking anything]
% /* XXX - We should probably check more values here */
% if (!pmp->pm_BytesPerSec || !SecPerClust
% || !pmp->pm_Heads
% #ifdef PC98
% || !pmp->pm_SecPerTrack || pmp->pm_SecPerTrack > 255) {
% #else
% || !pmp->pm_SecPerTrack || pmp->pm_SecPerTrack > 63) {
% #endif
% error = EINVAL;
% goto error_exit;
% }
Not a very good check.
% if (pmp->pm_Sectors == 0) {
% pmp->pm_HiddenSects = getulong(b50->bpbHiddenSecs);
% pmp->pm_HugeSectors = getulong(b50->bpbHugeSectors);
% } else {
% pmp->pm_HiddenSects = getushort(b33->bpbHiddenSecs);
% pmp->pm_HugeSectors = pmp->pm_Sectors;
% }
Not a consistency check, but how the extension works.
% if (pmp->pm_HugeSectors > 0xffffffff /
% (pmp->pm_BytesPerSec / sizeof(struct direntry)) + 1) {
% /*
% * We cannot deal currently with this size of disk
% * due to fileid limitations (see msdosfs_getattr and
% * msdosfs_readdir)
% */
% error = EINVAL;
% printf("mountmsdosfs(): disk too big, sorry\n");
% goto error_exit;
% }
Consistency check only as a side effect.
%
% if (pmp->pm_RootDirEnts == 0) {
% if (bsp->bs710.bsBootSectSig2 != BOOTSIG2
% || bsp->bs710.bsBootSectSig3 != BOOTSIG3
% || pmp->pm_Sectors
% || pmp->pm_FATsecs
% || getushort(b710->bpbFSVers)) {
% error = EINVAL;
% printf("mountmsdosfs(): bad FAT32 filesystem\n");
% goto error_exit;
% }
Not a very good consistency check.
% pmp->pm_fatmask = FAT32_MASK;
% pmp->pm_fatmult = 4;
% pmp->pm_fatdiv = 1;
% pmp->pm_FATsecs = getulong(b710->bpbBigFATsecs);
% if (getushort(b710->bpbExtFlags) & FATMIRROR)
% pmp->pm_curfat = getushort(b710->bpbExtFlags) & FATNUM;
% else
% pmp->pm_flags |= MSDOSFS_FATMIRROR;
% } else
% pmp->pm_flags |= MSDOSFS_FATMIRROR;
%
% /*
% * Check a few values (could do some more):
% * - logical sector size: power of 2, >= block size
% * - sectors per cluster: power of 2, >= 1
% * - number of sectors: >= 1, <= size of partition
% * - number of FAT sectors: >= 1
% */
% if ( (SecPerClust == 0)
% || (SecPerClust & (SecPerClust - 1))
% || (pmp->pm_BytesPerSec < DEV_BSIZE)
% || (pmp->pm_BytesPerSec & (pmp->pm_BytesPerSec - 1))
% || (pmp->pm_HugeSectors == 0)
% || (pmp->pm_FATsecs == 0)
% ) {
% error = EINVAL;
% goto error_exit;
% }
More not very good consistency checks.
Better checks would determine the location of the FAT and root directory
and check that is there.
% if (pmp->pm_fatmask == 0) {
% if (pmp->pm_maxcluster
% <= ((CLUST_RSRVD - CLUST_FIRST) & FAT12_MASK)) {
% /*
% * This will usually be a floppy disk. This size makes
% * sure that one fat entry will not be split across
% * multiple blocks.
% */
% pmp->pm_fatmask = FAT12_MASK;
% pmp->pm_fatmult = 3;
% pmp->pm_fatdiv = 2;
% } else {
% pmp->pm_fatmask = FAT16_MASK;
% pmp->pm_fatmult = 2;
% pmp->pm_fatdiv = 1;
% }
% }
We do check the FAT, but default to FAT16 if it doesn't lool like FAT12.
% [... a few more]
Bruce
More information about the freebsd-arch
mailing list