1: /* 2: * Copyright (c) 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 1.4 (2.11BSD GTE) 1996/9/13 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 two queues for buffers: 19: * one for buffers containing ``useful'' information (the cache) 20: * one for buffers containing ``non-useful'' information 21: * (and empty buffers, pushed onto the front) 22: * These queues contain the buffers which are available for 23: * reallocation, are kept in lru order. When not on one of these queues, 24: * the buffers are ``checked out'' to drivers which use the available list 25: * pointers to keep track of them in their i/o active queues. 26: */ 27: 28: /* 29: * Bufhd structures used at the head of the hashed buffer queues. 30: * We only need three words for these, so this abbreviated 31: * definition saves some space. 32: */ 33: struct bufhd 34: { 35: short b_flags; /* see defines below */ 36: struct buf *b_forw, *b_back; /* fwd/bkwd pointer in chain */ 37: }; 38: struct buf 39: { 40: short b_flags; /* see defines below */ 41: struct buf *b_forw, *b_back; /* hash chain (2 way street) */ 42: struct buf *av_forw, *av_back; /* position on free list if not BUSY */ 43: #define b_actf av_forw /* alternate names for driver queue */ 44: #define b_actl av_back /* head - isn't history wonderful */ 45: u_short b_bcount; /* transfer count */ 46: #define b_active b_bcount /* driver queue head: drive active */ 47: char b_error; /* returned after I/O */ 48: char b_xmem; /* high order core address */ 49: dev_t b_dev; /* major+minor device name */ 50: union { 51: caddr_t b_addr; /* low order core address */ 52: } b_un; 53: daddr_t b_blkno; /* block # on device */ 54: u_short b_resid; /* words not transferred after error */ 55: #define b_cylin b_resid /* disksort */ 56: #define b_errcnt b_resid /* while i/o in progress: # retries */ 57: }; 58: 59: /* 60: * We never use BQ_LOCKED or BQ_EMPTY, but if you want the 4.X block I/O 61: * code to drop in, you have to have BQ_AGE and BQ_LRU *after* the first 62: * queue, and it only costs 6 bytes of data space. 63: */ 64: #define BQUEUES 3 /* number of free buffer queues */ 65: 66: #define BQ_LOCKED 0 /* super-blocks &c */ 67: #define BQ_LRU 1 /* lru, useful buffers */ 68: #define BQ_AGE 2 /* rubbish */ 69: #define BQ_EMPTY 3 /* buffer headers with no memory */ 70: 71: /* Flags to low-level allocation routines. */ 72: #define B_CLRBUF 0x01 /* Request allocated buffer be cleared. */ 73: #define B_SYNC 0x02 /* Do all allocations synchronously. */ 74: 75: #define bawrite(bp) {(bp)->b_flags |= B_ASYNC; bwrite(bp);} 76: #define bfree(bp) (bp)->b_bcount = 0 77: #define bftopaddr(bp) ((u_int)(bp)->b_un.b_addr >> 6 | (bp)->b_xmem << 10) 78: 79: #if defined(KERNEL) && !defined(SUPERVISOR) 80: #define BUFHSZ 16 /* must be power of 2 */ 81: #define BUFHASH(dev,blkno) ((struct buf *)&bufhash[((long)(dev) + blkno) & ((long)(BUFHSZ - 1))]) 82: extern struct buf buf[]; /* the buffer pool itself */ 83: extern int nbuf; /* number of buffer headers */ 84: extern struct bufhd bufhash[]; /* heads of hash lists */ 85: extern struct buf bfreelist[]; /* heads of available lists */ 86: 87: struct buf *balloc(); 88: struct buf *getblk(); 89: struct buf *geteblk(); 90: struct buf *getnewbuf(); 91: struct buf *bread(); 92: struct buf *breada(); 93: #endif 94: 95: /* 96: * These flags are kept in b_flags. 97: */ 98: #define B_WRITE 0x00000 /* non-read pseudo-flag */ 99: #define B_READ 0x00001 /* read when I/O occurs */ 100: #define B_DONE 0x00002 /* transaction finished */ 101: #define B_ERROR 0x00004 /* transaction aborted */ 102: #define B_BUSY 0x00008 /* not on av_forw/back list */ 103: #define B_PHYS 0x00010 /* physical IO */ 104: #define B_MAP 0x00020 /* alloc UNIBUS */ 105: #define B_WANTED 0x00040 /* issue wakeup when BUSY goes off */ 106: #define B_AGE 0x00080 /* delayed write for correct aging */ 107: #define B_ASYNC 0x00100 /* don't wait for I/O completion */ 108: #define B_DELWRI 0x00200 /* write at exit of avail list */ 109: #define B_TAPE 0x00400 /* this is a magtape (no bdwrite) */ 110: #define B_INVAL 0x00800 /* does not contain valid info */ 111: #define B_BAD 0x01000 /* bad block revectoring in progress */ 112: #define B_LOCKED 0x02000 /* locked in core (not reusable) */ 113: #define B_UBAREMAP 0x04000 /* addr UNIBUS virtual, not physical */ 114: #define B_RAMREMAP 0x08000 /* remapped into ramdisk */ 115: 116: /* 117: * Insq/Remq for the buffer hash lists. 118: */ 119: #define bremhash(bp) { \ 120: (bp)->b_back->b_forw = (bp)->b_forw; \ 121: (bp)->b_forw->b_back = (bp)->b_back; \ 122: } 123: #define binshash(bp, dp) { \ 124: (bp)->b_forw = (dp)->b_forw; \ 125: (bp)->b_back = (dp); \ 126: (dp)->b_forw->b_back = (bp); \ 127: (dp)->b_forw = (bp); \ 128: } 129: 130: /* 131: * Insq/Remq for the buffer free lists. 132: */ 133: #define bremfree(bp) { \ 134: (bp)->av_back->av_forw = (bp)->av_forw; \ 135: (bp)->av_forw->av_back = (bp)->av_back; \ 136: } 137: #define binsheadfree(bp, dp) { \ 138: (dp)->av_forw->av_back = (bp); \ 139: (bp)->av_forw = (dp)->av_forw; \ 140: (dp)->av_forw = (bp); \ 141: (bp)->av_back = (dp); \ 142: } 143: #define binstailfree(bp, dp) { \ 144: (dp)->av_back->av_forw = (bp); \ 145: (bp)->av_back = (dp)->av_back; \ 146: (dp)->av_back = (bp); \ 147: (bp)->av_forw = (dp); \ 148: } 149: 150: /* 151: * Take a buffer off the free list it's on and 152: * mark it as being use (B_BUSY) by a device. 153: */ 154: #define notavail(bp) { \ 155: register int x = splbio(); \ 156: bremfree(bp); \ 157: (bp)->b_flags |= B_BUSY; \ 158: splx(x); \ 159: } 160: 161: #define iodone biodone 162: #define iowait biowait