sbin/fsck_msdosfs does not handle media with 2K blocks

Julian H. Stacey jhs at
Fri Mar 1 01:52:29 UTC 2013

Hi hackers at
cc: gdt at NetBSD, paulp at	(< grep @ src/sbin/fsck_msdosfs/*.c)
cc: rnordier at			(< man newfs_msdos)
cc: Tom Rhodes <trhodes at>	(< man 5 msdosfs>

sbin/fsck_msdosfs (FreeBSD 9.1-RELEASE) fails on 2K block media,
media in this case, an mp3 player:

sysctl kern.geom.debugflags=16
        kern.geom.debugflags: 16 -> 16

/sbin/fsck_msdosfs /dev/da0s1
        	** /dev/da0s1
	could not read boot block (Invalid argument)

	"vendor" "0x066f"; "product" "0x8000"; "devclass" "0x00";
	"devsubclass" "0x00"; "intclass" "0x08"; "intsubclass"
	"0x06"; "intprotocol" "0x50" ; "release" "0x1001";

/sys/dev/usb/usbdevs: vendor SIGMATEL         0x066f  Sigmatel

dd if=/dev/da0   bs=2k of=da0   # 242304+0 records	496238592 bytes
dd if=/dev/da0s1 bs=2k of=da0s1 # 242256+0 records	496140288 bytes
echo "2048 242304 * p" | dc	# 			496238592
echo "2048 242256 * p" | dc	# 			496140288

fdisk /dev/da0
        cylinders=118 heads=64 sectors/track=32 (2048 blks/cyl)
        Media sector size is 2048
        Warning: BIOS sector numbering starts with sector 1
        Information from DOS bootblock is:
        The data for partition 1 is:
        sysid 6 (0x06),(Primary DOS, 16 bit FAT (>= 32MB))
            start 48, size 242256 (473 Meg), flag 80 (active)
                beg: cyl 0/ head 1/ sector 1;
                end: cyl 630/ head 7/ sector 48

( I think this unit's FS got corrupted. Possibly as part of media error ?
  This unit (when not USB connected, but powered on battery as a
  player, flashed its LCD display on & off, (ame warning as to also
  indicate a low battery) whereas other units of same type with
  same battery powered up OK, & battery is OK, so player is probably
  also seeing a bad FS. )

I tried this:
	sysctl kern.geom.debugflags=16
	dd if=/dev/da0s1 bs=2k of=image
	mdconfig -a -t vnode -f image
	/sbin/fsck_msdosfs -y /dev/md2
		** /dev/md2
		** Phase 1 - Read and Compare FATs
		** Phase 2 - Check Cluster Chains
		** Phase 3 - Checking Directories
		/audio has entries after end of directory
		Extend? yes
		/audio has entries after end of directory
		Extend? yes
		long filename record cluster start != 0
		Invalid long filename entry for volume label
		Remove? yes
		** Phase 4 - Checking for Lost Files
		139 files, 60280 free (7535 clusters)
	... Repeating fsck above, shows the same errors above ...
	newfs_msdos -F 16 -S 2048 /dev/md2
		newfs_msdos: Cannot get number of sectors per track,
			Operation not supported
		newfs_msdos: Cannot get number of heads,
			Operation not supported
		newfs_msdos: trim 21 sectors to adjust to a multiple of 63
		/dev/md2: 242192 sectors in 15137 FAT16 clusters
			 (32768 bytes/cluster)
		BytesPerSec=2048 SecPerClust=16 ResSectors=1 FATs=2
			RootDirEnts=512 Media=0xf0 FATsecs=15 SecPerTrack=63
			Heads=16 HiddenSecs=0 HugeSectors=242235
	/sbin/fsck_msdosfs -y /dev/md2
		** /dev/md2
		** Phase 1 - Read and Compare FATs
		** Phase 2 - Check Cluster Chains
		** Phase 3 - Checking Directories
		** Phase 4 - Checking for Lost Files
		1 files, 484384 free (15137 clusters)
	mount -t msdosfs /dev/md2 /mnt
	umount /mnt
	mdconfig -d -u 2
	dd if=image bs=2k of=/dev/da0s1
		dd: /dev/da0s1: Input/output error
		80+0 records in 79+0 records out
		161792 bytes transferred in 32.715037 secs (4945 bytes/sec)
	... Remove & Reinsert & waited for devd & unmounted after auto-mount...
	Repeated dd & same error.
	... Remove & Reinsert & wait for devd automount
	ls /usb/sigmatel	... it has the new empty FS with SETTINGS.DAT
	... but still the LCD flashes
	fdisk -B /dev/da0
		fdisk: /boot/mbr: length must be a multiple of sector size
	cat /boot/mbr /boot/mbr /boot/mbr /boot/mbr > /boot/mbr2k
	fdisk -B -b /boot/mbr2k /dev/da0
		Should we write new partition table? [n] y
	... still the LCD flashes
	fdisk -i /dev/da0
	fdisk -u /dev/da0
	( Not Tried: newfs_msdos with -s 512 to see if the Sigmatel chipset
		will play it, but not much point as fdisk says 2K ... )

So it seems this particular unit has a problem (that other units
of same manufacture here do not have). I can't think what else to try ?

It seems I discovered a limitation in FreeBSD (while doing the above):
	We should hack various sources to [also?] allow R/W of 2K
	media blocks , eg inc. here:
		readboot(int dosfs, struct bootblock *boot)
		u_char block[DOSBOOTBLOCKSIZE];
		if (read(dosfs, block, sizeof block) != sizeof block) {
			perror("could not read boot block");
	Who might best hack those sources ?
	Maybe someone since 1997 Wolfgang Solfrank & 1995 Martin Husemann 
	be interested?

Julian Stacey, BSD Unix Linux C Sys Eng Consultant, Munich
 Reply below not above, like a play script.  Indent old text with "> ".
 Send plain text.  No quoted-printable, HTML, base64, multipart/alternative.

More information about the freebsd-hackers mailing list