summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMatthew Dillon <dillon@FreeBSD.org>2001-01-29 08:19:28 +0000
committerMatthew Dillon <dillon@FreeBSD.org>2001-01-29 08:19:28 +0000
commit2a9737202a796c0433107731c76fa72d031db7bb (patch)
tree0147f3b748423c26e2fe284e70d74ba5077d6b77
parent52a90b77f903ba63ca499997038088085019dfee (diff)
Notes
-rw-r--r--sys/fs/specfs/spec_vnops.c23
-rw-r--r--sys/miscfs/specfs/spec_vnops.c23
2 files changed, 32 insertions, 14 deletions
diff --git a/sys/fs/specfs/spec_vnops.c b/sys/fs/specfs/spec_vnops.c
index ba4655852c7a..6b33df4777f9 100644
--- a/sys/fs/specfs/spec_vnops.c
+++ b/sys/fs/specfs/spec_vnops.c
@@ -347,10 +347,12 @@ spec_fsync(ap)
struct buf *bp;
struct buf *nbp;
int s;
+ int maxretry = 10000; /* large, arbitrarily chosen */
if (!vn_isdisk(vp, NULL))
return (0);
+loop1:
/*
* MARK/SCAN initialization to avoid infinite loops
*/
@@ -364,7 +366,7 @@ spec_fsync(ap)
/*
* Flush all dirty buffers associated with a block device.
*/
-loop:
+loop2:
s = splbio();
for (bp = TAILQ_FIRST(&vp->v_dirtyblkhd); bp; bp = nbp) {
nbp = TAILQ_NEXT(bp, b_vnbufs);
@@ -384,20 +386,27 @@ loop:
splx(s);
bawrite(bp);
}
- goto loop;
+ goto loop2;
}
+
+ /*
+ * If synchronous the caller expects us to completely resolve all
+ * dirty buffers in the system. Wait for in-progress I/O to
+ * complete (which could include background bitmap writes), then
+ * retry if dirty blocks still exist.
+ */
if (ap->a_waitfor == MNT_WAIT) {
while (vp->v_numoutput) {
vp->v_flag |= VBWAIT;
(void) tsleep((caddr_t)&vp->v_numoutput, PRIBIO + 1, "spfsyn", 0);
}
-#ifdef DIAGNOSTIC
if (!TAILQ_EMPTY(&vp->v_dirtyblkhd)) {
- vprint("spec_fsync: dirty", vp);
- splx(s);
- goto loop;
+ if (--maxretry != 0) {
+ splx(s);
+ goto loop1;
+ }
+ vprint("spec_fsync: giving up on dirty", vp);
}
-#endif
}
splx(s);
return (0);
diff --git a/sys/miscfs/specfs/spec_vnops.c b/sys/miscfs/specfs/spec_vnops.c
index ba4655852c7a..6b33df4777f9 100644
--- a/sys/miscfs/specfs/spec_vnops.c
+++ b/sys/miscfs/specfs/spec_vnops.c
@@ -347,10 +347,12 @@ spec_fsync(ap)
struct buf *bp;
struct buf *nbp;
int s;
+ int maxretry = 10000; /* large, arbitrarily chosen */
if (!vn_isdisk(vp, NULL))
return (0);
+loop1:
/*
* MARK/SCAN initialization to avoid infinite loops
*/
@@ -364,7 +366,7 @@ spec_fsync(ap)
/*
* Flush all dirty buffers associated with a block device.
*/
-loop:
+loop2:
s = splbio();
for (bp = TAILQ_FIRST(&vp->v_dirtyblkhd); bp; bp = nbp) {
nbp = TAILQ_NEXT(bp, b_vnbufs);
@@ -384,20 +386,27 @@ loop:
splx(s);
bawrite(bp);
}
- goto loop;
+ goto loop2;
}
+
+ /*
+ * If synchronous the caller expects us to completely resolve all
+ * dirty buffers in the system. Wait for in-progress I/O to
+ * complete (which could include background bitmap writes), then
+ * retry if dirty blocks still exist.
+ */
if (ap->a_waitfor == MNT_WAIT) {
while (vp->v_numoutput) {
vp->v_flag |= VBWAIT;
(void) tsleep((caddr_t)&vp->v_numoutput, PRIBIO + 1, "spfsyn", 0);
}
-#ifdef DIAGNOSTIC
if (!TAILQ_EMPTY(&vp->v_dirtyblkhd)) {
- vprint("spec_fsync: dirty", vp);
- splx(s);
- goto loop;
+ if (--maxretry != 0) {
+ splx(s);
+ goto loop1;
+ }
+ vprint("spec_fsync: giving up on dirty", vp);
}
-#endif
}
splx(s);
return (0);