summaryrefslogtreecommitdiffstats
path: root/sys/ufs
diff options
context:
space:
mode:
authorscottl <scottl@FreeBSD.org>2014-04-15 07:54:17 +0000
committerscottl <scottl@FreeBSD.org>2014-04-15 07:54:17 +0000
commitd06a5364e17ff063e07e31b5fe45847341006157 (patch)
treec300ae58b3d8cd089b89f53985ba2c7b5a0dc993 /sys/ufs
parentc804ca5e7864982aa741bb5f6db7f746bf826790 (diff)
downloadFreeBSD-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.c12
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");
/*
OpenPOWER on IntegriCloud