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