: (taking hackers off to reduce noise) oops. I guess I didn't take it off hackers. Sorry about that.
Yah yah, I know, 'Matt's making a billion postings again'. In anycase, I sent a patch set to Stephan and julian, and since I didn't take it off the list like I said I would I guess I might as well post the patch set and the revised test program too for anyone following along. Note that the patch set is against DragonFly, but should easily patch into 4.x. Stephan and Julian will deal with 4.xisms and 5.xisms. The idea with the fix is as follows: * It's hard to make the VM system invalidate buffers, so don't try. Instead, make UFS recognize the IO_INVAL ioflag and mark the buffer appropriately in the putpages -> generic put pages -> VOP_WRITE() path. This only occurs if the msync'd map was writable. If the msync'd map was only readable, then the data is not flushed through the vnode system and the pages will not be removed if there happens to be a buffer associated with them, even if the buffer is clean. I think this is reasonable. Not perfect, but reasonable. * Set clean_only to TRUE when calling vm_object_page_remove(), which causes vm_object_page_remove() to ignore wired or dirty pages. This code is called for both readable and writable maps so we can't just remove the page unconditionallty, hence clean_only should be set to TRUE. This means that any pages associated with the buffer cache will NOT be removed if the map was read-only. If the map was writable, then the IO_INVAL fix above will destroy the buffer and the page should wind up not being wired any more, and thus will be properly removed. That's it! -Matt /* * y.c */ #include <sys/types.h> #include <sys/mman.h> #include <stdio.h> #include <unistd.h> #include <fcntl.h> int main(int ac, char **av) { int fd; char *ptr1; char *ptr2; char buf[4096]; fd = open("test.dat", O_RDWR|O_CREAT|O_TRUNC, 0666); ftruncate(fd, 4096); ptr1 = mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0); *ptr1 = 'A'; read(fd, buf, 4096); ptr2 = mmap(NULL, 4096, PROT_READ, MAP_SHARED, fd, 0); if (msync(ptr1, 4096, MS_INVALIDATE | MS_SYNC) < 0) perror("msync"); sleep(4); printf("contents of *ptr1 is %d\n", *ptr1); printf("contents of *ptr2 is %d\n", *ptr2); return(0); } Index: vm/vm_map.c =================================================================== RCS file: /cvs/src/sys/vm/vm_map.c,v retrieving revision 1.24 diff -u -r1.24 vm_map.c --- vm/vm_map.c 23 Mar 2004 22:54:32 -0000 1.24 +++ vm/vm_map.c 23 Apr 2004 02:56:17 -0000 @@ -2212,7 +2212,7 @@ vm_object_page_remove(object, OFF_TO_IDX(offset), OFF_TO_IDX(offset + size + PAGE_MASK), - FALSE); + TRUE); vm_object_deallocate(object); } start += size; Index: vfs/ufs/ufs_readwrite.c =================================================================== RCS file: /cvs/src/sys/vfs/ufs/ufs_readwrite.c,v retrieving revision 1.9 diff -u -r1.9 ufs_readwrite.c --- vfs/ufs/ufs_readwrite.c 26 Jul 2003 22:04:27 -0000 1.9 +++ vfs/ufs/ufs_readwrite.c 23 Apr 2004 03:05:50 -0000 @@ -531,6 +531,8 @@ bp->b_flags |= B_DIRECT; if (ioflag & IO_NOWDRAIN) bp->b_flags |= B_NOWDRAIN; + if ((ioflag & (IO_SYNC|IO_INVAL)) == (IO_SYNC|IO_INVAL)) + bp->b_flags |= B_NOCACHE; if (uio->uio_offset + xfersize > ip->i_size) { ip->i_size = uio->uio_offset + xfersize; _______________________________________________ [EMAIL PROTECTED] mailing list http://lists.freebsd.org/mailman/listinfo/freebsd-hackers To unsubscribe, send any mail to "[EMAIL PROTECTED]"