|
|
1.1 root 1: /*
2: * Copyright (c) 1982, 1986 Regents of the University of California.
3: * All rights reserved. The Berkeley software License Agreement
4: * specifies the terms and conditions for redistribution.
5: *
6: * @(#)buf.h 7.6 (Berkeley) 5/14/88
7: */
8:
9: /*
10: * The header for buffers in the buffer pool and otherwise used
11: * to describe a block i/o request is given here.
12: *
13: * Each buffer in the pool is usually doubly linked into 2 lists:
14: * hashed into a chain by <dev,blkno> so it can be located in the cache,
15: * and (usually) on (one of several) queues. These lists are circular and
16: * doubly linked for easy removal.
17: *
18: * There are currently three queues for buffers:
19: * one for buffers which must be kept permanently (super blocks)
20: * one for buffers containing ``useful'' information (the cache)
21: * one for buffers containing ``non-useful'' information
22: * (and empty buffers, pushed onto the front)
23: * The latter two queues contain the buffers which are available for
24: * reallocation, are kept in lru order. When not on one of these queues,
25: * the buffers are ``checked out'' to drivers which use the available list
26: * pointers to keep track of them in their i/o active queues.
27: */
28:
29: /*
30: * Bufhd structures used at the head of the hashed buffer queues.
31: * We only need three words for these, so this abbreviated
32: * definition saves some space.
33: */
34: struct bufhd
35: {
36: long b_flags; /* see defines below */
37: struct buf *b_forw, *b_back; /* fwd/bkwd pointer in chain */
38: };
39: struct buf
40: {
41: long b_flags; /* too much goes here to describe */
42: struct buf *b_forw, *b_back; /* hash chain (2 way street) */
43: struct buf *av_forw, *av_back; /* position on free list if not BUSY */
44: #define b_actf av_forw /* alternate names for driver queue */
45: #define b_actl av_back /* head - isn't history wonderful */
46: long b_bcount; /* transfer count */
47: long b_bufsize; /* size of allocated buffer */
48: #define b_active b_bcount /* driver queue head: drive active */
49: short b_error; /* returned after I/O */
50: dev_t b_dev; /* major+minor device name */
51: union {
52: caddr_t b_addr; /* low order core address */
53: int *b_words; /* words for clearing */
54: struct fs *b_fs; /* superblocks */
55: struct csum *b_cs; /* superblock summary information */
56: struct cg *b_cg; /* cylinder group block */
57: struct dinode *b_dino; /* ilist */
58: daddr_t *b_daddr; /* indirect block */
59: } b_un;
60: daddr_t b_blkno; /* block # on device */
61: long b_resid; /* words not transferred after error */
62: #define b_errcnt b_resid /* while i/o in progress: # retries */
63: struct proc *b_proc; /* proc doing physical or swap I/O */
64: int (*b_iodone)(); /* function called by iodone */
65: int b_pfcent; /* center page when swapping cluster */
66: };
67:
68: #define BQUEUES 4 /* number of free buffer queues */
69:
70: #define BQ_LOCKED 0 /* super-blocks &c */
71: #define BQ_LRU 1 /* lru, useful buffers */
72: #define BQ_AGE 2 /* rubbish */
73: #define BQ_EMPTY 3 /* buffer headers with no memory */
74:
75: #ifdef KERNEL
76: #define BUFHSZ 512
77: #define RND (MAXBSIZE/DEV_BSIZE)
78: #if ((BUFHSZ&(BUFHSZ-1)) == 0)
79: #define BUFHASH(dev, dblkno) \
80: ((struct buf *)&bufhash[((int)(dev)+(((int)(dblkno))/RND))&(BUFHSZ-1)])
81: #else
82: #define BUFHASH(dev, dblkno) \
83: ((struct buf *)&bufhash[((int)(dev)+(((int)(dblkno))/RND)) % BUFHSZ])
84: #endif
85:
86: struct buf *buf; /* the buffer pool itself */
87: char *buffers;
88: int nbuf; /* number of buffer headers */
89: int bufpages; /* number of memory pages in the buffer pool */
90: struct buf *swbuf; /* swap I/O headers */
91: int nswbuf;
92: struct bufhd bufhash[BUFHSZ]; /* heads of hash lists */
93: struct buf bfreelist[BQUEUES]; /* heads of available lists */
94: struct buf bswlist; /* head of free swap header list */
95: struct buf *bclnlist; /* head of cleaned page list */
96:
97: struct buf *alloc();
98: struct buf *realloccg();
99: struct buf *baddr();
100: struct buf *getblk();
101: struct buf *geteblk();
102: struct buf *getnewbuf();
103: struct buf *bread();
104: struct buf *breada();
105:
106: unsigned minphys();
107: #endif
108:
109: /*
110: * These flags are kept in b_flags.
111: */
112: #define B_WRITE 0x000000 /* non-read pseudo-flag */
113: #define B_READ 0x000001 /* read when I/O occurs */
114: #define B_DONE 0x000002 /* transaction finished */
115: #define B_ERROR 0x000004 /* transaction aborted */
116: #define B_BUSY 0x000008 /* not on av_forw/back list */
117: #define B_PHYS 0x000010 /* physical IO */
118: #define B_XXX 0x000020 /* was B_MAP, alloc UNIBUS on pdp-11 */
119: #define B_WANTED 0x000040 /* issue wakeup when BUSY goes off */
120: #define B_AGE 0x000080 /* delayed write for correct aging */
121: #define B_ASYNC 0x000100 /* don't wait for I/O completion */
122: #define B_DELWRI 0x000200 /* write at exit of avail list */
123: #define B_TAPE 0x000400 /* this is a magtape (no bdwrite) */
124: #define B_UAREA 0x000800 /* add u-area to a swap operation */
125: #define B_PAGET 0x001000 /* page in/out of page table space */
126: #define B_DIRTY 0x002000 /* dirty page to be pushed out async */
127: #define B_PGIN 0x004000 /* pagein op, so swap() can count it */
128: #define B_CACHE 0x008000 /* did bread find us in the cache ? */
129: #define B_INVAL 0x010000 /* does not contain valid info */
130: #define B_LOCKED 0x020000 /* locked in core (not reusable) */
131: #define B_HEAD 0x040000 /* a buffer header, not a buffer */
132: #define B_BAD 0x100000 /* bad block revectoring in progress */
133: #define B_CALL 0x200000 /* call b_iodone from iodone */
134: #define B_RAW 0x400000 /* set by physio for raw transfers */
135:
136: /*
137: * Insq/Remq for the buffer hash lists.
138: */
139: #define bremhash(bp) { \
140: (bp)->b_back->b_forw = (bp)->b_forw; \
141: (bp)->b_forw->b_back = (bp)->b_back; \
142: }
143: #define binshash(bp, dp) { \
144: (bp)->b_forw = (dp)->b_forw; \
145: (bp)->b_back = (dp); \
146: (dp)->b_forw->b_back = (bp); \
147: (dp)->b_forw = (bp); \
148: }
149:
150: /*
151: * Insq/Remq for the buffer free lists.
152: */
153: #define bremfree(bp) { \
154: (bp)->av_back->av_forw = (bp)->av_forw; \
155: (bp)->av_forw->av_back = (bp)->av_back; \
156: }
157: #define binsheadfree(bp, dp) { \
158: (dp)->av_forw->av_back = (bp); \
159: (bp)->av_forw = (dp)->av_forw; \
160: (dp)->av_forw = (bp); \
161: (bp)->av_back = (dp); \
162: }
163: #define binstailfree(bp, dp) { \
164: (dp)->av_back->av_forw = (bp); \
165: (bp)->av_back = (dp)->av_back; \
166: (dp)->av_back = (bp); \
167: (bp)->av_forw = (dp); \
168: }
169:
170: /*
171: * Take a buffer off the free list it's on and
172: * mark it as being use (B_BUSY) by a device.
173: */
174: #define notavail(bp) { \
175: int x = splbio(); \
176: bremfree(bp); \
177: (bp)->b_flags |= B_BUSY; \
178: splx(x); \
179: }
180:
181: #define iodone biodone
182: #define iowait biowait
183:
184: /*
185: * Zero out a buffer's data portion.
186: */
187: #define clrbuf(bp) { \
188: blkclr((bp)->b_un.b_addr, (unsigned)(bp)->b_bcount); \
189: (bp)->b_resid = 0; \
190: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.