Annotation of coherent/d/etc/fsck/virtual.c, revision 1.1.1.1

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 ( tmpfile == 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(tmpfile, 2)) ) {
                     82:                        if ( -1 == (tmp = creat(tmpfile, 0600)) )
                     83:                                fatal("Cannot create temp file \"%s\"", 
                     84:                                                                tmpfile);
                     85:                        close(tmp);
                     86:                        tmp = open(tmpfile, 2);
                     87:                        unlink(tmpfile);
                     88:                }
                     89:                if ( -1 == fstat(tmp, &st) )
                     90:                        fatal("Can't stat temp file \"%s\"", tmpfile);
                     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 ( tmpfile != 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

unix.superglobalmegacorp.com

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