summaryrefslogtreecommitdiffstats
path: root/sys/fs
diff options
context:
space:
mode:
authorjeff <jeff@FreeBSD.org>2003-02-09 11:28:35 +0000
committerjeff <jeff@FreeBSD.org>2003-02-09 11:28:35 +0000
commit87e306ad712d6a7daef1073b7fb94c0fa90908d2 (patch)
tree48d962faa6bfdae347b467d003b11e355ce17172 /sys/fs
parent75e9ed76e4bbf5978303d4d7ee581c86bef55c50 (diff)
downloadFreeBSD-src-87e306ad712d6a7daef1073b7fb94c0fa90908d2.zip
FreeBSD-src-87e306ad712d6a7daef1073b7fb94c0fa90908d2.tar.gz
- Cleanup unlocked accesses to buf flags by introducing a new b_vflag member
that is protected by the vnode lock. - Move B_SCANNED into b_vflags and call it BV_SCANNED. - Create a vop_stdfsync() modeled after spec's sync. - Replace spec_fsync, msdos_fsync, and hpfs_fsync with the stdfsync and some fs specific processing. This gives all of these filesystems proper behavior wrt MNT_WAIT/NOWAIT and the use of the B_SCANNED flag. - Annotate the locking in buf.h
Diffstat (limited to 'sys/fs')
-rw-r--r--sys/fs/hpfs/hpfs_vnops.c39
-rw-r--r--sys/fs/msdosfs/msdosfs_vnops.c41
-rw-r--r--sys/fs/specfs/spec_vnops.c83
3 files changed, 9 insertions, 154 deletions
diff --git a/sys/fs/hpfs/hpfs_vnops.c b/sys/fs/hpfs/hpfs_vnops.c
index d207c52..6578095 100644
--- a/sys/fs/hpfs/hpfs_vnops.c
+++ b/sys/fs/hpfs/hpfs_vnops.c
@@ -87,48 +87,15 @@ hpfs_fsync(ap)
struct thread *a_td;
} */ *ap;
{
- struct vnode *vp = ap->a_vp;
- int s;
- struct buf *bp, *nbp;
-
/*
- * Flush all dirty buffers associated with a vnode.
+ * Flush our dirty buffers.
*/
-loop:
- VI_LOCK(vp);
- s = splbio();
- for (bp = TAILQ_FIRST(&vp->v_dirtyblkhd); bp; bp = nbp) {
- nbp = TAILQ_NEXT(bp, b_vnbufs);
- VI_UNLOCK(vp);
- if (BUF_LOCK(bp, LK_EXCLUSIVE | LK_NOWAIT)) {
- VI_LOCK(vp);
- continue;
- }
- if ((bp->b_flags & B_DELWRI) == 0)
- panic("hpfs_fsync: not dirty");
- bremfree(bp);
- splx(s);
- (void) bwrite(bp);
- goto loop;
- }
- while (vp->v_numoutput) {
- vp->v_iflag |= VI_BWAIT;
- msleep((caddr_t)&vp->v_numoutput, VI_MTX(vp), PRIBIO + 1,
- "hpfsn", 0);
- }
-#ifdef DIAGNOSTIC
- if (!TAILQ_EMPTY(&vp->v_dirtyblkhd)) {
- vprint("hpfs_fsync: dirty", vp);
- goto loop;
- }
-#endif
- VI_UNLOCK(vp);
- splx(s);
+ vop_stdfsync(ap);
/*
* Write out the on-disc version of the vnode.
*/
- return hpfs_update(VTOHP(vp));
+ return hpfs_update(VTOHP(ap->a_vp));
}
static int
diff --git a/sys/fs/msdosfs/msdosfs_vnops.c b/sys/fs/msdosfs/msdosfs_vnops.c
index 0137920..d368775 100644
--- a/sys/fs/msdosfs/msdosfs_vnops.c
+++ b/sys/fs/msdosfs/msdosfs_vnops.c
@@ -806,45 +806,12 @@ msdosfs_fsync(ap)
struct thread *a_td;
} */ *ap;
{
- struct vnode *vp = ap->a_vp;
- int s;
- struct buf *bp, *nbp;
-
/*
- * Flush all dirty buffers associated with a vnode.
+ * Flush our dirty buffers.
*/
-loop:
- s = splbio();
- VI_LOCK(vp);
- for (bp = TAILQ_FIRST(&vp->v_dirtyblkhd); bp; bp = nbp) {
- nbp = TAILQ_NEXT(bp, b_vnbufs);
- VI_UNLOCK(vp);
- if (BUF_LOCK(bp, LK_EXCLUSIVE | LK_NOWAIT)) {
- VI_LOCK(vp);
- continue;
- }
- if ((bp->b_flags & B_DELWRI) == 0)
- panic("msdosfs_fsync: not dirty");
- bremfree(bp);
- splx(s);
- /* XXX Could do bawrite */
- (void) bwrite(bp);
- goto loop;
- }
- while (vp->v_numoutput) {
- vp->v_iflag |= VI_BWAIT;
- (void) msleep((caddr_t)&vp->v_numoutput, VI_MTX(vp),
- PRIBIO + 1, "msdosfsn", 0);
- }
-#ifdef DIAGNOSTIC
- if (!TAILQ_EMPTY(&vp->v_dirtyblkhd)) {
- vprint("msdosfs_fsync: dirty", vp);
- goto loop;
- }
-#endif
- VI_UNLOCK(vp);
- splx(s);
- return (deupdat(VTODE(vp), ap->a_waitfor == MNT_WAIT));
+ vop_stdfsync(ap);
+
+ return (deupdat(VTODE(ap->a_vp), ap->a_waitfor == MNT_WAIT));
}
static int
diff --git a/sys/fs/specfs/spec_vnops.c b/sys/fs/specfs/spec_vnops.c
index 5c8d73f..1b34ac8 100644
--- a/sys/fs/specfs/spec_vnops.c
+++ b/sys/fs/specfs/spec_vnops.c
@@ -416,89 +416,10 @@ spec_fsync(ap)
struct thread *a_td;
} */ *ap;
{
- struct vnode *vp = ap->a_vp;
- struct buf *bp;
- struct buf *nbp;
- int s, error = 0;
- int maxretry = 100; /* large, arbitrarily chosen */
-
- if (!vn_isdisk(vp, NULL))
+ if (!vn_isdisk(ap->a_vp, NULL))
return (0);
- VI_LOCK(vp);
-loop1:
- /*
- * MARK/SCAN initialization to avoid infinite loops.
- */
- s = splbio();
- TAILQ_FOREACH(bp, &vp->v_dirtyblkhd, b_vnbufs) {
- bp->b_flags &= ~B_SCANNED;
- bp->b_error = 0;
- }
- splx(s);
-
- /*
- * Flush all dirty buffers associated with a block device.
- */
-loop2:
- s = splbio();
- for (bp = TAILQ_FIRST(&vp->v_dirtyblkhd); bp != NULL; bp = nbp) {
- nbp = TAILQ_NEXT(bp, b_vnbufs);
- if ((bp->b_flags & B_SCANNED) != 0)
- continue;
- VI_UNLOCK(vp);
- bp->b_flags |= B_SCANNED;
- if (BUF_LOCK(bp, LK_EXCLUSIVE | LK_NOWAIT)) {
- VI_LOCK(vp);
- continue;
- }
- if ((bp->b_flags & B_DELWRI) == 0)
- panic("spec_fsync: not dirty");
- if ((vp->v_vflag & VV_OBJBUF) && (bp->b_flags & B_CLUSTEROK)) {
- BUF_UNLOCK(bp);
- vfs_bio_awrite(bp);
- splx(s);
- } else {
- bremfree(bp);
- splx(s);
- bawrite(bp);
- }
- VI_LOCK(vp);
- 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_iflag |= VI_BWAIT;
- msleep((caddr_t)&vp->v_numoutput, VI_MTX(vp),
- PRIBIO + 1, "spfsyn", 0);
- }
- if (!TAILQ_EMPTY(&vp->v_dirtyblkhd)) {
- /*
- * If we are unable to write any of these buffers
- * then we fail now rather than trying endlessly
- * to write them out.
- */
- TAILQ_FOREACH(bp, &vp->v_dirtyblkhd, b_vnbufs)
- if ((error = bp->b_error) == 0)
- continue;
- if (error == 0 && --maxretry >= 0) {
- splx(s);
- goto loop1;
- }
- vprint("spec_fsync: giving up on dirty", vp);
- error = EAGAIN;
- }
- }
- VI_UNLOCK(vp);
- splx(s);
- return (error);
+ return (vop_stdfsync(ap));
}
/*
OpenPOWER on IntegriCloud