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:
(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.