386BSD 0.1 development
[unix-history] / usr / src / sys.386bsd / sys / buf.h
CommitLineData
f4566079
WJ
1/*
2 * Copyright (c) 1982, 1986, 1989 Regents of the University of California.
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. All advertising materials mentioning features or use of this software
14 * must display the following acknowledgement:
15 * This product includes software developed by the University of
16 * California, Berkeley and its contributors.
17 * 4. Neither the name of the University nor the names of its contributors
18 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 * SUCH DAMAGE.
32 *
33 * @(#)buf.h 7.11 (Berkeley) 5/9/90
34 */
35
36/*
37 * The header for buffers in the buffer pool and otherwise used
38 * to describe a block i/o request is given here.
39 *
40 * Each buffer in the pool is usually doubly linked into 2 lists:
41 * hashed into a chain by <dev,blkno> so it can be located in the cache,
42 * and (usually) on (one of several) queues. These lists are circular and
43 * doubly linked for easy removal.
44 *
45 * There are currently three queues for buffers:
46 * one for buffers which must be kept permanently (super blocks)
47 * one for buffers containing ``useful'' information (the cache)
48 * one for buffers containing ``non-useful'' information
49 * (and empty buffers, pushed onto the front)
50 * The latter two queues contain the buffers which are available for
51 * reallocation, are kept in lru order. When not on one of these queues,
52 * the buffers are ``checked out'' to drivers which use the available list
53 * pointers to keep track of them in their i/o active queues.
54 */
55
56/*
57 * Bufhd structures used at the head of the hashed buffer queues.
58 * We only need three words for these, so this abbreviated
59 * definition saves some space.
60 */
61struct bufhd
62{
63 long b_flags; /* see defines below */
64 struct buf *b_forw, *b_back; /* fwd/bkwd pointer in chain */
65};
66struct buf
67{
68 long b_flags; /* too much goes here to describe */
69 struct buf *b_forw, *b_back; /* hash chain (2 way street) */
70 struct buf *av_forw, *av_back; /* position on free list if not BUSY */
71 struct buf *b_blockf, **b_blockb;/* associated vnode */
72#define b_actf av_forw /* alternate names for driver queue */
73#define b_actl av_back /* head - isn't history wonderful */
74 long b_bcount; /* transfer count */
75 long b_bufsize; /* size of allocated buffer */
76#define b_active b_bcount /* driver queue head: drive active */
77 short b_error; /* returned after I/O */
78 dev_t b_dev; /* major+minor device name */
79 union {
80 caddr_t b_addr; /* low order core address */
81 int *b_words; /* words for clearing */
82 struct fs *b_fs; /* superblocks */
83 struct csum *b_cs; /* superblock summary information */
84 struct cg *b_cg; /* cylinder group block */
85 struct dinode *b_dino; /* ilist */
86 daddr_t *b_daddr; /* indirect block */
87 } b_un;
88 daddr_t b_lblkno; /* logical block number */
89 daddr_t b_blkno; /* block # on device */
90 long b_resid; /* words not transferred after error */
91#define b_errcnt b_resid /* while i/o in progress: # retries */
92 struct proc *b_proc; /* proc doing physical or swap I/O */
93 int (*b_iodone)(); /* function called by iodone */
94 struct vnode *b_vp; /* vnode for dev */
95 int b_pfcent; /* center page when swapping cluster */
96 struct ucred *b_rcred; /* ref to read credentials */
97 struct ucred *b_wcred; /* ref to write credendtials */
98 int b_dirtyoff; /* offset in buffer of dirty region */
99 int b_dirtyend; /* offset of end of dirty region */
100 caddr_t b_saveaddr; /* original b_addr for PHYSIO */
101};
102
103#define BQUEUES 4 /* number of free buffer queues */
104
105#define BQ_LOCKED 0 /* super-blocks &c */
106#define BQ_LRU 1 /* lru, useful buffers */
107#define BQ_AGE 2 /* rubbish */
108#define BQ_EMPTY 3 /* buffer headers with no memory */
109
110#ifdef KERNEL
111#define BUFHSZ 512
112#define RND (MAXBSIZE/DEV_BSIZE)
113#if ((BUFHSZ&(BUFHSZ-1)) == 0)
114#define BUFHASH(dvp, dblkno) \
115 ((struct buf *)&bufhash[((int)(dvp)+(((int)(dblkno))/RND))&(BUFHSZ-1)])
116#else
117#define BUFHASH(dvp, dblkno) \
118 ((struct buf *)&bufhash[((int)(dvp)+(((int)(dblkno))/RND)) % BUFHSZ])
119#endif
120
121struct buf *buf; /* the buffer pool itself */
122char *buffers;
123int nbuf; /* number of buffer headers */
124int bufpages; /* number of memory pages in the buffer pool */
125struct buf *swbuf; /* swap I/O headers */
126int nswbuf;
127struct bufhd bufhash[BUFHSZ]; /* heads of hash lists */
128struct buf bfreelist[BQUEUES]; /* heads of available lists */
129struct buf bswlist; /* head of free swap header list */
130struct buf *bclnlist; /* head of cleaned page list */
131
132void bufinit();
133int bread(struct vnode *, daddr_t, int, struct ucred *, struct buf **);
134int breada(struct vnode *, daddr_t, int, daddr_t, int, struct ucred *,
135 struct buf **);
136int bwrite(struct buf *);
137void bawrite(struct buf *);
138void bdwrite(struct buf *);
139void brelse(struct buf *);
140struct buf *incore(struct vnode *, daddr_t);
141struct buf *getblk(struct vnode *, daddr_t, int);
142struct buf *geteblk(int);
143int biowait(struct buf *);
144int biodone(struct buf *);
145void allocbuf(struct buf *, int);
146
147#endif
148
149/*
150 * These flags are kept in b_flags.
151 */
152#define B_WRITE 0x000000 /* non-read pseudo-flag */
153#define B_READ 0x000001 /* read when I/O occurs */
154#define B_DONE 0x000002 /* transaction finished */
155#define B_ERROR 0x000004 /* transaction aborted */
156#define B_BUSY 0x000008 /* not on av_forw/back list */
157#define B_PHYS 0x000010 /* physical IO */
158#define B_XXX 0x000020 /* was B_MAP, alloc UNIBUS on pdp-11 */
159#define B_WANTED 0x000040 /* issue wakeup when BUSY goes off */
160#define B_AGE 0x000080 /* delayed write for correct aging */
161#define B_ASYNC 0x000100 /* don't wait for I/O completion */
162#define B_DELWRI 0x000200 /* write at exit of avail list */
163#define B_TAPE 0x000400 /* this is a magtape (no bdwrite) */
164#define B_VMPAGE 0x000800 /* buffer from virtual memory */
165#define B_MALLOC 0x001000 /* buffer from malloc space */
166#define B_DIRTY 0x002000 /* dirty page to be pushed out async */
167#define B_PGIN 0x004000 /* pagein op, so swap() can count it */
168#define B_CACHE 0x008000 /* did bread find us in the cache ? */
169#define B_INVAL 0x010000 /* does not contain valid info */
170#define B_LOCKED 0x020000 /* locked in core (not reusable) */
171#define B_HEAD 0x040000 /* a buffer header, not a buffer */
172#define B_BAD 0x100000 /* bad block revectoring in progress */
173#define B_CALL 0x200000 /* call b_iodone from iodone */
174#define B_RAW 0x400000 /* set by physio for raw transfers */
175#define B_NOCACHE 0x800000 /* do not cache block after use */
176
177/*
178 * Insq/Remq for the buffer hash lists.
179 */
180#define bremhash(bp) { \
181 (bp)->b_back->b_forw = (bp)->b_forw; \
182 (bp)->b_forw->b_back = (bp)->b_back; \
183}
184#define binshash(bp, dp) { \
185 (bp)->b_forw = (dp)->b_forw; \
186 (bp)->b_back = (dp); \
187 (dp)->b_forw->b_back = (bp); \
188 (dp)->b_forw = (bp); \
189}
190
191/*
192 * Insq/Remq for the buffer free lists.
193 */
194#define bremfree(bp) { \
195 (bp)->av_back->av_forw = (bp)->av_forw; \
196 (bp)->av_forw->av_back = (bp)->av_back; \
197}
198#define binsheadfree(bp, dp) { \
199 (dp)->av_forw->av_back = (bp); \
200 (bp)->av_forw = (dp)->av_forw; \
201 (dp)->av_forw = (bp); \
202 (bp)->av_back = (dp); \
203}
204#define binstailfree(bp, dp) { \
205 (dp)->av_back->av_forw = (bp); \
206 (bp)->av_back = (dp)->av_back; \
207 (dp)->av_back = (bp); \
208 (bp)->av_forw = (dp); \
209}
210
211#define iodone biodone
212#define iowait biowait
213
214/*
215 * Zero out a buffer's data portion.
216 */
217#define clrbuf(bp) { \
218 bzero((bp)->b_un.b_addr, (unsigned)(bp)->b_bcount); \
219 (bp)->b_resid = 0; \
220}
221#define B_CLRBUF 0x1 /* request allocated buffer be cleared */
222#define B_SYNC 0x2 /* do all allocations synchronously */