Annotation of coherent/d/conf/tboot/bio.c, revision 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.