Author: mckusick
Date: Fri Jan 26 18:17:11 2018
New Revision: 328444
URL: https://svnweb.freebsd.org/changeset/base/328444

Log:
  For many years the message "fsync: giving up on dirty" has occationally
  appeared on UFS/FFS filesystems. In some cases it was promptly followed
  by a panic of "softdep_deallocate_dependencies: dangling deps". This fix
  should eliminate both of these occurences.
  
  Submitted by: Andreas Longwitz <longwitz at incore.de>
  Reviewed by:  kib
  Tested by:    Peter Holm (pho)
  PR:           225423
  MFC after:    1 week

Modified:
  head/sys/kern/vfs_default.c

Modified: head/sys/kern/vfs_default.c
==============================================================================
--- head/sys/kern/vfs_default.c Fri Jan 26 17:56:20 2018        (r328443)
+++ head/sys/kern/vfs_default.c Fri Jan 26 18:17:11 2018        (r328444)
@@ -631,13 +631,21 @@ vop_stdfsync(ap)
                struct thread *a_td;
        } */ *ap;
 {
-       struct vnode *vp = ap->a_vp;
-       struct buf *bp;
+       struct vnode *vp;
+       struct buf *bp, *nbp;
        struct bufobj *bo;
-       struct buf *nbp;
-       int error = 0;
-       int maxretry = 1000;     /* large, arbitrarily chosen */
+       struct mount *mp;
+       int error, maxretry;
 
+       error = 0;
+       maxretry = 10000;     /* large, arbitrarily chosen */
+       vp = ap->a_vp;
+       mp = NULL;
+       if (vp->v_type == VCHR) {
+               VI_LOCK(vp);
+               mp = vp->v_rdev->si_mountpt;
+               VI_UNLOCK(vp);
+       }
        bo = &vp->v_bufobj;
        BO_LOCK(bo);
 loop1:
@@ -680,6 +688,8 @@ loop2:
                        bremfree(bp);
                        bawrite(bp);
                }
+               if (maxretry < 1000)
+                       pause("dirty", hz < 1000 ? 1 : hz / 1000);
                BO_LOCK(bo);
                goto loop2;
        }
@@ -701,7 +711,8 @@ loop2:
                        TAILQ_FOREACH(bp, &bo->bo_dirty.bv_hd, b_bobufs)
                                if ((error = bp->b_error) != 0)
                                        break;
-                       if (error == 0 && --maxretry >= 0)
+                       if ((mp != NULL && mp->mnt_secondary_writes > 0) ||
+                           (error == 0 && --maxretry >= 0))
                                goto loop1;
                        error = EAGAIN;
                }
_______________________________________________
svn-src-all@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to