|
|
1.1 ! root 1: /* ! 2: * Virtual memory for fsck. Uses hash algorithm ! 3: * rather than LRU to get it up fast. ! 4: */ ! 5: #include "assert.h" /* special copy with printf() not fprintf() */ ! 6: #include <sys/stat.h> ! 7: #include "fsck.h" ! 8: #if SMALLMODEL ! 9: ! 10: #define VBLKB 9 /* bytes in virtual block as power of 2 */ ! 11: #define VBLK (1 << VBLKB) /* bytes in a virtual block */ ! 12: #define MBKSB 6 /* number of virtual blocks as power of 2 */ ! 13: #define MBKS (1 << MBKSB) /* number of virtual blocks */ ! 14: ! 15: #define DVTMP "/dev/rram1" /* Default Virtual Temp Filename */ ! 16: #define DVTMPCLS "/dev/rram1close" /* Default Virtual Temp File Close */ ! 17: #define MAJORRAM 8 /* Major Device Number for the Ram Disk */ ! 18: ! 19: struct mapper { ! 20: unsigned dirty:1; ! 21: unsigned what_in:15; /* which block is in memory */ ! 22: }; ! 23: ! 24: static unsigned long flagdsp, blkdsp, dupdsp, duplim; ! 25: static struct mapper map[MBKS]; ! 26: static unsigned char data[MBKS][VBLK]; ! 27: static int tmp; ! 28: ! 29: static char *dvtmp = DVTMP; ! 30: static char *dvtmpcls = DVTMPCLS; ! 31: ! 32: /* ! 33: * Init file system for virtual arrays. ! 34: * Data is ordered links, flags, blocks then dups. ! 35: */ ! 36: initV(links, flags, blocks, dups) ! 37: unsigned links, flags, blocks, dups; ! 38: { ! 39: register long bp; ! 40: struct stat st; ! 41: unsigned datasiz; ! 42: ! 43: flagdsp = links; ! 44: blkdsp = flagdsp + flags; ! 45: dupdsp = blkdsp + blocks; ! 46: duplim = dupdsp + dups; ! 47: ! 48: memset(map, 0, sizeof(map)); /* zero ram arrays */ ! 49: memset(data, 0, sizeof(data)); ! 50: ! 51: tmp = -1; ! 52: ! 53: datasiz = sizeof(data); ! 54: if ( duplim < datasiz ) ! 55: return; ! 56: ! 57: if ( tempFile == NULL ) { ! 58: switch ( is_fs(dvtmp) ) { ! 59: case -1: ! 60: fatal( ! 61: "Can't access ram disk \"%s\", use the -t option", dvtmp); ! 62: case 0: ! 63: break; ! 64: case 1: ! 65: fatal( ! 66: "Possible file system on ram disk \"%s\", use the -t option", dvtmp); ! 67: } ! 68: if ( (-1 == stat(dvtmp, &st)) || !(st.st_mode&S_IFCHR) || ! 69: (major(st.st_rdev) != MAJORRAM) ) ! 70: fatal("Ram disk \"%s\" not mknod'ed properly", ! 71: dvtmp); ! 72: if ( -1 == (tmp = open(dvtmp, 2)) ) ! 73: fatal("Cannot open read/write Ram Disk \"%s\"", dvtmp); ! 74: ! 75: /* Ram disk driver may not promise zeroed start. ! 76: * This code may go later. Extra write not important. */ ! 77: for(bp = 0; bp < duplim; bp += VBLK) /* zero disk stuff */ ! 78: if ( VBLK != write(tmp, data[0], VBLK) ) ! 79: fatal("Error writing to tmp file"); ! 80: } else { ! 81: if ( -1 == (tmp = open(tempFile, 2)) ) { ! 82: if ( -1 == (tmp = creat(tempFile, 0600)) ) ! 83: fatal("Cannot create temp file \"%s\"", ! 84: tempFile); ! 85: close(tmp); ! 86: tmp = open(tempFile, 2); ! 87: unlink(tempFile); ! 88: } ! 89: if ( -1 == fstat(tmp, &st) ) ! 90: fatal("Can't stat temp file \"%s\"", tempFile); ! 91: if ( st.st_dev == fsysrdev ) ! 92: fatal("Temp File must not be on file system to fsck"); ! 93: } ! 94: } ! 95: ! 96: /* ! 97: * cleanup virtual system ! 98: */ ! 99: cleanV() ! 100: { ! 101: struct stat st; ! 102: ! 103: if ( tmp == -1 ) /* No Virtual Temp File Opened */ ! 104: return; ! 105: ! 106: close(tmp); ! 107: if ( tempFile != NULL ) /* Virtual File not Default RAMDisk */ ! 108: return; ! 109: /* Virtual File is Default RAMDisk */ ! 110: if ( (-1 == stat(dvtmpcls, &st)) || !(st.st_mode&S_IFCHR) || ! 111: (major(st.st_rdev) != MAJORRAM) || ! 112: ((minor(st.st_rdev)&0x7F) != 0) ) ! 113: fatal("Ram disk close \"%s\" not mknod'ed properly", dvtmpcls); ! 114: if ( -1 == (tmp = open(dvtmpcls, 2)) ) ! 115: fatal("Cannot open Ram Disk Close \"%s\"", dvtmpcls); ! 116: if ( close(tmp) < 0 ) ! 117: fatal("Cannot close Ram Disk Close \"%s\"", dvtmpcls); ! 118: } ! 119: ! 120: /* ! 121: * All actions for virtual array ! 122: */ ! 123: findblock(bp, action, odata) ! 124: long bp; /* data address */ ! 125: enum vact action; /* what to do */ ! 126: unsigned odata; /* optional data */ ! 127: { ! 128: unsigned which, what_in, byte_no, bit; ! 129: unsigned long diskad; ! 130: unsigned char *byte; ! 131: extern long lseek(); ! 132: ! 133: switch(action) { /* use displacment to correct part of file */ ! 134: case testBlock: ! 135: case markBlock: ! 136: case unmarkBlock: ! 137: bit = 1 << (bp & 7); ! 138: bp >>= 3; ! 139: case grabBlock: /* 8 at a time for copy */ ! 140: assert(bp >= 0); ! 141: bp += blkdsp; ! 142: assert(bp < dupdsp); ! 143: break; ! 144: case testDup: ! 145: case markDup: ! 146: case unmarkDup: ! 147: bit = 1 << (bp & 7); ! 148: bp >>= 3; ! 149: case setDup: /* 8 at a time for copy */ ! 150: assert(bp >= 0); ! 151: bp += dupdsp; ! 152: assert(bp < duplim); ! 153: break; ! 154: case Flags: ! 155: case setFlags: ! 156: case orFlags: ! 157: assert(bp > 0); ! 158: bp += flagdsp - 1; ! 159: assert(bp < blkdsp); ! 160: break; ! 161: case linkCtr: ! 162: case incLinkctr: ! 163: case setLinkctr: ! 164: assert(bp > 0); ! 165: bp--; ! 166: assert(bp < flagdsp); ! 167: } ! 168: ! 169: byte_no = bp & (VBLK - 1); ! 170: bp >>= VBLKB; ! 171: which = bp & (MBKS - 1); ! 172: bp >>= MBKSB; ! 173: what_in = bp & 0x7fff; ! 174: ! 175: if((diskad = map[which].what_in) != what_in) { ! 176: if(map[which].dirty) { ! 177: diskad <<= VBLKB + MBKSB; ! 178: diskad += which << VBLKB; ! 179: if(-1 == lseek(tmp, diskad, 0)) ! 180: fatal("Error seeking tmp file"); ! 181: if(VBLK != write(tmp, data[which], VBLK)) ! 182: fatal("Error writing tmp file"); ! 183: } ! 184: diskad = what_in; ! 185: diskad <<= VBLKB + MBKSB; ! 186: diskad += which << VBLKB; ! 187: if(-1 == lseek(tmp, diskad, 0)) ! 188: fatal("Error seeking tmp file"); ! 189: if(VBLK != read(tmp, data[which], VBLK)) ! 190: memset(data[which], 0, VBLK); ! 191: map[which].what_in = what_in; ! 192: map[which].dirty = 0; /* clean */ ! 193: } ! 194: byte = &data[which][byte_no]; ! 195: ! 196: switch(action) { ! 197: case testBlock: ! 198: case testDup: ! 199: return(*byte & bit); ! 200: case markBlock: ! 201: case markDup: ! 202: map[which].dirty = 1; ! 203: return(*byte |= bit); ! 204: case unmarkBlock: ! 205: case unmarkDup: ! 206: map[which].dirty = 1; ! 207: return(*byte ^= bit); ! 208: case linkCtr: ! 209: case Flags: ! 210: case grabBlock: ! 211: return(*byte); ! 212: case setLinkctr: ! 213: case setFlags: ! 214: case setDup: ! 215: map[which].dirty = 1; ! 216: return(*byte = odata); ! 217: case orFlags: ! 218: map[which].dirty = 1; ! 219: return(*byte |= odata); ! 220: case incLinkctr: ! 221: map[which].dirty = 1; ! 222: return(++*byte); ! 223: default: ! 224: fatal("Bad action in virtual system"); ! 225: } ! 226: } ! 227: ! 228: /* ! 229: * copy virtual memory blockmap to dupmap ! 230: * read and write groups to avoid possable thrashing. ! 231: */ ! 232: void ! 233: copyV(size) ! 234: unsigned size; ! 235: { ! 236: char buf[128]; ! 237: register int i; ! 238: long bp, bs; ! 239: ! 240: for(bs = bp = 0; bp < size; ) { ! 241: for(i = 0; (i < 128) && (bp < size); i++, bp++) ! 242: buf[i] = findblock(bp, grabBlock); ! 243: ! 244: for(i = 0; (i < 128) && (bs < size); i++, bs++) ! 245: findblock(bs, setDup, buf[i]); ! 246: } ! 247: } ! 248: ! 249: #ifdef TEST ! 250: fatal(s) ! 251: char *s; ! 252: { ! 253: printf("%s\n", s); ! 254: exit(1); ! 255: } ! 256: ! 257: static char buf[80]; ! 258: gbuf() ! 259: { ! 260: if(NULL == gets(buf)) { ! 261: unlink("vtmp"); ! 262: exit(0); ! 263: } ! 264: return(buf[0]); ! 265: } ! 266: ! 267: main() ! 268: { ! 269: unsigned long b; ! 270: char data; ! 271: ! 272: initV(10000, 10000, 20000); ! 273: for(;;) { ! 274: printf("b = block, d = dup, f = flags, l = linkctr\n"); ! 275: switch(gbuf()) { ! 276: case 'l': ! 277: printf("s = set, d = display, i = increment: then loc\n"); ! 278: gbuf(); ! 279: sscanf(buf + 2, "%ld", &b); ! 280: switch(buf[0]) { ! 281: case 's': ! 282: setlinkctr(b, 0); /* no data */ ! 283: case 'd': ! 284: printf("%d\n", linkctr(b)); ! 285: break; ! 286: case 'i': ! 287: printf("%d\n", inclinkctr(b)); ! 288: } ! 289: break; ! 290: case 'f': ! 291: printf("d = display, s = set, o = or: then loc\n"); ! 292: gbuf(); ! 293: sscanf(buf + 2, "%ld %c", &b, &data); ! 294: switch(buf[0]) { ! 295: case 's': ! 296: setflags(b, data); ! 297: case 'd': ! 298: break; ! 299: case 'o': ! 300: orflags(b, data); ! 301: } ! 302: printf("%c\n", flags(b)); ! 303: break; ! 304: case 'b': ! 305: printf("t = test, m = mark, u = unmark: then loc\n"); ! 306: gbuf(); ! 307: sscanf(buf + 2, "%ld", &b); ! 308: switch(buf[0]) { ! 309: case 'm': ! 310: markblock(b); ! 311: case 't': ! 312: break; ! 313: case 'u': ! 314: unmarkblock(b); ! 315: } ! 316: printf("%c\n", testblock(b) ? '1' : '0'); ! 317: break; ! 318: case 'd': ! 319: printf("t = test, m = mark, u = unmark: then loc\n"); ! 320: gbuf(); ! 321: sscanf(buf + 2, "%ld", &b); ! 322: switch(buf[0]) { ! 323: case 'm': ! 324: markdup(b); ! 325: case 't': ! 326: break; ! 327: case 'u': ! 328: unmarkdup(b); ! 329: } ! 330: printf("%c\n", testdup(b) ? '1' : '0'); ! 331: break; ! 332: } ! 333: } ! 334: } ! 335: #endif ! 336: #endif
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.