Subject: kern/2896: An msdosfs patch to handle disks whose sector size != DEV_BSIZE.
To: None <gnats-bugs@gnats.netbsd.org>
From: MINOURA Makoto <minoura@kw.netlaputa.or.jp>
List: netbsd-bugs
Date: 10/28/1996 00:00:35
>Number:         2896
>Category:       kern
>Synopsis:       An msdosfs patch to handle disks whose sector size != DEV_BSIZE.
>Confidential:   no
>Severity:       non-critical
>Priority:       medium
>Responsible:    kern-bug-people (Kernel Bug People)
>State:          open
>Class:          change-request
>Submitter-Id:   net
>Arrival-Date:   Sun Oct 27 07:05:01 1996
>Last-Modified:
>Originator:     MINOURA Makoto
>Organization:
MINOURA, Makoto <minoura@kw.netlaputa.or.jp>
Nakahara-ku Kawasaki-Shi, JAPAN
>Release:        1.2
>Environment:
System: NetBSD daisy 1.2 NetBSD 1.2 (DAISY) #25: Sun Oct 27 22:15:03 JST 1996 root@daisy:/usr/src/sys/arch/i386/compile/DAISY i386


>Description:
	In Japan, the format of which sector size=1024, number of sector=8,
	number of track=77 was the most popular one especially for 130mm
	(5inch) FD for a long time, because it was adopted by the Japanese
	best seller PC, NEC PC-9801 series (and also others, including x68k).
	It is still used widely in some situations.  I made a patch for
	the i386 FD driver to recognize this type of FD (which I sent
	as another report), and found out that msdosfs has a problem as well.

	Current (as of 1.2) msdosfs assumes the disk sector size is
	same as DEV_BSIZE (usually 512bytes), and gives the physical
	block number to bread()/getblk() as its arguments.

	There seems to be similar code in the `if (GEMDOSFS)' blocks.
	To ensure I/Os not to be done from/to the middle of the physical
	block (but logical boundary), the same method is not usable.

	To use NEC format msdos fs, the floppy driver must support such
	(physical) format.  As of 1.2, at least x68k port does.  I sent i386
	patch, and am working on sparc.
>How-To-Repeat:
>Fix:
Quick dirty hack...
diff -crN msdosfs.ORIG/msdosfs_denode.c msdosfs/msdosfs_denode.c
*** msdosfs.ORIG/msdosfs_denode.c	Sat Feb 10 21:33:32 1996
--- msdosfs/msdosfs_denode.c	Sun Oct 27 21:49:04 1996
***************
*** 431,441 ****
  	if ((boff = length & pmp->pm_crbomask) != 0) {
  		if (isadir) {
  			bn = cntobn(pmp, eofentry);
! 			error = bread(pmp->pm_devvp, bn, pmp->pm_bpcluster,
  			    NOCRED, &bp);
  		} else {
  			bn = de_blk(pmp, length);
! 			error = bread(DETOV(dep), bn, pmp->pm_bpcluster,
  			    NOCRED, &bp);
  		}
  		if (error) {
--- 431,441 ----
  	if ((boff = length & pmp->pm_crbomask) != 0) {
  		if (isadir) {
  			bn = cntobn(pmp, eofentry);
! 			error = pbread(pmp->pm_devvp, bn, pmp->pm_bpcluster,
  			    NOCRED, &bp);
  		} else {
  			bn = de_blk(pmp, length);
! 			error = pbread(DETOV(dep), bn, pmp->pm_bpcluster,
  			    NOCRED, &bp);
  		}
  		if (error) {
diff -crN msdosfs.ORIG/msdosfs_fat.c msdosfs/msdosfs_fat.c
*** msdosfs.ORIG/msdosfs_fat.c	Sat Feb 10 21:33:33 1996
--- msdosfs/msdosfs_fat.c	Sun Oct 27 22:48:18 1996
***************
*** 223,229 ****
  		if (bn != bp_bn) {
  			if (bp)
  				brelse(bp);
! 			error = bread(pmp->pm_devvp, bn, bsize, NOCRED, &bp);
  			if (error) {
  				brelse(bp);
  				return (error);
--- 223,229 ----
  		if (bn != bp_bn) {
  			if (bp)
  				brelse(bp);
! 			error = pbread(pmp->pm_devvp, bn, bsize, NOCRED, &bp);
  			if (error) {
  				brelse(bp);
  				return (error);
***************
*** 349,355 ****
  	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);
  		bcopy(bp->b_data, bpn->b_data, bp->b_bcount);
  		if (pmp->pm_flags & MSDOSFSMNT_WAITONFAT)
  			bwrite(bpn);
--- 349,355 ----
  	for (i = 1; i < pmp->pm_FATs; i++) {
  		fatbn += pmp->pm_FATsecs;
  		/* getblk() never fails */
! 		bpn = pgetblk(pmp->pm_devvp, fatbn, bp->b_bcount, 0, 0);
  		bcopy(bp->b_data, bpn->b_data, bp->b_bcount);
  		if (pmp->pm_flags & MSDOSFSMNT_WAITONFAT)
  			bwrite(bpn);
***************
*** 491,497 ****
  
  	byteoffset = FATOFS(pmp, cn);
  	fatblock(pmp, byteoffset, &bn, &bsize, &bo);
! 	if ((error = bread(pmp->pm_devvp, bn, bsize, NOCRED, &bp)) != 0) {
  		brelse(bp);
  		return (error);
  	}
--- 491,497 ----
  
  	byteoffset = FATOFS(pmp, cn);
  	fatblock(pmp, byteoffset, &bn, &bsize, &bo);
! 	if ((error = pbread(pmp->pm_devvp, bn, bsize, NOCRED, &bp)) != 0) {
  		brelse(bp);
  		return (error);
  	}
***************
*** 562,568 ****
  	while (count > 0) {
  		byteoffset = FATOFS(pmp, start);
  		fatblock(pmp, byteoffset, &bn, &bsize, &bo);
! 		error = bread(pmp->pm_devvp, bn, bsize, NOCRED, &bp);
  		if (error) {
  			brelse(bp);
  			return (error);
--- 562,568 ----
  	while (count > 0) {
  		byteoffset = FATOFS(pmp, start);
  		fatblock(pmp, byteoffset, &bn, &bsize, &bo);
! 		error = pbread(pmp->pm_devvp, bn, bsize, NOCRED, &bp);
  		if (error) {
  			brelse(bp);
  			return (error);
***************
*** 792,798 ****
  		if (lbn != bn) {
  			if (bp)
  				updatefats(pmp, bp, lbn);
! 			error = bread(pmp->pm_devvp, bn, bsize, NOCRED, &bp);
  			if (error) {
  				brelse(bp);
  				return (error);
--- 792,798 ----
  		if (lbn != bn) {
  			if (bp)
  				updatefats(pmp, bp, lbn);
! 			error = pbread(pmp->pm_devvp, bn, bsize, NOCRED, &bp);
  			if (error) {
  				brelse(bp);
  				return (error);
***************
*** 860,866 ****
  			if (bp)
  				brelse(bp);
  			fatblock(pmp, byteoffset, &bn, &bsize, NULL);
! 			error = bread(pmp->pm_devvp, bn, bsize, NOCRED, &bp);
  			if (error) {
  				brelse(bp);
  				return (error);
--- 860,866 ----
  			if (bp)
  				brelse(bp);
  			fatblock(pmp, byteoffset, &bn, &bsize, NULL);
! 			error = pbread(pmp->pm_devvp, bn, bsize, NOCRED, &bp);
  			if (error) {
  				brelse(bp);
  				return (error);
***************
*** 986,1005 ****
  				 * Get the buf header for the new block of the file.
  				 */
  				if (dep->de_Attributes & ATTR_DIRECTORY)
! 					bp = getblk(pmp->pm_devvp, cntobn(pmp, cn++),
  						    pmp->pm_bpcluster, 0, 0);
  				else {
! 					bp = getblk(DETOV(dep), de_cn2bn(pmp, frcn++),
  					    pmp->pm_bpcluster, 0, 0);
  					/*
  					 * Do the bmap now, as in msdosfs_write
  					 */
  					if (pcbmap(dep,
! 					    de_bn2cn(pmp, bp->b_lblkno),
  					    &bp->b_blkno, 0, 0))
  						bp->b_blkno = -1;
  					if (bp->b_blkno == -1)
  						panic("extendfile: pcbmap");
  				}
  				clrbuf(bp);
  				if (bpp) {
--- 986,1006 ----
  				 * Get the buf header for the new block of the file.
  				 */
  				if (dep->de_Attributes & ATTR_DIRECTORY)
! 					bp = pgetblk(pmp->pm_devvp, cntobn(pmp, cn++),
  						    pmp->pm_bpcluster, 0, 0);
  				else {
! 					bp = pgetblk(DETOV(dep), de_cn2bn(pmp, frcn++),
  					    pmp->pm_bpcluster, 0, 0);
  					/*
  					 * Do the bmap now, as in msdosfs_write
  					 */
  					if (pcbmap(dep,
! 					    de_bn2cn(pmp, bp->b_lblkno / pmp->pm_pblk),
  					    &bp->b_blkno, 0, 0))
  						bp->b_blkno = -1;
  					if (bp->b_blkno == -1)
  						panic("extendfile: pcbmap");
+ 					bp->b_blkno *= pmp->pm_pblk;
  				}
  				clrbuf(bp);
  				if (bpp) {
diff -crN msdosfs.ORIG/msdosfs_lookup.c msdosfs/msdosfs_lookup.c
*** msdosfs.ORIG/msdosfs_lookup.c	Fri Mar  8 21:26:34 1996
--- msdosfs/msdosfs_lookup.c	Sun Oct 27 21:49:04 1996
***************
*** 260,266 ****
  				break;
  			return (error);
  		}
! 		error = bread(pmp->pm_devvp, bn, blsize, NOCRED, &bp);
  		if (error) {
  			brelse(bp);
  			return (error);
--- 260,266 ----
  				break;
  			return (error);
  		}
! 		error = pbread(pmp->pm_devvp, bn, blsize, NOCRED, &bp);
  		if (error) {
  			brelse(bp);
  			return (error);
***************
*** 625,631 ****
  	diroffset = ddep->de_fndoffset;
  	if (dirclust != MSDOSFSROOT)
  		diroffset &= pmp->pm_crbomask;
! 	if ((error = bread(pmp->pm_devvp, bn, blsize, NOCRED, &bp)) != 0) {
  		brelse(bp);
  		return error;
  	}
--- 625,631 ----
  	diroffset = ddep->de_fndoffset;
  	if (dirclust != MSDOSFSROOT)
  		diroffset &= pmp->pm_crbomask;
! 	if ((error = pbread(pmp->pm_devvp, bn, blsize, NOCRED, &bp)) != 0) {
  		brelse(bp);
  		return error;
  	}
***************
*** 655,661 ****
  				if (error)
  					return error;
  
! 				error = bread(pmp->pm_devvp, bn, blsize,
  					      NOCRED, &bp);
  				if (error) {
  					brelse(bp);
--- 655,661 ----
  				if (error)
  					return error;
  
! 				error = pbread(pmp->pm_devvp, bn, blsize,
  					      NOCRED, &bp);
  				if (error) {
  					brelse(bp);
***************
*** 718,724 ****
  				return (1);	/* it's empty */
  			return (0);
  		}
! 		error = bread(pmp->pm_devvp, bn, blsize, NOCRED, &bp);
  		if (error) {
  			brelse(bp);
  			return (0);
--- 718,724 ----
  				return (1);	/* it's empty */
  			return (0);
  		}
! 		error = pbread(pmp->pm_devvp, bn, blsize, NOCRED, &bp);
  		if (error) {
  			brelse(bp);
  			return (0);
***************
*** 803,809 ****
  		}
  		pmp = dep->de_pmp;
  		scn = dep->de_StartCluster;
! 		error = bread(pmp->pm_devvp, cntobn(pmp, scn),
  			      pmp->pm_bpcluster, NOCRED, &bp);
  		if (error)
  			break;
--- 803,809 ----
  		}
  		pmp = dep->de_pmp;
  		scn = dep->de_StartCluster;
! 		error = pbread(pmp->pm_devvp, cntobn(pmp, scn),
  			      pmp->pm_bpcluster, NOCRED, &bp);
  		if (error)
  			break;
***************
*** 861,867 ****
  	    && 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) {
  		brelse(*bpp);
  		*bpp = NULL;
  		return (error);
--- 861,867 ----
  	    && 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 = pbread(pmp->pm_devvp, bn, blsize, NOCRED, bpp)) != 0) {
  		brelse(*bpp);
  		*bpp = NULL;
  		return (error);
***************
*** 918,924 ****
  		error = pcbmap(pdep, de_cluster(pmp, offset), &bn, 0, &blsize);
  		if (error)
  			return error;
! 		error = bread(pmp->pm_devvp, bn, blsize, NOCRED, &bp);
  		if (error) {
  			brelse(bp);
  			return error;
--- 918,924 ----
  		error = pcbmap(pdep, de_cluster(pmp, offset), &bn, 0, &blsize);
  		if (error)
  			return error;
! 		error = pbread(pmp->pm_devvp, bn, blsize, NOCRED, &bp);
  		if (error) {
  			brelse(bp);
  			return error;
***************
*** 980,986 ****
  					return 0;
  				return error;
  			}
! 			error = bread(pmp->pm_devvp, bn, blsize, NOCRED, &bp);
  			if (error) {
  				brelse(bp);
  				return error;
--- 980,986 ----
  					return 0;
  				return error;
  			}
! 			error = pbread(pmp->pm_devvp, bn, blsize, NOCRED, &bp);
  			if (error) {
  				brelse(bp);
  				return error;
***************
*** 1031,1037 ****
  	for (cn = 0;; cn++) {
  		if (pcbmap(dep, cn, &bn, 0, &blsize))
  			return 0;
! 		if (bread(pmp->pm_devvp, bn, blsize, NOCRED, &bp)) {
  			brelse(bp);
  			return 0;
  		}
--- 1031,1037 ----
  	for (cn = 0;; cn++) {
  		if (pcbmap(dep, cn, &bn, 0, &blsize))
  			return 0;
! 		if (pbread(pmp->pm_devvp, bn, blsize, NOCRED, &bp)) {
  			brelse(bp);
  			return 0;
  		}
diff -crN msdosfs.ORIG/msdosfs_vfsops.c msdosfs/msdosfs_vfsops.c
*** msdosfs.ORIG/msdosfs_vfsops.c	Wed Mar 20 21:25:18 1996
--- msdosfs/msdosfs_vfsops.c	Sun Oct 27 22:09:10 1996
***************
*** 316,322 ****
  	 * 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)
  		goto error_exit;
  	bp->b_flags |= B_AGE;
  	bsp = (union bootsector *)bp->b_data;
--- 316,322 ----
  	 * 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, BLKDEV_IOSIZE, NOCRED, &bp)) != 0)
  		goto error_exit;
  	bp->b_flags |= B_AGE;
  	bsp = (union bootsector *)bp->b_data;
***************
*** 400,405 ****
--- 400,406 ----
  		pmp->pm_FATsecs     *= tmp;
  		SecPerClust         *= tmp;
  	}
+ 	pmp->pm_pblk = pmp->pm_BytesPerSec / DEV_BSIZE;
  	pmp->pm_fatblk = pmp->pm_ResSectors;
  	pmp->pm_rootdirblk = pmp->pm_fatblk +
  	    (pmp->pm_FATs * pmp->pm_FATsecs);
diff -crN msdosfs.ORIG/msdosfs_vnops.c msdosfs/msdosfs_vnops.c
*** msdosfs.ORIG/msdosfs_vnops.c	Wed Jul 31 20:37:34 1996
--- msdosfs/msdosfs_vnops.c	Sun Oct 27 21:58:05 1996
***************
*** 455,470 ****
  		 * vnode for the directory.
  		 */
  		if (isadir) {
! 			error = bread(pmp->pm_devvp, lbn, blsize, NOCRED, &bp);
  		} else {
  			rablock = lbn + 1;
  			if (vp->v_lastr + 1 == lbn &&
  			    de_cn2off(pmp, rablock) < dep->de_FileSize)
! 				error = breada(vp, de_cn2bn(pmp, lbn),
  				    pmp->pm_bpcluster, de_cn2bn(pmp, rablock),
  				    pmp->pm_bpcluster, NOCRED, &bp);
  			else
! 				error = bread(vp, de_cn2bn(pmp, lbn),
  				    pmp->pm_bpcluster, NOCRED, &bp);
  			vp->v_lastr = lbn;
  		}
--- 455,470 ----
  		 * vnode for the directory.
  		 */
  		if (isadir) {
! 			error = pbread(pmp->pm_devvp, lbn, blsize, NOCRED, &bp);
  		} else {
  			rablock = lbn + 1;
  			if (vp->v_lastr + 1 == lbn &&
  			    de_cn2off(pmp, rablock) < dep->de_FileSize)
! 				error = pbreada(vp, de_cn2bn(pmp, lbn),
  				    pmp->pm_bpcluster, de_cn2bn(pmp, rablock),
  				    pmp->pm_bpcluster, NOCRED, &bp);
  			else
! 				error = pbread(vp, de_cn2bn(pmp, lbn),
  				    pmp->pm_bpcluster, NOCRED, &bp);
  			vp->v_lastr = lbn;
  		}
***************
*** 592,598 ****
  			 * or we write the cluster from its start beyond EOF,
  			 * then no need to read data from disk.
  			 */
! 			bp = getblk(thisvp, bn, pmp->pm_bpcluster, 0, 0);
  			clrbuf(bp);
  			/*
  			 * Do the bmap now, since pcbmap needs buffers
--- 592,598 ----
  			 * or we write the cluster from its start beyond EOF,
  			 * then no need to read data from disk.
  			 */
! 			bp = pgetblk(thisvp, bn, pmp->pm_bpcluster, 0, 0);
  			clrbuf(bp);
  			/*
  			 * Do the bmap now, since pcbmap needs buffers
***************
*** 600,609 ****
  			 */
  			if (bp->b_blkno == bp->b_lblkno) {
  				error = pcbmap(dep,
! 					       de_bn2cn(pmp, bp->b_lblkno),
  					       &bp->b_blkno, 0, 0);
  				if (error)
  					bp->b_blkno = -1;
  			}
  			if (bp->b_blkno == -1) {
  				brelse(bp);
--- 600,610 ----
  			 */
  			if (bp->b_blkno == bp->b_lblkno) {
  				error = pcbmap(dep,
! 					       de_bn2cn(pmp, bp->b_lblkno / pmp->pm_pblk),
  					       &bp->b_blkno, 0, 0);
  				if (error)
  					bp->b_blkno = -1;
+ 				bp->b_blkno *= pmp->pm_pblk;
  			}
  			if (bp->b_blkno == -1) {
  				brelse(bp);
***************
*** 615,622 ****
  			/*
  			 * The block we need to write into exists, so read it in.
  			 */
! 			error = bread(thisvp, bn, pmp->pm_bpcluster,
! 				      NOCRED, &bp);
  			if (error) {
  				brelse(bp);
  				break;
--- 616,623 ----
  			/*
  			 * The block we need to write into exists, so read it in.
  			 */
! 			error = pbread(thisvp, bn, pmp->pm_bpcluster,
! 				       NOCRED, &bp);
  			if (error) {
  				brelse(bp);
  				break;
***************
*** 1137,1144 ****
  			panic("msdosfs_rename: updating .. in root directory?\n");
  		} else
  			bn = cntobn(pmp, cn);
! 		error = bread(pmp->pm_devvp, bn, pmp->pm_bpcluster,
! 			      NOCRED, &bp);
  		if (error) {
  			/* XXX should really panic here, fs is corrupt */
  			brelse(bp);
--- 1138,1145 ----
  			panic("msdosfs_rename: updating .. in root directory?\n");
  		} else
  			bn = cntobn(pmp, cn);
! 		error = pbread(pmp->pm_devvp, bn, pmp->pm_bpcluster,
! 			       NOCRED, &bp);
  		if (error) {
  			/* XXX should really panic here, fs is corrupt */
  			brelse(bp);
***************
*** 1244,1250 ****
  	 */
  	bn = cntobn(pmp, newcluster);
  	/* always succeeds */
! 	bp = getblk(pmp->pm_devvp, bn, pmp->pm_bpcluster, 0, 0);
  	bzero(bp->b_data, pmp->pm_bpcluster);
  	bcopy(&dosdirtemplate, bp->b_data, sizeof dosdirtemplate);
  	denp = (struct direntry *)bp->b_data;
--- 1245,1251 ----
  	 */
  	bn = cntobn(pmp, newcluster);
  	/* always succeeds */
! 	bp = pgetblk(pmp->pm_devvp, bn, pmp->pm_bpcluster, 0, 0);
  	bzero(bp->b_data, pmp->pm_bpcluster);
  	bcopy(&dosdirtemplate, bp->b_data, sizeof dosdirtemplate);
  	denp = (struct direntry *)bp->b_data;
***************
*** 1509,1515 ****
  		n = min(n, diff);
  		if ((error = pcbmap(dep, lbn, &bn, &cn, &blsize)) != 0)
  			break;
! 		error = bread(pmp->pm_devvp, bn, blsize, NOCRED, &bp);
  		if (error) {
  			brelse(bp);
  			return (error);
--- 1510,1516 ----
  		n = min(n, diff);
  		if ((error = pcbmap(dep, lbn, &bn, &cn, &blsize)) != 0)
  			break;
! 		error = pbread(pmp->pm_devvp, bn, blsize, NOCRED, &bp);
  		if (error) {
  			brelse(bp);
  			return (error);
***************
*** 1816,1827 ****
  	 * don't allow files with holes, so we shouldn't ever see this.
  	 */
  	if (bp->b_blkno == bp->b_lblkno) {
! 		error = pcbmap(dep, de_bn2cn(dep->de_pmp, bp->b_lblkno),
  			       &bp->b_blkno, 0, 0);
  		if (error)
  			bp->b_blkno = -1;
  		if (bp->b_blkno == -1)
  			clrbuf(bp);
  	}
  	if (bp->b_blkno == -1) {
  		biodone(bp);
--- 1817,1829 ----
  	 * don't allow files with holes, so we shouldn't ever see this.
  	 */
  	if (bp->b_blkno == bp->b_lblkno) {
! 		error = pcbmap(dep, de_bn2cn(dep->de_pmp, bp->b_lblkno / dep->de_pmp->pm_pblk),
  			       &bp->b_blkno, 0, 0);
  		if (error)
  			bp->b_blkno = -1;
  		if (bp->b_blkno == -1)
  			clrbuf(bp);
+ 		bp->b_blkno *= dep->de_pmp->pm_pblk;
  	}
  	if (bp->b_blkno == -1) {
  		biodone(bp);
diff -crN msdosfs.ORIG/msdosfsmount.h msdosfs/msdosfsmount.h
*** msdosfs.ORIG/msdosfsmount.h	Sat Feb 10 21:33:35 1996
--- msdosfs/msdosfsmount.h	Sun Oct 27 22:49:50 1996
***************
*** 58,63 ****
--- 58,64 ----
  	mode_t pm_mask;		/* mask to and with file protection bits */
  	struct vnode *pm_devvp;	/* vnode for block device mntd */
  	struct bpb50 pm_bpb;	/* BIOS parameter blk for this fs */
+ 	u_int pm_pblk;		/* physical block size (# of logical block) */
  	u_long pm_fatblk;	/* block # of first FAT */
  	u_long pm_rootdirblk;	/* block # of root directory */
  	u_long pm_rootdirsize;	/* size in blocks (not clusters) */
***************
*** 185,190 ****
--- 186,202 ----
  	((dirclu) == MSDOSFSROOT \
  	 ? roottobn((pmp), (dirofs)) \
  	 : cntobn((pmp), (dirclu)))
+ 
+ /*
+  * Special bread / getblk whose arguments are in physical block
+  */
+ #define pbread(vn, blk, sz, cred, bp) \
+ 	bread(vn, (blk) * pmp->pm_pblk, sz, cred, bp)
+ #define pgetblk(vn, blk, sz, sf, st) \
+ 	getblk(vn, (blk) * pmp->pm_pblk, sz, sf, st)
+ #define pbreada(vn, blk, sz, rab, rabsz, cred, bp) \
+ 	breada(vn, (blk) * pmp->pm_pblk, sz, \
+ 	(rab) * pmp->pm_pblk, rabsz, cred, bp)
  
  /*
   * Prototypes for MSDOSFS virtual filesystem operations

>Audit-Trail:
>Unformatted: