Annotation of sys/sys/buf.h, Revision 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