@#$@#$ crap. I think I found a dirty-mmap edge case with truncation. It requires a change to vm_page_set_validclean(), which of course is one of the core routines in the VM system.
Basically what happens is that ftruncate() calls vnode_pager_setsize() which eventually calls vm_page_set_validclean(). If you happened to mmap() the truncation point shared R+W and dirty it, then truncate to something that isn't a multiple DEV_BSIZE.. for example, if you were to truncate to an offset of '10', and a buffer has not been instantiated or marked dirty for the block yet, then the truncate operation will clear the dirty bit on the page and your 10 bytes of dirty data will never get synced and will disappear if the page is freed. vm_page_set_validclean() needs to set the valid bits and clear the dirty bits associated with (base,size) within the page. If base and/or size is unaligned then the valid and dirty bits encompass the bits associated with any overlapping DEV_BSIZEd chunks. This is fine for setting valid, but not correct when clearing dirty. Only dirty bits for DEV_BSIZE chunks that are fully enclosed in the range can be cleared. The fix is easy, but a little scary due to being right smack in the middle of the VM system. -- In anycase, I think I got it licked. I'm going to run this nfs tester program overnight on a local filesystem, NFSv2, and NFSv3 mount. Cross your fingers! If it survives I'll start comitting to -current tomorrow. I give it about a 70% chance of surviving. -Matt To Unsubscribe: send mail to [EMAIL PROTECTED] with "unsubscribe freebsd-hackers" in the body of the message