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