Annotation of sys/sys/buf.h, Revision 1.1.1.1
1.1 nbrk 1: /* $OpenBSD: buf.h,v 1.57 2007/05/28 18:08:47 pedro Exp $ */
2: /* $NetBSD: buf.h,v 1.25 1997/04/09 21:12:17 mycroft Exp $ */
3:
4: /*
5: * Copyright (c) 1982, 1986, 1989, 1993
6: * The Regents of the University of California. All rights reserved.
7: * (c) UNIX System Laboratories, Inc.
8: * All or some portions of this file are derived from material licensed
9: * to the University of California by American Telephone and Telegraph
10: * Co. or Unix System Laboratories, Inc. and are reproduced herein with
11: * the permission of UNIX System Laboratories, Inc.
12: *
13: * Redistribution and use in source and binary forms, with or without
14: * modification, are permitted provided that the following conditions
15: * are met:
16: * 1. Redistributions of source code must retain the above copyright
17: * notice, this list of conditions and the following disclaimer.
18: * 2. Redistributions in binary form must reproduce the above copyright
19: * notice, this list of conditions and the following disclaimer in the
20: * documentation and/or other materials provided with the distribution.
21: * 3. Neither the name of the University nor the names of its contributors
22: * may be used to endorse or promote products derived from this software
23: * without specific prior written permission.
24: *
25: * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
26: * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
27: * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
28: * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
29: * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
30: * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
31: * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
32: * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
33: * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
34: * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
35: * SUCH DAMAGE.
36: *
37: * @(#)buf.h 8.7 (Berkeley) 1/21/94
38: */
39:
40: #ifndef _SYS_BUF_H_
41: #define _SYS_BUF_H_
42: #include <sys/queue.h>
43:
44: #define NOLIST ((struct buf *)0x87654321)
45:
46: struct buf;
47: struct vnode;
48:
49: LIST_HEAD(bufhead, buf);
50:
51: /*
52: * To avoid including <ufs/ffs/softdep.h>
53: */
54:
55: LIST_HEAD(workhead, worklist);
56:
57: /*
58: * These are currently used only by the soft dependency code, hence
59: * are stored once in a global variable. If other subsystems wanted
60: * to use these hooks, a pointer to a set of bio_ops could be added
61: * to each buffer.
62: */
63: extern struct bio_ops {
64: void (*io_start)(struct buf *);
65: void (*io_complete)(struct buf *);
66: void (*io_deallocate)(struct buf *);
67: void (*io_movedeps)(struct buf *, struct buf *);
68: int (*io_countdeps)(struct buf *, int, int);
69: } bioops;
70:
71: /*
72: * The buffer header describes an I/O operation in the kernel.
73: */
74: struct buf {
75: LIST_ENTRY(buf) b_list; /* All allocated buffers. */
76: LIST_ENTRY(buf) b_hash; /* Hash chain. */
77: LIST_ENTRY(buf) b_vnbufs; /* Buffer's associated vnode. */
78: TAILQ_ENTRY(buf) b_freelist; /* Free list position if not active. */
79: time_t b_synctime; /* Time this buffer should be flushed */
80: struct buf *b_actf, **b_actb; /* Device driver queue when active. */
81: struct proc *b_proc; /* Associated proc; NULL if kernel. */
82: volatile long b_flags; /* B_* flags. */
83: int b_error; /* Errno value. */
84: long b_bufsize; /* Allocated buffer size. */
85: long b_bcount; /* Valid bytes in buffer. */
86: size_t b_resid; /* Remaining I/O. */
87: dev_t b_dev; /* Device associated with buffer. */
88: caddr_t b_data; /* associated data */
89: void *b_saveaddr; /* Original b_data for physio. */
90: daddr64_t b_lblkno; /* Logical block number. */
91: daddr64_t b_blkno; /* Underlying physical block number. */
92: /* Function to call upon completion.
93: * Will be called at splbio(). */
94: void (*b_iodone)(struct buf *);
95: struct vnode *b_vp; /* Device vnode. */
96: int b_dirtyoff; /* Offset in buffer of dirty region. */
97: int b_dirtyend; /* Offset of end of dirty region. */
98: int b_validoff; /* Offset in buffer of valid region. */
99: int b_validend; /* Offset of end of valid region. */
100: struct workhead b_dep; /* List of filesystem dependencies. */
101: };
102:
103: /*
104: * bufq
105: * flexible buffer queue routines
106: */
107: struct bufq {
108: void (*bufq_free)(struct bufq *);
109: void (*bufq_add)(struct bufq *, struct buf *);
110: struct buf *(*bufq_get)(struct bufq *);
111: };
112:
113: struct bufq_default {
114: struct bufq bufq;
115: struct buf bufq_head[3];
116: };
117:
118: #define BUFQ_ALLOC(_type) bufq_default_alloc() /* XXX */
119: #define BUFQ_FREE(_bufq) (_bufq)->bufq_free(_bufq)
120: #define BUFQ_ADD(_bufq, _bp) (_bufq)->bufq_add(_bufq, _bp)
121: #define BUFQ_GET(_bufq) (_bufq)->bufq_get(_bufq)
122:
123: struct bufq *bufq_default_alloc(void);
124: void bufq_default_free(struct bufq *);
125: void bufq_default_add(struct bufq *, struct buf *);
126: struct buf *bufq_default_get(struct bufq *);
127:
128: /*
129: * For portability with historic industry practice, the cylinder number has
130: * to be maintained in the `b_resid' field.
131: */
132: #define b_cylinder b_resid /* Cylinder number for disksort(). */
133:
134: /* Device driver compatibility definitions. */
135: #define b_active b_bcount /* Driver queue head: drive active. */
136: #define b_errcnt b_resid /* Retry count while I/O in progress. */
137:
138: /*
139: * These flags are kept in b_flags.
140: */
141: #define B_AGE 0x00000001 /* Move to age queue when I/O done. */
142: #define B_NEEDCOMMIT 0x00000002 /* Needs committing to stable storage */
143: #define B_ASYNC 0x00000004 /* Start I/O, do not wait. */
144: #define B_BAD 0x00000008 /* Bad block revectoring in progress. */
145: #define B_BUSY 0x00000010 /* I/O in progress. */
146: #define B_CACHE 0x00000020 /* Bread found us in the cache. */
147: #define B_CALL 0x00000040 /* Call b_iodone from biodone. */
148: #define B_DELWRI 0x00000080 /* Delay I/O until buffer reused. */
149: #define B_DONE 0x00000200 /* I/O completed. */
150: #define B_EINTR 0x00000400 /* I/O was interrupted */
151: #define B_ERROR 0x00000800 /* I/O error occurred. */
152: #define B_INVAL 0x00002000 /* Does not contain valid info. */
153: #define B_NOCACHE 0x00008000 /* Do not cache block after use. */
154: #define B_PHYS 0x00040000 /* I/O to user memory. */
155: #define B_RAW 0x00080000 /* Set by physio for raw transfers. */
156: #define B_READ 0x00100000 /* Read buffer. */
157: #define B_WANTED 0x00800000 /* Process wants this buffer. */
158: #define B_WRITE 0x00000000 /* Write buffer (pseudo flag). */
159: #define B_WRITEINPROG 0x01000000 /* Write in progress. */
160: #define B_XXX 0x02000000 /* Debugging flag. */
161: #define B_DEFERRED 0x04000000 /* Skipped over for cleaning */
162: #define B_SCANNED 0x08000000 /* Block already pushed during sync */
163: #define B_PDAEMON 0x10000000 /* I/O started by pagedaemon */
164:
165: #define B_BITS "\010\001AGE\002NEEDCOMMIT\003ASYNC\004BAD\005BUSY\006CACHE" \
166: "\007CALL\010DELWRI\012DONE\013EINTR\014ERROR" \
167: "\016INVAL\020NOCACHE\023PHYS\024RAW\025READ" \
168: "\030WANTED\031WRITEINPROG\032XXX\033DEFERRED" \
169: "\034SCANNED\035PDAEMON"
170:
171: /*
172: * This structure describes a clustered I/O. It is stored in the b_saveaddr
173: * field of the buffer on which I/O is done. At I/O completion, cluster
174: * callback uses the structure to parcel I/O's to individual buffers, and
175: * then free's this structure.
176: */
177: struct cluster_save {
178: long bs_bcount; /* Saved b_bcount. */
179: long bs_bufsize; /* Saved b_bufsize. */
180: void *bs_saveaddr; /* Saved b_addr. */
181: int bs_nchildren; /* Number of associated buffers. */
182: struct buf **bs_children; /* List of associated buffers. */
183: };
184:
185: /*
186: * Zero out the buffer's data area.
187: */
188: #define clrbuf(bp) { \
189: bzero((bp)->b_data, (u_int)(bp)->b_bcount); \
190: (bp)->b_resid = 0; \
191: }
192:
193:
194: /* Flags to low-level allocation routines. */
195: #define B_CLRBUF 0x01 /* Request allocated buffer be cleared. */
196: #define B_SYNC 0x02 /* Do all allocations synchronously. */
197:
198: struct cluster_info {
199: daddr64_t ci_lastr; /* last read (read-ahead) */
200: daddr64_t ci_lastw; /* last write (write cluster) */
201: daddr64_t ci_cstart; /* start block of cluster */
202: daddr64_t ci_lasta; /* last allocation */
203: int ci_clen; /* length of current cluster */
204: int ci_ralen; /* Read-ahead length */
205: daddr64_t ci_maxra; /* last readahead block */
206: };
207:
208: #ifdef _KERNEL
209: __BEGIN_DECLS
210: extern int bufpages; /* Max number of pages for buffers' data */
211: extern struct pool bufpool;
212: extern struct bufhead bufhead;
213:
214: void bawrite(struct buf *);
215: void bdwrite(struct buf *);
216: void biodone(struct buf *);
217: int biowait(struct buf *);
218: int bread(struct vnode *, daddr64_t, int, struct ucred *, struct buf **);
219: int breadn(struct vnode *, daddr64_t, int, daddr64_t *, int *, int,
220: struct ucred *, struct buf **);
221: void brelse(struct buf *);
222: void bremfree(struct buf *);
223: void bufinit(void);
224: void buf_dirty(struct buf *);
225: void buf_undirty(struct buf *);
226: int bwrite(struct buf *);
227: struct buf *getblk(struct vnode *, daddr64_t, int, int, int);
228: struct buf *geteblk(int);
229: struct buf *incore(struct vnode *, daddr64_t);
230:
231: void minphys(struct buf *bp);
232: int physio(void (*strategy)(struct buf *), struct buf *bp, dev_t dev,
233: int flags, void (*minphys)(struct buf *), struct uio *uio);
234: void brelvp(struct buf *);
235: void reassignbuf(struct buf *);
236: void bgetvp(struct vnode *, struct buf *);
237:
238: void buf_replacevnode(struct buf *, struct vnode *);
239: void buf_daemon(struct proc *);
240: void buf_replacevnode(struct buf *, struct vnode *);
241: void buf_daemon(struct proc *);
242: int bread_cluster(struct vnode *, daddr64_t, int, struct buf **);
243:
244: #ifdef DEBUG
245: void buf_print(struct buf *);
246: #endif
247:
248: static __inline void
249: buf_start(struct buf *bp)
250: {
251: if (bioops.io_start)
252: (*bioops.io_start)(bp);
253: }
254:
255: static __inline void
256: buf_complete(struct buf *bp)
257: {
258: if (bioops.io_complete)
259: (*bioops.io_complete)(bp);
260: }
261:
262: static __inline void
263: buf_deallocate(struct buf *bp)
264: {
265: if (bioops.io_deallocate)
266: (*bioops.io_deallocate)(bp);
267: }
268:
269: static __inline void
270: buf_movedeps(struct buf *bp, struct buf *bp2)
271: {
272: if (bioops.io_movedeps)
273: (*bioops.io_movedeps)(bp, bp2);
274: }
275:
276: static __inline int
277: buf_countdeps(struct buf *bp, int i, int islocked)
278: {
279: if (bioops.io_countdeps)
280: return ((*bioops.io_countdeps)(bp, i, islocked));
281: else
282: return (0);
283: }
284:
285: void cluster_write(struct buf *, struct cluster_info *, u_quad_t);
286:
287: __END_DECLS
288: #endif
289: #endif /* !_SYS_BUF_H_ */
CVSweb