svn commit: r248563 - head/sys/kern

Konstantin Belousov kib at FreeBSD.org
Wed Mar 20 21:08:01 UTC 2013


Author: kib
Date: Wed Mar 20 21:08:00 2013
New Revision: 248563
URL: http://svnweb.freebsd.org/changeset/base/248563

Log:
  In bufwrite(), a dirty buffer is moved to the clean queue before the
  bufobj counter of the writes in progress is incremented.  Other thread
  inspecting the bufobj would consider it clean.
  
  For the regular vnodes, the vnode lock is typically held both by the
  thread performing the bufwrite() and an other thread doing syncing,
  which prevents the situation.  On the other hand, writes to the VCHR
  vnodes are done without holding vnode lock.
  
  Increment the write ref counter for the buffer object before calling
  bundirty().
  
  Sponsored by:	The FreeBSD Foundation
  Tested by:	pho
  MFC after:	2 weeks

Modified:
  head/sys/kern/vfs_bio.c

Modified: head/sys/kern/vfs_bio.c
==============================================================================
--- head/sys/kern/vfs_bio.c	Wed Mar 20 21:07:49 2013	(r248562)
+++ head/sys/kern/vfs_bio.c	Wed Mar 20 21:08:00 2013	(r248563)
@@ -1044,7 +1044,13 @@ bufwrite(struct buf *bp)
 	else
 		vp_md = 0;
 
-	/* Mark the buffer clean */
+	/*
+	 * Mark the buffer clean.  Increment the bufobj write count
+	 * before bundirty() call, to prevent other thread from seeing
+	 * empty dirty list and zero counter for writes in progress,
+	 * falsely indicating that the bufobj is clean.
+	 */
+	bufobj_wref(bp->b_bufobj);
 	bundirty(bp);
 
 	bp->b_flags &= ~B_DONE;
@@ -1052,7 +1058,6 @@ bufwrite(struct buf *bp)
 	bp->b_flags |= B_CACHE;
 	bp->b_iocmd = BIO_WRITE;
 
-	bufobj_wref(bp->b_bufobj);
 	vfs_busy_pages(bp, 1);
 
 	/*


More information about the svn-src-all mailing list