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