Page MenuHomeFreeBSD

D44319.diff
No OneTemporary

D44319.diff

diff --git a/sys/fs/msdosfs/msdosfs_denode.c b/sys/fs/msdosfs/msdosfs_denode.c
--- a/sys/fs/msdosfs/msdosfs_denode.c
+++ b/sys/fs/msdosfs/msdosfs_denode.c
@@ -428,11 +428,12 @@
if ((boff = length & pmp->pm_crbomask) != 0) {
if (isadir) {
bn = cntobn(pmp, eofentry);
- error = bread(pmp->pm_devvp, bn, pmp->pm_bpcluster,
+ error = breadb(pmp->pm_devvp, bntolbn(pmp, bn), bn, pmp->pm_bpcluster,
NOCRED, &bp);
} else {
- error = bread(DETOV(dep), de_cluster(pmp, length),
- pmp->pm_bpcluster, cred, &bp);
+ bn = de_cluster(pmp, length);
+ error = breadb(DETOV(dep), bntolbn(pmp, bn), bn, pmp->pm_bpcluster,
+ cred, &bp);
}
if (error) {
#ifdef MSDOSFS_DEBUG
@@ -503,6 +504,7 @@
struct msdosfsmount *pmp = dep->de_pmp;
struct vnode *vp = DETOV(dep);
struct buf *bp;
+ daddr_t bn;
off_t eof_clusteroff;
u_long count;
int error;
@@ -547,7 +549,8 @@
* actual buffer content which might exist in the tail of the
* already valid cluster.
*/
- error = bread(vp, de_cluster(pmp, dep->de_FileSize), pmp->pm_bpcluster,
+ bn = de_cluster(pmp, dep->de_FileSize);
+ error = breadb(vp, bntolbn(pmp, bn), bn, pmp->pm_bpcluster,
NOCRED, &bp);
if (error != 0)
goto rewind;
diff --git a/sys/fs/msdosfs/msdosfs_fat.c b/sys/fs/msdosfs/msdosfs_fat.c
--- a/sys/fs/msdosfs/msdosfs_fat.c
+++ b/sys/fs/msdosfs/msdosfs_fat.c
@@ -204,7 +204,8 @@
if (bn != bp_bn) {
if (bp)
brelse(bp);
- error = bread(pmp->pm_devvp, bn, bsize, NOCRED, &bp);
+ error = breadb(pmp->pm_devvp, bntolbn(pmp, bn), bn, bsize,
+ NOCRED, &bp);
if (error) {
return (error);
}
@@ -339,8 +340,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, 0);
+ bpn = getblkb(pmp->pm_devvp, bntolbn(pmp, fatbn), fatbn,
+ bp->b_bcount, 0, 0, 0);
memcpy(bpn->b_data, bp->b_data, bp->b_bcount);
/* Force the clean bit on in the other copies. */
if (cleanfat == 16)
@@ -509,7 +510,8 @@
byteoffset = FATOFS(pmp, cn);
fatblock(pmp, byteoffset, &bn, &bsize, &bo);
- error = bread(pmp->pm_devvp, bn, bsize, NOCRED, &bp);
+ error = breadb(pmp->pm_devvp, bntolbn(pmp, bn), bn, bsize,
+ NOCRED, &bp);
if (error) {
return (error);
}
@@ -591,7 +593,8 @@
while (count > 0) {
byteoffset = FATOFS(pmp, start);
fatblock(pmp, byteoffset, &bn, &bsize, &bo);
- error = bread(pmp->pm_devvp, bn, bsize, NOCRED, &bp);
+ error = breadb(pmp->pm_devvp, bntolbn(pmp, bn), bn, bsize,
+ NOCRED, &bp);
if (error) {
return (error);
}
@@ -845,7 +848,8 @@
if (lbn != bn) {
if (bp)
updatefats(pmp, bp, lbn);
- error = bread(pmp->pm_devvp, bn, bsize, NOCRED, &bp);
+ error = breadb(pmp->pm_devvp, bntolbn(pmp, bn), bn, bsize,
+ NOCRED, &bp);
if (error) {
MSDOSFS_UNLOCK_MP(pmp);
return (error);
@@ -927,7 +931,8 @@
if (bp != NULL)
brelse(bp);
fatblock(pmp, byteoffset, &bn, &bsize, NULL);
- error = bread(pmp->pm_devvp, bn, bsize, NOCRED, &bp);
+ error = breadb(pmp->pm_devvp, bntolbn(pmp, bn), bn, bsize,
+ NOCRED, &bp);
if (error != 0)
return (error);
}
@@ -946,8 +951,10 @@
if (cn == 0 && readcn != ((pmp->pm_fatmask & 0xffffff00) |
pmp->pm_bpb.bpbMedia)) {
#ifdef MSDOSFS_DEBUG
- printf("mountmsdosfs(): Media descriptor in BPB"
- "does not match FAT ID\n");
+ printf("mountmsdosfs(): Media descriptor in BPB (%#x) "
+ "does not match FAT ID (%#lx)\n",
+ (pmp->pm_fatmask & 0xffffff00) | pmp->pm_bpb.bpbMedia,
+ readcn);
#endif
brelse(bp);
return (EINVAL);
@@ -1076,19 +1083,21 @@
/*
* 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++),
+ if (dep->de_Attributes & ATTR_DIRECTORY) {
+ blkno = cntobn(pmp, cn++);
+ bp = getblkb(pmp->pm_devvp,
+ bntolbn(pmp, blkno), blkno,
pmp->pm_bpcluster, 0, 0, 0);
- else {
- bp = getblk(DETOV(dep),
- frcn++,
+ } else {
+ blkno = frcn++;
+ bp = getblkb(DETOV(dep),
+ bntolbn(pmp, blkno), blkno,
pmp->pm_bpcluster, 0, 0, 0);
/*
* Do the bmap now, as in msdosfs_write
*/
if (pcbmap(dep,
- bp->b_lblkno,
+ bp->b_blkno,
&blkno, 0, 0))
bp->b_blkno = -1;
if (bp->b_blkno == -1)
@@ -1160,7 +1169,8 @@
*/
byteoffset = FATOFS(pmp, 1);
fatblock(pmp, byteoffset, &bn, &bsize, &bo);
- error = bread(pmp->pm_devvp, bn, bsize, NOCRED, &bp);
+ error = breadb(pmp->pm_devvp, bntolbn(pmp, bn), bn, bsize,
+ NOCRED, &bp);
if (error)
return (error);
diff --git a/sys/fs/msdosfs/msdosfs_lookup.c b/sys/fs/msdosfs/msdosfs_lookup.c
--- a/sys/fs/msdosfs/msdosfs_lookup.c
+++ b/sys/fs/msdosfs/msdosfs_lookup.c
@@ -253,7 +253,8 @@
break;
return (error);
}
- error = bread(pmp->pm_devvp, bn, blsize, NOCRED, &bp);
+ error = breadb(pmp->pm_devvp, bntolbn(pmp, bn), bn, blsize,
+ NOCRED, &bp);
if (error) {
return (error);
}
@@ -678,7 +679,8 @@
diroffset = ddep->de_fndoffset;
if (dirclust != MSDOSFSROOT)
diroffset &= pmp->pm_crbomask;
- if ((error = bread(pmp->pm_devvp, bn, blsize, NOCRED, &bp)) != 0) {
+ if ((error = breadb(pmp->pm_devvp, bntolbn(pmp, bn), bn, blsize,
+ NOCRED, &bp)) != 0) {
brelse(bp);
return error;
}
@@ -711,8 +713,8 @@
if (error)
return error;
- error = bread(pmp->pm_devvp, bn, blsize,
- NOCRED, &bp);
+ error = breadb(pmp->pm_devvp, bntolbn(pmp, bn),
+ bn, blsize, NOCRED, &bp);
if (error) {
return error;
}
@@ -778,7 +780,8 @@
return (1); /* it's empty */
return (0);
}
- error = bread(pmp->pm_devvp, bn, blsize, NOCRED, &bp);
+ error = breadb(pmp->pm_devvp, bntolbn(pmp, bn), bn, blsize,
+ NOCRED, &bp);
if (error) {
return (0);
}
@@ -834,6 +837,7 @@
doscheckpath(struct denode *source, struct denode *target, daddr_t *wait_scn)
{
daddr_t scn;
+ daddr_t bn;
struct msdosfsmount *pmp;
struct direntry *ep;
struct denode *dep;
@@ -866,7 +870,8 @@
break;
}
scn = dep->de_StartCluster;
- error = bread(pmp->pm_devvp, cntobn(pmp, scn),
+ bn = cntobn(pmp, scn);
+ error = breadb(pmp->pm_devvp, bntolbn(pmp, bn), bn,
pmp->pm_bpcluster, NOCRED, &bp);
if (error != 0)
break;
@@ -934,7 +939,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 = breadb(pmp->pm_devvp, bntolbn(pmp, bn), bn, blsize,
+ NOCRED, bpp)) != 0) {
brelse(*bpp);
*bpp = NULL;
return (error);
@@ -991,7 +997,8 @@
error = pcbmap(pdep, de_cluster(pmp, offset), &bn, 0, &blsize);
if (error)
return error;
- error = bread(pmp->pm_devvp, bn, blsize, NOCRED, &bp);
+ error = breadb(pmp->pm_devvp, bntolbn(pmp, bn), bn, blsize,
+ NOCRED, &bp);
if (error) {
return error;
}
@@ -1068,7 +1075,8 @@
return 0;
return error;
}
- error = bread(pmp->pm_devvp, bn, blsize, NOCRED, &bp);
+ error = breadb(pmp->pm_devvp, bntolbn(pmp, bn), bn, blsize,
+ NOCRED, &bp);
if (error) {
return error;
}
diff --git a/sys/fs/msdosfs/msdosfs_vfsops.c b/sys/fs/msdosfs/msdosfs_vfsops.c
--- a/sys/fs/msdosfs/msdosfs_vfsops.c
+++ b/sys/fs/msdosfs/msdosfs_vfsops.c
@@ -457,7 +457,8 @@
printf("rootdir_free: dirclu=%d dirleft=%d readsize=%lu\n",
dirclu, dirleft, readsize);
#endif
- if (bread(pmp->pm_devvp, dirclu, readsize, NOCRED, &bp) != 0) {
+ if (breadb(pmp->pm_devvp, bntolbn(pmp, dirclu), dirclu, readsize,
+ NOCRED, &bp) != 0) {
printf("rootdir_free: read error\n");
if (bp != NULL)
brelse(bp);
@@ -757,12 +758,27 @@
goto error_exit;
}
+ /*
+ * Prevent re-use of the buffer since it has been fetched without offset.
+ */
+ bp->b_flags |= B_NOCACHE|B_NOREUSE;
+
/*
* Release the bootsector buffer.
*/
brelse(bp);
bp = NULL;
+ /*
+ * Calculate sector offset required to align clusters with page boundaries.
+ */
+ pmp->pm_cacheblockoffs = -pmp->pm_firstcluster % de_off2bn(pmp, PAGE_SIZE);
+//#ifdef MSDOSFS_DEBUG
+ printf("mountmsdosfs(): firstcluster=%lu bpcluster=%lu bnshift=%lu cacheblockoffs=%lu\n",
+ pmp->pm_firstcluster, pmp->pm_bpcluster, pmp->pm_bnshift, pmp->pm_cacheblockoffs);
+//#endif
+// pmp->pm_cacheblockoffs = 0;
+
/*
* Check the fsinfo sector if we have one. Silently fix up our
* in-core copy of fp->fsinxtfree if it is unknown (0xffffffff)
@@ -771,8 +787,10 @@
*/
if (pmp->pm_fsinfo) {
struct fsinfo *fp;
+ daddr_t bn;
- if ((error = bread(devvp, pmp->pm_fsinfo, pmp->pm_BytesPerSec,
+ bn = pmp->pm_fsinfo;
+ if ((error = breadb(devvp, bntolbn(pmp, bn), bn, pmp->pm_BytesPerSec,
NOCRED, &bp)) != 0)
goto error_exit;
fp = (struct fsinfo *)bp->b_data;
@@ -1073,6 +1091,7 @@
{
struct fsinfo *fp;
struct buf *bp;
+ daddr_t bn;
int error;
MSDOSFS_LOCK_MP(pmp);
@@ -1080,7 +1099,8 @@
error = 0;
goto unlock;
}
- error = bread(pmp->pm_devvp, pmp->pm_fsinfo, pmp->pm_BytesPerSec,
+ bn = pmp->pm_fsinfo;
+ error = breadb(pmp->pm_devvp, bntolbn(pmp, bn), bn, pmp->pm_BytesPerSec,
NOCRED, &bp);
if (error != 0) {
goto unlock;
diff --git a/sys/fs/msdosfs/msdosfs_vnops.c b/sys/fs/msdosfs/msdosfs_vnops.c
--- a/sys/fs/msdosfs/msdosfs_vnops.c
+++ b/sys/fs/msdosfs/msdosfs_vnops.c
@@ -573,18 +573,20 @@
break;
} else if (error)
break;
- error = bread(pmp->pm_devvp, lbn, blsize, NOCRED, &bp);
+ error = breadb(pmp->pm_devvp, bntolbn(pmp, lbn), lbn, blsize,
+ NOCRED, &bp);
} else if (de_cn2off(pmp, rablock) >= dep->de_FileSize) {
- error = bread(vp, lbn, blsize, NOCRED, &bp);
- } else if ((vp->v_mount->mnt_flag & MNT_NOCLUSTERR) == 0) {
+ error = breadb(vp, bntolbn(pmp, lbn), lbn, blsize, NOCRED, &bp);
+ } else if ((vp->v_mount->mnt_flag & MNT_NOCLUSTERR) == 0 &&
+ pmp->pm_cacheblockoffs == 0) {
error = cluster_read(vp, dep->de_FileSize, lbn, blsize,
NOCRED, on + uio->uio_resid, seqcount, 0, &bp);
} else if (seqcount > 1) {
rasize = blsize;
- error = breadn(vp, lbn,
+ error = breadbn(vp, bntolbn(pmp, lbn), lbn,
blsize, &rablock, &rasize, 1, NOCRED, &bp);
} else {
- error = bread(vp, lbn, blsize, NOCRED, &bp);
+ error = breadb(vp, bntolbn(pmp, lbn), lbn, blsize, NOCRED, &bp);
}
if (error) {
brelse(bp);
@@ -729,7 +731,8 @@
* 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, 0);
+ bp = getblkb(thisvp, bntolbn(pmp, bn), bn, pmp->pm_bpcluster,
+ 0, 0, 0);
/*
* This call to vfs_bio_clrbuf() ensures that
* even if vn_io_fault_uiomove() below faults,
@@ -741,8 +744,8 @@
* Do the bmap now, since pcbmap needs buffers
* for the FAT table. (see msdosfs_strategy)
*/
- if (bp->b_blkno == bp->b_lblkno) {
- error = pcbmap(dep, bp->b_lblkno, &bn, 0, 0);
+ if (bntolbn(pmp, bp->b_blkno) == bp->b_lblkno) { // XXX ???
+ error = pcbmap(dep, bp->b_blkno, &bn, 0, 0);
if (error)
bp->b_blkno = -1;
else
@@ -758,7 +761,8 @@
/*
* The block we need to write into exists, so read it in.
*/
- error = bread(thisvp, bn, pmp->pm_bpcluster, cred, &bp);
+ error = breadb(thisvp, bntolbn(pmp, bn), bn, pmp->pm_bpcluster,
+ cred, &bp);
if (error) {
break;
}
@@ -797,7 +801,8 @@
else if (vm_page_count_severe() || buf_dirty_count_severe())
bawrite(bp);
else if (n + croffset == pmp->pm_bpcluster) {
- if ((vp->v_mount->mnt_flag & MNT_NOCLUSTERW) == 0)
+ if ((vp->v_mount->mnt_flag & MNT_NOCLUSTERW) == 0 &&
+ pmp->pm_cacheblockoffs == 0)
cluster_write(vp, &dep->de_clusterw, bp,
dep->de_FileSize, seqcount, 0);
else
@@ -1237,10 +1242,10 @@
if (cn == MSDOSFSROOT) {
/* this should never happen */
panic("msdosfs_rename(): updating .. in root directory?");
- } else
- bn = cntobn(pmp, cn);
- error = bread(pmp->pm_devvp, bn, pmp->pm_bpcluster,
- NOCRED, &bp);
+ }
+ bn = cntobn(pmp, cn);
+ error = breadb(pmp->pm_devvp, bntolbn(pmp, bn), bn,
+ pmp->pm_bpcluster, NOCRED, &bp);
if (error != 0) {
printf("%s: block read error %d while renaming dir\n",
pmp->pm_mountp->mnt_stat.f_mntonname,
@@ -1380,7 +1385,8 @@
*/
bn = cntobn(pmp, newcluster);
/* always succeeds */
- bp = getblk(pmp->pm_devvp, bn, pmp->pm_bpcluster, 0, 0, 0);
+ bp = getblkb(pmp->pm_devvp, bntolbn(pmp, bn), bn, pmp->pm_bpcluster,
+ 0, 0, 0);
memset(bp->b_data, 0, pmp->pm_bpcluster);
memcpy(bp->b_data, &dosdirtemplate, sizeof dosdirtemplate);
denp = (struct direntry *)bp->b_data;
@@ -1629,7 +1635,8 @@
error = pcbmap(dep, lbn, &bn, &cn, &blsize);
if (error)
break;
- error = bread(pmp->pm_devvp, bn, blsize, NOCRED, &bp);
+ error = breadb(pmp->pm_devvp, bntolbn(pmp, bn), bn, blsize,
+ NOCRED, &bp);
if (error) {
return (error);
}
diff --git a/sys/fs/msdosfs/msdosfsmount.h b/sys/fs/msdosfs/msdosfsmount.h
--- a/sys/fs/msdosfs/msdosfsmount.h
+++ b/sys/fs/msdosfs/msdosfsmount.h
@@ -91,6 +91,7 @@
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_cacheblockoffs; /* offset from physical block to buffer cache block number */
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 */
@@ -201,6 +202,13 @@
*/
#define de_bn2off(pmp, bn) \
((bn) << (pmp)->pm_bnshift)
+
+/*
+ * Convert offset to block number
+ */
+#define de_off2bn(pmp, off) \
+ ((off) >> (pmp)->pm_bnshift)
+
/*
* Map a cluster number into a filesystem relative block number.
*/
@@ -213,6 +221,12 @@
#define roottobn(pmp, dirofs) \
(de_blk((pmp), (dirofs)) + (pmp)->pm_rootdirblk)
+/*
+ * Calculate buffer cache block number from disk block number
+ */
+#define bntolbn(pmp, bn) \
+ ((pmp)->pm_cacheblockoffs + (bn))
+
/*
* Calculate block number for directory entry at cluster dirclu, offset
* dirofs
diff --git a/sys/kern/vfs_bio.c b/sys/kern/vfs_bio.c
--- a/sys/kern/vfs_bio.c
+++ b/sys/kern/vfs_bio.c
@@ -3289,7 +3289,7 @@
*/
if (ncl != 1) {
BUF_UNLOCK(bp);
- nwritten = cluster_wbuild(vp, size, lblkno - j, ncl,
+ nwritten = cluster_wbuild(vp, size, lblkno - j, ncl, // XXX only lblkno used !!!
gbflags);
return (nwritten);
}
@@ -3914,17 +3914,24 @@
}
}
+struct buf *
+getblkb(struct vnode *vp, daddr_t blkno, daddr_t dblkno, int size, int slpflag,
+ int slptimeo, int flags)
+{
+ struct buf *bp;
+ int error;
+
+ error = getblkx(vp, blkno, dblkno, size, slpflag, slptimeo, flags, &bp);
+ if (error != 0)
+ return (NULL);
+ return (bp);
+}
+
struct buf *
getblk(struct vnode *vp, daddr_t blkno, int size, int slpflag, int slptimeo,
int flags)
{
- struct buf *bp;
- int error;
-
- error = getblkx(vp, blkno, blkno, size, slpflag, slptimeo, flags, &bp);
- if (error != 0)
- return (NULL);
- return (bp);
+ return (getblkb(vp, blkno, blkno, size, slpflag, slptimeo, flags));
}
/*
diff --git a/sys/sys/buf.h b/sys/sys/buf.h
--- a/sys/sys/buf.h
+++ b/sys/sys/buf.h
@@ -549,12 +549,18 @@
#define bread(vp, blkno, size, cred, bpp) \
breadn_flags(vp, blkno, blkno, size, NULL, NULL, 0, cred, 0, \
NULL, bpp)
+#define breadb(vp, blkno, dblkno, size, cred, bpp) \
+ breadn_flags(vp, blkno, dblkno, size, NULL, NULL, 0, cred, 0, \
+ NULL, bpp)
#define bread_gb(vp, blkno, size, cred, gbflags, bpp) \
breadn_flags(vp, blkno, blkno, size, NULL, NULL, 0, cred, \
gbflags, NULL, bpp)
#define breadn(vp, blkno, size, rablkno, rabsize, cnt, cred, bpp) \
breadn_flags(vp, blkno, blkno, size, rablkno, rabsize, cnt, cred, \
0, NULL, bpp)
+#define breadbn(vp, blkno, dblkno, size, rablkno, rabsize, cnt, cred, bpp) \
+ breadn_flags(vp, blkno, dblkno, size, rablkno, rabsize, cnt, cred, \
+ 0, NULL, bpp)
int breadn_flags(struct vnode *, daddr_t, daddr_t, int, daddr_t *, int *,
int, struct ucred *, int, void (*)(struct buf *), struct buf **);
void bdwrite(struct buf *);
@@ -574,6 +580,7 @@
struct buf *gbincore(struct bufobj *, daddr_t);
struct buf *gbincore_unlocked(struct bufobj *, daddr_t);
struct buf *getblk(struct vnode *, daddr_t, int, int, int, int);
+struct buf *getblkb(struct vnode *, daddr_t, daddr_t, int, int, int, int);
int getblkx(struct vnode *vp, daddr_t blkno, daddr_t dblkno, int size,
int slpflag, int slptimeo, int flags, struct buf **bpp);
struct buf *geteblk(int, int);

File Metadata

Mime Type
text/plain
Expires
Tue, Nov 19, 7:41 AM (20 h, 57 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
14712630
Default Alt Text
D44319.diff (16 KB)

Event Timeline