Author: kib Date: Thu Sep 5 12:56:08 2013 New Revision: 255245 URL: http://svnweb.freebsd.org/changeset/base/255245
Log: The vm_pageout_flush() functions sbusies pages in the passed pages run. After that, the pager put method is called, usually translated to VOP_WRITE(). For the filesystems which use buffer cache, bufwrite() sbusies the buffer pages again, waiting for the xbusy state to drain. The later is done in vfs_drain_busy_pages(), which is called with the buffer pages already sbusied (by vm_pageout_flush()). Since vfs_drain_busy_pages() can only wait for one page at the time, and during the wait, the object lock is dropped, previous pages in the buffer must be protected from other threads busying them. Up to the moment, it was done by xbusying the pages, that is incompatible with the sbusy state in the new implementation of busy. Switch to sbusy. Reported and tested by: pho Sponsored by: The FreeBSD Foundation Modified: head/sys/kern/vfs_bio.c Modified: head/sys/kern/vfs_bio.c ============================================================================== --- head/sys/kern/vfs_bio.c Thu Sep 5 12:54:40 2013 (r255244) +++ head/sys/kern/vfs_bio.c Thu Sep 5 12:56:08 2013 (r255245) @@ -3994,7 +3994,7 @@ vfs_drain_busy_pages(struct buf *bp) m = bp->b_pages[i]; if (vm_page_xbusied(m)) { for (; last_busied < i; last_busied++) - vm_page_xbusy(bp->b_pages[last_busied]); + vm_page_sbusy(bp->b_pages[last_busied]); while (vm_page_xbusied(m)) { vm_page_lock(m); VM_OBJECT_WUNLOCK(bp->b_bufobj->bo_object); @@ -4004,7 +4004,7 @@ vfs_drain_busy_pages(struct buf *bp) } } for (i = 0; i < last_busied; i++) - vm_page_xunbusy(bp->b_pages[i]); + vm_page_sunbusy(bp->b_pages[i]); } /* _______________________________________________ svn-src-head@freebsd.org mailing list http://lists.freebsd.org/mailman/listinfo/svn-src-head To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"