Date: Mon, 18 Jan 1999 06:17:32 -0800 (PST) From: Chris Timmons <skynyrd@opus.cts.cwu.edu> To: Matthew Dillon <dillon@apollo.backplane.com> Cc: freebsd-current@FreeBSD.ORG, John Polstra <jdp@polstra.com>, luoqi@FreeBSD.ORG Subject: Re: NFS problem found - pleaes try this patch. Message-ID: <Pine.BSF.3.96.990118061551.29878C-100000@opus.cts.cwu.edu> In-Reply-To: <199901181336.FAA72182@apollo.backplane.com>
next in thread | previous in thread | raw e-mail | index | archive | help
Good work! I have to run at the moment but it looks like you nailed this
one. Your explanation coincides perfectly with the symptoms.
Thanks!
-Chris
On Mon, 18 Jan 1999, Matthew Dillon wrote:
> 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?Pine.BSF.3.96.990118061551.29878C-100000>
