BSD 4_4 release
[unix-history] / usr / src / sys / sys / buf.h
index aa7deb8..7fcef91 100644 (file)
@@ -1,25 +1,42 @@
 /*
 /*
- * Copyright (c) 1982, 1986, 1989 Regents of the University of California.
- * All rights reserved.
+ * Copyright (c) 1982, 1986, 1989, 1993
+ *     The Regents of the University of California.  All rights reserved.
  *
  *
- * Redistribution is only permitted until one year after the first shipment
- * of 4.4BSD by the Regents.  Otherwise, redistribution and use in source and
- * binary forms are permitted provided that: (1) source distributions retain
- * this entire copyright notice and comment, and (2) distributions including
- * binaries display the following acknowledgement:  This product includes
- * software developed by the University of California, Berkeley and its
- * contributors'' in the documentation or other materials provided with the
- * distribution and in all advertising materials mentioning features or use
- * of this software.  Neither the name of the University nor the names of
- * its contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- * THIS SOFTWARE IS PROVIDED AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *     This product includes software developed by the University of
+ *     California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
  *
  *
- *     @(#)buf.h       7.11 (Berkeley) 5/9/90
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ *     @(#)buf.h       8.1 (Berkeley) 6/2/93
  */
 
  */
 
+#ifndef _BUF_H_
+#define        _BUF_H_
+#include <sys/queue.h>
+
 /*
  * The header for buffers in the buffer pool and otherwise used
  * to describe a block i/o request is given here.
 /*
  * The header for buffers in the buffer pool and otherwise used
  * to describe a block i/o request is given here.
  * pointers to keep track of them in their i/o active queues.
  */
 
  * pointers to keep track of them in their i/o active queues.
  */
 
-/*
- * Bufhd structures used at the head of the hashed buffer queues.
- * We only need three words for these, so this abbreviated
- * definition saves some space.
- */
-struct bufhd
-{
-       long    b_flags;                /* see defines below */
-       struct  buf *b_forw, *b_back;   /* fwd/bkwd pointer in chain */
-};
-struct buf
-{
-       long    b_flags;                /* too much goes here to describe */
-       struct  buf *b_forw, *b_back;   /* hash chain (2 way street) */
-       struct  buf *av_forw, *av_back; /* position on free list if not BUSY */
-       struct  buf *b_blockf, **b_blockb;/* associated vnode */
-#define        b_actf  av_forw                 /* alternate names for driver queue */
-#define        b_actl  av_back                 /*    head - isn't history wonderful */
+struct buf {
+       volatile long   b_flags;        /* too much goes here to describe */
+       struct  queue_entry b_hash;     /* hash chain */
+       struct  queue_entry b_vnbufs;   /* associated vnode */
+       struct  queue_entry b_freelist; /* position on free list if not BUSY */
+       struct  buf *b_actf, **b_actb;  /* device driver I/O queue when BUSY */
        long    b_bcount;               /* transfer count */
        long    b_bufsize;              /* size of allocated buffer */
        long    b_bcount;               /* transfer count */
        long    b_bufsize;              /* size of allocated buffer */
-#define        b_active b_bcount               /* driver queue head: drive active */
        short   b_error;                /* returned after I/O */
        dev_t   b_dev;                  /* major+minor device name */
        union {
            caddr_t b_addr;             /* low order core address */
            int *b_words;               /* words for clearing */
        short   b_error;                /* returned after I/O */
        dev_t   b_dev;                  /* major+minor device name */
        union {
            caddr_t b_addr;             /* low order core address */
            int *b_words;               /* words for clearing */
-           struct fs *b_fs;            /* superblocks */
+           struct fs *b_fs;            /* UFS superblocks */
+           struct lfs *b_lfs;          /* LFS superblocks */
            struct csum *b_cs;          /* superblock summary information */
            struct cg *b_cg;            /* cylinder group block */
            struct dinode *b_dino;      /* ilist */
            struct csum *b_cs;          /* superblock summary information */
            struct cg *b_cg;            /* cylinder group block */
            struct dinode *b_dino;      /* ilist */
@@ -75,9 +80,8 @@ struct buf
        daddr_t b_lblkno;               /* logical block number */
        daddr_t b_blkno;                /* block # on device */
        long    b_resid;                /* words not transferred after error */
        daddr_t b_lblkno;               /* logical block number */
        daddr_t b_blkno;                /* block # on device */
        long    b_resid;                /* words not transferred after error */
-#define        b_errcnt b_resid                /* while i/o in progress: # retries */
        struct  proc *b_proc;           /* proc doing physical or swap I/O */
        struct  proc *b_proc;           /* proc doing physical or swap I/O */
-       int     (*b_iodone)();          /* function called by iodone */
+       void    (*b_iodone)();          /* function called by iodone */
        struct  vnode *b_vp;            /* vnode for dev */
        int     b_pfcent;               /* center page when swapping cluster */
        struct  ucred *b_rcred;         /* ref to read credentials */
        struct  vnode *b_vp;            /* vnode for dev */
        int     b_pfcent;               /* center page when swapping cluster */
        struct  ucred *b_rcred;         /* ref to read credentials */
@@ -85,105 +89,97 @@ struct buf
        int     b_dirtyoff;             /* offset in buffer of dirty region */
        int     b_dirtyend;             /* offset of end of dirty region */
        caddr_t b_saveaddr;             /* original b_addr for PHYSIO */
        int     b_dirtyoff;             /* offset in buffer of dirty region */
        int     b_dirtyend;             /* offset of end of dirty region */
        caddr_t b_saveaddr;             /* original b_addr for PHYSIO */
+       int     b_validoff;             /* offset in buffer of valid region */
+       int     b_validend;             /* offset of end of valid region */
 };
 
 };
 
-#define        BQUEUES         4               /* number of free buffer queues */
-
-#define        BQ_LOCKED       0               /* super-blocks &c */
-#define        BQ_LRU          1               /* lru, useful buffers */
-#define        BQ_AGE          2               /* rubbish */
-#define        BQ_EMPTY        3               /* buffer headers with no memory */
+/*
+ * Defines for device drivers.
+ */
+#define        b_active b_bcount               /* driver queue head: drive active */
+#define        b_errcnt b_resid                /* while i/o in progress: # retries */
 
 
-#ifdef KERNEL
-#define        BUFHSZ  512
-#define RND    (MAXBSIZE/DEV_BSIZE)
-#if    ((BUFHSZ&(BUFHSZ-1)) == 0)
-#define        BUFHASH(dvp, dblkno)    \
-       ((struct buf *)&bufhash[((int)(dvp)+(((int)(dblkno))/RND))&(BUFHSZ-1)])
-#else
-#define        BUFHASH(dvp, dblkno)    \
-       ((struct buf *)&bufhash[((int)(dvp)+(((int)(dblkno))/RND)) % BUFHSZ])
-#endif
+/*
+ * This structure describes a clustered I/O.  It is
+ * stored in the b_saveaddr field of the buffer on
+ * which I/O is performed.  At I/O completion, cluster
+ * callback uses the structure to parcel I/Os to
+ * individual buffers, and then frees this structure.
+ */
+struct cluster_save {
+       long    bs_bcount;
+       long    bs_bufsize;
+       caddr_t bs_saveaddr;
+       int     bs_nchildren;
+       struct buf **bs_children;
+};
 
 
+#ifdef KERNEL
 struct buf *buf;               /* the buffer pool itself */
 char   *buffers;
 int    nbuf;                   /* number of buffer headers */
 int    bufpages;               /* number of memory pages in the buffer pool */
 struct buf *swbuf;             /* swap I/O headers */
 int    nswbuf;
 struct buf *buf;               /* the buffer pool itself */
 char   *buffers;
 int    nbuf;                   /* number of buffer headers */
 int    bufpages;               /* number of memory pages in the buffer pool */
 struct buf *swbuf;             /* swap I/O headers */
 int    nswbuf;
-struct bufhd bufhash[BUFHSZ];  /* heads of hash lists */
-struct buf bfreelist[BQUEUES]; /* heads of available lists */
 struct buf bswlist;            /* head of free swap header list */
 struct buf *bclnlist;          /* head of cleaned page list */
 
 struct buf bswlist;            /* head of free swap header list */
 struct buf *bclnlist;          /* head of cleaned page list */
 
-struct buf *getblk();
-struct buf *geteblk();
-struct buf *getnewbuf();
-
-unsigned minphys();
+__BEGIN_DECLS
+int    allocbuf __P((struct buf *, int));
+int    bawrite __P((struct buf *));
+int    bdwrite __P((struct buf *));
+void   biodone __P((struct buf *));
+int    biowait __P((struct buf *));
+int    bread __P((struct vnode *, daddr_t, int,
+           struct ucred *, struct buf **));
+int    breadn __P((struct vnode *, daddr_t, int, daddr_t *, int *, int,
+           struct ucred *, struct buf **));
+int    brelse __P((struct buf *));
+void   bufinit __P((void));
+int    bwrite __P((struct buf *));
+void   cluster_callback __P((struct buf *));
+int    cluster_read __P((struct vnode *, u_quad_t, daddr_t, long,
+           struct ucred *, struct buf **));
+void   cluster_write __P((struct buf *, u_quad_t));
+struct buf *getblk __P((struct vnode *, daddr_t, int, int, int));
+struct buf *geteblk __P((int));
+struct buf *getnewbuf __P((int slpflag, int slptimeo));
+struct buf *incore __P((struct vnode *, daddr_t));
+u_int  minphys __P((struct buf *bp));
+__END_DECLS
 #endif
 
 /*
  * These flags are kept in b_flags.
  */
 #endif
 
 /*
  * These flags are kept in b_flags.
  */
-#define        B_WRITE         0x000000        /* non-read pseudo-flag */
-#define        B_READ          0x000001        /* read when I/O occurs */
-#define        B_DONE          0x000002        /* transaction finished */
-#define        B_ERROR         0x000004        /* transaction aborted */
-#define        B_BUSY          0x000008        /* not on av_forw/back list */
-#define        B_PHYS          0x000010        /* physical IO */
-#define        B_XXX           0x000020        /* was B_MAP, alloc UNIBUS on pdp-11 */
-#define        B_WANTED        0x000040        /* issue wakeup when BUSY goes off */
-#define        B_AGE           0x000080        /* delayed write for correct aging */
-#define        B_ASYNC         0x000100        /* don't wait for I/O completion */
-#define        B_DELWRI        0x000200        /* write at exit of avail list */
-#define        B_TAPE          0x000400        /* this is a magtape (no bdwrite) */
-#define        B_UAREA         0x000800        /* add u-area to a swap operation */
-#define        B_PAGET         0x001000        /* page in/out of page table space */
-#define        B_DIRTY         0x002000        /* dirty page to be pushed out async */
-#define        B_PGIN          0x004000        /* pagein op, so swap() can count it */
-#define        B_CACHE         0x008000        /* did bread find us in the cache ? */
-#define        B_INVAL         0x010000        /* does not contain valid info  */
-#define        B_LOCKED        0x020000        /* locked in core (not reusable) */
-#define        B_HEAD          0x040000        /* a buffer header, not a buffer */
-#define        B_BAD           0x100000        /* bad block revectoring in progress */
-#define        B_CALL          0x200000        /* call b_iodone from iodone */
-#define        B_RAW           0x400000        /* set by physio for raw transfers */
-#define        B_NOCACHE       0x800000        /* do not cache block after use */
-
-/*
- * Insq/Remq for the buffer hash lists.
- */
-#define        bremhash(bp) { \
-       (bp)->b_back->b_forw = (bp)->b_forw; \
-       (bp)->b_forw->b_back = (bp)->b_back; \
-}
-#define        binshash(bp, dp) { \
-       (bp)->b_forw = (dp)->b_forw; \
-       (bp)->b_back = (dp); \
-       (dp)->b_forw->b_back = (bp); \
-       (dp)->b_forw = (bp); \
-}
-
-/*
- * Insq/Remq for the buffer free lists.
- */
-#define        bremfree(bp) { \
-       (bp)->av_back->av_forw = (bp)->av_forw; \
-       (bp)->av_forw->av_back = (bp)->av_back; \
-}
-#define        binsheadfree(bp, dp) { \
-       (dp)->av_forw->av_back = (bp); \
-       (bp)->av_forw = (dp)->av_forw; \
-       (dp)->av_forw = (bp); \
-       (bp)->av_back = (dp); \
-}
-#define        binstailfree(bp, dp) { \
-       (dp)->av_back->av_forw = (bp); \
-       (bp)->av_back = (dp)->av_back; \
-       (dp)->av_back = (bp); \
-       (bp)->av_forw = (dp); \
-}
+#define        B_WRITE         0x00000000      /* non-read pseudo-flag */
+#define        B_READ          0x00000001      /* read when I/O occurs */
+#define        B_DONE          0x00000002      /* transaction finished */
+#define        B_ERROR         0x00000004      /* transaction aborted */
+#define        B_BUSY          0x00000008      /* not on av_forw/back list */
+#define        B_PHYS          0x00000010      /* physical IO */
+#define        B_XXX           0x00000020      /* was B_MAP, alloc UNIBUS on pdp-11 */
+#define        B_WANTED        0x00000040      /* issue wakeup when BUSY goes off */
+#define        B_AGE           0x00000080      /* delayed write for correct aging */
+#define        B_ASYNC         0x00000100      /* don't wait for I/O completion */
+#define        B_DELWRI        0x00000200      /* write at exit of avail list */
+#define        B_TAPE          0x00000400      /* this is a magtape (no bdwrite) */
+#define        B_UAREA         0x00000800      /* add u-area to a swap operation */
+#define        B_PAGET         0x00001000      /* page in/out of page table space */
+#define        B_DIRTY         0x00002000      /* dirty page to be pushed out async */
+#define        B_PGIN          0x00004000      /* pagein op, so swap() can count it */
+#define        B_CACHE         0x00008000      /* did bread find us in the cache ? */
+#define        B_INVAL         0x00010000      /* does not contain valid info  */
+#define        B_LOCKED        0x00020000      /* locked in core (not reusable) */
+#define        B_HEAD          0x00040000      /* a buffer header, not a buffer */
+#define        B_GATHERED      0x00080000      /* LFS: already in a segment */
+#define        B_BAD           0x00100000      /* bad block revectoring in progress */
+#define        B_CALL          0x00200000      /* call b_iodone from iodone */
+#define        B_RAW           0x00400000      /* set by physio for raw transfers */
+#define        B_NOCACHE       0x00800000      /* do not cache block after use */
+#define        B_WRITEINPROG   0x01000000      /* write in progress on buffer */
+#define        B_APPENDWRITE   0x02000000      /* append-write in progress on buffer */
+#define        B_EINTR         0x04000000      /* I/O was interrupted */
 
 #define        iodone  biodone
 #define        iowait  biowait
 
 #define        iodone  biodone
 #define        iowait  biowait
@@ -197,3 +193,4 @@ unsigned minphys();
 }
 #define B_CLRBUF       0x1     /* request allocated buffer be cleared */
 #define B_SYNC         0x2     /* do all allocations synchronously */
 }
 #define B_CLRBUF       0x1     /* request allocated buffer be cleared */
 #define B_SYNC         0x2     /* do all allocations synchronously */
+#endif /* !_BUF_H_ */