Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F102875406
D44319.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
16 KB
Referenced Files
None
Subscribers
None
D44319.diff
View Options
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
Details
Attached
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)
Attached To
Mode
D44319: Support 64KB cluster size in MSDOSFS
Attached
Detach File
Event Timeline
Log In to Comment