-
-/*
- * Insure that no part of a specified block is in an incore buffer.
- */
-blkflush(dev, blkno, size)
- dev_t dev;
- daddr_t blkno;
- long size;
-{
- register struct buf *ep;
- struct buf *dp;
- daddr_t start, last;
- int s;
-
- start = blkno;
- last = start + btodb(size) - 1;
- dp = BUFHASH(dev, blkno);
-loop:
- for (ep = dp->b_forw; ep != dp; ep = ep->b_forw) {
- if (ep->b_dev != dev || (ep->b_flags&B_INVAL))
- continue;
- /* look for overlap */
- if (ep->b_bcount == 0 || ep->b_blkno > last ||
- ep->b_blkno + btodb(ep->b_bcount) <= start)
- continue;
- s = spl6();
- 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);
- bwrite(ep);
- goto loop;
- }
- splx(s);
- }
-}
-
-/*
- * Make sure all write-behind blocks
- * on dev (or NODEV for all)
- * are flushed out.
- * (from umount and update)
- */
-bflush(dev)
- dev_t dev;
-{
- register struct buf *bp;
- register struct buf *flist;
- int s;
-
-loop:
- s = spl6();
- 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);
- bwrite(bp);
- splx(s);
- goto loop;
- }
- }
- splx(s);
-}
-
-/*
- * Pick up the device's error number and pass it to the user;
- * if there is an error but the number is 0 set a generalized
- * code. Actually the latter is always true because devices
- * don't yet return specific errors.
- */
-geterror(bp)
- register struct buf *bp;
-{
- int error = 0;
-
- if (bp->b_flags&B_ERROR)
- if ((error = bp->b_error)==0)
- return (EIO);
- return (error);
-}
-
-/*
- * 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)
-
- 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;
-}