NetBSD Problem Report #17398

Received: (qmail 23640 invoked by uid 605); 25 Jun 2002 22:01:59 -0000
Message-Id: <20020625220159.ACB0011122@www.netbsd.org>
Date: Tue, 25 Jun 2002 15:01:59 -0700 (PDT)
From: trevin@xmission.com
Sender: gnats-bugs-owner@netbsd.org
Reply-To: trevin@xmission.com
To: gnats-bugs@gnats.netbsd.org
Subject: msdosfs does not support sector size != DEV_BSIZE
X-Send-Pr-Version: www-1.0

>Number:         17398
>Category:       kern
>Synopsis:       msdosfs does not support sector size != DEV_BSIZE
>Confidential:   no
>Severity:       non-critical
>Priority:       medium
>Responsible:    scw
>State:          closed
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Tue Jun 25 22:02:00 +0000 2002
>Closed-Date:    Sat Nov 25 20:50:28 +0000 2006
>Last-Modified:  Sat Nov 25 20:50:28 +0000 2006
>Originator:     Trevin Beattie
>Release:        NetBSD-1.6A (-current as of June 8, 2002)
>Organization:
>Environment:
NetBSD clyde.wh.ca.us 1.6A NetBSD 1.6A (CLYDE) #30: Tue Jun 25 14:13:40 PDT 2002
     trevin@clyde.wh.ca.us:/home/trevin/src/sys/arch/i386/compile/CLYDE i386

>Description:
Some time ago, it was decided and implemented that all device I/O done
in the kernel (bread(), b_blkno) would be done in units of DEV_BSIZE.
Device drivers would handle converting DEV_BSIZE block numbers to
physical sectors, and file systems would handle converting fs block
numbers to DEV_BSIZE.  The msdosfs currently still performs all bread()
functions using sector numbers.

Also, the newfs_msdos utility does not store the boot signature in the
correct place on large sector disks.  The boot signature should be at
offset 0x1fe in the BPB; newfs_msdos currently stores it 2 bytes from
the end of the sector.

>How-To-Repeat:
The best proof requires a removable disk with a 1KB or 2KB sector size.
(I use a 640MB optical disk.)  Format the disk using a Windows 9x or NT
OS (using a FAT file system; my disk came out with FAT16).  Attempt to
mount the disk in NetBSD.  You won't get past the "invalid argument"
error presented when msdosfs tries to read a partial boot sector.

>Fix:
The following patches fix both msdosfs and newfs_msdos.  These are
valid for NetBSD-current as of June 8, 2002.  The patches supercede
PR #kern/2896, and also fix PR #kern/3459.

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))) {

>Release-Note:
>Audit-Trail:

From: Trevin Beattie <trevin@xmission.com>
To: gnats-bugs@netbsd.org
Cc:  
Subject: Re: kern/17398
Date: Wed, 26 Jun 2002 09:43:20 -0700

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

 Oops; I had forgotten to check fsck_msdos after I had fixed newfs_msdos.
 Like the others, this utility only required a few minor changes in the way
 it reads the boot block and fsinfo sectors.  Actually, it worked as-is on
 the block device; this change just makes it work with the character (raw)
 device as well.

 --Boundary_(ID_/AyJezE8zQe1OK4kPwRtGg)
 Content-type: text/plain; charset=iso-8859-1; NAME=fsck_msdos-patch
 Content-transfer-encoding: 7BIT
 Content-disposition: attachment; filename=fsck_msdos-patch

 diff -u /usr/src/sbin/fsck_msdos/boot.c /home/trevin/src/sbin/fsck_msdos/boot.c
 --- /usr/src/sbin/fsck_msdos/boot.c	Sun Dec 23 04:01:47 2001
 +++ /home/trevin/src/sbin/fsck_msdos/boot.c	Wed Jun 26 09:30:00 2002
 @@ -47,17 +47,22 @@
  #include "ext.h"
  #include "fsutil.h"

 +#define MAXSECTSIZE 32768
 +#define FSINFOSIZE (2 * DOSBOOTBLOCKSIZE)
 +#define max(a,b) (((a) > (b)) ? (b) : (a))
 +
  int
  readboot(dosfs, boot)
  	int dosfs;
  	struct bootblock *boot;
  {
 -	u_char block[DOSBOOTBLOCKSIZE];
 -	u_char fsinfo[2 * DOSBOOTBLOCKSIZE];
 -	u_char backup[DOSBOOTBLOCKSIZE];
 +	u_char block[MAXSECTSIZE];
 +	u_char fsinfo[MAXSECTSIZE];
 +	u_char backup[MAXSECTSIZE];
  	int ret = FSOK;
 -	
 -	if (read(dosfs, block, sizeof block) < sizeof block) {
 +
 +	/* XXX - we should really read one sector, but we don't have the sector size yet */
 +	if (read(dosfs, block, MAXSECTSIZE) < (ssize_t) DOSBOOTBLOCKSIZE) {
  		perror("could not read boot block");
  		return FSFATAL;
  	}
 @@ -108,8 +113,8 @@

  		if (lseek(dosfs, boot->FSInfo * boot->BytesPerSec, SEEK_SET)
  		    != boot->FSInfo * boot->BytesPerSec
 -		    || read(dosfs, fsinfo, sizeof fsinfo)
 -		    != sizeof fsinfo) {
 +		    || read(dosfs, fsinfo, max(FSINFOSIZE, boot->BytesPerSec))
 +		    < FSINFOSIZE) {
  			perror("could not read fsinfo block");
  			return FSFATAL;
  		}
 @@ -135,8 +140,8 @@
  				fsinfo[0x3ff] = 0xaa;
  				if (lseek(dosfs, boot->FSInfo * boot->BytesPerSec, SEEK_SET)
  				    != boot->FSInfo * boot->BytesPerSec
 -				    || write(dosfs, fsinfo, sizeof fsinfo)
 -				    != sizeof fsinfo) {
 +				    || write(dosfs, fsinfo, max(FSINFOSIZE, boot->BytesPerSec))
 +				    < (ssize_t) FSINFOSIZE) {
  					perror("Unable to write FSInfo");
  					return FSFATAL;
  				}
 @@ -155,7 +160,8 @@

  		if (lseek(dosfs, boot->Backup * boot->BytesPerSec, SEEK_SET)
  		    != boot->Backup * boot->BytesPerSec
 -		    || read(dosfs, backup, sizeof backup) != sizeof  backup) {
 +		    || read(dosfs, backup, max(DOSBOOTBLOCKSIZE, boot->BytesPerSec))
 +		    < (ssize_t) DOSBOOTBLOCKSIZE) {
  			perror("could not read backup bootblock");
  			return FSFATAL;
  		}
 @@ -233,11 +239,12 @@
  	int dosfs;
  	struct bootblock *boot;
  {
 -	u_char fsinfo[2 * DOSBOOTBLOCKSIZE];
 +	u_char fsinfo[MAXSECTSIZE];

  	if (lseek(dosfs, boot->FSInfo * boot->BytesPerSec, SEEK_SET)
  	    != boot->FSInfo * boot->BytesPerSec
 -	    || read(dosfs, fsinfo, sizeof fsinfo) != sizeof fsinfo) {
 +	    || read(dosfs, fsinfo, max(FSINFOSIZE, boot->BytesPerSec))
 +	    < (ssize_t) FSINFOSIZE) {
  		perror("could not read fsinfo block");
  		return FSFATAL;
  	}
 @@ -251,8 +258,8 @@
  	fsinfo[0x1ef] = (u_char)(boot->FSNext >> 24);
  	if (lseek(dosfs, boot->FSInfo * boot->BytesPerSec, SEEK_SET)
  	    != boot->FSInfo * boot->BytesPerSec
 -	    || write(dosfs, fsinfo, sizeof fsinfo)
 -	    != sizeof fsinfo) {
 +	    || write(dosfs, fsinfo, max(FSINFOSIZE, boot->BytesPerSec))
 +	    < (ssize_t) FSINFOSIZE) {
  		perror("Unable to write FSInfo");
  		return FSFATAL;
  	}

 --Boundary_(ID_/AyJezE8zQe1OK4kPwRtGg)
 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_/AyJezE8zQe1OK4kPwRtGg)--
Responsible-Changed-From-To: kern-bug-people->scw
Responsible-Changed-By: scw@netbsd.org
Responsible-Changed-When: Tue, 10 Oct 2006 09:27:00 +0100
Responsible-Changed-Why:
I'll take this one. I have it working partially on -current.


State-Changed-From-To: open->analyzed
State-Changed-By: scw@netbsd.org
State-Changed-When: Tue, 10 Oct 2006 09:27:00 +0100
State-Changed-Why:
The patch is partially working with -current in my local tree.


From: Steve Woodford <scw@netbsd.org>
To: gnats-bugs@NetBSD.org
Cc: 
Subject: PR/17398 CVS commit: src/sys/fs/msdosfs
Date: Sat, 25 Nov 2006 12:17:30 +0000 (UTC)

 Module Name:	src
 Committed By:	scw
 Date:		Sat Nov 25 12:17:30 UTC 2006

 Modified Files:
 	src/sys/fs/msdosfs: msdosfs_denode.c msdosfs_fat.c msdosfs_lookup.c
 	    msdosfs_vfsops.c msdosfs_vnops.c msdosfsmount.h

 Log Message:
 Support FAT filesystems on non-DEV_BSIZE media.

 Based on the patches provided in PR kern/17398 by Trevin Beattie.


 To generate a diff of this commit:
 cvs rdiff -r1.16 -r1.17 src/sys/fs/msdosfs/msdosfs_denode.c
 cvs rdiff -r1.11 -r1.12 src/sys/fs/msdosfs/msdosfs_fat.c \
     src/sys/fs/msdosfs/msdosfsmount.h
 cvs rdiff -r1.9 -r1.10 src/sys/fs/msdosfs/msdosfs_lookup.c
 cvs rdiff -r1.39 -r1.40 src/sys/fs/msdosfs/msdosfs_vfsops.c
 cvs rdiff -r1.33 -r1.34 src/sys/fs/msdosfs/msdosfs_vnops.c

 Please note that diffs are not public domain; they are subject to the
 copyright notices on the relevant files.

From: Steve Woodford <scw@netbsd.org>
To: gnats-bugs@NetBSD.org
Cc: 
Subject: PR/17398 CVS commit: src/sbin/newfs_msdos
Date: Sat, 25 Nov 2006 12:29:33 +0000 (UTC)

 Module Name:	src
 Committed By:	scw
 Date:		Sat Nov 25 12:29:33 UTC 2006

 Modified Files:
 	src/sbin/newfs_msdos: newfs_msdos.8 newfs_msdos.c

 Log Message:
 Don't use negative offsets from "bpb.bps" when writing out values such
 as DOSMAGIC in the MBR. In non-512 byte media, the MBR is still 512
 bytes in length.

 Based on the patches provided in PR kern/17398 by Trevin Beattie.


 To generate a diff of this commit:
 cvs rdiff -r1.14 -r1.15 src/sbin/newfs_msdos/newfs_msdos.8
 cvs rdiff -r1.23 -r1.24 src/sbin/newfs_msdos/newfs_msdos.c

 Please note that diffs are not public domain; they are subject to the
 copyright notices on the relevant files.

State-Changed-From-To: analyzed->closed
State-Changed-By: scw@netbsd.org
State-Changed-When: Sat, 25 Nov 2006 20:50:28 +0000
State-Changed-Why:
Supplied patch applied to NetBSD-current. Thanks!


>Unformatted:

NetBSD Home
NetBSD PR Database Search

(Contact us) $NetBSD: query-full-pr,v 1.39 2013/11/01 18:47:49 spz Exp $
$NetBSD: gnats_config.sh,v 1.8 2006/05/07 09:23:38 tsutsui Exp $
Copyright © 1994-2007 The NetBSD Foundation, Inc. ALL RIGHTS RESERVED.