1*65791Smckusick /*-
2*65791Smckusick * Copyright (c) 1982, 1986, 1989, 1993
3*65791Smckusick * The Regents of the University of California. All rights reserved.
4*65791Smckusick * (c) UNIX System Laboratories, Inc.
5*65791Smckusick * All or some portions of this file are derived from material licensed
6*65791Smckusick * to the University of California by American Telephone and Telegraph
7*65791Smckusick * Co. or Unix System Laboratories, Inc. and are reproduced herein with
8*65791Smckusick * the permission of UNIX System Laboratories, Inc.
949678Smckusick *
1049678Smckusick * %sccs.include.redist.c%
1149678Smckusick *
12*65791Smckusick * from: @(#)vfs_bio.c 8.6 (Berkeley) 1/11/94
1349678Smckusick */
1449678Smckusick
15*65791Smckusick #include <sys/param.h>
16*65791Smckusick #include <sys/systm.h>
17*65791Smckusick #include <sys/proc.h>
18*65791Smckusick #include <sys/buf.h>
19*65791Smckusick #include <sys/vnode.h>
20*65791Smckusick #include <sys/mount.h>
21*65791Smckusick #include <sys/trace.h>
22*65791Smckusick #include <sys/malloc.h>
23*65791Smckusick #include <sys/resourcevar.h>
2449678Smckusick
2549678Smckusick /*
26*65791Smckusick * Definitions for the buffer hash lists.
2749678Smckusick */
28*65791Smckusick #define BUFHASH(dvp, lbn) \
29*65791Smckusick (&bufhashtbl[((int)(dvp) / sizeof(*(dvp)) + (int)(lbn)) & bufhash])
30*65791Smckusick LIST_HEAD(bufhashhdr, buf) *bufhashtbl, invalhash;
31*65791Smckusick u_long bufhash;
32*65791Smckusick
33*65791Smckusick /*
34*65791Smckusick * Insq/Remq for the buffer hash lists.
35*65791Smckusick */
36*65791Smckusick #define binshash(bp, dp) LIST_INSERT_HEAD(dp, bp, b_hash)
37*65791Smckusick #define bremhash(bp) LIST_REMOVE(bp, b_hash)
38*65791Smckusick
39*65791Smckusick /*
40*65791Smckusick * Definitions for the buffer free lists.
41*65791Smckusick */
42*65791Smckusick #define BQUEUES 4 /* number of free buffer queues */
43*65791Smckusick
44*65791Smckusick #define BQ_LOCKED 0 /* super-blocks &c */
45*65791Smckusick #define BQ_LRU 1 /* lru, useful buffers */
46*65791Smckusick #define BQ_AGE 2 /* rubbish */
47*65791Smckusick #define BQ_EMPTY 3 /* buffer headers with no memory */
48*65791Smckusick
49*65791Smckusick TAILQ_HEAD(bqueues, buf) bufqueues[BQUEUES];
50*65791Smckusick int needbuffer;
51*65791Smckusick
52*65791Smckusick /*
53*65791Smckusick * Insq/Remq for the buffer free lists.
54*65791Smckusick */
55*65791Smckusick #define binsheadfree(bp, dp) TAILQ_INSERT_HEAD(dp, bp, b_freelist)
56*65791Smckusick #define binstailfree(bp, dp) TAILQ_INSERT_TAIL(dp, bp, b_freelist)
57*65791Smckusick
58*65791Smckusick void
bremfree(bp)59*65791Smckusick bremfree(bp)
60*65791Smckusick struct buf *bp;
6149678Smckusick {
62*65791Smckusick struct bqueues *dp = NULL;
6349678Smckusick
6449678Smckusick /*
65*65791Smckusick * We only calculate the head of the freelist when removing
66*65791Smckusick * the last element of the list as that is the only time that
67*65791Smckusick * it is needed (e.g. to reset the tail pointer).
68*65791Smckusick *
69*65791Smckusick * NB: This makes an assumption about how tailq's are implemented.
7049678Smckusick */
71*65791Smckusick if (bp->b_freelist.tqe_next == NULL) {
72*65791Smckusick for (dp = bufqueues; dp < &bufqueues[BQUEUES]; dp++)
73*65791Smckusick if (dp->tqh_last == &bp->b_freelist.tqe_next)
74*65791Smckusick break;
75*65791Smckusick if (dp == &bufqueues[BQUEUES])
76*65791Smckusick panic("bremfree: lost tail");
77*65791Smckusick }
78*65791Smckusick TAILQ_REMOVE(dp, bp, b_freelist);
7949678Smckusick }
8049678Smckusick
8149678Smckusick /*
82*65791Smckusick * Initialize buffers and hash links for buffers.
8349678Smckusick */
84*65791Smckusick void
bufinit()85*65791Smckusick bufinit()
8649678Smckusick {
87*65791Smckusick register struct buf *bp;
88*65791Smckusick struct bqueues *dp;
89*65791Smckusick register int i;
90*65791Smckusick int base, residual;
9149678Smckusick
92*65791Smckusick for (dp = bufqueues; dp < &bufqueues[BQUEUES]; dp++)
93*65791Smckusick TAILQ_INIT(dp);
94*65791Smckusick bufhashtbl = hashinit(nbuf, M_CACHE, &bufhash);
95*65791Smckusick base = bufpages / nbuf;
96*65791Smckusick residual = bufpages % nbuf;
97*65791Smckusick for (i = 0; i < nbuf; i++) {
98*65791Smckusick bp = &buf[i];
99*65791Smckusick bzero((char *)bp, sizeof *bp);
100*65791Smckusick bp->b_dev = NODEV;
101*65791Smckusick bp->b_rcred = NOCRED;
102*65791Smckusick bp->b_wcred = NOCRED;
103*65791Smckusick bp->b_vnbufs.le_next = NOLIST;
104*65791Smckusick bp->b_data = buffers + i * MAXBSIZE;
105*65791Smckusick if (i < residual)
106*65791Smckusick bp->b_bufsize = (base + 1) * CLBYTES;
107*65791Smckusick else
108*65791Smckusick bp->b_bufsize = base * CLBYTES;
109*65791Smckusick bp->b_flags = B_INVAL;
110*65791Smckusick dp = bp->b_bufsize ? &bufqueues[BQ_AGE] : &bufqueues[BQ_EMPTY];
111*65791Smckusick binsheadfree(bp, dp);
112*65791Smckusick binshash(bp, &invalhash);
113*65791Smckusick }
114*65791Smckusick }
115*65791Smckusick
116*65791Smckusick bread(a1, a2, a3, a4, a5)
117*65791Smckusick struct vnode *a1;
118*65791Smckusick daddr_t a2;
119*65791Smckusick int a3;
120*65791Smckusick struct ucred *a4;
121*65791Smckusick struct buf **a5;
122*65791Smckusick {
123*65791Smckusick
12449678Smckusick /*
12549678Smckusick * Body deleted.
12649678Smckusick */
12749678Smckusick return (EIO);
12849678Smckusick }
12949678Smckusick
130*65791Smckusick breadn(a1, a2, a3, a4, a5, a6, a7, a8)
131*65791Smckusick struct vnode *a1;
132*65791Smckusick daddr_t a2; int a3;
133*65791Smckusick daddr_t a4[]; int a5[];
134*65791Smckusick int a6;
135*65791Smckusick struct ucred *a7;
136*65791Smckusick struct buf **a8;
13749678Smckusick {
13849678Smckusick
13949678Smckusick /*
14049678Smckusick * Body deleted.
14149678Smckusick */
14249678Smckusick return (EIO);
14349678Smckusick }
14449678Smckusick
145*65791Smckusick bwrite(a1)
146*65791Smckusick struct buf *a1;
14749678Smckusick {
14849678Smckusick
14949678Smckusick /*
15049678Smckusick * Body deleted.
15149678Smckusick */
15249678Smckusick return (EIO);
15349678Smckusick }
15449678Smckusick
155*65791Smckusick int
vn_bwrite(ap)156*65791Smckusick vn_bwrite(ap)
157*65791Smckusick struct vop_bwrite_args *ap;
15849678Smckusick {
159*65791Smckusick return (bwrite(ap->a_bp));
160*65791Smckusick }
16149678Smckusick
162*65791Smckusick bdwrite(a1)
163*65791Smckusick struct buf *a1;
164*65791Smckusick {
165*65791Smckusick
16649678Smckusick /*
16749678Smckusick * Body deleted.
16849678Smckusick */
16949678Smckusick return;
17049678Smckusick }
17149678Smckusick
172*65791Smckusick bawrite(a1)
173*65791Smckusick struct buf *a1;
17449678Smckusick {
17549678Smckusick
17649678Smckusick /*
17749678Smckusick * Body deleted.
17849678Smckusick */
17949678Smckusick return;
18049678Smckusick }
18149678Smckusick
182*65791Smckusick brelse(a1)
183*65791Smckusick struct buf *a1;
18449678Smckusick {
18549678Smckusick
18649678Smckusick /*
18749678Smckusick * Body deleted.
18849678Smckusick */
18949678Smckusick return;
19049678Smckusick }
19149678Smckusick
192*65791Smckusick struct buf *
incore(a1,a2)193*65791Smckusick incore(a1, a2)
194*65791Smckusick struct vnode *a1;
195*65791Smckusick daddr_t a2;
19649678Smckusick {
19749678Smckusick
19849678Smckusick /*
19949678Smckusick * Body deleted.
20049678Smckusick */
20149678Smckusick return (0);
20249678Smckusick }
20349678Smckusick
20449678Smckusick struct buf *
getblk(a1,a2,a3,a4,a5)205*65791Smckusick getblk(a1, a2, a3, a4, a5)
206*65791Smckusick struct vnode *a1;
207*65791Smckusick daddr_t a2;
208*65791Smckusick int a3, a4, a5;
20949678Smckusick {
21049678Smckusick
21149678Smckusick /*
21249678Smckusick * Body deleted.
21349678Smckusick */
214*65791Smckusick return ((struct buf *)0);
21549678Smckusick }
21649678Smckusick
21749678Smckusick struct buf *
geteblk(a1)218*65791Smckusick geteblk(a1)
219*65791Smckusick int a1;
22049678Smckusick {
22149678Smckusick
22249678Smckusick /*
22349678Smckusick * Body deleted.
22449678Smckusick */
225*65791Smckusick return ((struct buf *)0);
22649678Smckusick }
22749678Smckusick
228*65791Smckusick allocbuf(a1, a2)
229*65791Smckusick struct buf *a1;
230*65791Smckusick int a2;
23149678Smckusick {
23249678Smckusick
23349678Smckusick /*
23449678Smckusick * Body deleted.
23549678Smckusick */
23649678Smckusick return (0);
23749678Smckusick }
23849678Smckusick
23949678Smckusick struct buf *
getnewbuf(a1,a2)240*65791Smckusick getnewbuf(a1, a2)
241*65791Smckusick int a1, a2;
24249678Smckusick {
24349678Smckusick
24449678Smckusick /*
24549678Smckusick * Body deleted.
24649678Smckusick */
247*65791Smckusick return ((struct buf *)0);
24849678Smckusick }
24949678Smckusick
250*65791Smckusick biowait(a1)
251*65791Smckusick struct buf *a1;
25249678Smckusick {
25349678Smckusick
25449678Smckusick /*
25549678Smckusick * Body deleted.
25649678Smckusick */
25749678Smckusick return (EIO);
25849678Smckusick }
25949678Smckusick
260*65791Smckusick void
biodone(a1)261*65791Smckusick biodone(a1)
262*65791Smckusick struct buf *a1;
26349678Smckusick {
26449678Smckusick
26549678Smckusick /*
26649678Smckusick * Body deleted.
26749678Smckusick */
268*65791Smckusick return;
26949678Smckusick }
270*65791Smckusick
271*65791Smckusick int
count_lock_queue()272*65791Smckusick count_lock_queue()
273*65791Smckusick {
274*65791Smckusick
275*65791Smckusick /*
276*65791Smckusick * Body deleted.
277*65791Smckusick */
278*65791Smckusick return (0);
279*65791Smckusick }
280*65791Smckusick
281*65791Smckusick #ifdef DIAGNOSTIC
282*65791Smckusick /*
283*65791Smckusick * Print out statistics on the current allocation of the buffer pool.
284*65791Smckusick * Can be enabled to print out on every ``sync'' by setting "syncprt"
285*65791Smckusick * in vfs_syscalls.c using sysctl.
286*65791Smckusick */
287*65791Smckusick void
vfs_bufstats()288*65791Smckusick vfs_bufstats()
289*65791Smckusick {
290*65791Smckusick int s, i, j, count;
291*65791Smckusick register struct buf *bp;
292*65791Smckusick register struct bqueues *dp;
293*65791Smckusick int counts[MAXBSIZE/CLBYTES+1];
294*65791Smckusick static char *bname[BQUEUES] = { "LOCKED", "LRU", "AGE", "EMPTY" };
295*65791Smckusick
296*65791Smckusick for (dp = bufqueues, i = 0; dp < &bufqueues[BQUEUES]; dp++, i++) {
297*65791Smckusick count = 0;
298*65791Smckusick for (j = 0; j <= MAXBSIZE/CLBYTES; j++)
299*65791Smckusick counts[j] = 0;
300*65791Smckusick s = splbio();
301*65791Smckusick for (bp = dp->tqh_first; bp; bp = bp->b_freelist.tqe_next) {
302*65791Smckusick counts[bp->b_bufsize/CLBYTES]++;
303*65791Smckusick count++;
304*65791Smckusick }
305*65791Smckusick splx(s);
306*65791Smckusick printf("%s: total-%d", bname[i], count);
307*65791Smckusick for (j = 0; j <= MAXBSIZE/CLBYTES; j++)
308*65791Smckusick if (counts[j] != 0)
309*65791Smckusick printf(", %d-%d", j * CLBYTES, counts[j]);
310*65791Smckusick printf("\n");
311*65791Smckusick }
312*65791Smckusick }
313*65791Smckusick #endif /* DIAGNOSTIC */
314