xref: /original-bsd/sys/sys/buf.h (revision d364528e)
1 /*
2  * Copyright (c) 1982, 1986, 1989 Regents of the University of California.
3  * All rights reserved.
4  *
5  * %sccs.include.redist.c%
6  *
7  *	@(#)buf.h	7.18 (Berkeley) 07/03/92
8  */
9 
10 #ifndef _BUF_H_
11 #define	_BUF_H_
12 
13 /*
14  * The header for buffers in the buffer pool and otherwise used
15  * to describe a block i/o request is given here.
16  *
17  * Each buffer in the pool is usually doubly linked into 2 lists:
18  * hashed into a chain by <dev,blkno> so it can be located in the cache,
19  * and (usually) on (one of several) queues.  These lists are circular and
20  * doubly linked for easy removal.
21  *
22  * There are currently three queues for buffers:
23  *	one for buffers which must be kept permanently (super blocks)
24  * 	one for buffers containing ``useful'' information (the cache)
25  *	one for buffers containing ``non-useful'' information
26  *		(and empty buffers, pushed onto the front)
27  * The latter two queues contain the buffers which are available for
28  * reallocation, are kept in lru order.  When not on one of these queues,
29  * the buffers are ``checked out'' to drivers which use the available list
30  * pointers to keep track of them in their i/o active queues.
31  */
32 
33 /*
34  * Bufhd structures used at the head of the hashed buffer queues.
35  * We only need three words for these, so this abbreviated
36  * definition saves some space.
37  */
38 struct bufhd
39 {
40 	volatile long	b_flags;	/* see defines below */
41 	struct	buf *b_forw, *b_back;	/* fwd/bkwd pointer in chain */
42 };
43 struct buf
44 {
45 	volatile long	b_flags;	/* too much goes here to describe */
46 	struct	buf *b_forw, *b_back;	/* hash chain (2 way street) */
47 	struct	buf *av_forw, *av_back;	/* position on free list if not BUSY */
48 	struct	buf *b_blockf, **b_blockb;/* associated vnode */
49 #define	b_actf	av_forw			/* alternate names for driver queue */
50 #define	b_actl	av_back			/*    head - isn't history wonderful */
51 	long	b_bcount;		/* transfer count */
52 	long	b_bufsize;		/* size of allocated buffer */
53 #define	b_active b_bcount		/* driver queue head: drive active */
54 	short	b_error;		/* returned after I/O */
55 	dev_t	b_dev;			/* major+minor device name */
56 	union {
57 	    caddr_t b_addr;		/* low order core address */
58 	    int	*b_words;		/* words for clearing */
59 	    struct fs *b_fs;		/* UFS superblocks */
60 	    struct lfs *b_lfs;		/* LFS superblocks */
61 	    struct csum *b_cs;		/* superblock summary information */
62 	    struct cg *b_cg;		/* cylinder group block */
63 	    struct dinode *b_dino;	/* ilist */
64 	    daddr_t *b_daddr;		/* indirect block */
65 	} b_un;
66 	daddr_t	b_lblkno;		/* logical block number */
67 	daddr_t	b_blkno;		/* block # on device */
68 	long	b_resid;		/* words not transferred after error */
69 #define	b_errcnt b_resid		/* while i/o in progress: # retries */
70 	struct  proc *b_proc;		/* proc doing physical or swap I/O */
71 	void	(*b_iodone)();		/* function called by iodone */
72 	struct	vnode *b_vp;		/* vnode for dev */
73 	int	b_pfcent;		/* center page when swapping cluster */
74 	struct	ucred *b_rcred;		/* ref to read credentials */
75 	struct	ucred *b_wcred;		/* ref to write credendtials */
76 	int	b_dirtyoff;		/* offset in buffer of dirty region */
77 	int	b_dirtyend;		/* offset of end of dirty region */
78 	caddr_t	b_saveaddr;		/* original b_addr for PHYSIO */
79 	int	b_validoff;		/* offset in buffer of valid region */
80 	int	b_validend;		/* offset of end of valid region */
81 };
82 
83 #define	BQUEUES		4		/* number of free buffer queues */
84 
85 #define	BQ_LOCKED	0		/* super-blocks &c */
86 #define	BQ_LRU		1		/* lru, useful buffers */
87 #define	BQ_AGE		2		/* rubbish */
88 #define	BQ_EMPTY	3		/* buffer headers with no memory */
89 
90 #ifdef	KERNEL
91 #define	BUFHSZ	512
92 #define RND	(MAXBSIZE/DEV_BSIZE)
93 #if	((BUFHSZ&(BUFHSZ-1)) == 0)
94 #define	BUFHASH(dvp, dblkno)	\
95 	((struct buf *)&bufhash[((int)(dvp)+(((int)(dblkno))/RND))&(BUFHSZ-1)])
96 #else
97 #define	BUFHASH(dvp, dblkno)	\
98 	((struct buf *)&bufhash[((int)(dvp)+(((int)(dblkno))/RND)) % BUFHSZ])
99 #endif
100 
101 struct	buf *buf;		/* the buffer pool itself */
102 char	*buffers;
103 int	nbuf;			/* number of buffer headers */
104 int	bufpages;		/* number of memory pages in the buffer pool */
105 struct	buf *swbuf;		/* swap I/O headers */
106 int	nswbuf;
107 struct	bufhd bufhash[BUFHSZ];	/* heads of hash lists */
108 struct	buf bfreelist[BQUEUES];	/* heads of available lists */
109 struct	buf bswlist;		/* head of free swap header list */
110 struct	buf *bclnlist;		/* head of cleaned page list */
111 
112 __BEGIN_DECLS
113 int	allocbuf __P((struct buf *, int));
114 int	bawrite __P((struct buf *));
115 int	bdwrite __P((struct buf *));
116 void	biodone __P((struct buf *));
117 int	biowait __P((struct buf *));
118 int	bread __P((struct vnode *, daddr_t, int,
119 	    struct ucred *, struct buf **));
120 int	breadn __P((struct vnode *, daddr_t, int, daddr_t *, int *, int,
121 	    struct ucred *, struct buf **));
122 int	brelse __P((struct buf *));
123 void	bufinit __P((void));
124 int	bwrite __P((struct buf *));
125 struct buf *getblk __P((struct vnode *, daddr_t, int));
126 struct buf *geteblk __P((int));
127 struct buf *getnewbuf __P((void));
128 int	incore __P((struct vnode *, daddr_t));
129 u_int	minphys __P((struct buf *bp));
130 __END_DECLS
131 #endif
132 
133 /*
134  * These flags are kept in b_flags.
135  */
136 #define	B_WRITE		0x000000	/* non-read pseudo-flag */
137 #define	B_READ		0x000001	/* read when I/O occurs */
138 #define	B_DONE		0x000002	/* transaction finished */
139 #define	B_ERROR		0x000004	/* transaction aborted */
140 #define	B_BUSY		0x000008	/* not on av_forw/back list */
141 #define	B_PHYS		0x000010	/* physical IO */
142 #define	B_XXX		0x000020	/* was B_MAP, alloc UNIBUS on pdp-11 */
143 #define	B_WANTED	0x000040	/* issue wakeup when BUSY goes off */
144 #define	B_AGE		0x000080	/* delayed write for correct aging */
145 #define	B_ASYNC		0x000100	/* don't wait for I/O completion */
146 #define	B_DELWRI	0x000200	/* write at exit of avail list */
147 #define	B_TAPE		0x000400	/* this is a magtape (no bdwrite) */
148 #define	B_UAREA		0x000800	/* add u-area to a swap operation */
149 #define	B_PAGET		0x001000	/* page in/out of page table space */
150 #define	B_DIRTY		0x002000	/* dirty page to be pushed out async */
151 #define	B_PGIN		0x004000	/* pagein op, so swap() can count it */
152 #define	B_CACHE		0x008000	/* did bread find us in the cache ? */
153 #define	B_INVAL		0x010000	/* does not contain valid info  */
154 #define	B_LOCKED	0x020000	/* locked in core (not reusable) */
155 #define	B_HEAD		0x040000	/* a buffer header, not a buffer */
156 #define	B_GATHERED	0x080000	/* LFS: already in a segment */
157 #define	B_BAD		0x100000	/* bad block revectoring in progress */
158 #define	B_CALL		0x200000	/* call b_iodone from iodone */
159 #define	B_RAW		0x400000	/* set by physio for raw transfers */
160 #define	B_NOCACHE	0x800000	/* do not cache block after use */
161 
162 /*
163  * Insq/Remq for the buffer hash lists.
164  */
165 #define	bremhash(bp) { \
166 	(bp)->b_back->b_forw = (bp)->b_forw; \
167 	(bp)->b_forw->b_back = (bp)->b_back; \
168 }
169 #define	binshash(bp, dp) { \
170 	(bp)->b_forw = (dp)->b_forw; \
171 	(bp)->b_back = (dp); \
172 	(dp)->b_forw->b_back = (bp); \
173 	(dp)->b_forw = (bp); \
174 }
175 
176 /*
177  * Insq/Remq for the buffer free lists.
178  */
179 #define	bremfree(bp) { \
180 	(bp)->av_back->av_forw = (bp)->av_forw; \
181 	(bp)->av_forw->av_back = (bp)->av_back; \
182 }
183 #define	binsheadfree(bp, dp) { \
184 	(dp)->av_forw->av_back = (bp); \
185 	(bp)->av_forw = (dp)->av_forw; \
186 	(dp)->av_forw = (bp); \
187 	(bp)->av_back = (dp); \
188 }
189 #define	binstailfree(bp, dp) { \
190 	(dp)->av_back->av_forw = (bp); \
191 	(bp)->av_back = (dp)->av_back; \
192 	(dp)->av_back = (bp); \
193 	(bp)->av_forw = (dp); \
194 }
195 
196 #define	iodone	biodone
197 #define	iowait	biowait
198 
199 /*
200  * Zero out a buffer's data portion.
201  */
202 #define	clrbuf(bp) { \
203 	blkclr((bp)->b_un.b_addr, (unsigned)(bp)->b_bcount); \
204 	(bp)->b_resid = 0; \
205 }
206 #define B_CLRBUF	0x1	/* request allocated buffer be cleared */
207 #define B_SYNC		0x2	/* do all allocations synchronously */
208 #endif /* !_BUF_H_ */
209