::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 
                                        <dil...@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 majord...@freebsd.org
with "unsubscribe freebsd-current" in the body of the message

Reply via email to