-/*
- * Make sure all write-behind blocks associated
- * with mount point are flushed out (from sync).
- */
-mntflushbuf(mountp, flags)
- struct mount *mountp;
- int flags;
-{
- USES_VOP_ISLOCKED;
- register struct vnode *vp;
-
- if ((mountp->mnt_flag & MNT_MPBUSY) == 0)
- panic("mntflushbuf: not busy");
-loop:
- for (vp = mountp->mnt_mounth; vp; vp = vp->v_mountf) {
- if (VOP_ISLOCKED(vp))
- continue;
- if (vget(vp))
- goto loop;
- vflushbuf(vp, flags);
- vput(vp);
- if (vp->v_mount != mountp)
- goto loop;
- }
-}
-
-/*
- * Flush all dirty buffers associated with a vnode.
- */
-vflushbuf(vp, flags)
- register struct vnode *vp;
- int flags;
-{
- register struct buf *bp;
- struct buf *nbp;
- int s;
-
-loop:
- s = splbio();
- for (bp = vp->v_dirtyblkhd; bp; bp = nbp) {
- nbp = bp->b_blockf;
- if ((bp->b_flags & B_BUSY))
- continue;
- if ((bp->b_flags & B_DELWRI) == 0)
- panic("vflushbuf: not dirty");
- bremfree(bp);
- bp->b_flags |= B_BUSY;
- splx(s);
- /*
- * Wait for I/O associated with indirect blocks to complete,
- * since there is no way to quickly wait for them below.
- * NB: This is really specific to ufs, but is done here
- * as it is easier and quicker.
- */
- if (bp->b_vp == vp || (flags & B_SYNC) == 0)
- (void) bawrite(bp);
- else
- (void) bwrite(bp);
- goto loop;
- }
- splx(s);
- if ((flags & B_SYNC) == 0)
- return;
- s = splbio();
- while (vp->v_numoutput) {
- vp->v_flag |= VBWAIT;
- sleep((caddr_t)&vp->v_numoutput, PRIBIO + 1);
- }
- splx(s);
- if (vp->v_dirtyblkhd) {
- vprint("vflushbuf: dirty", vp);
- goto loop;
- }
-}
-