-
-/*
- * Ensure that no part of a specified block is in an incore buffer.
-#ifdef SECSIZE
- * "size" is given in device blocks (the units of b_blkno).
-#endif SECSIZE
-#ifdef SECSIZE
- * "size" is given in device blocks (the units of b_blkno).
-#endif SECSIZE
- */
-blkflush(vp, blkno, size)
- struct vnode *vp;
- daddr_t blkno;
-#ifdef SECSIZE
- int size;
-#else SECSIZE
- long size;
-#endif SECSIZE
-{
- register struct buf *ep;
- struct buf *dp;
- daddr_t start, last;
- int s, error, allerrors = 0;
-
- start = blkno;
-#ifdef SECSIZE
- last = start + size - 1;
-#else SECSIZE
- last = start + btodb(size) - 1;
-#endif SECSIZE
- dp = BUFHASH(vp, blkno);
-loop:
- for (ep = dp->b_forw; ep != dp; ep = ep->b_forw) {
- if (ep->b_vp != vp || (ep->b_flags & B_INVAL))
- continue;
- /* look for overlap */
- if (ep->b_bcount == 0 || ep->b_blkno > last ||
-#ifdef SECSIZE
- ep->b_blkno + ep->b_bcount / ep->b_blksize <= start)
-#else SECSIZE
- ep->b_blkno + btodb(ep->b_bcount) <= start)
-#endif SECSIZE
- continue;
- s = splbio();
- if (ep->b_flags&B_BUSY) {
- ep->b_flags |= B_WANTED;
- sleep((caddr_t)ep, PRIBIO+1);
- splx(s);
- goto loop;
- }
- if (ep->b_flags & B_DELWRI) {
- splx(s);
- notavail(ep);
- if (error = bwrite(ep))
- allerrors = error;
- goto loop;
- }
- splx(s);
- }
- return (allerrors);
-}
-
-/*
- * Make sure all write-behind blocks associated
- * with vp are flushed out (from sync).
- */
-bflush(dev)
- dev_t dev;
-{
- register struct buf *bp;
- register struct buf *flist;
- int s;
-
-loop:
- s = splbio();
- for (flist = bfreelist; flist < &bfreelist[BQ_EMPTY]; flist++)
- for (bp = flist->av_forw; bp != flist; bp = bp->av_forw) {
- if ((bp->b_flags & B_DELWRI) == 0)
- continue;
- if (dev == NODEV || dev == bp->b_dev) {
- bp->b_flags |= B_ASYNC;
- notavail(bp);
- (void) bwrite(bp);
- splx(s);
- goto loop;
- }
- }
- splx(s);
-}
-
-#ifdef unused
-/*
- * Invalidate blocks associated with vp which are on the freelist.
- * Make sure all write-behind blocks associated with vp are flushed out.
- */
-binvalfree(vp)
- struct vnode *vp;
-{
- register struct buf *bp;
- register struct buf *flist;
- int s;
-
-loop:
- s = splbio();
- for (flist = bfreelist; flist < &bfreelist[BQ_EMPTY]; flist++)
- for (bp = flist->av_forw; bp != flist; bp = bp->av_forw) {
- if (vp == (struct vnode *) 0 || vp == bp->b_vp) {
- if (bp->b_flags & B_DELWRI) {
- bp->b_flags |= B_ASYNC;
- notavail(bp);
- (void) splx(s);
- (void) bwrite(bp);
- } else {
- bp->b_flags |= B_INVAL;
- brelvp(bp);
- (void) splx(s);
- }
- goto loop;
- }
- }
- (void) splx(s);
-}
-#endif /* unused */
-
-/*
- * Invalidate in core blocks belonging to closed or umounted filesystem
- *
- * This is not nicely done at all - the buffer ought to be removed from the
- * hash chains & have its dev/blkno fields clobbered, but unfortunately we
- * can't do that here, as it is quite possible that the block is still
- * being used for i/o. Eventually, all disc drivers should be forced to
- * have a close routine, which ought ensure that the queue is empty, then
- * properly flush the queues. Until that happy day, this suffices for
- * correctness. ... kre
- */
-binval(dev)
- dev_t dev;
-{
- register struct buf *bp;
- register struct bufhd *hp;
-#define dp ((struct buf *)hp)
-
-loop:
- for (hp = bufhash; hp < &bufhash[BUFHSZ]; hp++)
- for (bp = dp->b_forw; bp != dp; bp = bp->b_forw)
- if (bp->b_dev == dev && (bp->b_flags & B_INVAL) == 0) {
- bp->b_flags |= B_INVAL;
- brelvp(bp);
- goto loop;
- }
-}
-
-brelvp(bp)
- struct buf *bp;
-{
- struct vnode *vp;
-
- if (bp->b_vp == (struct vnode *) 0)
- return;
- vp = bp->b_vp;
- bp->b_vp = (struct vnode *) 0;
- vrele(vp);
-}