A bug in specfs's fsync dating back to Kirk's original softupdates work 
    ( which required a similar mark/scan fix to the FFS fsync ) appears to 
    have been exposed by recent pageout peformance commits I made.

    I've committed a mark/scan fix to specfs's fsync, which appears
    to solve the lockups Poul was getting doing a 'cvs update -PdA' under
    -current.  It should solve the problem for the other two people who
    reported the same lockup.

    I'm not sure why -stable isn't affected.  The bug is in -stable as well.
    I'll MFC it in two days unless I see complaints sooner.  It's a simple
    bug fix.

    At some point I need to go through all the fsync implementations...
    they need the same sort of placemarker fix that I threw into the
    pageout daemon scan.  The current code uses the 'goto loop' hack, which
    is terribly inefficient when combined with a heavily loaded 
    softupdates-enabled system.

                                        -Matt


Index: spec_vnops.c
===================================================================
RCS file: /home/ncvs/src/sys/miscfs/specfs/spec_vnops.c,v
retrieving revision 1.147
retrieving revision 1.148
diff -u -r1.147 -r1.148
--- spec_vnops.c        2000/12/26 19:41:37     1.147
+++ spec_vnops.c        2000/12/30 23:32:24     1.148
@@ -31,7 +31,7 @@
  * SUCH DAMAGE.
  *
  *     @(#)spec_vnops.c        8.14 (Berkeley) 5/21/95
- * $FreeBSD: src/sys/miscfs/specfs/spec_vnops.c,v 1.147 2000/12/26 19:41:37 dillon 
Exp $
+ * $FreeBSD: src/sys/miscfs/specfs/spec_vnops.c,v 1.148 2000/12/30 23:32:24 dillon 
+Exp $
  */
 
 #include <sys/param.h>
@@ -352,12 +352,25 @@
                return (0);
 
        /*
+        * MARK/SCAN initialization to avoid infinite loops
+        */
+       s = splbio();
+        for (bp = TAILQ_FIRST(&vp->v_dirtyblkhd); bp;
+             bp = TAILQ_NEXT(bp, b_vnbufs)) {
+                bp->b_flags &= ~B_SCANNED;
+       }
+       splx(s);
+
+       /*
         * Flush all dirty buffers associated with a block device.
         */
 loop:
        s = splbio();
        for (bp = TAILQ_FIRST(&vp->v_dirtyblkhd); bp; bp = nbp) {
                nbp = TAILQ_NEXT(bp, b_vnbufs);
+               if ((bp->b_flags & B_SCANNED) != 0)
+                       continue;
+               bp->b_flags |= B_SCANNED;
                if (BUF_LOCK(bp, LK_EXCLUSIVE | LK_NOWAIT))
                        continue;
                if ((bp->b_flags & B_DELWRI) == 0)


To Unsubscribe: send mail to [EMAIL PROTECTED]
with "unsubscribe freebsd-current" in the body of the message

Reply via email to