xref: /netbsd/sys/sys/buf.h (revision c4a72b64)
1 /*	$NetBSD: buf.h,v 1.55 2002/10/06 17:05:56 thorpej Exp $	*/
2 
3 /*-
4  * Copyright (c) 1999, 2000 The NetBSD Foundation, Inc.
5  * All rights reserved.
6  *
7  * This code is derived from software contributed to The NetBSD Foundation
8  * by Jason R. Thorpe of the Numerical Aerospace Simulation Facility,
9  * NASA Ames Research Center.
10  *
11  * Redistribution and use in source and binary forms, with or without
12  * modification, are permitted provided that the following conditions
13  * are met:
14  * 1. Redistributions of source code must retain the above copyright
15  *    notice, this list of conditions and the following disclaimer.
16  * 2. Redistributions in binary form must reproduce the above copyright
17  *    notice, this list of conditions and the following disclaimer in the
18  *    documentation and/or other materials provided with the distribution.
19  * 3. All advertising materials mentioning features or use of this software
20  *    must display the following acknowledgement:
21  *	This product includes software developed by the NetBSD
22  *	Foundation, Inc. and its contributors.
23  * 4. Neither the name of The NetBSD Foundation nor the names of its
24  *    contributors may be used to endorse or promote products derived
25  *    from this software without specific prior written permission.
26  *
27  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
28  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
29  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
30  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
31  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
32  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
33  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
34  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
35  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
36  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
37  * POSSIBILITY OF SUCH DAMAGE.
38  */
39 
40 /*
41  * Copyright (c) 1982, 1986, 1989, 1993
42  *	The Regents of the University of California.  All rights reserved.
43  * (c) UNIX System Laboratories, Inc.
44  * All or some portions of this file are derived from material licensed
45  * to the University of California by American Telephone and Telegraph
46  * Co. or Unix System Laboratories, Inc. and are reproduced herein with
47  * the permission of UNIX System Laboratories, Inc.
48  *
49  * Redistribution and use in source and binary forms, with or without
50  * modification, are permitted provided that the following conditions
51  * are met:
52  * 1. Redistributions of source code must retain the above copyright
53  *    notice, this list of conditions and the following disclaimer.
54  * 2. Redistributions in binary form must reproduce the above copyright
55  *    notice, this list of conditions and the following disclaimer in the
56  *    documentation and/or other materials provided with the distribution.
57  * 3. All advertising materials mentioning features or use of this software
58  *    must display the following acknowledgement:
59  *	This product includes software developed by the University of
60  *	California, Berkeley and its contributors.
61  * 4. Neither the name of the University nor the names of its contributors
62  *    may be used to endorse or promote products derived from this software
63  *    without specific prior written permission.
64  *
65  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
66  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
67  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
68  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
69  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
70  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
71  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
72  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
73  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
74  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
75  * SUCH DAMAGE.
76  *
77  *	@(#)buf.h	8.9 (Berkeley) 3/30/95
78  */
79 
80 #ifndef _SYS_BUF_H_
81 #define	_SYS_BUF_H_
82 
83 #include <sys/pool.h>
84 #include <sys/queue.h>
85 
86 struct buf;
87 struct mount;
88 struct vnode;
89 
90 #define NOLIST ((struct buf *)0x87654321)
91 
92 /*
93  * To avoid including <ufs/ffs/softdep.h>
94  */
95 LIST_HEAD(workhead, worklist);
96 
97 /*
98  * Device driver buffer queue.
99  */
100 struct bufq_state {
101 	void (*bq_put)(struct bufq_state *, struct buf *);
102 	struct buf *(*bq_get)(struct bufq_state *, int);
103 	void *bq_private;
104 	int bq_flags;			/* Flags from bufq_alloc() */
105 };
106 
107 /*
108  * Flags for bufq_alloc.
109  */
110 #define BUFQ_SORT_RAWBLOCK	0x0001	/* Sort by b_rawblkno */
111 #define BUFQ_SORT_CYLINDER	0x0002	/* Sort by b_cylinder, b_rawblkno */
112 
113 #define BUFQ_FCFS		0x0010	/* First-come first-serve */
114 #define BUFQ_DISKSORT		0x0020	/* Min seek sort */
115 #define BUFQ_READ_PRIO		0x0030	/* Min seek and read priority */
116 
117 #define BUFQ_SORT_MASK		0x000f
118 #define BUFQ_METHOD_MASK	0x00f0
119 
120 #ifdef _KERNEL
121 
122 void	bufq_alloc(struct bufq_state *, int);
123 void	bufq_free(struct bufq_state *);
124 
125 #define BUFQ_PUT(bufq, bp) \
126 	(*(bufq)->bq_put)((bufq), (bp))	/* Put buffer in queue */
127 #define BUFQ_GET(bufq) \
128 	(*(bufq)->bq_get)((bufq), 1)	/* Get and remove buffer from queue */
129 #define BUFQ_PEEK(bufq) \
130 	(*(bufq)->bq_get)((bufq), 0)	/* Get buffer from queue */
131 
132 #endif /* _KERNEL */
133 
134 /*
135  * These are currently used only by the soft dependency code, hence
136  * are stored once in a global variable. If other subsystems wanted
137  * to use these hooks, a pointer to a set of bio_ops could be added
138  * to each buffer.
139  */
140 struct bio_ops {
141  	void	(*io_start) __P((struct buf *));
142  	void	(*io_complete) __P((struct buf *));
143  	void	(*io_deallocate) __P((struct buf *));
144  	int	(*io_fsync) __P((struct vnode *));
145  	int	(*io_sync) __P((struct mount *));
146 	void	(*io_movedeps) __P((struct buf *, struct buf *));
147 	int	(*io_countdeps) __P((struct buf *, int));
148 	void	(*io_pageiodone) __P((struct buf *));
149 };
150 
151 /*
152  * The buffer header describes an I/O operation in the kernel.
153  */
154 struct buf {
155 	LIST_ENTRY(buf) b_hash;		/* Hash chain. */
156 	LIST_ENTRY(buf) b_vnbufs;	/* Buffer's associated vnode. */
157 	TAILQ_ENTRY(buf) b_freelist;	/* Free list position if not active. */
158 	TAILQ_ENTRY(buf) b_actq;	/* Device driver queue when active. */
159 	struct  proc *b_proc;		/* Associated proc if B_PHYS set. */
160 	volatile long	b_flags;	/* B_* flags. */
161 	int	b_error;		/* Errno value. */
162 	long	b_bufsize;		/* Allocated buffer size. */
163 	long	b_bcount;		/* Valid bytes in buffer. */
164 	long	b_resid;		/* Remaining I/O. */
165 	dev_t	b_dev;			/* Device associated with buffer. */
166 	struct {
167 		caddr_t	b_addr;		/* Memory, superblocks, indirect etc. */
168 	} b_un;
169 	void	*b_saveaddr;		/* Original b_addr for physio. */
170 	daddr_t	b_lblkno;		/* Logical block number. */
171 	daddr_t	b_blkno;		/* Underlying physical block number
172 					   (partition relative) */
173 	daddr_t	b_rawblkno;		/* Raw underlying physical block
174 					   number (not partition relative) */
175 					/* Function to call upon completion. */
176 	void	(*b_iodone) __P((struct buf *));
177 	struct	vnode *b_vp;		/* File vnode. */
178 	void	*b_private;		/* Private data for owner */
179 	off_t	b_dcookie;		/* Offset cookie if dir block */
180 	struct  workhead b_dep;		/* List of filesystem dependencies. */
181 };
182 
183 /*
184  * For portability with historic industry practice, the cylinder number has
185  * to be maintained in the `b_resid' field.
186  */
187 #define	b_cylinder b_resid		/* Cylinder number for disksort(). */
188 
189 /* Device driver compatibility definitions. */
190 #define	b_data	 b_un.b_addr		/* b_un.b_addr is not changeable. */
191 
192 /*
193  * These flags are kept in b_flags.
194  */
195 #define	B_AGE		0x00000001	/* Move to age queue when I/O done. */
196 #define	B_NEEDCOMMIT	0x00000002	/* Needs committing to stable storage */
197 #define	B_ASYNC		0x00000004	/* Start I/O, do not wait. */
198 #define	B_BAD		0x00000008	/* Bad block revectoring in progress. */
199 #define	B_BUSY		0x00000010	/* I/O in progress. */
200 #define B_SCANNED	0x00000020	/* Block already pushed during sync */
201 #define	B_CALL		0x00000040	/* Call b_iodone from biodone. */
202 #define	B_DELWRI	0x00000080	/* Delay I/O until buffer reused. */
203 #define	B_DIRTY		0x00000100	/* Dirty page to be pushed out async. */
204 #define	B_DONE		0x00000200	/* I/O completed. */
205 #define	B_EINTR		0x00000400	/* I/O was interrupted */
206 #define	B_ERROR		0x00000800	/* I/O error occurred. */
207 #define	B_GATHERED	0x00001000	/* LFS: already in a segment. */
208 #define	B_INVAL		0x00002000	/* Does not contain valid info. */
209 #define	B_LOCKED	0x00004000	/* Locked in core (not reusable). */
210 #define	B_NOCACHE	0x00008000	/* Do not cache block after use. */
211 #define	B_CACHE		0x00020000	/* Bread found us in the cache. */
212 #define	B_PHYS		0x00040000	/* I/O to user memory. */
213 #define	B_RAW		0x00080000	/* Set by physio for raw transfers. */
214 #define	B_READ		0x00100000	/* Read buffer. */
215 #define	B_TAPE		0x00200000	/* Magnetic tape I/O. */
216 #define	B_WANTED	0x00800000	/* Process wants this buffer. */
217 #define	B_WRITE		0x00000000	/* Write buffer (pseudo flag). */
218 #define	B_XXX		0x02000000	/* Debugging flag. */
219 #define	B_VFLUSH	0x04000000	/* Buffer is being synced. */
220 
221 /*
222  * This structure describes a clustered I/O.  It is stored in the b_saveaddr
223  * field of the buffer on which I/O is done.  At I/O completion, cluster
224  * callback uses the structure to parcel I/O's to individual buffers, and
225  * then free's this structure.
226  */
227 struct cluster_save {
228 	long	bs_bcount;		/* Saved b_bcount. */
229 	long	bs_bufsize;		/* Saved b_bufsize. */
230 	void	*bs_saveaddr;		/* Saved b_addr. */
231 	int	bs_nchildren;		/* Number of associated buffers. */
232 	struct buf **bs_children;	/* List of associated buffers. */
233 };
234 
235 /*
236  * Zero out the buffer's data area.
237  */
238 #define	clrbuf(bp)							\
239 do {									\
240 	memset((bp)->b_data, 0, (u_int)(bp)->b_bcount);			\
241 	(bp)->b_resid = 0;						\
242 } while (/* CONSTCOND */ 0)
243 
244 /* Flags to low-level allocation routines. */
245 #define B_CLRBUF	0x01	/* Request allocated buffer be cleared. */
246 #define B_SYNC		0x02	/* Do all allocations synchronously. */
247 
248 #ifdef _KERNEL
249 
250 extern	struct bio_ops bioops;
251 extern	u_int nbuf;		/* The number of buffer headers */
252 extern	struct buf *buf;	/* The buffer headers. */
253 extern	char *buffers;		/* The buffer contents. */
254 extern	u_int bufpages;		/* Number of memory pages in the buffer pool. */
255 extern	u_int nswbuf;		/* Number of swap I/O buffer headers. */
256 
257 extern	struct pool bufpool;	/* I/O buf pool */
258 
259 __BEGIN_DECLS
260 void	allocbuf __P((struct buf *, int));
261 void	bawrite __P((struct buf *));
262 void	bdirty __P((struct buf *));
263 void	bdwrite __P((struct buf *));
264 void	biodone __P((struct buf *));
265 int	biowait __P((struct buf *));
266 int	bread __P((struct vnode *, daddr_t, int,
267 		   struct ucred *, struct buf **));
268 int	breada __P((struct vnode *, daddr_t, int, daddr_t, int,
269 		    struct ucred *, struct buf **));
270 int	breadn __P((struct vnode *, daddr_t, int, daddr_t *, int *, int,
271 		    struct ucred *, struct buf **));
272 void	brelse __P((struct buf *));
273 void	bremfree __P((struct buf *));
274 void	bufinit __P((void));
275 int	bwrite __P((struct buf *));
276 void	cluster_callback __P((struct buf *));
277 int	cluster_read __P((struct vnode *, u_quad_t, daddr_t, long,
278 			  struct ucred *, struct buf **));
279 void	cluster_write __P((struct buf *, u_quad_t));
280 struct buf *getblk __P((struct vnode *, daddr_t, int, int, int));
281 struct buf *geteblk __P((int));
282 struct buf *getnewbuf __P((int slpflag, int slptimeo));
283 struct buf *incore __P((struct vnode *, daddr_t));
284 
285 void	minphys __P((struct buf *bp));
286 int	physio __P((void (*strategy)(struct buf *), struct buf *bp, dev_t dev,
287 		    int flags, void (*minphys)(struct buf *), struct uio *uio));
288 
289 void  brelvp __P((struct buf *));
290 void  reassignbuf __P((struct buf *, struct vnode *));
291 void  bgetvp __P((struct vnode *, struct buf *));
292 #ifdef DDB
293 void	vfs_buf_print __P((struct buf *, int, void (*)(const char *, ...)));
294 #endif
295 __END_DECLS
296 #endif
297 #endif /* !_SYS_BUF_H_ */
298