diff options
author | mckusick <mckusick@FreeBSD.org> | 2012-06-09 22:26:53 +0000 |
---|---|---|
committer | mckusick <mckusick@FreeBSD.org> | 2012-06-09 22:26:53 +0000 |
commit | 070b3c041473a0ce18654dc5b1e1100d4b7896d2 (patch) | |
tree | d0832916f61477a3c6d7f67475b77a699821937a /sys/kern/vfs_default.c | |
parent | 7847bbf8a2150048a56126fdec1b5b3ae0c6df9f (diff) | |
download | FreeBSD-src-070b3c041473a0ce18654dc5b1e1100d4b7896d2.zip FreeBSD-src-070b3c041473a0ce18654dc5b1e1100d4b7896d2.tar.gz |
When synchronously syncing a device (MNT_WAIT), wait for buffers
to become available. Otherwise we may excessively spin and fail
with ``fsync: giving up on dirty''.
Reviewed by: kib
Tested by: Peter Holm
MFC after: 1 week
Diffstat (limited to 'sys/kern/vfs_default.c')
-rw-r--r-- | sys/kern/vfs_default.c | 13 |
1 files changed, 11 insertions, 2 deletions
diff --git a/sys/kern/vfs_default.c b/sys/kern/vfs_default.c index 91b30a8..b807db8 100644 --- a/sys/kern/vfs_default.c +++ b/sys/kern/vfs_default.c @@ -646,8 +646,17 @@ loop2: if ((bp->b_vflags & BV_SCANNED) != 0) continue; bp->b_vflags |= BV_SCANNED; - if (BUF_LOCK(bp, LK_EXCLUSIVE | LK_NOWAIT, NULL)) - continue; + if (BUF_LOCK(bp, LK_EXCLUSIVE | LK_NOWAIT, NULL)) { + if (ap->a_waitfor != MNT_WAIT) + continue; + if (BUF_LOCK(bp, + LK_EXCLUSIVE | LK_INTERLOCK | LK_SLEEPFAIL, + BO_MTX(bo)) != 0) { + BO_LOCK(bo); + goto loop1; + } + BO_LOCK(bo); + } BO_UNLOCK(bo); KASSERT(bp->b_bufobj == bo, ("bp %p wrong b_bufobj %p should be %p", |