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