aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKirk McKusick <mckusick@FreeBSD.org>2018-01-26 18:17:11 +0000
committerKirk McKusick <mckusick@FreeBSD.org>2018-01-26 18:17:11 +0000
commit4d93711d80f6ccbec7269d8ad117ac47b459d426 (patch)
treebde79781bd2571d3f8499504a67091cacecec455
parent919cf86c871a6f98fe3174189571bdb07f012950 (diff)
downloadsrc-4d93711d80f6ccbec7269d8ad117ac47b459d426.tar.gz
src-4d93711d80f6ccbec7269d8ad117ac47b459d426.zip
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
Notes
Notes: svn path=/head/; revision=328444
-rw-r--r--sys/kern/vfs_default.c23
1 files changed, 17 insertions, 6 deletions
diff --git a/sys/kern/vfs_default.c b/sys/kern/vfs_default.c
index 734c2f2e6011..d09e0d91b96f 100644
--- a/sys/kern/vfs_default.c
+++ b/sys/kern/vfs_default.c
@@ -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;
}