Files
retrobsd/sys/include/buf.h
Serge Vakulenko d1f1e614f0 Kernel sources reformated with 4 space indent, no tabs.
Unused file include/trace.h deleted.
2015-06-23 19:00:24 -07:00

228 lines
7.1 KiB
C

/*
* Copyright (c) 1986 Regents of the University of California.
* All rights reserved. The Berkeley software License Agreement
* specifies the terms and conditions for redistribution.
*/
/*
* The header for buffers in the buffer pool and otherwise used
* to describe a block i/o request is given here.
*
* Each buffer in the pool is usually doubly linked into 2 lists:
* hashed into a chain by <dev,blkno> so it can be located in the cache,
* and (usually) on (one of several) queues. These lists are circular and
* doubly linked for easy removal.
*
* There are currently two queues for buffers:
* one for buffers containing ``useful'' information (the cache)
* one for buffers containing ``non-useful'' information
* (and empty buffers, pushed onto the front)
* These queues contain the buffers which are available for
* reallocation, are kept in lru order. When not on one of these queues,
* the buffers are ``checked out'' to drivers which use the available list
* 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
{
int b_flags; /* see defines below */
struct buf *b_forw, *b_back; /* fwd/bkwd pointer in chain */
};
struct buf
{
int b_flags; /* see defines below */
struct buf *b_forw, *b_back; /* hash chain (2 way street) */
struct buf *av_forw, *av_back; /* position on free list if not BUSY */
#define b_actf av_forw /* alternate names for driver queue */
#define b_actl av_back /* head - isn't history wonderful */
u_int b_bcount; /* transfer count */
#define b_active b_bcount /* driver queue head: drive active */
int b_error; /* returned after I/O */
dev_t b_dev; /* major+minor device name */
caddr_t b_addr; /* core address */
daddr_t b_blkno; /* block # on device */
u_int b_resid; /* words not transferred after error */
#define b_cylin b_resid /* disksort */
#define b_errcnt b_resid /* while i/o in progress: # retries */
};
/*
* We never use BQ_LOCKED or BQ_EMPTY, but if you want the 4.X block I/O
* code to drop in, you have to have BQ_AGE and BQ_LRU *after* the first
* queue, and it only costs 6 bytes of data space.
*/
#define BQUEUES 3 /* 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 */
/* Flags to low-level allocation routines. */
#define B_CLRBUF 0x01 /* Request allocated buffer be cleared. */
#define B_SYNC 0x02 /* Do all allocations synchronously. */
#define bawrite(bp) { (bp)->b_flags |= B_ASYNC; bwrite(bp); }
#define bfree(bp) (bp)->b_bcount = 0
#ifdef KERNEL
struct inode;
#define BUFHSZ 16 /* must be power of 2 */
#define BUFHASH(dev,bn) ((struct buf*) &bufhash [((dev) + bn) & (BUFHSZ - 1)])
extern struct buf buf[]; /* the buffer pool itself */
extern char bufdata[]; /* core data */
extern struct bufhd bufhash[]; /* heads of hash lists */
extern struct buf bfreelist[]; /* heads of available lists */
/*
* Assign a buffer for the given block. If the appropriate
*/
struct buf *getblk (dev_t dev, daddr_t blkno);
/*
* Allocate a block in the file system.
*/
struct buf *balloc (struct inode *ip, int flags);
/*
* Get an empty block.
*/
struct buf *geteblk (void);
/*
* Read in (if necessary) the block and return a buffer pointer.
*/
struct buf *bread (dev_t dev, daddr_t blkno);
/*
* Read in the block, like bread, but also start I/O on the
* read-ahead block.
*/
struct buf *breada (dev_t dev, daddr_t blkno, daddr_t rablkno);
/*
* Write the buffer, waiting for completion. Then release the buffer.
*/
void bwrite (struct buf *bp);
/*
* Release the buffer, with delayed write.
*/
void bdwrite (struct buf *bp);
/*
* Mark I/O complete on a buffer.
*/
void biodone (struct buf *bp);
/*
* Release the buffer, with no I/O implied.
*/
void brelse (struct buf *bp);
/*
* Wait for I/O completion on the buffer.
*/
void biowait (struct buf *bp);
/*
* See if the block is associated with some buffer.
*/
int incore (dev_t dev, daddr_t blkno);
/*
* Make sure all write-behind blocks on dev are flushed out.
*/
void bflush (dev_t dev);
/*
* Insure that no part of a specified block is in an incore buffer.
*/
void blkflush (dev_t dev, daddr_t blkno);
/*
* Invalidate in core blocks belonging to closed or umounted filesystem.
*/
void binval (dev_t dev);
/*
* Pick up the device's error number and pass it to the user.
*/
int geterror (struct buf *bp);
#endif /* KERNEL */
/*
* These flags are kept in b_flags.
*/
#define B_WRITE 0x00000 /* non-read pseudo-flag */
#define B_READ 0x00001 /* read when I/O occurs */
#define B_DONE 0x00002 /* transaction finished */
#define B_ERROR 0x00004 /* transaction aborted */
#define B_BUSY 0x00008 /* not on av_forw/back list */
#define B_PHYS 0x00010 /* physical IO */
#define B_MAP 0x00020 /* alloc UNIBUS */
#define B_WANTED 0x00040 /* issue wakeup when BUSY goes off */
#define B_AGE 0x00080 /* delayed write for correct aging */
#define B_ASYNC 0x00100 /* don't wait for I/O completion */
#define B_DELWRI 0x00200 /* write at exit of avail list */
#define B_TAPE 0x00400 /* this is a magtape (no bdwrite) */
#define B_INVAL 0x00800 /* does not contain valid info */
#define B_BAD 0x01000 /* bad block revectoring in progress */
#define B_LOCKED 0x02000 /* locked in core (not reusable) */
#define B_UBAREMAP 0x04000 /* addr UNIBUS virtual, not physical */
#define B_RAMREMAP 0x08000 /* remapped into ramdisk */
/*
* 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); \
}
/*
* Take a buffer off the free list it's on and
* mark it as being use (B_BUSY) by a device.
*/
#define notavail(bp) { \
register int x = splbio(); \
bremfree(bp); \
(bp)->b_flags |= B_BUSY; \
splx(x); \
}