/*
- * 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.
* 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 */
-#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 */
- 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 */
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 */
- 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 */
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 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 *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.
*/
-#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 B_CLRBUF 0x1 /* request allocated buffer be cleared */
#define B_SYNC 0x2 /* do all allocations synchronously */
+#endif /* !_BUF_H_ */