summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sys/fs/specfs/spec_vnops.c13
-rw-r--r--sys/miscfs/specfs/spec_vnops.c13
2 files changed, 26 insertions, 0 deletions
diff --git a/sys/fs/specfs/spec_vnops.c b/sys/fs/specfs/spec_vnops.c
index f3d7f11f0644..ba4655852c7a 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)
diff --git a/sys/miscfs/specfs/spec_vnops.c b/sys/miscfs/specfs/spec_vnops.c
index f3d7f11f0644..ba4655852c7a 100644
--- a/sys/miscfs/specfs/spec_vnops.c
+++ b/sys/miscfs/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)