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