|
|
1.1 ! root 1: /* ! 2: * Copyright (c) 1982, 1986, 1989 Regents of the University of California. ! 3: * All rights reserved. ! 4: * ! 5: * Redistribution and use in source and binary forms, with or without ! 6: * modification, are permitted provided that the following conditions ! 7: * are met: ! 8: * 1. Redistributions of source code must retain the above copyright ! 9: * notice, this list of conditions and the following disclaimer. ! 10: * 2. Redistributions in binary form must reproduce the above copyright ! 11: * notice, this list of conditions and the following disclaimer in the ! 12: * documentation and/or other materials provided with the distribution. ! 13: * 3. All advertising materials mentioning features or use of this software ! 14: * must display the following acknowledgement: ! 15: * This product includes software developed by the University of ! 16: * California, Berkeley and its contributors. ! 17: * 4. Neither the name of the University nor the names of its contributors ! 18: * may be used to endorse or promote products derived from this software ! 19: * without specific prior written permission. ! 20: * ! 21: * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND ! 22: * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ! 23: * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ! 24: * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE ! 25: * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ! 26: * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS ! 27: * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) ! 28: * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT ! 29: * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY ! 30: * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF ! 31: * SUCH DAMAGE. ! 32: * ! 33: * @(#)buf.h 7.11 (Berkeley) 5/9/90 ! 34: */ ! 35: ! 36: /* ! 37: * The header for buffers in the buffer pool and otherwise used ! 38: * to describe a block i/o request is given here. ! 39: * ! 40: * Each buffer in the pool is usually doubly linked into 2 lists: ! 41: * hashed into a chain by <dev,blkno> so it can be located in the cache, ! 42: * and (usually) on (one of several) queues. These lists are circular and ! 43: * doubly linked for easy removal. ! 44: * ! 45: * There are currently three queues for buffers: ! 46: * one for buffers which must be kept permanently (super blocks) ! 47: * one for buffers containing ``useful'' information (the cache) ! 48: * one for buffers containing ``non-useful'' information ! 49: * (and empty buffers, pushed onto the front) ! 50: * The latter two queues contain the buffers which are available for ! 51: * reallocation, are kept in lru order. When not on one of these queues, ! 52: * the buffers are ``checked out'' to drivers which use the available list ! 53: * pointers to keep track of them in their i/o active queues. ! 54: */ ! 55: ! 56: /* ! 57: * Bufhd structures used at the head of the hashed buffer queues. ! 58: * We only need three words for these, so this abbreviated ! 59: * definition saves some space. ! 60: */ ! 61: struct bufhd ! 62: { ! 63: long b_flags; /* see defines below */ ! 64: struct buf *b_forw, *b_back; /* fwd/bkwd pointer in chain */ ! 65: }; ! 66: struct buf ! 67: { ! 68: long b_flags; /* too much goes here to describe */ ! 69: struct buf *b_forw, *b_back; /* hash chain (2 way street) */ ! 70: struct buf *av_forw, *av_back; /* position on free list if not BUSY */ ! 71: struct buf *b_blockf, **b_blockb;/* associated vnode */ ! 72: #define b_actf av_forw /* alternate names for driver queue */ ! 73: #define b_actl av_back /* head - isn't history wonderful */ ! 74: long b_bcount; /* transfer count */ ! 75: long b_bufsize; /* size of allocated buffer */ ! 76: #define b_active b_bcount /* driver queue head: drive active */ ! 77: short b_error; /* returned after I/O */ ! 78: dev_t b_dev; /* major+minor device name */ ! 79: union { ! 80: caddr_t b_addr; /* low order core address */ ! 81: int *b_words; /* words for clearing */ ! 82: struct fs *b_fs; /* superblocks */ ! 83: struct csum *b_cs; /* superblock summary information */ ! 84: struct cg *b_cg; /* cylinder group block */ ! 85: struct dinode *b_dino; /* ilist */ ! 86: daddr_t *b_daddr; /* indirect block */ ! 87: } b_un; ! 88: daddr_t b_lblkno; /* logical block number */ ! 89: daddr_t b_blkno; /* block # on device */ ! 90: long b_resid; /* words not transferred after error */ ! 91: #define b_errcnt b_resid /* while i/o in progress: # retries */ ! 92: struct proc *b_proc; /* proc doing physical or swap I/O */ ! 93: int (*b_iodone)(); /* function called by iodone */ ! 94: struct vnode *b_vp; /* vnode for dev */ ! 95: int b_pfcent; /* center page when swapping cluster */ ! 96: struct ucred *b_rcred; /* ref to read credentials */ ! 97: struct ucred *b_wcred; /* ref to write credendtials */ ! 98: int b_dirtyoff; /* offset in buffer of dirty region */ ! 99: int b_dirtyend; /* offset of end of dirty region */ ! 100: caddr_t b_saveaddr; /* original b_addr for PHYSIO */ ! 101: }; ! 102: ! 103: #define BQUEUES 4 /* number of free buffer queues */ ! 104: ! 105: #define BQ_LOCKED 0 /* super-blocks &c */ ! 106: #define BQ_LRU 1 /* lru, useful buffers */ ! 107: #define BQ_AGE 2 /* rubbish */ ! 108: #define BQ_EMPTY 3 /* buffer headers with no memory */ ! 109: ! 110: #ifdef KERNEL ! 111: #define BUFHSZ 512 ! 112: #define RND (MAXBSIZE/DEV_BSIZE) ! 113: #if ((BUFHSZ&(BUFHSZ-1)) == 0) ! 114: #define BUFHASH(dvp, dblkno) \ ! 115: ((struct buf *)&bufhash[((int)(dvp)+(((int)(dblkno))/RND))&(BUFHSZ-1)]) ! 116: #else ! 117: #define BUFHASH(dvp, dblkno) \ ! 118: ((struct buf *)&bufhash[((int)(dvp)+(((int)(dblkno))/RND)) % BUFHSZ]) ! 119: #endif ! 120: ! 121: struct buf *buf; /* the buffer pool itself */ ! 122: char *buffers; ! 123: int nbuf; /* number of buffer headers */ ! 124: int bufpages; /* number of memory pages in the buffer pool */ ! 125: struct buf *swbuf; /* swap I/O headers */ ! 126: int nswbuf; ! 127: struct bufhd bufhash[BUFHSZ]; /* heads of hash lists */ ! 128: struct buf bfreelist[BQUEUES]; /* heads of available lists */ ! 129: struct buf bswlist; /* head of free swap header list */ ! 130: struct buf *bclnlist; /* head of cleaned page list */ ! 131: ! 132: struct buf *getblk(); ! 133: struct buf *geteblk(); ! 134: struct buf *getnewbuf(); ! 135: ! 136: unsigned minphys(); ! 137: #endif ! 138: ! 139: /* ! 140: * These flags are kept in b_flags. ! 141: */ ! 142: #define B_WRITE 0x000000 /* non-read pseudo-flag */ ! 143: #define B_READ 0x000001 /* read when I/O occurs */ ! 144: #define B_DONE 0x000002 /* transaction finished */ ! 145: #define B_ERROR 0x000004 /* transaction aborted */ ! 146: #define B_BUSY 0x000008 /* not on av_forw/back list */ ! 147: #define B_PHYS 0x000010 /* physical IO */ ! 148: #define B_XXX 0x000020 /* was B_MAP, alloc UNIBUS on pdp-11 */ ! 149: #define B_WANTED 0x000040 /* issue wakeup when BUSY goes off */ ! 150: #define B_AGE 0x000080 /* delayed write for correct aging */ ! 151: #define B_ASYNC 0x000100 /* don't wait for I/O completion */ ! 152: #define B_DELWRI 0x000200 /* write at exit of avail list */ ! 153: #define B_TAPE 0x000400 /* this is a magtape (no bdwrite) */ ! 154: #define B_UAREA 0x000800 /* add u-area to a swap operation */ ! 155: #define B_PAGET 0x001000 /* page in/out of page table space */ ! 156: #define B_DIRTY 0x002000 /* dirty page to be pushed out async */ ! 157: #define B_PGIN 0x004000 /* pagein op, so swap() can count it */ ! 158: #define B_CACHE 0x008000 /* did bread find us in the cache ? */ ! 159: #define B_INVAL 0x010000 /* does not contain valid info */ ! 160: #define B_LOCKED 0x020000 /* locked in core (not reusable) */ ! 161: #define B_HEAD 0x040000 /* a buffer header, not a buffer */ ! 162: #define B_BAD 0x100000 /* bad block revectoring in progress */ ! 163: #define B_CALL 0x200000 /* call b_iodone from iodone */ ! 164: #define B_RAW 0x400000 /* set by physio for raw transfers */ ! 165: #define B_NOCACHE 0x800000 /* do not cache block after use */ ! 166: ! 167: /* ! 168: * Insq/Remq for the buffer hash lists. ! 169: */ ! 170: #define bremhash(bp) { \ ! 171: (bp)->b_back->b_forw = (bp)->b_forw; \ ! 172: (bp)->b_forw->b_back = (bp)->b_back; \ ! 173: } ! 174: #define binshash(bp, dp) { \ ! 175: (bp)->b_forw = (dp)->b_forw; \ ! 176: (bp)->b_back = (dp); \ ! 177: (dp)->b_forw->b_back = (bp); \ ! 178: (dp)->b_forw = (bp); \ ! 179: } ! 180: ! 181: /* ! 182: * Insq/Remq for the buffer free lists. ! 183: */ ! 184: #define bremfree(bp) { \ ! 185: (bp)->av_back->av_forw = (bp)->av_forw; \ ! 186: (bp)->av_forw->av_back = (bp)->av_back; \ ! 187: } ! 188: #define binsheadfree(bp, dp) { \ ! 189: (dp)->av_forw->av_back = (bp); \ ! 190: (bp)->av_forw = (dp)->av_forw; \ ! 191: (dp)->av_forw = (bp); \ ! 192: (bp)->av_back = (dp); \ ! 193: } ! 194: #define binstailfree(bp, dp) { \ ! 195: (dp)->av_back->av_forw = (bp); \ ! 196: (bp)->av_back = (dp)->av_back; \ ! 197: (dp)->av_back = (bp); \ ! 198: (bp)->av_forw = (dp); \ ! 199: } ! 200: ! 201: #define iodone biodone ! 202: #define iowait biowait ! 203: ! 204: /* ! 205: * Zero out a buffer's data portion. ! 206: */ ! 207: #define clrbuf(bp) { \ ! 208: blkclr((bp)->b_un.b_addr, (unsigned)(bp)->b_bcount); \ ! 209: (bp)->b_resid = 0; \ ! 210: } ! 211: #define B_CLRBUF 0x1 /* request allocated buffer be cleared */ ! 212: #define B_SYNC 0x2 /* do all allocations synchronously */
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.