home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
NeXTSTEP 3.2 (Developer)
/
NS_dev_3.2.iso
/
NextDeveloper
/
Headers
/
bsd
/
sys
/
buf.h
< prev
next >
Wrap
Text File
|
1993-10-19
|
7KB
|
225 lines
/*
* Copyright (c) 1982, 1986 Regents of the University of California.
* All rights reserved. The Berkeley software License Agreement
* specifies the terms and conditions for redistribution.
*
* @(#)buf.h 7.1 (Berkeley) 6/4/86
*
* History
* 05-Jul-90 Doug Mitchell at NeXT
* Added B_KERNSPACE flag.
*/
#ifndef _SYS_BUF_
#define _SYS_BUF_
#import <sys/types.h>
/*
* The header for buffers in the buffer pool and otherwise used
* to describe a block i/o request is given here. The routines
* which manipulate these things are given in bio.c.
*
* 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 three queues for buffers:
* one for buffers which must be kept permanently (super blocks)
* one for buffers containing ``useful'' information (the cache)
* one for buffers containing ``non-useful'' information
* (and empty buffers, pushed onto the front)
* The latter two 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
{
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 */
#define b_actf av_forw /* alternate names for driver queue */
#define b_actl av_back /* head - isn't history wonderful */
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 csum *b_cs; /* superblock summary information */
struct cg *b_cg; /* cylinder group block */
struct dinode *b_dino; /* ilist */
daddr_t *b_daddr; /* indirect block */
} b_un;
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 */
int b_pfcent; /* center page when swapping cluster */
#ifdef NeXT
int b_sort_key; /* used by disk sort */
int b_rtpri; /* realtime priority */
#define RTPRI_NONE 0
#define RTPRI_MIN 1
#define RTPRI_MAX 127
#endif NeXT
struct vnode *b_vp; /* vnode associated with block */
};
#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 */
#ifdef KERNEL
#if NeXT
#define BUFHSZ 16
#else NeXT
#define BUFHSZ 512
#endif NeXT
#define RND (MAXBSIZE/1024)
#define BUFHASH(dvp, dblkno) \
((struct buf *)&bufhash[((u_int)(dvp)+(((int)(dblkno))/RND)) % BUFHSZ])
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 bufhd bufhash[BUFHSZ]; /* heads of hash lists */
struct buf bfreelist[BQUEUES]; /* heads of available lists */
#if NeXT
struct buf *swbuf;
struct buf *swbuf_freelist;
struct buf *swbuf_cleanlist;
int nswbuf;
#endif
struct buf *alloc();
struct buf *realloccg();
struct buf *baddr();
struct buf *getblk();
struct buf *geteblk();
struct buf *getnewbuf();
struct buf *bread();
struct buf *breada();
#if NeXT
struct buf *getemptybuf();
struct buf *getpblk();
struct buf *breadp();
#endif NeXT
struct vnode *bdevvp(); /* Added for use by the specfs routines */
unsigned minphys();
#endif
/*
* These flags are kept in b_flags.
*/
#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) */
#if NeXT
#define B_PAGEOUT 0x00000800 /* Pageout operation */
#define B_PAGEIN 0x00001000 /* Pagein operation */
#else
#define B_UAREA 0x00000800 /* add u-area to a swap operation */
#define B_PAGET 0x00001000 /* page in/out of page table space */
#define B_PGIN 0x00004000 /* pagein op, so swap() can count it */
#endif
#define B_DIRTY 0x00002000 /* dirty page to be pushed out async */
#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_BAD 0x00100000 /* bad block revectoring in progress */
#define B_CALL 0x00200000 /* call b_iodone from iodone */
#define B_NOCACHE 0x00400000 /* don't cache block when released */
#define B_PRIVATE 0x02000000 /* memory attached to buffer is private */
#define B_KERNSPACE 0x04000000 /* physical I/O to kernel space */
/*
* 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) { \
int x = splbio(); \
bremfree(bp); \
(bp)->b_flags |= B_BUSY; \
(void) splx(x); \
}
#define iodone biodone
#define iowait biowait
/*
* Zero out a buffer's data portion.
*/
#define clrbuf(bp) { \
blkclr((bp)->b_un.b_addr, (unsigned)(bp)->b_bcount); \
(bp)->b_resid = 0; \
}
#endif _SYS_BUF_