From owner-freebsd-current Mon Apr 12 14:26:32 1999 Delivered-To: freebsd-current@freebsd.org Received: from apollo.backplane.com (apollo.backplane.com [209.157.86.2]) by hub.freebsd.org (Postfix) with ESMTP id 2A2111562F for ; Mon, 12 Apr 1999 14:26:29 -0700 (PDT) (envelope-from dillon@apollo.backplane.com) Received: (from dillon@localhost) by apollo.backplane.com (8.9.3/8.9.1) id OAA07023; Mon, 12 Apr 1999 14:24:07 -0700 (PDT) (envelope-from dillon) Date: Mon, 12 Apr 1999 14:24:07 -0700 (PDT) From: Matthew Dillon Message-Id: <199904122124.OAA07023@apollo.backplane.com> To: Matthew Jacob Cc: freebsd-current@FreeBSD.ORG Subject: Re: we still have NFS problems in -current? References: Sender: owner-freebsd-current@FreeBSD.ORG Precedence: bulk X-Loop: FreeBSD.ORG :> :> 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 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