1 /*- 2 * Copyright (c) 1982, 1986, 1989, 1993 3 * The Regents of the University of California. All rights reserved. 4 * (c) UNIX System Laboratories, Inc. 5 * All or some portions of this file are derived from material licensed 6 * to the University of California by American Telephone and Telegraph 7 * Co. or Unix System Laboratories, Inc. and are reproduced herein with 8 * the permission of UNIX System Laboratories, Inc. 9 * 10 * %sccs.include.redist.c% 11 * 12 * from: @(#)vfs_bio.c 8.6 (Berkeley) 1/11/94 13 */ 14 15 #include <sys/param.h> 16 #include <sys/systm.h> 17 #include <sys/proc.h> 18 #include <sys/buf.h> 19 #include <sys/vnode.h> 20 #include <sys/mount.h> 21 #include <sys/trace.h> 22 #include <sys/malloc.h> 23 #include <sys/resourcevar.h> 24 25 /* 26 * Definitions for the buffer hash lists. 27 */ 28 #define BUFHASH(dvp, lbn) \ 29 (&bufhashtbl[((int)(dvp) / sizeof(*(dvp)) + (int)(lbn)) & bufhash]) 30 LIST_HEAD(bufhashhdr, buf) *bufhashtbl, invalhash; 31 u_long bufhash; 32 33 /* 34 * Insq/Remq for the buffer hash lists. 35 */ 36 #define binshash(bp, dp) LIST_INSERT_HEAD(dp, bp, b_hash) 37 #define bremhash(bp) LIST_REMOVE(bp, b_hash) 38 39 /* 40 * Definitions for the buffer free lists. 41 */ 42 #define BQUEUES 4 /* number of free buffer queues */ 43 44 #define BQ_LOCKED 0 /* super-blocks &c */ 45 #define BQ_LRU 1 /* lru, useful buffers */ 46 #define BQ_AGE 2 /* rubbish */ 47 #define BQ_EMPTY 3 /* buffer headers with no memory */ 48 49 TAILQ_HEAD(bqueues, buf) bufqueues[BQUEUES]; 50 int needbuffer; 51 52 /* 53 * Insq/Remq for the buffer free lists. 54 */ 55 #define binsheadfree(bp, dp) TAILQ_INSERT_HEAD(dp, bp, b_freelist) 56 #define binstailfree(bp, dp) TAILQ_INSERT_TAIL(dp, bp, b_freelist) 57 58 void 59 bremfree(bp) 60 struct buf *bp; 61 { 62 struct bqueues *dp = NULL; 63 64 /* 65 * We only calculate the head of the freelist when removing 66 * the last element of the list as that is the only time that 67 * it is needed (e.g. to reset the tail pointer). 68 * 69 * NB: This makes an assumption about how tailq's are implemented. 70 */ 71 if (bp->b_freelist.tqe_next == NULL) { 72 for (dp = bufqueues; dp < &bufqueues[BQUEUES]; dp++) 73 if (dp->tqh_last == &bp->b_freelist.tqe_next) 74 break; 75 if (dp == &bufqueues[BQUEUES]) 76 panic("bremfree: lost tail"); 77 } 78 TAILQ_REMOVE(dp, bp, b_freelist); 79 } 80 81 /* 82 * Initialize buffers and hash links for buffers. 83 */ 84 void 85 bufinit() 86 { 87 register struct buf *bp; 88 struct bqueues *dp; 89 register int i; 90 int base, residual; 91 92 for (dp = bufqueues; dp < &bufqueues[BQUEUES]; dp++) 93 TAILQ_INIT(dp); 94 bufhashtbl = hashinit(nbuf, M_CACHE, &bufhash); 95 base = bufpages / nbuf; 96 residual = bufpages % nbuf; 97 for (i = 0; i < nbuf; i++) { 98 bp = &buf[i]; 99 bzero((char *)bp, sizeof *bp); 100 bp->b_dev = NODEV; 101 bp->b_rcred = NOCRED; 102 bp->b_wcred = NOCRED; 103 bp->b_vnbufs.le_next = NOLIST; 104 bp->b_data = buffers + i * MAXBSIZE; 105 if (i < residual) 106 bp->b_bufsize = (base + 1) * CLBYTES; 107 else 108 bp->b_bufsize = base * CLBYTES; 109 bp->b_flags = B_INVAL; 110 dp = bp->b_bufsize ? &bufqueues[BQ_AGE] : &bufqueues[BQ_EMPTY]; 111 binsheadfree(bp, dp); 112 binshash(bp, &invalhash); 113 } 114 } 115 116 bread(a1, a2, a3, a4, a5) 117 struct vnode *a1; 118 daddr_t a2; 119 int a3; 120 struct ucred *a4; 121 struct buf **a5; 122 { 123 124 /* 125 * Body deleted. 126 */ 127 return (EIO); 128 } 129 130 breadn(a1, a2, a3, a4, a5, a6, a7, a8) 131 struct vnode *a1; 132 daddr_t a2; int a3; 133 daddr_t a4[]; int a5[]; 134 int a6; 135 struct ucred *a7; 136 struct buf **a8; 137 { 138 139 /* 140 * Body deleted. 141 */ 142 return (EIO); 143 } 144 145 bwrite(a1) 146 struct buf *a1; 147 { 148 149 /* 150 * Body deleted. 151 */ 152 return (EIO); 153 } 154 155 int 156 vn_bwrite(ap) 157 struct vop_bwrite_args *ap; 158 { 159 return (bwrite(ap->a_bp)); 160 } 161 162 bdwrite(a1) 163 struct buf *a1; 164 { 165 166 /* 167 * Body deleted. 168 */ 169 return; 170 } 171 172 bawrite(a1) 173 struct buf *a1; 174 { 175 176 /* 177 * Body deleted. 178 */ 179 return; 180 } 181 182 brelse(a1) 183 struct buf *a1; 184 { 185 186 /* 187 * Body deleted. 188 */ 189 return; 190 } 191 192 struct buf * 193 incore(a1, a2) 194 struct vnode *a1; 195 daddr_t a2; 196 { 197 198 /* 199 * Body deleted. 200 */ 201 return (0); 202 } 203 204 struct buf * 205 getblk(a1, a2, a3, a4, a5) 206 struct vnode *a1; 207 daddr_t a2; 208 int a3, a4, a5; 209 { 210 211 /* 212 * Body deleted. 213 */ 214 return ((struct buf *)0); 215 } 216 217 struct buf * 218 geteblk(a1) 219 int a1; 220 { 221 222 /* 223 * Body deleted. 224 */ 225 return ((struct buf *)0); 226 } 227 228 allocbuf(a1, a2) 229 struct buf *a1; 230 int a2; 231 { 232 233 /* 234 * Body deleted. 235 */ 236 return (0); 237 } 238 239 struct buf * 240 getnewbuf(a1, a2) 241 int a1, a2; 242 { 243 244 /* 245 * Body deleted. 246 */ 247 return ((struct buf *)0); 248 } 249 250 biowait(a1) 251 struct buf *a1; 252 { 253 254 /* 255 * Body deleted. 256 */ 257 return (EIO); 258 } 259 260 void 261 biodone(a1) 262 struct buf *a1; 263 { 264 265 /* 266 * Body deleted. 267 */ 268 return; 269 } 270 271 int 272 count_lock_queue() 273 { 274 275 /* 276 * Body deleted. 277 */ 278 return (0); 279 } 280 281 #ifdef DIAGNOSTIC 282 /* 283 * Print out statistics on the current allocation of the buffer pool. 284 * Can be enabled to print out on every ``sync'' by setting "syncprt" 285 * in vfs_syscalls.c using sysctl. 286 */ 287 void 288 vfs_bufstats() 289 { 290 int s, i, j, count; 291 register struct buf *bp; 292 register struct bqueues *dp; 293 int counts[MAXBSIZE/CLBYTES+1]; 294 static char *bname[BQUEUES] = { "LOCKED", "LRU", "AGE", "EMPTY" }; 295 296 for (dp = bufqueues, i = 0; dp < &bufqueues[BQUEUES]; dp++, i++) { 297 count = 0; 298 for (j = 0; j <= MAXBSIZE/CLBYTES; j++) 299 counts[j] = 0; 300 s = splbio(); 301 for (bp = dp->tqh_first; bp; bp = bp->b_freelist.tqe_next) { 302 counts[bp->b_bufsize/CLBYTES]++; 303 count++; 304 } 305 splx(s); 306 printf("%s: total-%d", bname[i], count); 307 for (j = 0; j <= MAXBSIZE/CLBYTES; j++) 308 if (counts[j] != 0) 309 printf(", %d-%d", j * CLBYTES, counts[j]); 310 printf("\n"); 311 } 312 } 313 #endif /* DIAGNOSTIC */ 314