diff options
author | dillon <dillon@FreeBSD.org> | 2000-12-30 23:32:24 +0000 |
---|---|---|
committer | dillon <dillon@FreeBSD.org> | 2000-12-30 23:32:24 +0000 |
commit | 41fd6873a8d4ace025f23279489d725279cab5ac (patch) | |
tree | 1649b2b51f1ca52cfa434945d1aef329a1ef61c3 /sys/fs/specfs | |
parent | 72cd3208b3c5a18d69cc4ff84ee418452d56324b (diff) | |
download | FreeBSD-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.c | 13 |
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) |