1 /* buf.h 4.19 82/12/17 */ 2 3 /* 4 * The header for buffers in the buffer pool and otherwise used 5 * to describe a block i/o request is given here. The routines 6 * which manipulate these things are given in bio.c. 7 * 8 * Each buffer in the pool is usually doubly linked into 2 lists: 9 * hashed into a chain by <dev,blkno> so it can be located in the cache, 10 * and (usually) on (one of several) queues. These lists are circular and 11 * doubly linked for easy removal. 12 * 13 * There are currently three queues for buffers: 14 * one for buffers which must be kept permanently (super blocks) 15 * one for buffers containing ``useful'' information (the cache) 16 * one for buffers containing ``non-useful'' information 17 * (and empty buffers, pushed onto the front) 18 * The latter two queues contain the buffers which are available for 19 * reallocation, are kept in lru order. When not on one of these queues, 20 * the buffers are ``checked out'' to drivers which use the available list 21 * pointers to keep track of them in their i/o active queues. 22 */ 23 24 /* 25 * Bufhd structures used at the head of the hashed buffer queues. 26 * We only need three words for these, so this abbreviated 27 * definition saves some space. 28 */ 29 struct bufhd 30 { 31 long b_flags; /* see defines below */ 32 struct buf *b_forw, *b_back; /* fwd/bkwd pointer in chain */ 33 }; 34 struct buf 35 { 36 long b_flags; /* too much goes here to describe */ 37 struct buf *b_forw, *b_back; /* hash chain (2 way street) */ 38 struct buf *av_forw, *av_back; /* position on free list if not BUSY */ 39 #define b_actf av_forw /* alternate names for driver queue */ 40 #define b_actl av_back /* head - isn't history wonderful */ 41 long b_bcount; /* transfer count */ 42 long b_bufsize; /* size of allocated buffer */ 43 #define b_active b_bcount /* driver queue head: drive active */ 44 short b_error; /* returned after I/O */ 45 dev_t b_dev; /* major+minor device name */ 46 union { 47 caddr_t b_addr; /* low order core address */ 48 int *b_words; /* words for clearing */ 49 struct fs *b_fs; /* superblocks */ 50 struct csum *b_cs; /* superblock summary information */ 51 struct cg *b_cg; /* cylinder group block */ 52 struct dinode *b_dino; /* ilist */ 53 daddr_t *b_daddr; /* indirect block */ 54 } b_un; 55 daddr_t b_blkno; /* block # on device */ 56 long b_resid; /* words not transferred after error */ 57 #define b_errcnt b_resid /* while i/o in progress: # retries */ 58 #define b_pfcent b_resid /* garbage: don't ask */ 59 struct proc *b_proc; /* proc doing physical or swap I/O */ 60 int (*b_iodone)(); /* function called by iodone */ 61 }; 62 63 #define BQUEUES 4 /* number of free buffer queues */ 64 65 #define BQ_LOCKED 0 /* super-blocks &c */ 66 #define BQ_LRU 1 /* lru, useful buffers */ 67 #define BQ_AGE 2 /* rubbish */ 68 #define BQ_EMPTY 3 /* buffer headers with no memory */ 69 70 #ifdef KERNEL 71 #define BUFHSZ 63 72 #define RND (MAXBSIZE/DEV_BSIZE) 73 #define BUFHASH(dev, dblkno) \ 74 ((struct buf *)&bufhash[((int)(dev)+(((int)(dblkno))/RND)) % BUFHSZ]) 75 76 struct buf *buf; /* the buffer pool itself */ 77 char *buffers; 78 int nbuf; 79 struct buf *swbuf; /* swap I/O headers */ 80 int nswbuf; 81 short *swsize; 82 int *swpf; 83 struct bufhd bufhash[BUFHSZ]; /* heads of hash lists */ 84 struct buf bfreelist[BQUEUES]; /* heads of available lists */ 85 struct buf bswlist; /* head of free swap header list */ 86 struct buf *bclnlist; /* head of cleaned page list */ 87 88 struct buf *alloc(); 89 struct buf *realloccg(); 90 struct buf *baddr(); 91 struct buf *getblk(); 92 struct buf *geteblk(); 93 struct buf *getnewbuf(); 94 struct buf *bread(); 95 struct buf *breada(); 96 97 unsigned minphys(); 98 #endif 99 100 /* 101 * These flags are kept in b_flags. 102 */ 103 #define B_WRITE 0x000000 /* non-read pseudo-flag */ 104 #define B_READ 0x000001 /* read when I/O occurs */ 105 #define B_DONE 0x000002 /* transaction finished */ 106 #define B_ERROR 0x000004 /* transaction aborted */ 107 #define B_BUSY 0x000008 /* not on av_forw/back list */ 108 #define B_PHYS 0x000010 /* physical IO */ 109 #define B_XXX 0x000020 /* was B_MAP, alloc UNIBUS on pdp-11 */ 110 #define B_WANTED 0x000040 /* issue wakeup when BUSY goes off */ 111 #define B_AGE 0x000080 /* delayed write for correct aging */ 112 #define B_ASYNC 0x000100 /* don't wait for I/O completion */ 113 #define B_DELWRI 0x000200 /* write at exit of avail list */ 114 #define B_TAPE 0x000400 /* this is a magtape (no bdwrite) */ 115 #define B_UAREA 0x000800 /* add u-area to a swap operation */ 116 #define B_PAGET 0x001000 /* page in/out of page table space */ 117 #define B_DIRTY 0x002000 /* dirty page to be pushed out async */ 118 #define B_PGIN 0x004000 /* pagein op, so swap() can count it */ 119 #define B_CACHE 0x008000 /* did bread find us in the cache ? */ 120 #define B_INVAL 0x010000 /* does not contain valid info */ 121 #define B_LOCKED 0x020000 /* locked in core (not reusable) */ 122 #define B_HEAD 0x040000 /* a buffer header, not a buffer */ 123 #define B_BAD 0x100000 /* bad block revectoring in progress */ 124 #define B_CALL 0x200000 /* call b_iodone from iodone */ 125 126 /* 127 * Insq/Remq for the buffer hash lists. 128 */ 129 #define bremhash(bp) { \ 130 (bp)->b_back->b_forw = (bp)->b_forw; \ 131 (bp)->b_forw->b_back = (bp)->b_back; \ 132 } 133 #define binshash(bp, dp) { \ 134 (bp)->b_forw = (dp)->b_forw; \ 135 (bp)->b_back = (dp); \ 136 (dp)->b_forw->b_back = (bp); \ 137 (dp)->b_forw = (bp); \ 138 } 139 140 /* 141 * Insq/Remq for the buffer free lists. 142 */ 143 #define bremfree(bp) { \ 144 (bp)->av_back->av_forw = (bp)->av_forw; \ 145 (bp)->av_forw->av_back = (bp)->av_back; \ 146 } 147 #define binsheadfree(bp, dp) { \ 148 (dp)->av_forw->av_back = (bp); \ 149 (bp)->av_forw = (dp)->av_forw; \ 150 (dp)->av_forw = (bp); \ 151 (bp)->av_back = (dp); \ 152 } 153 #define binstailfree(bp, dp) { \ 154 (dp)->av_back->av_forw = (bp); \ 155 (bp)->av_back = (dp)->av_back; \ 156 (dp)->av_back = (bp); \ 157 (bp)->av_forw = (dp); \ 158 } 159 160 /* 161 * Take a buffer off the free list it's on and 162 * mark it as being use (B_BUSY) by a device. 163 */ 164 #define notavail(bp) { \ 165 int x = spl6(); \ 166 bremfree(bp); \ 167 (bp)->b_flags |= B_BUSY; \ 168 splx(x); \ 169 } 170 171 #define iodone biodone 172 #define iowait biowait 173 174 /* 175 * Zero out a buffer's data portion. 176 */ 177 #define clrbuf(bp) { \ 178 blkclr(bp->b_un.b_addr, bp->b_bcount); \ 179 bp->b_resid = 0; \ 180 } 181 182 #ifdef sun 183 /* 184 * Declarations for buffer space rmaps 185 */ 186 struct map *buffermap; 187 #define BUFMAPSIZE 256 188 189 /* 190 * "Average" size of a buffer 191 * nbuf*AVGBSIZE is total amount of buffer data 192 */ 193 #define AVGBSIZE 2048 194 195 /* 196 * Unit of buffer space allocation 197 */ 198 #define BUFALLOCSIZE 1024 199 #endif 200