[BACK]Return to buf.h CVS log [TXT][DIR] Up to [local] / sys / sys

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