From 87e306ad712d6a7daef1073b7fb94c0fa90908d2 Mon Sep 17 00:00:00 2001 From: jeff Date: Sun, 9 Feb 2003 11:28:35 +0000 Subject: - 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 --- sys/fs/hpfs/hpfs_vnops.c | 39 ++------------------ sys/fs/msdosfs/msdosfs_vnops.c | 41 ++------------------- sys/fs/specfs/spec_vnops.c | 83 +----------------------------------------- 3 files changed, 9 insertions(+), 154 deletions(-) (limited to 'sys/fs') 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)); } /* -- cgit v1.1