From owner-freebsd-fs@FreeBSD.ORG Tue Sep 27 11:55:13 2005 Return-Path: X-Original-To: fs@FreeBSD.org Delivered-To: freebsd-fs@FreeBSD.ORG Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id 7BC6F16A41F for ; Tue, 27 Sep 2005 11:55:13 +0000 (GMT) (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 C668943D53 for ; Tue, 27 Sep 2005 11:55:12 +0000 (GMT) (envelope-from bde@zeta.org.au) Received: from mailproxy2.pacific.net.au (mailproxy2.pacific.net.au [61.8.0.87]) by mailout1.pacific.net.au (8.13.4/8.13.4/Debian-3) with ESMTP id j8RBsbjo003183; Tue, 27 Sep 2005 21:54:37 +1000 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-3) with ESMTP id j8RBsWU2013878; Tue, 27 Sep 2005 21:54:33 +1000 Date: Tue, 27 Sep 2005 21:54:32 +1000 (EST) From: Bruce Evans X-X-Sender: bde@delplex.bde.org To: Mikhail Teterin In-Reply-To: <200509261654.01697.mi+mx@aldan.algebra.com> Message-ID: <20050927201946.C24713@delplex.bde.org> References: <02b301c5c2ba$4b2b9460$c901a8c0@workdog> <200509261654.01697.mi+mx@aldan.algebra.com> MIME-Version: 1.0 Content-Type: TEXT/PLAIN; charset=US-ASCII; format=flowed Cc: gayn.winters@bristolsystems.com, fs@FreeBSD.org Subject: Re: can not mount a large FAT32 filesystem X-BeenThere: freebsd-fs@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: Filesystems List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 27 Sep 2005 11:55:13 -0000 On Mon, 26 Sep 2005, Mikhail Teterin wrote: > This is a flash card (Hitachi microdrive) inserted into a USB flash-reader. > There is no BIOS. > > Not only does the card work fine in the camera (which formatted it), but > Windows has no problems with it either. I'd rather help fix our FAT32 > support, than find a work-around... > > Is anyone on fs@ interested? The original symptomps and Gayn's comments are > attached. Thanks! Attachment is even better than top posting inhibiting replies, although not as good as a url. %% > I have a 4Gb flash-card with FAT32 filesystem. Whenever I try to mount %% > it (on 5.x and 4.x) I get: %% > %% > msdos: /dev/da0s1: Invalid argument (It should actually say "msdosfs" in 5.x. This renaming mainly breaks compatibility.) mount(8)'s error reporting is bad. The EINVAL error here is not completely obscure -- it normally means that the file system is invalid, but the error for msdosfs vs msdos is very obscure -- IIRC it is ENOENT meaning that the module for the file system wasn't found, but mount(8) reports this as mount_msdos[fs] not being found despite this mount utility being present. %% > and the kernel complains: %% > %% > da0: reading primary partition table: error reading fsbn 0 I think this error message is only printed by 4.x. While error messages printed using diskerr() are much better than their replacements in 5+.x, this one is unfortunately missing the low-level error code so it is hard to tell why the read failed. %% > mountmsdosfs(): bad FAT32 filesystem This error seems to be unrelated. (I don't know how msdosfs got this far, since the previous error is for the whole disk and should be fatal -- see below.) The code in msdosfs in 4.x for this is: % 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; % } % 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; The file system's boot block passed several checks before here; in particular it must have been readable. Apparently (pmp->pm_RootDirEnts == 0) implies FAT32 and then one of the other checks fails. If it weren't for the error reading sector 0, I would expect just a minor compatibility problem here. %% > The method works with smaller cards in the same card-reader. This card %% > works fine inside the camera, and I can get the pictures via. PTP %% > protocol using gphoto. %% > %% > Fdisk da0 says: %% > %% > ******* Working on device /dev/da0 ******* %% > parameters extracted from in-core disklabel are: %% > cylinders=7936 heads=16 sectors/track=63 (1008 blks/cyl) %% > %% > Figures below won't work with BIOS for partitions not in cyl 1 %% > parameters to be used for BIOS calculations are: %% > cylinders=7936 heads=16 sectors/track=63 (1008 blks/cyl) %% > %% > Media sector size is 512 %% > Warning: BIOS sector numbering starts with sector 1 %% > Information from DOS bootblock is: %% > The data for partition 1 is: %% > sysid 12,(DOS or Windows 95 with 32 bit FAT, LBA) %% > start 63, size 7998417 (3905 Meg), flag 80 (active) %% > beg: cyl 0/ head 1/ sector 1; %% > end: cyl 766/ head 15/ sector 63 I don't know how fdisk managed to read the MBR, since the kernel couldn't. There seem to be no "geometry" problems here. 63 sectors/track is normal. 16 heads only works with not-very-old BIOSes, since it gives more than 1024 cylinders, but the card is new so it may assume a not-very-old BIOS). The ending head number in the partition entry matches 16 heads. The star and size match the starting and ending C/H/S (C matches mod 1024). For some reason, the last complete cylinder isn't used, and for the usual reasons, the 1 sector following the last complete cylinder isn't used. %% > Disklabel da0 says: %% > %% > # /dev/da0: %% > type: SCSI %% > disk: SanDisk %% > label: ImageMate II %% > flags: %% > bytes/sector: 512 %% > sectors/track: 63 %% > tracks/cylinder: 16 %% > sectors/cylinder: 1008 %% > cylinders: 7936 %% > sectors/unit: 7999489 %% > ... This is consistent with the fdisk output. %% Perhaps someone else can help sort this out better than I can, but I do %% note that fdisk doesn't seem to be using the last (logical) cylinder, %% because it reports using 7998417 + 63 = 7998480 sectors which is exactly %% 1008 sectors less than 7936 cylinders * 1008 sectors/cylinder = 7999488 %% sectors. (Why disklabel reports one more sector 7999489 is a mystery to %% me.) Disklabel probably reports 7999489 sectors because that is the actual number of sectors. Remember that the geometry of H=16/S=63 is invented. 16*63 just happens not to divide 7999489 evenly. It seems to be normal for ATA disks for the number of sectors to be dumbed down so that it is a multiple of H*S, but this is a SCSI disk. %% Assuming your BIOS supports LBA, you could try (back up first of course) %% using fdisk to rewrite the label, or use fdisk to use all the logical %% cylinders on the card. Also, since you are not trying to boot from the %% card, having it marked Active is unnecessary at best. This probably won't help. In 4.x, the initial error is from subr_diskmbr.c: % mbr_offset = DOSBBSECTOR; % reread_mbr: % /* Read master boot record. */ % bp = geteblk((int)lp->d_secsize); % bp->b_dev = dkmodpart(dkmodslice(dev, WHOLE_DISK_SLICE), RAW_PART); % bp->b_blkno = mbr_offset; % bp->b_bcount = lp->d_secsize; % bp->b_flags |= B_READ; % BUF_STRATEGY(bp, 1); % if (biowait(bp) != 0) { % diskerr(bp, "reading primary partition table: error", % LOG_PRINTF, 0, (struct disklabel *)NULL); % printf("\n"); % error = EIO; % goto done; % } % ... % done: % bp->b_flags |= B_INVAL | B_AGE; % brelse(bp); % if (error == EINVAL) % error = 0; % return (error); % } It is hard to see how this causes the observed symptoms. An error here seems most likely to be caused by the sector size being wrong, but should prevent all opens of the disk. But we know that both fdisk(8) and the start of msdosfs mount can open and read the disk. fdisk opens the whole disk and sees normal things. msdosfs mount should be opening slice s1, and that is more likely to not work than opening the whole disk. Certainly the above error prevents slice s1 being correctly located, so msdosfs mount shouldn't see normal things. But we know that msdosfs sees some normal things before it sees a problem. Try reading slice s1 using dd. I would expect this to fail. Bruce