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