Revise and improve ntfs_subr.c 1.30: read only a single cluster at a time

in ntfs_writentvattr_plain and ntfs_readntvattr_plain, and purge the boot
block from the buffer cache if isn't exactly one cluster long. These two
changes work around the same buffer cache bug that ntfs_subr.c 1.30 tried
to, but in a different way. This may decrease throughput by reading smaller
amounts of data from the disk at a time, but may increase it by avoiding
bogus writes of clean buffers.
Problem (re)reported by Karel J. Bosschaart on -current.
This commit is contained in:
tjr 2003-07-26 02:21:49 +00:00
parent 3c92e21eeb
commit 7abd31ac6d
2 changed files with 28 additions and 17 deletions

View File

@ -1442,9 +1442,16 @@ ntfs_writentvattr_plain(
off = ntfs_btocnoff(off);
while (left && ccl) {
tocopy = min(left,
min(ntfs_cntob(ccl) - off, MAXBSIZE - off));
/*
* Always read and write single clusters at a time -
* we need to avoid requesting differently-sized
* blocks at the same disk offsets to avoid
* confusing the buffer cache.
*/
tocopy = min(left, ntfs_cntob(1) - off);
cl = ntfs_btocl(tocopy + off);
KASSERT(cl == 1 && tocopy <= ntfs_cntob(1),
("single cluster limit mistake"));
ddprintf(("ntfs_writentvattr_plain: write: " \
"cn: 0x%x cl: %d, off: %d len: %d, left: %d\n",
(u_int32_t) cn, (u_int32_t) cl,
@ -1540,23 +1547,19 @@ ntfs_readntvattr_plain(
off = ntfs_btocnoff(off);
while (left && ccl) {
tocopy = min(left,
min(ntfs_cntob(ccl) - off,
MAXBSIZE - off));
cl = ntfs_btocl(tocopy + off);
/*
* If 'off' pushes us to next
* block, don't attempt to read whole
* 'tocopy' at once. This is to avoid
* bread() with varying 'size' for
* same 'blkno', which is not good.
* Always read single clusters at a
* time - we need to avoid reading
* differently-sized blocks at the
* same disk offsets to avoid
* confusing the buffer cache.
*/
if (cl > ntfs_btocl(tocopy)) {
tocopy -=
ntfs_btocnoff(tocopy + off);
cl--;
}
tocopy = min(left,
ntfs_cntob(1) - off);
cl = ntfs_btocl(tocopy + off);
KASSERT(cl == 1 &&
tocopy <= ntfs_cntob(1),
("single cluster limit mistake"));
ddprintf(("ntfs_readntvattr_plain: " \
"read: cn: 0x%x cl: %d, " \

View File

@ -311,6 +311,14 @@ ntfs_mountfs(devvp, mp, argsp, td)
goto out;
ntmp = malloc( sizeof *ntmp, M_NTFSMNT, M_WAITOK | M_ZERO);
bcopy( bp->b_data, &ntmp->ntm_bootfile, sizeof(struct bootfile) );
/*
* We must not cache the boot block if its size is not exactly
* one cluster in order to avoid confusing the buffer cache when
* the boot file is read later by ntfs_readntvattr_plain(), which
* reads a cluster at a time.
*/
if (ntfs_cntob(1) != BBSIZE)
bp->b_flags |= B_NOCACHE;
brelse( bp );
bp = NULL;