- 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.

Reported by:	pho
Discussed with:	mckusick
Sponsored by:	EMC / Isilon Storage Division
MFC after:	2 weeks
This commit is contained in:
Jeff Roberson 2014-03-06 00:13:21 +00:00
parent c13a58b022
commit 4803948fe2
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=262814

View File

@ -259,9 +259,17 @@ ffs_syncvnode(struct vnode *vp, int waitfor, int flags)
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");
/*