Author: kib
Date: Sun Sep 22 19:23:48 2013
New Revision: 255797
URL: http://svnweb.freebsd.org/changeset/base/255797

Log:
  Increase the chance of the buffer write from the bufdaemon helper
  context to succeed.  If the locked vnode which owns the buffer to be
  written is shared locked, try the non-blocking upgrade of the lock to
  exclusive.
  
  PR:   kern/178997
  Reported and tested by:       Klaus Weber <[email protected]>
  Sponsored by: The FreeBSD Foundation
  MFC after:    1 week
  Approved by:  re (marius)

Modified:
  head/sys/kern/vfs_bio.c

Modified: head/sys/kern/vfs_bio.c
==============================================================================
--- head/sys/kern/vfs_bio.c     Sun Sep 22 19:15:24 2013        (r255796)
+++ head/sys/kern/vfs_bio.c     Sun Sep 22 19:23:48 2013        (r255797)
@@ -2624,6 +2624,8 @@ flushbufqueues(struct vnode *lvp, int ta
        int hasdeps;
        int flushed;
        int queue;
+       int error;
+       bool unlock;
 
        flushed = 0;
        queue = QUEUE_DIRTY;
@@ -2699,7 +2701,16 @@ flushbufqueues(struct vnode *lvp, int ta
                        BUF_UNLOCK(bp);
                        continue;
                }
-               if (vn_lock(vp, LK_EXCLUSIVE | LK_NOWAIT | LK_CANRECURSE) == 0) 
{
+               if (lvp == NULL) {
+                       unlock = true;
+                       error = vn_lock(vp, LK_EXCLUSIVE | LK_NOWAIT);
+               } else {
+                       ASSERT_VOP_LOCKED(vp, "getbuf");
+                       unlock = false;
+                       error = VOP_ISLOCKED(vp) == LK_EXCLUSIVE ? 0 :
+                           vn_lock(vp, LK_UPGRADE | LK_NOWAIT);
+               }
+               if (error == 0) {
                        mtx_unlock(&bqdirty);
                        CTR3(KTR_BUF, "flushbufqueue(%p) vp %p flags %X",
                            bp, bp->b_vp, bp->b_flags);
@@ -2711,7 +2722,8 @@ flushbufqueues(struct vnode *lvp, int ta
                                notbufdflushes++;
                        }
                        vn_finished_write(mp);
-                       VOP_UNLOCK(vp, 0);
+                       if (unlock)
+                               VOP_UNLOCK(vp, 0);
                        flushwithdeps += hasdeps;
                        flushed++;
 
_______________________________________________
[email protected] mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "[email protected]"

Reply via email to