diff options
author | scottl <scottl@FreeBSD.org> | 2014-04-15 07:54:17 +0000 |
---|---|---|
committer | scottl <scottl@FreeBSD.org> | 2014-04-15 07:54:17 +0000 |
commit | d06a5364e17ff063e07e31b5fe45847341006157 (patch) | |
tree | c300ae58b3d8cd089b89f53985ba2c7b5a0dc993 /sys/ufs | |
parent | c804ca5e7864982aa741bb5f6db7f746bf826790 (diff) | |
download | FreeBSD-src-d06a5364e17ff063e07e31b5fe45847341006157.zip FreeBSD-src-d06a5364e17ff063e07e31b5fe45847341006157.tar.gz |
MFC r262814
- If we fail to do a non-blocking acquire of a buf lock while doing a
waiting sync pass we need to do a blocking acquire and restart.
Another thread, typically the buf daemon, may have this buf locked and
if we don't wait we can fail to sync the file. This lead to a great
variety of softdep panics because we rely on all dependencies being
flushed before proceeding in several cases.
Submitted by: jeffr
Diffstat (limited to 'sys/ufs')
-rw-r--r-- | sys/ufs/ffs/ffs_vnops.c | 12 |
1 files changed, 10 insertions, 2 deletions
diff --git a/sys/ufs/ffs/ffs_vnops.c b/sys/ufs/ffs/ffs_vnops.c index a498587..423d811 100644 --- a/sys/ufs/ffs/ffs_vnops.c +++ b/sys/ufs/ffs/ffs_vnops.c @@ -259,9 +259,17 @@ loop: continue; if (bp->b_lblkno > lbn) panic("ffs_syncvnode: syncing truncated data."); - if (BUF_LOCK(bp, LK_EXCLUSIVE | LK_NOWAIT, NULL)) + if (BUF_LOCK(bp, LK_EXCLUSIVE | LK_NOWAIT, NULL) == 0) { + BO_UNLOCK(bo); + } else if (wait != 0) { + if (BUF_LOCK(bp, + LK_EXCLUSIVE | LK_SLEEPFAIL | LK_INTERLOCK, + BO_LOCKPTR(bo)) != 0) { + bp->b_vflags &= ~BV_SCANNED; + goto next; + } + } else continue; - BO_UNLOCK(bo); if ((bp->b_flags & B_DELWRI) == 0) panic("ffs_fsync: not dirty"); /* |