diff options
author | martin <martin@FreeBSD.org> | 1994-10-23 00:41:17 +0000 |
---|---|---|
committer | martin <martin@FreeBSD.org> | 1994-10-23 00:41:17 +0000 |
commit | 63e85e7c8644715d13f23d9dc7fade8324c3e3ec (patch) | |
tree | 547be33a14c6c44794857fa0df231b08fc5847fb /sys/fs | |
parent | 70966e6f5bcf30711b23262449505980e3baa18a (diff) | |
download | FreeBSD-src-63e85e7c8644715d13f23d9dc7fade8324c3e3ec.zip FreeBSD-src-63e85e7c8644715d13f23d9dc7fade8324c3e3ec.tar.gz |
Fixed panic when unmounting floppy msdos filesystems. Problem was
we weren't flushing dirty buffers. Fix stolen from ffs_fsync()
Diffstat (limited to 'sys/fs')
-rw-r--r-- | sys/fs/msdosfs/msdosfs_vnops.c | 37 |
1 files changed, 30 insertions, 7 deletions
diff --git a/sys/fs/msdosfs/msdosfs_vnops.c b/sys/fs/msdosfs/msdosfs_vnops.c index 8649817..7773f59 100644 --- a/sys/fs/msdosfs/msdosfs_vnops.c +++ b/sys/fs/msdosfs/msdosfs_vnops.c @@ -1,4 +1,4 @@ -/* $Id: msdosfs_vnops.c,v 1.4 1994/09/28 16:45:14 dfr Exp $ */ +/* $Id: msdosfs_vnops.c,v 1.5 1994/10/06 21:06:53 davidg Exp $ */ /* $NetBSD: msdosfs_vnops.c,v 1.20 1994/08/21 18:44:13 ws Exp $ */ /*- @@ -787,20 +787,43 @@ msdosfs_fsync(ap) struct proc *a_p; } */ *ap; { - struct vnode *vp = ap->a_vp; + register struct vnode *vp = ap->a_vp; + register struct buf *bp; int wait = ap->a_waitfor == MNT_WAIT; struct timespec ts; + struct buf *nbp; + int s; TIMEVAL_TO_TIMESPEC(&time, &ts); -#if 0 /* - * Does this call to vflushbuf() do anything? I can find no code - * anywhere that sets v_dirtyblkhd in the vnode, which vflushbuf() - * seems to depend upon. + * Flush all dirty buffers associated with a vnode. */ - vflushbuf(vp, wait ? B_SYNC : 0); +loop: + s = splbio(); + for (bp = vp->v_dirtyblkhd.lh_first; bp; bp = nbp) { + nbp = bp->b_vnbufs.le_next; + if ((bp->b_flags & B_BUSY)) + continue; + if ((bp->b_flags & B_DELWRI) == 0) + panic("msdosfs_fsync: not dirty"); + bremfree(bp); + bp->b_flags |= B_BUSY; + splx(s); + (void) bwrite(bp); + goto loop; + } + while (vp->v_numoutput) { + vp->v_flag |= VBWAIT; + (void) tsleep((caddr_t)&vp->v_numoutput, PRIBIO + 1, "msdosfsn", 0); + } +#ifdef DIAGNOSTIC + if (vp->v_dirtyblkhd.lh_first) { + vprint("msdosfs_fsync: dirty", vp); + goto loop; + } #endif + splx(s); return deupdat(VTODE(vp), &ts, wait); } |