Subject: Supporting sector size != DEV_BSIZE on msdosfs
To: None <tech-kern@netbsd.org>
From: Trevin Beattie <trevin@xmission.com>
List: tech-kern
Date: 06/25/2002 15:09:36
--Boundary_(ID_0WR5Y7Ybix8OUShjXygBPA)
Content-type: text/plain; charset=us-ascii
Content-transfer-encoding: 7BIT

I just got through fixing and testing msdosfs to work with large sector
sizes.  The only reason it took me two days instead of one was because I
had made a stupid one-word mistake in the code (BSIZE instead of BSHIFT --
big difference!)  This file system was a real pleasure to work on, because
nothing in it relied on DEV_BSIZE at all.  Everything was done in terms of
sectors.  So all I had to do was adjust the argument passed to bread() (and
a couple of other little spots).

I was also very happy to find that newfs_msdos had already been written to
accomodate a wider variety of sector sizes that I even though possible.
But I did have to make one small change to it -- it put the boot signature
in the wrong place.  This change necessitated changing the minimum sector
size from 128 to 512 bytes.  If anyone has evidence of a 128- or
256-bytes/sector disk created by DOS, we may need to add some more code in
there.

The changes are very simple, and as long as nobody objects to the name I
made up for the new conversion macro (de_bn2kb() => convert sector # to
kernel block #), I believe it is suitable for merging into the NetBSD
source tree!

These patches have been submitted to NetBSD as PR #17398.

--Boundary_(ID_0WR5Y7Ybix8OUShjXygBPA)
Content-type: text/plain; charset=iso-8859-1; NAME=msdos-patches
Content-transfer-encoding: 7BIT
Content-disposition: attachment; filename=msdos-patches

diff -u /usr/src/sys/msdosfs/msdosfs_denode.c /home/trevin/src/sys/msdosfs/msdosfs_denode.c
--- /usr/src/sys/msdosfs/msdosfs_denode.c	Wed Jun  5 03:53:35 2002
+++ /home/trevin/src/sys/msdosfs/msdosfs_denode.c	Tue Jun 25 11:44:46 2002
@@ -444,8 +444,8 @@
 	if ((boff = length & pmp->pm_crbomask) != 0) {
 		if (isadir) {
 			bn = cntobn(pmp, eofentry);
-			error = bread(pmp->pm_devvp, bn, pmp->pm_bpcluster,
-			    NOCRED, &bp);
+			error = bread(pmp->pm_devvp, de_bn2kb(pmp, bn),
+				      pmp->pm_bpcluster, NOCRED, &bp);
 			if (error) {
 				brelse(bp);
 #ifdef MSDOSFS_DEBUG
diff -u /usr/src/sys/msdosfs/msdosfs_fat.c /home/trevin/src/sys/msdosfs/msdosfs_fat.c
--- /usr/src/sys/msdosfs/msdosfs_fat.c	Sun Nov 11 04:29:16 2001
+++ /home/trevin/src/sys/msdosfs/msdosfs_fat.c	Tue Jun 25 11:44:59 2002
@@ -140,7 +140,7 @@
 pcbmap(dep, findcn, bnp, cnp, sp)
 	struct denode *dep;
 	u_long findcn;		/* file relative cluster to get		 */
-	daddr_t *bnp;		/* returned filesys relative blk number	 */
+	daddr_t *bnp;		/* returned filesys rel sector number	 */
 	u_long *cnp;		/* returned cluster number		 */
 	int *sp;		/* returned block size			 */
 {
@@ -226,7 +226,8 @@
 		if (bn != bp_bn) {
 			if (bp)
 				brelse(bp);
-			error = bread(pmp->pm_devvp, bn, bsize, NOCRED, &bp);
+			error = bread(pmp->pm_devvp, de_bn2kb(pmp, bn), bsize,
+					NOCRED, &bp);
 			if (error) {
 				brelse(bp);
 				return (error);
@@ -354,7 +355,13 @@
 				+ ffs(pmp->pm_inusemap[cn / N_INUSEBITS]
 				      ^ (u_int)-1) - 1;
 		}
-		if (bread(pmp->pm_devvp, pmp->pm_fsinfo, 1024, NOCRED, &bpn) != 0) {
+		/*
+		 * XXX  If the fsinfo block is stored on media with
+		 *	2KB or larger sectors, is the fsinfo structure
+		 *	padded at the end or in the middle?
+		 */
+		if (bread(pmp->pm_devvp, de_bn2kb(pmp, pmp->pm_fsinfo), 1024,
+				NOCRED, &bpn) != 0) {
 			/*
 			 * Ignore the error, but turn off FSInfo update for the future.
 			 */
@@ -386,7 +393,8 @@
 		for (i = 1; i < pmp->pm_FATs; i++) {
 			fatbn += pmp->pm_FATsecs;
 			/* getblk() never fails */
-			bpn = getblk(pmp->pm_devvp, fatbn, bp->b_bcount, 0, 0);
+			bpn = getblk(pmp->pm_devvp, de_bn2kb(pmp, fatbn),
+				     bp->b_bcount, 0, 0);
 			memcpy(bpn->b_data, bp->b_data, bp->b_bcount);
 			if (pmp->pm_flags & MSDOSFSMNT_WAITONFAT)
 				bwrite(bpn);
@@ -535,7 +543,8 @@
 
 	byteoffset = FATOFS(pmp, cn);
 	fatblock(pmp, byteoffset, &bn, &bsize, &bo);
-	if ((error = bread(pmp->pm_devvp, bn, bsize, NOCRED, &bp)) != 0) {
+	if ((error = bread(pmp->pm_devvp, de_bn2kb(pmp, bn), bsize,
+				NOCRED, &bp)) != 0) {
 		brelse(bp);
 		return (error);
 	}
@@ -618,7 +627,7 @@
 	while (count > 0) {
 		byteoffset = FATOFS(pmp, start);
 		fatblock(pmp, byteoffset, &bn, &bsize, &bo);
-		error = bread(pmp->pm_devvp, bn, bsize, NOCRED, &bp);
+		error = bread(pmp->pm_devvp, de_bn2kb(pmp, bn), bsize, NOCRED, &bp);
 		if (error) {
 			brelse(bp);
 			return (error);
@@ -859,7 +868,8 @@
 		if (lbn != bn) {
 			if (bp)
 				updatefats(pmp, bp, lbn);
-			error = bread(pmp->pm_devvp, bn, bsize, NOCRED, &bp);
+			error = bread(pmp->pm_devvp, de_bn2kb(pmp, bn), bsize,
+					NOCRED, &bp);
 			if (error) {
 				brelse(bp);
 				return (error);
@@ -932,7 +942,8 @@
 			if (bp)
 				brelse(bp);
 			fatblock(pmp, byteoffset, &bn, &bsize, NULL);
-			error = bread(pmp->pm_devvp, bn, bsize, NOCRED, &bp);
+			error = bread(pmp->pm_devvp, de_bn2kb(pmp, bn), bsize,
+				      NOCRED, &bp);
 			if (error) {
 				brelse(bp);
 				return (error);
@@ -1059,7 +1070,8 @@
 		if ((flags & DE_CLEAR) &&
 		    (dep->de_Attributes & ATTR_DIRECTORY)) {
 			while (got-- > 0) {
-				bp = getblk(pmp->pm_devvp, cntobn(pmp, cn++),
+				bp = getblk(pmp->pm_devvp,
+					    de_bn2kb(pmp, cntobn(pmp, cn++)),
 					    pmp->pm_bpcluster, 0, 0);
 				clrbuf(bp);
 				if (bpp) {
diff -u /usr/src/sys/msdosfs/msdosfs_lookup.c /home/trevin/src/sys/msdosfs/msdosfs_lookup.c
--- /usr/src/sys/msdosfs/msdosfs_lookup.c	Sun Nov 11 04:29:17 2001
+++ /home/trevin/src/sys/msdosfs/msdosfs_lookup.c	Tue Jun 25 11:45:13 2002
@@ -224,7 +224,8 @@
 				break;
 			return (error);
 		}
-		error = bread(pmp->pm_devvp, bn, blsize, NOCRED, &bp);
+		error = bread(pmp->pm_devvp, de_bn2kb(pmp, bn), blsize,
+				NOCRED, &bp);
 		if (error) {
 			brelse(bp);
 			return (error);
@@ -647,7 +648,8 @@
 	clusoffset = ddep->de_fndoffset;
 	if (dirclust != MSDOSFSROOT)
 		clusoffset &= pmp->pm_crbomask;
-	if ((error = bread(pmp->pm_devvp, bn, blsize, NOCRED, &bp)) != 0) {
+	if ((error = bread(pmp->pm_devvp, de_bn2kb(pmp, bn), blsize,
+				NOCRED, &bp)) != 0) {
 		brelse(bp);
 		goto err_norollback;
 	}
@@ -684,8 +686,8 @@
 				if (error)
 					goto rollback;
 
-				error = bread(pmp->pm_devvp, bn, blsize,
-					      NOCRED, &bp);
+				error = bread(pmp->pm_devvp, de_bn2kb(pmp, bn),
+						blsize, NOCRED, &bp);
 				if (error) {
 					brelse(bp);
 					goto rollback;
@@ -737,7 +739,8 @@
 	       &bn, NULL, &blsize);
 	if (rberror)
 		goto err_norollback;
-	if ((rberror = bread(pmp->pm_devvp, bn, blsize, NOCRED, &bp)) != 0) {
+	if ((rberror = bread(pmp->pm_devvp, de_bn2kb(pmp, bn), blsize,
+				NOCRED, &bp)) != 0) {
 		brelse(bp);
 		goto err_norollback;
 	}
@@ -764,8 +767,8 @@
 			if (rberror)
 				goto err_norollback;
 
-			rberror = bread(pmp->pm_devvp, bn, blsize,
-				      NOCRED, &bp);
+			rberror = bread(pmp->pm_devvp, de_bn2kb(pmp, bn),
+					blsize, NOCRED, &bp);
 			if (rberror) {
 				brelse(bp);
 				goto err_norollback;
@@ -814,7 +817,7 @@
 				return (1);	/* it's empty */
 			return (0);
 		}
-		error = bread(pmp->pm_devvp, bn, blsize, NOCRED, &bp);
+		error = bread(pmp->pm_devvp, de_bn2kb(pmp, bn), blsize, NOCRED, &bp);
 		if (error) {
 			brelse(bp);
 			return (0);
@@ -907,7 +910,7 @@
 			break;
 		}
 		scn = dep->de_StartCluster;
-		error = bread(pmp->pm_devvp, cntobn(pmp, scn),
+		error = bread(pmp->pm_devvp, de_bn2kb(pmp, cntobn(pmp, scn)),
 			      pmp->pm_bpcluster, NOCRED, &bp);
 		if (error)
 			break;
@@ -974,7 +977,8 @@
 	    && de_blk(pmp, diroffset + blsize) > pmp->pm_rootdirsize)
 		blsize = de_bn2off(pmp, pmp->pm_rootdirsize) & pmp->pm_crbomask;
 	bn = detobn(pmp, dirclust, diroffset);
-	if ((error = bread(pmp->pm_devvp, bn, blsize, NOCRED, bpp)) != 0) {
+	if ((error = bread(pmp->pm_devvp, de_bn2kb(pmp, bn), blsize,
+				NOCRED, bpp)) != 0) {
 		brelse(*bpp);
 		*bpp = NULL;
 		return (error);
@@ -1033,7 +1037,7 @@
 		error = pcbmap(pdep, de_cluster(pmp, offset), &bn, 0, &blsize);
 		if (error)
 			return error;
-		error = bread(pmp->pm_devvp, bn, blsize, NOCRED, &bp);
+		error = bread(pmp->pm_devvp, de_bn2kb(pmp, bn), blsize, NOCRED, &bp);
 		if (error) {
 			brelse(bp);
 			return error;
@@ -1109,7 +1113,8 @@
 					return 0;
 				return error;
 			}
-			error = bread(pmp->pm_devvp, bn, blsize, NOCRED, &bp);
+			error = bread(pmp->pm_devvp, de_bn2kb(pmp, bn), blsize,
+					NOCRED, &bp);
 			if (error) {
 				brelse(bp);
 				return error;
@@ -1160,7 +1165,7 @@
 	for (cn = 0;; cn++) {
 		if (pcbmap(dep, cn, &bn, 0, &blsize))
 			return 0;
-		if (bread(pmp->pm_devvp, bn, blsize, NOCRED, &bp)) {
+		if (bread(pmp->pm_devvp, de_bn2kb(pmp, bn), blsize, NOCRED, &bp)) {
 			brelse(bp);
 			return 0;
 		}
diff -u /usr/src/sys/msdosfs/msdosfs_vfsops.c /home/trevin/src/sys/msdosfs/msdosfs_vfsops.c
--- /usr/src/sys/msdosfs/msdosfs_vfsops.c	Tue Mar 26 04:17:58 2002
+++ /home/trevin/src/sys/msdosfs/msdosfs_vfsops.c	Tue Jun 25 11:45:29 2002
@@ -403,21 +403,21 @@
 	bp  = NULL; /* both used in error_exit */
 	pmp = NULL;
 
+	/*
+	 * We need the disklabel to calculate the size of a FAT entry
+	 * later on. Also make sure the partition contains a filesystem
+	 * of type FS_MSDOS. This doesn't work for floppies, so we have
+	 * to check for them too.
+	 *
+	 * There might still be parts of the msdos fs driver which
+	 * assume that the size of a sector will always be 512 bytes.
+	 * Let's root them out...
+	 */
+	error = VOP_IOCTL(devvp, DIOCGPART, (caddr_t)&dpart,
+			  FREAD, NOCRED, p);
+	if (error)
+		goto error_exit;
 	if (argp->flags & MSDOSFSMNT_GEMDOSFS) {
-		/*
-	 	 * We need the disklabel to calculate the size of a FAT entry
-		 * later on. Also make sure the partition contains a filesystem
-		 * of type FS_MSDOS. This doesn't work for floppies, so we have
-		 * to check for them too.
-	 	 *
-	 	 * At least some parts of the msdos fs driver seem to assume
-		 * that the size of a disk block will always be 512 bytes.
-		 * Let's check it...
-		 */
-		error = VOP_IOCTL(devvp, DIOCGPART, (caddr_t)&dpart,
-				  FREAD, NOCRED, p);
-		if (error)
-			goto error_exit;
 		tmp   = dpart.part->p_fstype;
 		dtype = dpart.disklab->d_type;
 		bsize = dpart.disklab->d_secsize;
@@ -431,7 +431,8 @@
 	 * Read the boot sector of the filesystem, and then check the
 	 * boot signature.  If not a dos boot sector then error out.
 	 */
-	if ((error = bread(devvp, 0, 512, NOCRED, &bp)) != 0)
+	if ((error = bread(devvp, 0, dpart.disklab->d_secsize,
+				NOCRED, &bp)) != 0)
 		goto error_exit;
 	bp->b_flags |= B_AGE;
 	bsp = (union bootsector *)bp->b_data;
@@ -645,7 +646,13 @@
 	if (pmp->pm_fsinfo) {
 		struct fsinfo *fp;
 
-		if ((error = bread(devvp, pmp->pm_fsinfo, 1024, NOCRED, &bp)) != 0)
+		/*
+		 * XXX  If the fsinfo block is stored on media with
+		 *	2KB or larger sectors, is the fsinfo structure
+		 *	padded at the end or in the middle?
+		 */
+		if ((error = bread(devvp, de_bn2kb(pmp, pmp->pm_fsinfo), 1024,
+					NOCRED, &bp)) != 0)
 			goto error_exit;
 		fp = (struct fsinfo *)bp->b_data;
 		if (!memcmp(fp->fsisig1, "RRaA", 4)
diff -u /usr/src/sys/msdosfs/msdosfs_vnops.c /home/trevin/src/sys/msdosfs/msdosfs_vnops.c
--- /usr/src/sys/msdosfs/msdosfs_vnops.c	Mon Mar 18 04:41:33 2002
+++ /home/trevin/src/sys/msdosfs/msdosfs_vnops.c	Tue Jun 25 11:50:32 2002
@@ -509,7 +509,7 @@
 		if (diff < n)
 			n = (long) diff;
 
-		/* convert cluster # to block # */
+		/* convert cluster # to sector # */
 		error = pcbmap(dep, lbn, &lbn, 0, &blsize);
 		if (error)
 			return (error);
@@ -519,7 +519,8 @@
 		 * do i/o with the vnode for the filesystem instead of the
 		 * vnode for the directory.
 		 */
-		error = bread(pmp->pm_devvp, lbn, blsize, NOCRED, &bp);
+		error = bread(pmp->pm_devvp, de_bn2kb(pmp, lbn), blsize,
+				NOCRED, &bp);
 		n = MIN(n, pmp->pm_bpcluster - bp->b_resid);
 		if (error) {
 			brelse(bp);
@@ -1112,8 +1113,8 @@
 			panic("msdosfs_rename: updating .. in root directory?\n");
 		} else
 			bn = cntobn(pmp, cn);
-		error = bread(pmp->pm_devvp, bn, pmp->pm_bpcluster,
-			      NOCRED, &bp);
+		error = bread(pmp->pm_devvp, de_bn2kb(pmp, bn),
+			      pmp->pm_bpcluster, NOCRED, &bp);
 		if (error) {
 			/* XXX should really panic here, fs is corrupt */
 			brelse(bp);
@@ -1227,7 +1228,7 @@
 	 */
 	bn = cntobn(pmp, newcluster);
 	/* always succeeds */
-	bp = getblk(pmp->pm_devvp, bn, pmp->pm_bpcluster, 0, 0);
+	bp = getblk(pmp->pm_devvp, de_bn2kb(pmp, bn), pmp->pm_bpcluster, 0, 0);
 	memset(bp->b_data, 0, pmp->pm_bpcluster);
 	memcpy(bp->b_data, &dosdirtemplate, sizeof dosdirtemplate);
 	denp = (struct direntry *)bp->b_data;
@@ -1465,7 +1466,7 @@
 	    || (FAT32(pmp) && dep->de_StartCluster == pmp->pm_rootdirblk)) {
 #if 0
 		printf("msdosfs_readdir(): going after . or .. in root dir, offset %d\n",
-		    offset);
+		    (int) offset);
 #endif
 		bias = 2 * sizeof(struct direntry);
 		if (offset < bias) {
@@ -1517,7 +1518,8 @@
 		n = MIN(n, diff);
 		if ((error = pcbmap(dep, lbn, &bn, &cn, &blsize)) != 0)
 			break;
-		error = bread(pmp->pm_devvp, bn, blsize, NOCRED, &bp);
+		error = bread(pmp->pm_devvp, de_bn2kb(pmp, bn), blsize,
+				NOCRED, &bp);
 		if (error) {
 			brelse(bp);
 			return (error);
@@ -1680,6 +1682,7 @@
 		int *a_runp;
 	} */ *ap = v;
 	struct denode *dep = VTODE(ap->a_vp);
+	int status;
 
 	if (ap->a_vpp != NULL)
 		*ap->a_vpp = dep->de_devvp;
@@ -1691,7 +1694,12 @@
 		 */
 		*ap->a_runp = 0;
 	}
-	return (pcbmap(dep, ap->a_bn, ap->a_bnp, 0, 0));
+	status = pcbmap(dep, ap->a_bn, ap->a_bnp, 0, 0);
+	/*
+	 * We need to scale *ap->a_bnp by sector_size/DEV_BSIZE
+	 */
+	*ap->a_bnp = de_bn2kb(dep->de_pmp, *ap->a_bnp);
+	return status;
 }
 
 int
@@ -1736,6 +1744,8 @@
 			bp->b_blkno = -1;
 		if (bp->b_blkno == -1)
 			clrbuf(bp);
+		else
+			bp->b_blkno = de_bn2kb(dep->de_pmp, bp->b_blkno);
 	}
 	if (bp->b_blkno == -1) {
 		biodone(bp);
diff -u /usr/src/sys/msdosfs/msdosfsmount.h /home/trevin/src/sys/msdosfs/msdosfsmount.h
--- /usr/src/sys/msdosfs/msdosfsmount.h	Sun Sep 16 03:45:56 2001
+++ /home/trevin/src/sys/msdosfs/msdosfsmount.h	Tue Jun 25 11:44:16 2002
@@ -88,16 +88,16 @@
 	struct vnode *pm_devvp;	/* vnode for block device mntd */
 	struct bpb50 pm_bpb;	/* BIOS parameter blk for this fs */
 	u_long pm_FATsecs;	/* actual number of fat sectors */
-	u_long pm_fatblk;	/* block # of first FAT */
-	u_long pm_rootdirblk;	/* block # (cluster # for FAT32) of root directory number */
-	u_long pm_rootdirsize;	/* size in blocks (not clusters) */
-	u_long pm_firstcluster;	/* block number of first cluster */
+	u_long pm_fatblk;	/* sector # of first FAT */
+	u_long pm_rootdirblk;	/* sector # (cluster # for FAT32) of root directory number */
+	u_long pm_rootdirsize;	/* size in sectors (not clusters) */
+	u_long pm_firstcluster;	/* sector number of first cluster */
 	u_long pm_nmbrofclusters;	/* # of clusters in filesystem */
 	u_long pm_maxcluster;	/* maximum cluster number */
 	u_long pm_freeclustercount;	/* number of free clusters */
 	u_long pm_cnshift;	/* shift file offset right this amount to get a cluster number */
 	u_long pm_crbomask;	/* and a file offset with this mask to get cluster rel offset */
-	u_long pm_bnshift;	/* shift file offset right this amount to get a block number */
+	u_long pm_bnshift;	/* shift file offset right this amount to get a sector number */
 	u_long pm_bpcluster;	/* bytes per cluster */
 	u_long pm_fmod;		/* ~0 if fs is modified, this can rollover to 0	*/
 	u_long pm_fatblocksize;	/* size of fat blocks in bytes */
@@ -143,18 +143,30 @@
 	 + ((dirofs) & (pmp)->pm_crbomask)))
 
 /*
- * Convert block number to cluster number
+ * Convert sector number to cluster number
  */
 #define	de_bn2cn(pmp, bn) \
 	((bn) >> ((pmp)->pm_cnshift - (pmp)->pm_bnshift))
 
 /*
- * Convert cluster number to block number
+ * Convert cluster number to sector number
  */
 #define	de_cn2bn(pmp, cn) \
 	((cn) << ((pmp)->pm_cnshift - (pmp)->pm_bnshift))
 
 /*
+ * Convert sector number to kernel block number
+ */
+#define de_bn2kb(pmp, bn) \
+	((bn) << ((pmp)->pm_bnshift - DEV_BSHIFT))
+
+/*
+ * Convert kernel block number to sector number
+ */
+#define de_kb2bn(pmp, kb) \
+	((kb) >> ((pmp)->pm_bnshift - DEV_BSHIFT))
+
+/*
  * Convert file offset to cluster number
  */
 #define de_cluster(pmp, off) \
@@ -167,7 +179,7 @@
 	(((size) + (pmp)->pm_bpcluster - 1) >> (pmp)->pm_cnshift)
 
 /*
- * Convert file offset to block number
+ * Convert file offset to sector number
  */
 #define de_blk(pmp, off) \
 	(de_cn2bn(pmp, de_cluster((pmp), (off))))
@@ -179,24 +191,24 @@
 	((cn) << (pmp)->pm_cnshift)
 
 /*
- * Convert block number to file offset
+ * Convert sector number to file offset
  */
 #define	de_bn2off(pmp, bn) \
 	((bn) << (pmp)->pm_bnshift)
 /*
- * Map a cluster number into a filesystem relative block number.
+ * Map a cluster number into a filesystem relative sector number.
  */
 #define	cntobn(pmp, cn) \
 	(de_cn2bn((pmp), (cn)-CLUST_FIRST) + (pmp)->pm_firstcluster)
 
 /*
- * Calculate block number for directory entry in root dir, offset dirofs
+ * Calculate sector number for directory entry in root dir, offset dirofs
  */
 #define	roottobn(pmp, dirofs) \
 	(de_blk((pmp), (dirofs)) + (pmp)->pm_rootdirblk)
 
 /*
- * Calculate block number for directory entry at cluster dirclu, offset
+ * Calculate sector number for directory entry at cluster dirclu, offset
  * dirofs
  */
 #define	detobn(pmp, dirclu, dirofs) \
diff -u /usr/src/sbin/newfs_msdos/newfs_msdos.8 /home/trevin/src/sbin/newfs_msdos/newfs_msdos.8
--- /usr/src/sbin/newfs_msdos/newfs_msdos.8	Sat Nov 17 03:51:34 2001
+++ /home/trevin/src/sbin/newfs_msdos/newfs_msdos.8	Tue Jun 25 14:15:11 2002
@@ -86,7 +86,7 @@
 .Qq Li "BSD  4.4" .
 .It Fl S Ar sector-size
 Number of bytes per sector.  Acceptable values are powers of 2
-in the range 128 through 32768.
+in the range 512 through 32768.
 .It Fl a Ar FAT-size
 Number of sectors per FAT.
 .It Fl b Ar block-size
diff -u /usr/src/sbin/newfs_msdos/newfs_msdos.c /home/trevin/src/sbin/newfs_msdos/newfs_msdos.c
--- /usr/src/sbin/newfs_msdos/newfs_msdos.c	Tue Sep 18 04:07:45 2001
+++ /home/trevin/src/sbin/newfs_msdos/newfs_msdos.c	Tue Jun 25 14:14:49 2002
@@ -68,7 +68,7 @@
 #define NPB	  2		/* nibbles per byte */
 
 #define DOSMAGIC  0xaa55	/* DOS magic number */
-#define MINBPS	  128		/* minimum bytes per sector */
+#define MINBPS	  512		/* minimum bytes per sector */
 #define MAXSPC	  128		/* maximum sectors per cluster */
 #define MAXNFT	  16		/* maximum number of FATs */
 #define DEFBLK	  4096		/* default block size */
@@ -635,17 +635,17 @@
 		    setstr(bs->oem, opt_O ? opt_O : "BSD  4.4",
 			   sizeof(bs->oem));
 		    memcpy(img + x1, bootcode, sizeof(bootcode));
-		    mk2(img + bpb.bps - 2, DOSMAGIC);
+		    mk2(img + 0x200 - 2, DOSMAGIC);
 		}
 	    } else if (fat == 32 && bpb.infs != MAXU16 &&
 		       (lsn == bpb.infs ||
 			(bpb.bkbs != MAXU16 &&
 			 lsn == bpb.bkbs + bpb.infs))) {
 		mk4(img, 0x41615252);
-		mk4(img + bpb.bps - 28, 0x61417272);
-		mk4(img + bpb.bps - 24, 0xffffffff);
-		mk4(img + bpb.bps - 20, bpb.rdcl);
-		mk2(img + bpb.bps - 2, DOSMAGIC);
+		mk4(img + 0x200 - 28, 0x61417272);
+		mk4(img + 0x200 - 24, 0xffffffff);
+		mk4(img + 0x200 - 20, bpb.rdcl);
+		mk2(img + 0x200 - 2, DOSMAGIC);
 	    } else if (lsn >= bpb.res && lsn < dir &&
 		       !((lsn - bpb.res) %
 			 (bpb.spf ? bpb.spf : bpb.bspf))) {

--Boundary_(ID_0WR5Y7Ybix8OUShjXygBPA)
Content-type: text/plain; charset=us-ascii
Content-transfer-encoding: 7BIT


-----------------------
Trevin Beattie          "Do not meddle in the affairs of wizards,
trevin@xmission.com     for you are crunchy and good with ketchup."
      {:->                                     --unknown

--Boundary_(ID_0WR5Y7Ybix8OUShjXygBPA)--