From owner-freebsd-current@FreeBSD.ORG Thu Jul 13 11:03:35 2006 Return-Path: X-Original-To: freebsd-current@FreeBSD.org Delivered-To: freebsd-current@FreeBSD.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id 94B7316A4E1; Thu, 13 Jul 2006 11:03:35 +0000 (UTC) (envelope-from bde@zeta.org.au) Received: from mailout1.pacific.net.au (mailout1.pacific.net.au [61.8.0.84]) by mx1.FreeBSD.org (Postfix) with ESMTP id EB09A43D46; Thu, 13 Jul 2006 11:03:34 +0000 (GMT) (envelope-from bde@zeta.org.au) Received: from mailproxy2.pacific.net.au (mailproxy2.pacific.net.au [61.8.2.163]) by mailout1.pacific.net.au (Postfix) with ESMTP id A91703295A8; Thu, 13 Jul 2006 21:03:33 +1000 (EST) Received: from katana.zip.com.au (katana.zip.com.au [61.8.7.246]) by mailproxy2.pacific.net.au (8.13.4/8.13.4/Debian-3sarge1) with ESMTP id k6DB3QSd011182; Thu, 13 Jul 2006 21:03:27 +1000 Date: Thu, 13 Jul 2006 21:03:26 +1000 (EST) From: Bruce Evans X-X-Sender: bde@delplex.bde.org To: Robert Watson In-Reply-To: <20060711124356.Y78628@fledge.watson.org> Message-ID: <20060713204716.D23325@delplex.bde.org> References: <20060708152801.GA3671@crodrigues.org> <44AFD7DF.8090002@errno.com> <20060708174606.GA29602@infradead.org> <44B2A51A.4040103@samsco.org> <20060710202219.GA29786@infradead.org> <20060711124356.Y78628@fledge.watson.org> MIME-Version: 1.0 Content-Type: TEXT/PLAIN; charset=US-ASCII; format=flowed X-Mailman-Approved-At: Thu, 13 Jul 2006 11:23:04 +0000 Cc: Christoph Hellwig , Craig Rodrigues , freebsd-current@FreeBSD.org, freebsd-arch@FreeBSD.org Subject: Re: [RFC] mount can figure out fstype automatically X-BeenThere: freebsd-current@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: Discussions about the use of FreeBSD-current List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 13 Jul 2006 11:03:35 -0000 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