4500: /* buf.h : I/O Buffer struct & Device Table
4501:  * Each buffer in the pool is usually doubly linked into 2 lists:
4502:  * the device with which it is currently associated (always)
4503:  * and also on a list of blocks available for allocation
4504:  * for other use (usually).
4505:  * The latter list is kept in last-used order, and the two
4506:  * lists are doubly linked to make it easy to remove
4507:  * a buffer from one list when it was found by
4508:  * looking through the other.
4509:  * A buffer is on the available list, and is liable
4510:  * to be reassigned to another disk block, if and only
4511:  * if it is not marked BUSY.  When a buffer is busy, the
4512:  * available-list pointers can be used for other purposes.
4513:  * Most drivers use the forward ptr as a link in their I/O
4514:  * active queue.
4515:  * A buffer header contains all the information required
4516:  * to perform I/O.
4517:  * Most of the routines which manipulate these things
4518:  * are in bio.c.
4519:  */
4520: struct buf
4521: {
4522:         int     b_flags;                /* see defines below */
4523:         struct  buf *b_forw;            /* headed by devtab of b_dev */
4524:         struct  buf *b_back;            /*  "  */
4525:         struct  buf *av_forw;           /* position on free list, */
4526:         struct  buf *av_back;           /*     if not BUSY*/
4527:         int     b_dev;                  /* major+minor device name */
4528:         int     b_wcount;               /* transfer count (usu. words) */
4529:         char    *b_addr;                /* low order core address */
4530:         char    *b_xmem;                /* high order core address */
4531:         char    *b_blkno;               /* block # on device */
4532:         char    b_error;                /* returned after I/O */
4533:         char    *b_resid;               /* words not transferred after error */
4534: 
4535: } buf[NBUF];
4536: /* ---------------------------       */
4537: 
4538: /*
4539:  * Each block device has a devtab, which contains private state stuff
4540:  * and 2 list heads: the b_forw/b_back list, which is doubly linked
4541:  * and has all the buffers currently associated with that major
4542:  * device; and the d_actf/d_actl list, which is private to the
4543:  * device but in fact is always used for the head and tail
4544:  * of the I/O queue for the device.
4545:  * Various routines in bio.c look at b_forw/b_back
4546:  * (notice they are the same as in the buf structure)
4547:  * but the rest is private to each device driver.
4548:  *
4549:  */
4550: 
4551: struct devtab
4552: {
4553:         char    d_active;               /* busy flag */
4554:         char    d_errcnt;               /* error count (for recovery) */
4555:         struct  buf *b_forw;            /* first buffer for this dev */
4556:         struct  buf *b_back;            /* last buffer for this dev */
4557:         struct  buf *d_actf;            /* head of I/O queue */
4558:         struct  buf *d_actl;            /* tail of I/O queue */
4559: };
4560: /* ---------------------------       */
4561: 
4562: /*
4563:  * This is the head of the queue of available
4564:  * buffers-- all unused except for the 2 list heads.
4565:  */
4566: struct  buf bfreelist;
4567: 
4568: /*
4569:  * These flags are kept in b_flags.
4570:  */
4571: #define B_WRITE 0       /* non-read pseudo-flag */
4572: #define B_READ  01      /* read when I/O occurs */
4573: #define B_DONE  02      /* transaction finished */
4574: #define B_ERROR 04      /* transaction aborted */
4575: #define B_BUSY  010     /* not on av_forw/back list */
4576: #define B_PHYS  020     /* Physical IO potentially using UNIBUS map */
4577: 
4578: #define B_MAP   040     /* This block has the UNIBUS map allocated */
4579: 
4580: #define B_WANTED 0100   /* issue wakeup when BUSY goes off */
4581: 
4582: #define B_RELOC 0200    /* no longer used */
4583: #define B_ASYNC 0400    /* don't wait for I/O completion */
4584: 
4585: #define B_DELWRI 01000  /* don't write till block leaves available list */






4700: bio.c file 
4701: /* Buffer Management & Block Device I/O
4702:  */
4703: 
4704: #include "../param.h"
4705: #include "../user.h"
4706: #include "../buf.h"
4707: #include "../conf.h"
4708: #include "../systm.h"
4709: #include "../proc.h"
4710: #include "../seg.h"
4711: 
4712: /*
4713:  * This is the set of buffers proper, whose heads
4714:  * were declared in buf.h.  There can exist buffer
4715:  * headers not pointing here that are used purely
4716:  * as arguments to the I/O routines to describe
4717:  * I/O to be done-- e.g. swbuf, just below, for
4718:  * swapping.
4719:  */
4720: char    buffers[NBUF][512];
4721: struct  buf     swbuf;
4722: 
4723: /*
4724:  * Declarations of the tables for the magtape devices;
4725:  * see bdwrite.
4726:  */
4727: int     tmtab;
4728: int     httab;
4729: 
4730: /*
4731:  * The following several routines allocate and free
4732:  * buffers with various side effects.  In general the
4733:  * arguments to an allocate routine are a device and
4734:  * a block number, and the value is a pointer to
4735:  * to the buffer header; the buffer is marked "busy"
4736:  * so that no on else can touch it.  If the block was
4737:  * already in core, no I/O need be done; if it is
4738:  * already busy, the process waits until it becomes free.
4739:  * The following routines allocate a buffer:
4740:  *      getblk
4741:  *      bread
4742:  *      breada
4743:  * Eventually the buffer must be released, possibly with the
4744:  * side effect of writing it out, by using one of
4745:  *      bwrite
4746:  *      bdwrite
4747:  *      bawrite
4748:  *      brelse
4749:  */
4750: 
4751: /*
4752:  * Read in (if necessary) the block and return a buffer pointer.
4753:  */
4754: bread(dev, blkno)
4755: {
4756:         register struct buf *rbp;
4757: 
4758:         rbp = getblk(dev, blkno);
4759:         if (rbp->b_flags&B_DONE)
4760:                 return(rbp);
4761:         rbp->b_flags =| B_READ;
4762:         rbp->b_wcount = -256;
4763:         (*bdevsw[dev.d_major].d_strategy)(rbp);
4764:         iowait(rbp);
4765:         return(rbp);
4766: }
4767: /* ---------------------------       */
4768: 
4769: /*
4770:  * Read in the block, like bread, but also start I/O on the
4771:  * read-ahead block (which is not allocated to the caller)
4772:  */
4773: breada(adev, blkno, rablkno)
4774: {
4775:         register struct buf *rbp, *rabp;
4776:         register int dev;
4777: 
4778:         dev = adev;
4779:         rbp = 0;
4780:         if (!incore(dev, blkno)) {
4781:                 rbp = getblk(dev, blkno);
4782:                 if ((rbp->b_flags&B_DONE) == 0) {
4783:                         rbp->b_flags =| B_READ;
4784:                         rbp->b_wcount = -256;
4785:                         (*bdevsw[adev.d_major].d_strategy)(rbp);
4786:                 }
4787:         }
4788:         if (rablkno && !incore(dev, rablkno)) {
4789:                 rabp = getblk(dev, rablkno);
4790:                 if (rabp->b_flags & B_DONE)
4791:                         brelse(rabp);
4792:                 else {
4793:                         rabp->b_flags =| B_READ|B_ASYNC;
4794:                         rabp->b_wcount = -256;
4795:                         (*bdevsw[adev.d_major].d_strategy)(rabp);
4796:                 }
4797:         }
4798:         if (rbp==0)
4799:                 return(bread(dev, blkno));
4800:         iowait(rbp);
4801:         return(rbp);
4802: }
4803: /* ---------------------------       */
4804: 
4805: /*
4806:  * Write the buffer, waiting for completion.
4807:  * Then release the buffer.
4808:  */
4809: bwrite(bp)
4810: struct buf *bp;
4811: {
4812:         register struct buf *rbp;
4813:         register flag;
4814: 
4815:         rbp = bp;
4816:         flag = rbp->b_flags;
4817:         rbp->b_flags =& ~(B_READ | B_DONE | B_ERROR | B_DELWRI);
4818:         rbp->b_wcount = -256;
4819:         (*bdevsw[rbp->b_dev.d_major].d_strategy)(rbp);
4820:         if ((flag&B_ASYNC) == 0) {
4821:                 iowait(rbp);
4822:                 brelse(rbp);
4823:         } else if ((flag&B_DELWRI)==0)
4824:                 geterror(rbp);
4825: }
4826: /* ---------------------------       */
4827: 
4828: /*
4829:  * Release the buffer, marking it so that if it is grabbed
4830:  * for another purpose it will be written out before being
4831:  * given up (e.g. when writing a partial block where it is
4832:  * assumed that another write for the same block will soon follow).
4833:  * This can't be done for magtape, since writes must be done
4834:  * in the same order as requested.
4835:  */
4836: bdwrite(bp)
4837: struct buf *bp;
4838: {
4839:         register struct buf *rbp;
4840:         register struct devtab *dp;
4841: 
4842:         rbp = bp;
4843:         dp = bdevsw[rbp->b_dev.d_major].d_tab;
4844:         if (dp == &tmtab || dp == &httab)
4845:                 bawrite(rbp);
4846:         else {
4847:                 rbp->b_flags =| B_DELWRI | B_DONE;
4848:                 brelse(rbp);
4849:         }
4850: }
4851: /* ---------------------------       */
4852: 
4853: /*
4854:  * Release the buffer, start I/O on it, but don't wait for completion.
4855:  */
4856: bawrite(bp)
4857: struct buf *bp;
4858: {
4859:         register struct buf *rbp;
4860: 
4861:         rbp = bp;
4862:         rbp->b_flags =| B_ASYNC;
4863:         bwrite(rbp);
4864: }
4865: /* ---------------------------       */
4866: 
4867: /* release the buffer, with no I/O implied.
4868:  */
4869: brelse(bp)
4870: struct buf *bp;
4871: {
4872:         register struct buf *rbp, **backp;
4873:         register int sps;
4874: 
4875:         rbp = bp;
4876:         if (rbp->b_flags&B_WANTED)
4877:                 wakeup(rbp);
4878:         if (bfreelist.b_flags&B_WANTED) {
4879:                 bfreelist.b_flags =& ~B_WANTED;
4880:                 wakeup(&bfreelist);
4881:         }
4882:         if (rbp->b_flags&B_ERROR)
4883:                 rbp->b_dev.d_minor = -1;  /* no assoc. on error */
4884:         backp = &bfreelist.av_back;
4885:         sps = PS->integ;
4886:         spl6();
4887:         rbp->b_flags =& ~(B_WANTED|B_BUSY|B_ASYNC);
4888:         (*backp)->av_forw = rbp;
4889:         rbp->av_back = *backp;
4890:         *backp = rbp;
4891:         rbp->av_forw = &bfreelist;
4892:         PS->integ = sps;
4893: }
4894: /* ---------------------------       */
4895: 
4896: /* See if the block is associated with some buffer
4897:  * (mainly to avoid getting hung up on a wait in breada)
4898:  */
4899: incore(adev, blkno)
4900: {
4901:         register int dev;
4902:         register struct buf *bp;
4903:         register struct devtab *dp;
4904: 
4905:         dev = adev;
4906:         dp = bdevsw[adev.d_major].d_tab;
4907:         for (bp=dp->b_forw; bp != dp; bp = bp->b_forw)
4908:                 if (bp->b_blkno==blkno && bp->b_dev==dev)
4909:                         return(bp);
4910:         return(0);
4911: }
4912: /* ---------------------------       */
4913: 
4914: /* Assign a buffer for the given block.  If the appropriate
4915:  * block is already associated, return it; otherwise search
4916:  * for the oldest non-busy buffer and reassign it.
4917:  * When a 512-byte area is wanted for some random reason
4918:  * (e.g. during exec, for the user arglist) getblk can be called
4919:  * with device NODEV to avoid unwanted associativity.
4920:  */
4921: getblk(dev, blkno)
4922: {
4923:         register struct buf *bp;
4924:         register struct devtab *dp;
4925:         extern lbolt;
4926: 
4927:         if(dev.d_major >= nblkdev)
4928:                 panic("blkdev");
4929: 
4930:     loop:
4931:         if (dev < 0)
4932:                 dp = &bfreelist;
4933:         else {
4934:                 dp = bdevsw[dev.d_major].d_tab;
4935:                 if(dp == NULL)
4936:                         panic("devtab");
4937:                 for (bp=dp->b_forw; bp != dp; bp = bp->b_forw) {
4938:                         if (bp->b_blkno!=blkno || bp->b_dev!=dev)
4939:                                 continue;
4940:                         spl6();
4941:                         if (bp->b_flags&B_BUSY) {
4942:                                 bp->b_flags =| B_WANTED;
4943:                                 sleep(bp, PRIBIO);
4944:                                 spl0();
4945:                                 goto loop;
4946:                         }
4947:                         spl0();
4948:                         notavail(bp);
4949:                         return(bp);
4950:                 }
4951:         }
4952:         spl6();
4953:         if (bfreelist.av_forw == &bfreelist) {
4954:                 bfreelist.b_flags =| B_WANTED;
4955:                 sleep(&bfreelist, PRIBIO);
4956:                 spl0();
4957:                 goto loop;
4958:         }
4959:         spl0();
4960:         notavail(bp = bfreelist.av_forw);
4961:         if (bp->b_flags & B_DELWRI) {
4962:                 bp->b_flags =| B_ASYNC;
4963:                 bwrite(bp);
4964:                 goto loop;
4965:         }
4966:         bp->b_flags = B_BUSY | B_RELOC;
4967:         bp->b_back->b_forw = bp->b_forw;
4968:         bp->b_forw->b_back = bp->b_back;
4969:         bp->b_forw = dp->b_forw;
4970:         bp->b_back = dp;
4971:         dp->b_forw->b_back = bp;
4972:         dp->b_forw = bp;
4973:         bp->b_dev = dev;
4974:         bp->b_blkno = blkno;
4975:         return(bp);
4976: }
4977: /* ---------------------------       */
4978: 
4979: /* Wait for I/O completion on the buffer; return errors
4980:  * to the user.
4981:  */
4982: iowait(bp)
4983: struct buf *bp;
4984: {
4985:         register struct buf *rbp;
4986: 
4987:         rbp = bp;
4988:         spl6();
4989:         while ((rbp->b_flags&B_DONE)==0)
4990:                 sleep(rbp, PRIBIO);
4991:         spl0();
4992:         geterror(rbp);
4993: }
4994: /* ---------------------------       */
4995: 
4996: /* Unlink a buffer from the available list and mark it busy.
4997:  * (internal interface)
4998:  */
4999: notavail(bp)
5000: struct buf *bp;
5001: {
5002:         register struct buf *rbp;
5003:         register int sps;
5004: 
5005:         rbp = bp;
5006:         sps = PS->integ;
5007:         spl6();
5008:         rbp->av_back->av_forw = rbp->av_forw;
5009:         rbp->av_forw->av_back = rbp->av_back;
5010:         rbp->b_flags =| B_BUSY;
5011:         PS->integ = sps;
5012: }
5013: /* ---------------------------       */
5014: 
5015: /* Mark I/O complete on a buffer, release it if I/O is asynchronous,
5016:  * and wake up anyone waiting for it.
5017:  */
5018: iodone(bp)
5019: struct buf *bp;
5020: {
5021:         register struct buf *rbp;
5022: 
5023:         rbp = bp;
5024:         if(rbp->b_flags&B_MAP)
5025:                 mapfree(rbp);
5026:         rbp->b_flags =| B_DONE;
5027:         if (rbp->b_flags&B_ASYNC)
5028:                 brelse(rbp);
5029:         else {
5030:                 rbp->b_flags =& ~B_WANTED;
5031:                 wakeup(rbp);
5032:         }
5033: }
5034: /* ---------------------------       */
5035: 
5036: /* Zero the core associated with a buffer.
5037:  */
5038: clrbuf(bp)
5039: int *bp;
5040: {
5041:         register *p;
5042:         register c;
5043: 
5044:         p = bp->b_addr;
5045:         c = 256;
5046:         do
5047:                 *p++ = 0;
5048:         while (--c);
5049: }
5050: /* ---------------------------       */
5051: 
5052: /* Initialize the buffer I/O system by freeing
5053:  * all buffers and setting all device buffer lists to empty.
5054:  */
5055: binit()
5056: {
5057:         register struct buf *bp;
5058:         register struct devtab *dp;
5059:         register int i;
5060:         struct bdevsw *bdp;
5061: 
5062:         bfreelist.b_forw = bfreelist.b_back =
5063:             bfreelist.av_forw = bfreelist.av_back = &bfreelist;
5064:         for (i=0; i<NBUF; i++) {
5065:                 bp = &buf[i];
5066:                 bp->b_dev = -1;
5067:                 bp->b_addr = buffers[i];
5068:                 bp->b_back = &bfreelist;
5069:                 bp->b_forw = bfreelist.b_forw;
5070:                 bfreelist.b_forw->b_back = bp;
5071:                 bfreelist.b_forw = bp;
5072:                 bp->b_flags = B_BUSY;
5073:                 brelse(bp);
5074:         }
5075:         i = 0;
5076:         for (bdp = bdevsw; bdp->d_open; bdp++) {
5077:                 dp = bdp->d_tab;
5078:                 if(dp) {
5079:                         dp->b_forw = dp;
5080:                         dp->b_back = dp;
5081:                 }
5082:                 i++;
5083:         }
5084:         nblkdev = i;
5085: }
5086: /* ---------------------------       */
5087: