summaryrefslogtreecommitdiffstats
path: root/sys/fs/specfs
diff options
context:
space:
mode:
authordillon <dillon@FreeBSD.org>2000-12-30 23:32:24 +0000
committerdillon <dillon@FreeBSD.org>2000-12-30 23:32:24 +0000
commit41fd6873a8d4ace025f23279489d725279cab5ac (patch)
tree1649b2b51f1ca52cfa434945d1aef329a1ef61c3 /sys/fs/specfs
parent72cd3208b3c5a18d69cc4ff84ee418452d56324b (diff)
downloadFreeBSD-src-41fd6873a8d4ace025f23279489d725279cab5ac.zip
FreeBSD-src-41fd6873a8d4ace025f23279489d725279cab5ac.tar.gz
Fix a lockup problem that occurs with 'cvs update'. specfs's fsync can
get into the same sort of infinite loop that ffs's fsync used to get into, probably due to background bitmap writes. The solution is the same.
Diffstat (limited to 'sys/fs/specfs')
-rw-r--r--sys/fs/specfs/spec_vnops.c13
1 files changed, 13 insertions, 0 deletions
diff --git a/sys/fs/specfs/spec_vnops.c b/sys/fs/specfs/spec_vnops.c
index f3d7f11..ba46558 100644
--- a/sys/fs/specfs/spec_vnops.c
+++ b/sys/fs/specfs/spec_vnops.c
@@ -352,12 +352,25 @@ spec_fsync(ap)
return (0);
/*
+ * MARK/SCAN initialization to avoid infinite loops
+ */
+ s = splbio();
+ for (bp = TAILQ_FIRST(&vp->v_dirtyblkhd); bp;
+ bp = TAILQ_NEXT(bp, b_vnbufs)) {
+ bp->b_flags &= ~B_SCANNED;
+ }
+ splx(s);
+
+ /*
* Flush all dirty buffers associated with a block device.
*/
loop:
s = splbio();
for (bp = TAILQ_FIRST(&vp->v_dirtyblkhd); bp; bp = nbp) {
nbp = TAILQ_NEXT(bp, b_vnbufs);
+ if ((bp->b_flags & B_SCANNED) != 0)
+ continue;
+ bp->b_flags |= B_SCANNED;
if (BUF_LOCK(bp, LK_EXCLUSIVE | LK_NOWAIT))
continue;
if ((bp->b_flags & B_DELWRI) == 0)
OpenPOWER on IntegriCloud