X-Git-Url: https://git.subgeniuskitty.com/unix-history/.git/blobdiff_plain/d2f871361f2f50ac202de6e6335a63fff05bb8a4..7b8b5a017ec860062c1f8626302492b3a164b77e:/usr/src/sys/kern/vfs_cluster.c diff --git a/usr/src/sys/kern/vfs_cluster.c b/usr/src/sys/kern/vfs_cluster.c index 4b8cb8ffc8..9be3827e7d 100644 --- a/usr/src/sys/kern/vfs_cluster.c +++ b/usr/src/sys/kern/vfs_cluster.c @@ -1,4 +1,4 @@ -/* vfs_cluster.c 3.11 %G% */ +/* vfs_cluster.c 4.5 %G% */ #include "../h/param.h" #include "../h/systm.h" @@ -10,6 +10,7 @@ #include "../h/seg.h" #include "../h/pte.h" #include "../h/vm.h" +#include "../h/trace.h" /* * The following several routines allocate and free @@ -99,6 +100,9 @@ daddr_t blkno; bp = getblk(dev, blkno); if (bp->b_flags&B_DONE) { +#ifdef EPAWNJ + trace(TR_BREAD|TR_HIT, dev, blkno); +#endif #ifdef DISKMON io_info.ncache++; #endif @@ -107,6 +111,9 @@ daddr_t blkno; bp->b_flags |= B_READ; bp->b_bcount = BSIZE; (*bdevsw[major(dev)].d_strategy)(bp); +#ifdef EPAWNJ + trace(TR_BREAD|TR_MISS, dev, blkno); +#endif #ifdef DISKMON io_info.nread++; #endif @@ -133,20 +140,33 @@ daddr_t blkno, rablkno; bp->b_flags |= B_READ; bp->b_bcount = BSIZE; (*bdevsw[major(dev)].d_strategy)(bp); +#ifdef EPAWNJ + trace(TR_BREAD|TR_MISS, dev, blkno); +#endif #ifdef DISKMON io_info.nread++; #endif u.u_vm.vm_inblk++; /* pay for read */ } +#ifdef EPAWNJ + else + trace(TR_BREAD|TR_HIT, dev, blkno); +#endif } if (rablkno && !incore(dev, rablkno)) { rabp = getblk(dev, rablkno); - if (rabp->b_flags & B_DONE) + if (rabp->b_flags & B_DONE) { brelse(rabp); - else { +#ifdef EPAWNJ + trace(TR_BREAD|TR_HIT|TR_RA, dev, blkno); +#endif + } else { rabp->b_flags |= B_READ|B_ASYNC; rabp->b_bcount = BSIZE; (*bdevsw[major(dev)].d_strategy)(rabp); +#ifdef EPAWNJ + trace(TR_BREAD|TR_MISS|TR_RA, dev, rablock); +#endif #ifdef DISKMON io_info.nreada++; #endif @@ -176,6 +196,9 @@ register struct buf *bp; #endif if ((flag&B_DELWRI) == 0) u.u_vm.vm_oublk++; /* noone paid yet */ +#ifdef EPAWNJ + trace(TR_BWRITE, bp->b_dev, dbtofsb(bp->b_blkno)); +#endif (*bdevsw[major(bp->b_dev)].d_strategy)(bp); if ((flag&B_ASYNC) == 0) { iowait(bp); @@ -271,7 +294,8 @@ daddr_t blkno; for (bp = &buf[bufhash[BUFHASH(blkno)]]; bp != &buf[-1]; bp = &buf[bp->b_hlink]) - if (bp->b_blkno == dblkno && bp->b_dev == dev) + if (bp->b_blkno == dblkno && bp->b_dev == dev + && !(bp->b_flags & B_INVAL)) return (1); return (0); } @@ -298,14 +322,17 @@ dev_t dev; daddr_t blkno; { register struct buf *bp, *dp, *ep; - register int i, x; - register int dblkno = fsbtodb(blkno); + register int i, x, dblkno; + if ((unsigned)blkno >= 1 << (sizeof(int)*NBBY-PGSHIFT)) + blkno = 1 << ((sizeof(int)*NBBY-PGSHIFT) + 1); + dblkno = fsbtodb(blkno); loop: (void) spl0(); for (bp = &buf[bufhash[BUFHASH(blkno)]]; bp != &buf[-1]; bp = &buf[bp->b_hlink]) { - if (bp->b_blkno != dblkno || bp->b_dev != dev) + if (bp->b_blkno != dblkno || bp->b_dev != dev + || bp->b_flags & B_INVAL) continue; (void) spl6(); if (bp->b_flags&B_BUSY) { @@ -339,7 +366,7 @@ daddr_t blkno; sleep((caddr_t)&bfreelist, PRIBIO+1); goto loop; } - spl0(); + (void) spl0(); bp = bfreelist.av_forw; notavail(bp); if (bp->b_flags & B_DELWRI) { @@ -350,6 +377,10 @@ daddr_t blkno; if (bp->b_dev == NODEV) goto done; /* INLINE EXPANSION OF bunhash(bp) */ +#ifdef EPAWNJ + trace(TR_BRELSE, bp->b_dev, dbtofsb(bp->b_blkno)); +#endif + (void) spl6(); i = BUFHASH(dbtofsb(bp->b_blkno)); x = bp - buf; if (bufhash[i] == x) { @@ -364,6 +395,7 @@ daddr_t blkno; panic("getblk"); } done: + (void) spl0(); /* END INLINE EXPANSION */ bp->b_flags = B_BUSY; bp->b_back->b_forw = bp->b_forw; @@ -404,8 +436,12 @@ loop: bwrite(bp); goto loop; } - if (bp->b_dev != NODEV) + if (bp->b_dev != NODEV) { +#ifdef EPAWNJ + trace(TR_BRELSE, bp->b_dev, dbtofsb(bp->b_blkno)); +#endif bunhash(bp); + } bp->b_flags = B_BUSY; bp->b_back->b_forw = bp->b_forw; bp->b_forw->b_back = bp->b_back; @@ -422,23 +458,26 @@ bunhash(bp) register struct buf *bp; { register struct buf *ep; - register int i, x; + register int i, x, s; if (bp->b_dev == NODEV) return; + s = spl6(); i = BUFHASH(dbtofsb(bp->b_blkno)); x = bp - buf; if (bufhash[i] == x) { bufhash[i] = bp->b_hlink; - return; + goto ret; } for (ep = &buf[bufhash[i]]; ep != &buf[-1]; ep = &buf[ep->b_hlink]) if (ep->b_hlink == x) { ep->b_hlink = bp->b_hlink; - return; + goto ret; } panic("bunhash"); +ret: + splx(s); } /* @@ -757,3 +796,26 @@ register struct buf *bp; if ((u.u_error = bp->b_error)==0) u.u_error = EIO; } + +/* + * 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, *dp; + + dp = bdevsw[major(dev)].d_tab; + + for (bp = dp->b_forw; bp != dp; bp = bp->b_forw) + if (bp->b_dev == dev) + bp->b_flags |= B_INVAL; +}