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>