vfs_bio.c revision 1542
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 * Redistribution and use in source and binary forms, with or without 11 * modification, are permitted provided that the following conditions 12 * are met: 13 * 1. Redistributions of source code must retain the above copyright 14 * notice, this list of conditions and the following disclaimer. 15 * 2. Redistributions in binary form must reproduce the above copyright 16 * notice, this list of conditions and the following disclaimer in the 17 * documentation and/or other materials provided with the distribution. 18 * 3. All advertising materials mentioning features or use of this software 19 * must display the following acknowledgement: 20 * This product includes software developed by the University of 21 * California, Berkeley and its contributors. 22 * 4. Neither the name of the University nor the names of its contributors 23 * may be used to endorse or promote products derived from this software 24 * without specific prior written permission. 25 * 26 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 27 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 28 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 29 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 30 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 31 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 32 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 33 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 34 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 35 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 36 * SUCH DAMAGE. 37 * 38 * from: @(#)vfs_bio.c 8.6 (Berkeley) 1/11/94 39 */ 40 41#include <sys/param.h> 42#include <sys/systm.h> 43#include <sys/proc.h> 44#include <sys/buf.h> 45#include <sys/vnode.h> 46#include <sys/mount.h> 47#include <sys/trace.h> 48#include <sys/malloc.h> 49#include <sys/resourcevar.h> 50 51/* 52 * Definitions for the buffer hash lists. 53 */ 54#define BUFHASH(dvp, lbn) \ 55 (&bufhashtbl[((int)(dvp) / sizeof(*(dvp)) + (int)(lbn)) & bufhash]) 56LIST_HEAD(bufhashhdr, buf) *bufhashtbl, invalhash; 57u_long bufhash; 58 59/* 60 * Insq/Remq for the buffer hash lists. 61 */ 62#define binshash(bp, dp) LIST_INSERT_HEAD(dp, bp, b_hash) 63#define bremhash(bp) LIST_REMOVE(bp, b_hash) 64 65/* 66 * Definitions for the buffer free lists. 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 75TAILQ_HEAD(bqueues, buf) bufqueues[BQUEUES]; 76int needbuffer; 77 78/* 79 * Insq/Remq for the buffer free lists. 80 */ 81#define binsheadfree(bp, dp) TAILQ_INSERT_HEAD(dp, bp, b_freelist) 82#define binstailfree(bp, dp) TAILQ_INSERT_TAIL(dp, bp, b_freelist) 83 84void 85bremfree(bp) 86 struct buf *bp; 87{ 88 struct bqueues *dp = NULL; 89 90 /* 91 * We only calculate the head of the freelist when removing 92 * the last element of the list as that is the only time that 93 * it is needed (e.g. to reset the tail pointer). 94 * 95 * NB: This makes an assumption about how tailq's are implemented. 96 */ 97 if (bp->b_freelist.tqe_next == NULL) { 98 for (dp = bufqueues; dp < &bufqueues[BQUEUES]; dp++) 99 if (dp->tqh_last == &bp->b_freelist.tqe_next) 100 break; 101 if (dp == &bufqueues[BQUEUES]) 102 panic("bremfree: lost tail"); 103 } 104 TAILQ_REMOVE(dp, bp, b_freelist); 105} 106 107/* 108 * Initialize buffers and hash links for buffers. 109 */ 110void 111bufinit() 112{ 113 register struct buf *bp; 114 struct bqueues *dp; 115 register int i; 116 int base, residual; 117 118 for (dp = bufqueues; dp < &bufqueues[BQUEUES]; dp++) 119 TAILQ_INIT(dp); 120 bufhashtbl = hashinit(nbuf, M_CACHE, &bufhash); 121 base = bufpages / nbuf; 122 residual = bufpages % nbuf; 123 for (i = 0; i < nbuf; i++) { 124 bp = &buf[i]; 125 bzero((char *)bp, sizeof *bp); 126 bp->b_dev = NODEV; 127 bp->b_rcred = NOCRED; 128 bp->b_wcred = NOCRED; 129 bp->b_vnbufs.le_next = NOLIST; 130 bp->b_data = buffers + i * MAXBSIZE; 131 if (i < residual) 132 bp->b_bufsize = (base + 1) * CLBYTES; 133 else 134 bp->b_bufsize = base * CLBYTES; 135 bp->b_flags = B_INVAL; 136 dp = bp->b_bufsize ? &bufqueues[BQ_AGE] : &bufqueues[BQ_EMPTY]; 137 binsheadfree(bp, dp); 138 binshash(bp, &invalhash); 139 } 140} 141 142bread(a1, a2, a3, a4, a5) 143 struct vnode *a1; 144 daddr_t a2; 145 int a3; 146 struct ucred *a4; 147 struct buf **a5; 148{ 149 150 /* 151 * Body deleted. 152 */ 153 return (EIO); 154} 155 156breadn(a1, a2, a3, a4, a5, a6, a7, a8) 157 struct vnode *a1; 158 daddr_t a2; int a3; 159 daddr_t a4[]; int a5[]; 160 int a6; 161 struct ucred *a7; 162 struct buf **a8; 163{ 164 165 /* 166 * Body deleted. 167 */ 168 return (EIO); 169} 170 171bwrite(a1) 172 struct buf *a1; 173{ 174 175 /* 176 * Body deleted. 177 */ 178 return (EIO); 179} 180 181int 182vn_bwrite(ap) 183 struct vop_bwrite_args *ap; 184{ 185 return (bwrite(ap->a_bp)); 186} 187 188bdwrite(a1) 189 struct buf *a1; 190{ 191 192 /* 193 * Body deleted. 194 */ 195 return; 196} 197 198bawrite(a1) 199 struct buf *a1; 200{ 201 202 /* 203 * Body deleted. 204 */ 205 return; 206} 207 208brelse(a1) 209 struct buf *a1; 210{ 211 212 /* 213 * Body deleted. 214 */ 215 return; 216} 217 218struct buf * 219incore(a1, a2) 220 struct vnode *a1; 221 daddr_t a2; 222{ 223 224 /* 225 * Body deleted. 226 */ 227 return (0); 228} 229 230struct buf * 231getblk(a1, a2, a3, a4, a5) 232 struct vnode *a1; 233 daddr_t a2; 234 int a3, a4, a5; 235{ 236 237 /* 238 * Body deleted. 239 */ 240 return ((struct buf *)0); 241} 242 243struct buf * 244geteblk(a1) 245 int a1; 246{ 247 248 /* 249 * Body deleted. 250 */ 251 return ((struct buf *)0); 252} 253 254allocbuf(a1, a2) 255 struct buf *a1; 256 int a2; 257{ 258 259 /* 260 * Body deleted. 261 */ 262 return (0); 263} 264 265struct buf * 266getnewbuf(a1, a2) 267 int a1, a2; 268{ 269 270 /* 271 * Body deleted. 272 */ 273 return ((struct buf *)0); 274} 275 276biowait(a1) 277 struct buf *a1; 278{ 279 280 /* 281 * Body deleted. 282 */ 283 return (EIO); 284} 285 286void 287biodone(a1) 288 struct buf *a1; 289{ 290 291 /* 292 * Body deleted. 293 */ 294 return; 295} 296 297int 298count_lock_queue() 299{ 300 301 /* 302 * Body deleted. 303 */ 304 return (0); 305} 306 307#ifdef DIAGNOSTIC 308/* 309 * Print out statistics on the current allocation of the buffer pool. 310 * Can be enabled to print out on every ``sync'' by setting "syncprt" 311 * in vfs_syscalls.c using sysctl. 312 */ 313void 314vfs_bufstats() 315{ 316 int s, i, j, count; 317 register struct buf *bp; 318 register struct bqueues *dp; 319 int counts[MAXBSIZE/CLBYTES+1]; 320 static char *bname[BQUEUES] = { "LOCKED", "LRU", "AGE", "EMPTY" }; 321 322 for (dp = bufqueues, i = 0; dp < &bufqueues[BQUEUES]; dp++, i++) { 323 count = 0; 324 for (j = 0; j <= MAXBSIZE/CLBYTES; j++) 325 counts[j] = 0; 326 s = splbio(); 327 for (bp = dp->tqh_first; bp; bp = bp->b_freelist.tqe_next) { 328 counts[bp->b_bufsize/CLBYTES]++; 329 count++; 330 } 331 splx(s); 332 printf("%s: total-%d", bname[i], count); 333 for (j = 0; j <= MAXBSIZE/CLBYTES; j++) 334 if (counts[j] != 0) 335 printf(", %d-%d", j * CLBYTES, counts[j]); 336 printf("\n"); 337 } 338} 339#endif /* DIAGNOSTIC */ 340