|
|
1.1 ! root 1: /* ! 2: * This file contains a ! 3: * mini disc buffer cache manager. ! 4: */ ! 5: #include <stdio.h> ! 6: #include <discbuf.h> ! 7: ! 8: DISCBUF *dblist; ! 9: FILE *dbfp; ! 10: ! 11: /* ! 12: * Claim a buffer and ! 13: * read block `block' into it. ! 14: * Return a pointer to the ! 15: * buffer. ! 16: */ ! 17: DISCBUF * ! 18: dbread(block) ! 19: long block; ! 20: { ! 21: register DISCBUF *dbp; ! 22: ! 23: dbp = dbgrab(block); ! 24: if ((dbp->db_flag&DB_OK) == 0) { ! 25: lseek(fileno(dbfp), BUFSIZ*dbp->db_block, 0); ! 26: if (read(fileno(dbfp), dbp->db_data, BUFSIZ) != BUFSIZ) ! 27: dbfatal("cache read error, block %D", block); ! 28: dbp->db_flag |= DB_OK; ! 29: } ! 30: return (dbp); ! 31: } ! 32: ! 33: /* ! 34: * This routine grabs a buffer ! 35: * and declares it to be the contents ! 36: * of block `block'. ! 37: * The data in the block is set to ! 38: * all zeros. ! 39: */ ! 40: DISCBUF * ! 41: dbzero(block) ! 42: long block; ! 43: { ! 44: register DISCBUF *dbp; ! 45: register char *p; ! 46: register n; ! 47: ! 48: dbp = dbgrab(block); ! 49: dbp->db_flag = DB_OK; ! 50: p = dbp->db_data; ! 51: n = BUFSIZ; ! 52: do { ! 53: *p++ = 0; ! 54: } while (--n); ! 55: return (dbp); ! 56: } ! 57: ! 58: /* ! 59: * Buffer grab. ! 60: * Try to find a buffer that ! 61: * has the block in it. ! 62: * If not, use the oldest free ! 63: * buffer. ! 64: */ ! 65: DISCBUF * ! 66: dbgrab(block) ! 67: long block; ! 68: { ! 69: register DISCBUF *dbp1, *dbp2; ! 70: register DISCBUF *fbp1, *fbp2; ! 71: ! 72: dbp1 = fbp1 = fbp2 = NULL; ! 73: dbp2 = dblist; ! 74: while (dbp2!=NULL && dbp2->db_block!=block) { ! 75: if (dbp2->db_refc == 0) { ! 76: fbp1 = dbp1; ! 77: fbp2 = dbp2; ! 78: } ! 79: dbp1 = dbp2; ! 80: dbp2 = dbp2->db_fp; ! 81: } ! 82: if (dbp2 == NULL) { ! 83: if (fbp2 == NULL) ! 84: dbfatal("cache full"); ! 85: dbp1 = fbp1; ! 86: dbp2 = fbp2; ! 87: if ((dbp2->db_flag&DB_DIRT) != 0) ! 88: dbwrite(dbp2); ! 89: dbp2->db_flag = 0; ! 90: dbp2->db_block = block; ! 91: } ! 92: ++dbp2->db_refc; ! 93: if (dbp1 != NULL) { ! 94: dbp1->db_fp = dbp2->db_fp; ! 95: dbp2->db_fp = dblist; ! 96: dblist = dbp2; ! 97: } ! 98: return (dbp2); ! 99: } ! 100: ! 101: /* ! 102: * Flush the buffer cache. All ! 103: * dirty buffers get written out to ! 104: * the disc. ! 105: * If `flag' is true the buffer ! 106: * cache is released. ! 107: */ ! 108: dbflush(flag) ! 109: { ! 110: register DISCBUF *dbp; ! 111: register DISCBUF *fbp; ! 112: ! 113: dbp = dblist; ! 114: while (dbp != NULL) { ! 115: if ((dbp->db_flag&(DB_OK|DB_DIRT)) == (DB_OK|DB_DIRT)) ! 116: dbwrite(dbp); ! 117: if (flag) { ! 118: fbp = dbp; ! 119: dbp = dbp->db_fp; ! 120: free((char *) fbp); ! 121: } else { ! 122: dbp->db_flag = 0; ! 123: dbp->db_refc = 0; ! 124: dbp = dbp->db_fp; ! 125: } ! 126: } ! 127: if (flag) ! 128: dblist = NULL; ! 129: } ! 130: ! 131: /* ! 132: * Allocate a buffer cache. ! 133: * The argument `nbuf' is the number ! 134: * of buffers to claim. ! 135: */ ! 136: dbclaim(nbuf) ! 137: { ! 138: register DISCBUF *dbp; ! 139: ! 140: if (dblist != NULL) ! 141: dbfatal("already claimed"); ! 142: while (nbuf--) { ! 143: if ((dbp = (DISCBUF *) malloc(sizeof(DISCBUF))) == NULL) ! 144: dbfatal("no memory"); ! 145: dbp->db_flag = 0; ! 146: dbp->db_refc = 0; ! 147: dbp->db_fp = dblist; ! 148: dblist = dbp; ! 149: } ! 150: } ! 151: ! 152: /* ! 153: * Write a buffer to the disc. ! 154: */ ! 155: dbwrite(dbp) ! 156: register DISCBUF *dbp; ! 157: { ! 158: lseek(fileno(dbfp), BUFSIZ*dbp->db_block, 0); ! 159: if (write(fileno(dbfp), dbp->db_data, BUFSIZ) != BUFSIZ) ! 160: dbfatal("cache write error, block %D", dbp->db_block); ! 161: } ! 162: ! 163: /* ! 164: * Release a buffer. ! 165: * The reference count is updated ! 166: */ ! 167: dbfree(dbp, flag) ! 168: register DISCBUF *dbp; ! 169: { ! 170: dbp->db_flag |= flag; ! 171: if (--dbp->db_refc < 0) ! 172: dbfatal("refc < 0"); ! 173: } ! 174: ! 175: /* ! 176: * Fatal errors. ! 177: */ ! 178: dbfatal(a) ! 179: { ! 180: fprintf(stderr, "discbuf: %r\n", &a); ! 181: exit(1); ! 182: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.