Date: Mon, 18 Jan 1999 05:36:36 -0800 (PST) From: Matthew Dillon <dillon@apollo.backplane.com> To: Chris Timmons <skynyrd@opus.cts.cwu.edu> Cc: freebsd-current@FreeBSD.ORG, John Polstra <jdp@polstra.com>, luoqi@FreeBSD.ORG Subject: NFS problem found - pleaes try this patch. Message-ID: <199901181336.FAA72182@apollo.backplane.com> References: <Pine.BSF.3.96.990117214309.11293A-100000@opus.cts.cwu.edu> <199901180800.AAA58279@apollo.backplane.com>
next in thread | previous in thread | raw e-mail | index | archive | help
::On the server I downgraded vfs_bio.c to rev 1.187 & rebooted; no luck. I
::then installed the same kernel (with the downgraded vfs_bio.c) to the
::client. Bingo. With both NFS client & server machine running rev 1.187,
::...
::-Chris
:
: Hmm. r1.88 are Luoqi's fixes to the handling of misaligned buffers. It is
: quite possible that there is a bug in there or with assumptions made in
: the NFS code in regards to how buffers are handled, but most of those
:...
: -Matt
Ok, I believe I have found the bug. Please test the patch included below.
I was able to make /usr/ports/x11/XFree86-contrib after applying this
patch ( and it was screwing up prior to that ).
The problem is in getblk() - code was added to validate the buffer and
to clear B_CACHE if the bp was not entirely valid. The problem is
that NFS uses B_CACHE to flag a dirty buffer that needs to be written out!
Additionally, a write() to an NFS based file may write data that is not
on a DEV_BSIZE'd boundry which causes a subsequent read() to improperly
clear B_CACHE.
There are almost certainly more problems like this -- using B_CACHE to
mark a buffer dirty is just plain dumb, it's no wonder NFS is so screwed
up!
-Matt
Matthew Dillon
<dillon@backplane.com>
Index: kern/vfs_bio.c
===================================================================
RCS file: /home/ncvs/src/sys/kern/vfs_bio.c,v
retrieving revision 1.192
diff -u -r1.192 vfs_bio.c
--- vfs_bio.c 1999/01/12 11:59:34 1.192
+++ vfs_bio.c 1999/01/18 13:25:27
@@ -1364,6 +1364,7 @@
break;
}
}
+
boffset = (i << PAGE_SHIFT) - (bp->b_offset & PAGE_MASK);
if (boffset < bp->b_dirtyoff) {
bp->b_dirtyoff = max(boffset, 0);
@@ -1457,7 +1458,14 @@
}
KASSERT(bp->b_offset != NOOFFSET,
("getblk: no buffer offset"));
+#if 0
/*
+ * XXX REMOVED XXX - this is bogus. It will cause the
+ * B_CACHE flag to be cleared for a partially constituted
+ * dirty buffer (NFS) that happens to have a write that is
+ * not on a DEV_BSIZE boundry!!!!!! XXX REMOVED XXXX
+ */
+ /*
* Check that the constituted buffer really deserves for the
* B_CACHE bit to be set. B_VMIO type buffers might not
* contain fully valid pages. Normal (old-style) buffers
@@ -1478,6 +1486,7 @@
poffset = 0;
}
}
+#endif
if (bp->b_usecount < BUF_MAXUSE)
++bp->b_usecount;
To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-current" in the body of the message
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?199901181336.FAA72182>
