summaryrefslogtreecommitdiffstats
path: root/sys/kern/vfs_default.c
diff options
context:
space:
mode:
authormckusick <mckusick@FreeBSD.org>2012-06-09 22:26:53 +0000
committermckusick <mckusick@FreeBSD.org>2012-06-09 22:26:53 +0000
commit070b3c041473a0ce18654dc5b1e1100d4b7896d2 (patch)
treed0832916f61477a3c6d7f67475b77a699821937a /sys/kern/vfs_default.c
parent7847bbf8a2150048a56126fdec1b5b3ae0c6df9f (diff)
downloadFreeBSD-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.c13
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",
OpenPOWER on IntegriCloud