Try this. In nfs_bioread(), nfs/nfs_bio.c:
Before, it was:
if (getpages && !(bp->b_flags & B_VMIO)) {
#ifdef DIAGNOSTIC
printf("nfs_bioread: non vmio buf found, discarding\n");
Try changin the if() to this:
if (
(getpages && !(bp->b_flags & B_VMIO)) ||
(bp->b_flags & (B_CACHE|B_DELWRI)) == B_DELWRI
) {
#ifdef DIAGNOSTIC
printf("nfs_bioread: non vmio buf found, discarding\n");
#endif
I believe what is going on is that bioread() is misinterpreting B_CACHE
to mean that it can discard the entire buffer. If B_DELWRI is set,
however, it must sync the buffer first.
What is occuring is that when a program write()'s non-contiguously and
then lseek's back and read()'s again, B_CACHE is getting cleared and the
buffer is being re-read from NFS without first being flushed to NFS,
causing the written data to be overwritten by the read.
I have NOT tested this well. It seems to solve the vi SEG fault problem.
-Matt
Matthew Dillon
<[email protected]>
To Unsubscribe: send mail to [email protected]
with "unsubscribe freebsd-current" in the body of the message