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: