Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 12 Apr 1999 14:24:07 -0700 (PDT)
From:      Matthew Dillon <dillon@apollo.backplane.com>
To:        Matthew Jacob <mjacob@feral.com>
Cc:        freebsd-current@FreeBSD.ORG
Subject:   Re: we still have NFS problems in -current?
Message-ID:  <199904122124.OAA07023@apollo.backplane.com>
References:   <Pine.LNX.4.04.9904121358300.24401-100000@feral-gw>

next in thread | previous in thread | raw e-mail | index | archive | help
:> 
:>     I found it.  The problem was introduced when we committed the
:>     mmap() zero-invalid-areas patch.  !@#$@#$#$%#%#@%@#%#@  NFS is such
:>     a fragile piece of junk!
:
:Why do you say that? :-)

    What it come down to is that due to the way m->valid is set, it is possible
    for mmap() to believe that a page is entirely valid when, in fact, it
    isn't, because partial NFS I/O must set the valid and dirty bits in the
    vm_page_t 'inclusively'.

    So, for example, if a page contains valid data from offsets 130-4095,
    vm_page_t->valid will still be VM_PAGE_BITS_ALL ( 0xFF ) rather then 0xFE.

    This causes mmap() to believe that the page is entirely valid when it
    isn't.

    Before we zerod out invalid areas the 'stale' data from a prior partial
    write, e.g. say a write from offset 0 through 120, would stick around in
    the buffer.  Hence, no crash.

    Now the data doesn't necessarily stick around.  The write is committed,
    the valid bit is clear, the new write to offsets 130-4095 sets the valid
    bits again and clears the 'stale' data.

    I'm working on a patch.  Sigh.  I think we may have to implement a
    'completely valid' flag for vm_page_t rather then depend on comparing
    m->valid against VM_PAGE_BITS_ALL.  What a mess.

    For now, turn off the mmap zeroing fix.  The patch is included below.

					-Matt
					Matthew Dillon 
					<dillon@backplane.com>



Index: vm/vm_page.c
===================================================================
RCS file: /home/ncvs/src/sys/vm/vm_page.c,v
retrieving revision 1.129
diff -u -r1.129 vm_page.c
--- vm_page.c	1999/04/05 19:38:29	1.129
+++ vm_page.c	1999/04/12 21:22:28
@@ -1491,11 +1491,13 @@
 	if ((frag = base & ~(DEV_BSIZE - 1)) != base &&
 	    (m->valid & (1 << (base >> DEV_BSHIFT))) == 0
 	) {
+#if 0
 		pmap_zero_page_area(
 		    VM_PAGE_TO_PHYS(m),
 		    frag,
 		    base - frag
 		);
+#endif
 	}
 
 	/*
@@ -1509,11 +1511,13 @@
 	if ((frag = endoff & ~(DEV_BSIZE - 1)) != endoff &&
 	    (m->valid & (1 << (endoff >> DEV_BSHIFT))) == 0
 	) {
+#if 0
 		pmap_zero_page_area(
 		    VM_PAGE_TO_PHYS(m),
 		    endoff,
 		    DEV_BSIZE - (endoff & (DEV_BSIZE - 1))
 		);
+#endif
 	}
 
 	/*


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?199904122124.OAA07023>