Annotation of coherent/d/conf/tboot/bio.c, revision 1.1.1.1

1.1       root        1: /*
                      2:  * bio.c -- buffer handling code.
                      3:  *
                      4:  * This code REALLY assumes single-threaded execution.  All locks are
                      5:  * advisory only and may be revoked without notice.
                      6:  *
                      7:  * See also bread() in diskio.c.
                      8:  */
                      9: 
                     10: #include <sys/types.h>
                     11: #include <sys/buf.h>
                     12: #include <sys/stat.h>
                     13: 
                     14: #include "tboot.h"
                     15: 
                     16: #define NBUF   23      /* Number of disk buffers in cache.  */
                     17: 
                     18: static BUF bufl[NBUF]; /* Buffer structures.  */
                     19: 
                     20: static char blockp[NBUF * BLOCK];      /* The blocks themselves.  */
                     21: static int buf_inited = (1==2);                /* Has bufinit been called?  */
                     22: 
                     23: 
                     24: /*
                     25:  * Initialise buffer headers.
                     26:  */
                     27: void
                     28: bufinit()
                     29: {
                     30:        int i;          /* Counter for buffer structures.  */
                     31:        BUF *bp;        /* Handy pointer for buffer shorthand.  */
                     32:        paddr_t p;      /* Physical memory of the buffers themselves.  */
                     33: 
                     34:        sanity_check("Entering bufinit()");
                     35: 
                     36:        if (buf_inited) {
                     37:                puts("\r\nbufinit() called too many times.\r\n");
                     38:                puts("Harmlessly ignored.\r\n");
                     39:                return;
                     40:        }
                     41:        buf_inited = (1==1);
                     42:        
                     43:        /* We're going to chop blockp up into disk buffers.  */
                     44:        p = (paddr_t) blockp;
                     45: 
                     46:        for (i = 0; i < NBUF; ++i) {
                     47:                bp = &(bufl[i]);        /* Shorthand... */
                     48:                bp->b_dev = NODEV;      /* Buffer is not associated with a device.  */
                     49:                bp->b_bno = (daddr_t) 0;
                     50:                bp->b_paddr = p;        /* Attach a physical buffer.  */
                     51:                sanity_check("bufinit() about to call gate_unlock()");
                     52:                gate_unlock(bp->b_gate);        /* Unlock the buffer.  */
                     53: 
                     54:                p += BLOCK;             /* Point to the next buffer.  */
                     55:        }
                     56:        sanity_check("Leaving bufinit()");
                     57: } /* bufinit() */
                     58: 
                     59: 
                     60: /*
                     61:  * Claim a buffer for a block.
                     62:  * Finds the buffer if it has already been accessed, otherwise,
                     63:  * picks another buffer.
                     64:  */
                     65: BUF *
                     66: bclaim(block)
                     67:        daddr_t block;
                     68: {
                     69:        int i;
                     70:        BUF *bp;
                     71:        BUF *best_buf;
                     72: 
                     73:        /* Be sure to initialize buffers the first time.  */
                     74:        if (!buf_inited) {
                     75:                bufinit();
                     76:        }
                     77: 
                     78:        sanity_check("Start of bclaim");
                     79: 
                     80:        best_buf = (BUF *) NULL;
                     81: 
                     82:        /* Look to see if this block is cached.  */
                     83:        for (i = 0; i < NBUF; ++i) {
                     84:                bp = &(bufl[i]);
                     85: 
                     86:                /* If this is exactly the buffer we want, grab it!  */
                     87:                if (block == bp->b_bno) {
                     88: #if 0
                     89:                        puts("!");      /* DEBUG buffer hit */
                     90: #endif /* 0 */
                     91:                        best_buf = bp;
                     92:                }
                     93:        }
                     94: 
                     95:        /*
                     96:         * If we couldn't find an exact match--pick another one.
                     97:         */     
                     98:        if ((BUF *) NULL == best_buf) {
                     99: #if 0
                    100:                puts("?");      /* DEBUG buffer miss*/
                    101: #endif
                    102:                sanity_check("About to call bpick()");
                    103:                best_buf = bpick(1);    /* Fetch a new block.  */
                    104:                sanity_check("bclaim() from bpick() to gate_unlock()");
                    105:        }
                    106: 
                    107:        /* ASSERTION: At this point we have a buffer we can claim.  */
                    108: 
                    109: 
                    110:        gate_lock(best_buf->b_gate);
                    111: 
                    112:        sanity_check("Returning from bclaim()");
                    113:        return(best_buf);
                    114: } /* bclaim() */
                    115: 
                    116: 
                    117: /*
                    118:  * Pick the next buffer for allocation.
                    119:  * Uses a round-robin scheme of buffer allocation, skipping over
                    120:  * locked buffers.  If all buffers are locked, they are forcibly
                    121:  * unlocked and the first one is picked.
                    122:  */
                    123: BUF *
                    124: bpick()
                    125: {
                    126:        static int next_bp = NBUF;
                    127: 
                    128:        int i;
                    129: 
                    130:        BUF *retval;
                    131: 
                    132:        retval = (BUF *) NULL;  /* Nothing found yet.  */
                    133: 
                    134:        for (i = 0; ((BUF *)NULL == retval) && (i < NBUF); ++i) {
                    135:                /* Wrap next_bp back to the beginning if needed.  */
                    136:                next_bp %= NBUF;
                    137: 
                    138:                /* If we've found an unlocked buffer, return it.  */
                    139:                if (!gate_locked(bufl[next_bp].b_gate)) {
                    140:                        /* Trash the contents.  */
                    141:                        bufl[next_bp].b_dev = (dev_t) NODEV;
                    142:                        bufl[next_bp].b_bno = (daddr_t) 0;
                    143: 
                    144:                        sanity_check("bpick().2");
                    145:                        retval = &(bufl[next_bp]);
                    146:                }
                    147:                ++next_bp;
                    148:        }
                    149: 
                    150:        if ((BUF *)NULL == retval) {
                    151:                buf_inited = FALSE;     /* Force bufinit() to actually run.  */
                    152:                bufinit();
                    153:                sanity_check("bpick().1");
                    154:                retval = &(bufl[0]);
                    155:                next_bp = 1;
                    156:        }
                    157:        
                    158:        return(retval);
                    159: } /* bpick() */
                    160: 
                    161: 
                    162: /*
                    163:  * Release a buffer for a block.
                    164:  */
                    165: void
                    166: brelease(bp)
                    167:        BUF *bp;
                    168: {
                    169: 
                    170:        /* Make sure the buffer is unlocked.  */
                    171:        sanity_check("brelease() about to call gate_unlock()");
                    172:        gate_unlock(bp->b_gate);
                    173: 
                    174:        if (0 != (BFMOD & bp->b_flag)){
                    175:                puts("Warning:  I don't know how to brelease() a modified buffer.\r\n");
                    176:        }
                    177:        sanity_check("Returning from brelease()");
                    178: } /* brelease() */
                    179: 
                    180: 
                    181: /*
                    182:  * Attempt to lock the gate 'g'.
                    183:  * Return TRUE on success, FALSE if it was already locked.
                    184:  */
                    185: int
                    186: gate_lock(g)
                    187:        GATE g;
                    188: {
                    189:        if (g[0]) {
                    190:                return(FALSE);
                    191:        }
                    192: 
                    193:        g[0] = TRUE;
                    194: 
                    195:        return(TRUE);
                    196: } /* gate_lock() */
                    197: 
                    198: 
                    199: /*
                    200:  * Check to see if the gate 'g' is locked.
                    201:  */
                    202: int
                    203: gate_locked(g)
                    204:        GATE g;
                    205: {
                    206:        return(g[0]? TRUE : FALSE);
                    207: } /* gate_locked() */
                    208: 
                    209: /*
                    210:  * Unlock the gate 'g'.
                    211:  */
                    212: void
                    213: gate_unlock(g)
                    214:        GATE g;
                    215: {
                    216: 
                    217:        sanity_check("Start of gate_unlock()");
                    218: 
                    219:        g[0] = FALSE;
                    220: 
                    221:        sanity_check("End of gate_unlock()");
                    222: } /* gate_unlock() */
                    223: 
                    224: /*
                    225:  * Sanity checker.
                    226:  * Prints contents of "message" if something is amiss and dumps you
                    227:  * into the monitor.
                    228:  *
                    229:  * Add tests and messages as needed.
                    230:  */
                    231: 
                    232: void
                    233: sanity_check(message)
                    234:        char *message;
                    235: {
                    236:        extern char sects, heads;
                    237:        extern BUF bufl[];
                    238:        
                    239:        static int d_data_inited = FALSE;       /* Is disk data inited?  */
                    240:        static uint16 osects;                   /* Correct number of sectors.  */
                    241:        static uint16 oheads;                   /* Correct number of heads.  */
                    242: 
                    243:        int i;
                    244:        static int paddr_ok_once = FALSE;
                    245:        int paddr_ok;
                    246: 
                    247:        if (!d_data_inited) {
                    248:                osects = sects;
                    249:                oheads = heads;
                    250:                d_data_inited = TRUE;
                    251:        } else {
                    252:                /* Test to see if disk information has been stomped on.  */
                    253:                if (osects != sects) {
                    254:                        puts(message);
                    255:                        puts(": dead sects.\r\n");
                    256:                        monitor();
                    257:                }
                    258:        
                    259:                if (oheads != heads) {
                    260:                        puts(message);
                    261:                        puts(": dead heads.\r\n");
                    262:                        monitor();
                    263:                }
                    264:        }
                    265: 
                    266: 
                    267:        /*
                    268:         * Don't flunk this test until it has been passed once.
                    269:         * Check to see if the b_paddr entries for buffers have
                    270:         * been stomped on.
                    271:         */
                    272:        paddr_ok = TRUE;
                    273: 
                    274:        for (i = 0; i < NBUF; ++i) {
                    275:                if (0 == (uint16) (bufl[i].b_paddr)) {
                    276:                        paddr_ok = FALSE;       /* Test failed.  */
                    277:                        break;
                    278:                }
                    279:        }
                    280: 
                    281:        if (paddr_ok) {
                    282:                paddr_ok_once = TRUE;
                    283:        } else if (paddr_ok_once) {
                    284:                puts(message);
                    285:                puts(": bad paddr in buffer.\r\n");
                    286:                monitor();
                    287:        }
                    288: 
                    289: } /* sanity_check() */

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.