Annotation of researchv9/cmd/mkfs.c, revision 1.1.1.1

1.1       root        1: static char *sccsid = "@(#)mkfs.c      4.2 (Berkeley) 4/20/81";
                      2: 
                      3: /*
                      4:  * Make a file system prototype.
                      5:  * usage: mkfs filsys proto/size [ m n ]
                      6:  */
                      7: #define        NIPB    (BSIZE(0)/sizeof(struct dinode))
                      8: #define        NDIRECT (BSIZE(0)/sizeof(struct direct))
                      9: #define        LADDR   10
                     10: #define        MAXFN   1000
                     11: #define MAXISIZE (65536-NIPB)
                     12: #ifndef STANDALONE
                     13: #include <stdio.h>
                     14: #include <a.out.h>
                     15: #endif
                     16: #include <sys/param.h>
                     17: #include <sys/ino.h>
                     18: #include <sys/inode.h>
                     19: #include <sys/filsys.h>
                     20: #include <sys/fblk.h>
                     21: #include <sys/dir.h>
                     22: time_t utime;
                     23: #ifndef STANDALONE
                     24: FILE   *fin;
                     25: #else
                     26: int    fin;
                     27: #endif
                     28: int    fsi;
                     29: int    fso;
                     30: char   *charp;
                     31: char   buf[BSIZE(0)];
                     32: union {
                     33:        struct fblk fb;
                     34:        char pad1[BSIZE(0)];
                     35: } fbun;
                     36: #define        fbuf    fbun.fb
                     37: #ifndef STANDALONE
                     38: struct exec head;
                     39: #endif
                     40: char   string[50];
                     41: union {
                     42:        struct filsys fs;
                     43:        char pad2[BSIZE(0)];
                     44: } fsun;
                     45: #define        filsys  fsun.fs
                     46: char   *fsys;
                     47: char   *proto;
                     48: int    f_n     = MAXFN;
                     49: int    f_m     = 3;
                     50: int    error;
                     51: ino_t  ino;
                     52: long   getnum();
                     53: daddr_t        alloc();
                     54: 
                     55: main(argc, argv)
                     56: char *argv[];
                     57: {
                     58:        int f, c;
                     59:        long n;
                     60: 
                     61: #ifndef STANDALONE
                     62:        time(&utime);
                     63:        if(argc < 3) {
                     64:                printf("usage: mkfs filsys proto/size [ m n ]\n");
                     65:                exit(1);
                     66:        }
                     67:        fsys = argv[1];
                     68:        proto = argv[2];
                     69: #else
                     70:        {
                     71:                static char protos[60];
                     72: 
                     73:                printf("file sys size: ");
                     74:                gets(protos);
                     75:                proto = protos;
                     76:        }
                     77: #endif
                     78: #ifdef STANDALONE
                     79:        {
                     80:                char fsbuf[100];
                     81: 
                     82:                do {
                     83:                        printf("file system: ");
                     84:                        gets(fsbuf);
                     85:                        fso = open(fsbuf, 1);
                     86:                        fsi = open(fsbuf, 0);
                     87:                } while (fso < 0 || fsi < 0);
                     88:        }
                     89:        fin = NULL;
                     90:        argc = 0;
                     91: #else
                     92:        fso = creat(fsys, 0666);
                     93:        if(fso < 0) {
                     94:                printf("%s: cannot create\n", fsys);
                     95:                exit(1);
                     96:        }
                     97:        fsi = open(fsys, 0);
                     98:        if(fsi < 0) {
                     99:                printf("%s: cannot open\n", fsys);
                    100:                exit(1);
                    101:        }
                    102:        fin = fopen(proto, "r");
                    103: #endif
                    104:        if(fin == NULL) {
                    105:                n = 0;
                    106:                for(f=0; c=proto[f]; f++) {
                    107:                        if(c<'0' || c>'9') {
                    108:                                printf("%s: cannot open\n", proto);
                    109:                                exit(1);
                    110:                        }
                    111:                        n = n*10 + (c-'0');
                    112:                }
                    113:                filsys.s_fsize = n;
                    114:                n = n/25;
                    115:                if(n <= 0)
                    116:                        n = 1;
                    117:                if(n > MAXISIZE/NIPB)
                    118:                        n = MAXISIZE/NIPB;
                    119:                filsys.s_isize = n + 2;
                    120:                printf("isize = %D\n", n*NIPB);
                    121:                charp = "d--777 0 0 $ ";
                    122:                goto f3;
                    123:        }
                    124: 
                    125: #ifndef STANDALONE
                    126:        /*
                    127:         * get name of boot load program
                    128:         * and read onto block 0
                    129:         */
                    130: 
                    131:        getstr();
                    132:        f = open(string, 0);
                    133:        if(f < 0) {
                    134:                printf("%s: cannot  open init\n", string);
                    135:                goto f2;
                    136:        }
                    137:        c = BSIZE(0);
                    138: /*
                    139:        read(f, (char *)&head, sizeof head);
                    140:        if(head.a_magic != OMAGIC) {
                    141:                printf("%s: bad format\n", string);
                    142:                goto f1;
                    143:        }
                    144:        c = head.a_text + head.a_data;
                    145:        if(c > BSIZE(0)) {
                    146:                printf("%s: too big\n", string);
                    147:                goto f1;
                    148:        }
                    149: */
                    150:        read(f, buf, c);
                    151:        wtfs((long)0, buf);
                    152: 
                    153: f1:
                    154:        close(f);
                    155: 
                    156:        /*
                    157:         * get total disk size
                    158:         * and inode block size
                    159:         */
                    160: 
                    161: f2:
                    162:        filsys.s_fsize = getnum();
                    163:        n = getnum();
                    164:        n /= NIPB;
                    165:        filsys.s_isize = n + 3;
                    166: 
                    167: #endif
                    168: f3:
                    169:        if(argc >= 5) {
                    170:                f_m = atoi(argv[3]);
                    171:                f_n = atoi(argv[4]);
                    172:                if(f_n <= 0 || f_n >= MAXFN)
                    173:                        f_n = MAXFN;
                    174:                if(f_m <= 0 || f_m > f_n)
                    175:                        f_m = 3;
                    176:        }
                    177:        filsys.s_m = f_m;
                    178:        filsys.s_n = f_n;
                    179:        printf("m/n = %d %d\n", f_m, f_n);
                    180:        if(filsys.s_isize >= filsys.s_fsize) {
                    181:                printf("%ld/%ld: bad ratio\n", filsys.s_fsize, filsys.s_isize-2);
                    182:                exit(1);
                    183:        }
                    184:        filsys.s_tfree = 0;
                    185:        filsys.s_tinode = 0;
                    186:        for(c=0; c<BSIZE(0); c++)
                    187:                buf[c] = 0;
                    188:        for(n=2; n!=filsys.s_isize; n++) {
                    189:                wtfs(n, buf);
                    190:                filsys.s_tinode += NIPB;
                    191:        }
                    192:        ino = 0;
                    193: 
                    194:        bflist();
                    195: 
                    196:        cfile((struct inode *)0);
                    197: 
                    198:        filsys.s_time = utime;
                    199:        wtfs((long)1, (char *)&filsys);
                    200: #ifndef STANDALONE
                    201:        exit(error);
                    202: #endif
                    203: }
                    204: 
                    205: cfile(par)
                    206: struct inode *par;
                    207: {
                    208:        struct inode in;
                    209:        int dbc, ibc;
                    210:        char db[BSIZE(0)];
                    211:        daddr_t ib[NINDIR(0)];
                    212:        int i, f, c;
                    213: 
                    214:        /*
                    215:         * get mode, uid and gid
                    216:         */
                    217: 
                    218:        getstr();
                    219:        in.i_mode = gmode(string[0], "-bcd", IFREG, IFBLK, IFCHR, IFDIR);
                    220:        in.i_mode |= gmode(string[1], "-u", 0, ISUID, 0, 0);
                    221:        in.i_mode |= gmode(string[2], "-g", 0, ISGID, 0, 0);
                    222:        for(i=3; i<6; i++) {
                    223:                c = string[i];
                    224:                if(c<'0' || c>'7') {
                    225:                        printf("%c/%s: bad octal mode digit\n", c, string);
                    226:                        error = 1;
                    227:                        c = 0;
                    228:                }
                    229:                in.i_mode |= (c-'0')<<(15-3*i);
                    230:        }
                    231:        in.i_uid = getnum();
                    232:        in.i_gid = getnum();
                    233: 
                    234:        /*
                    235:         * general initialization prior to
                    236:         * switching on format
                    237:         */
                    238: 
                    239:        ino++;
                    240:        in.i_number = ino;
                    241:        for(i=0; i<BSIZE(0); i++)
                    242:                db[i] = 0;
                    243:        for(i=0; i<NINDIR(0); i++)
                    244:                ib[i] = (daddr_t)0;
                    245:        in.i_nlink = 1;
                    246:        in.i_size = 0;
                    247:        for(i=0; i<NADDR; i++)
                    248:                in.i_un.i_addr[i] = (daddr_t)0;
                    249:        if(par == (struct inode *)0) {
                    250:                par = &in;
                    251:                in.i_nlink--;
                    252:        }
                    253:        dbc = 0;
                    254:        ibc = 0;
                    255:        switch(in.i_mode&IFMT) {
                    256: 
                    257:        case IFREG:
                    258:                /*
                    259:                 * regular file
                    260:                 * contents is a file name
                    261:                 */
                    262: 
                    263:                getstr();
                    264:                f = open(string, 0);
                    265:                if(f < 0) {
                    266:                        printf("%s: cannot open\n", string);
                    267:                        error = 1;
                    268:                        break;
                    269:                }
                    270:                while((i=read(f, db, BSIZE(0))) > 0) {
                    271:                        in.i_size += i;
                    272:                        newblk(&dbc, db, &ibc, ib);
                    273:                }
                    274:                close(f);
                    275:                break;
                    276: 
                    277:        case IFBLK:
                    278:        case IFCHR:
                    279:                /*
                    280:                 * special file
                    281:                 * content is maj/min types
                    282:                 */
                    283: 
                    284:                i = getnum() & 0377;
                    285:                f = getnum() & 0377;
                    286:                in.i_un.i_addr[0] = (i<<8) | f;
                    287:                break;
                    288: 
                    289:        case IFDIR:
                    290:                /*
                    291:                 * directory
                    292:                 * put in extra links
                    293:                 * call recursively until
                    294:                 * name of "$" found
                    295:                 */
                    296: 
                    297:                par->i_nlink++;
                    298:                in.i_nlink++;
                    299:                entry(in.i_number, ".", &dbc, db, &ibc, ib);
                    300:                entry(par->i_number, "..", &dbc, db, &ibc, ib);
                    301:                in.i_size = 2*sizeof(struct direct);
                    302:                for(;;) {
                    303:                        getstr();
                    304:                        if(string[0]=='$' && string[1]=='\0')
                    305:                                break;
                    306:                        entry(ino+1, string, &dbc, db, &ibc, ib);
                    307:                        in.i_size += sizeof(struct direct);
                    308:                        cfile(&in);
                    309:                }
                    310:                break;
                    311:        }
                    312:        if(dbc != 0)
                    313:                newblk(&dbc, db, &ibc, ib);
                    314:        iput(&in, &ibc, ib);
                    315: }
                    316: 
                    317: gmode(c, s, m0, m1, m2, m3)
                    318: char c, *s;
                    319: {
                    320:        int i;
                    321: 
                    322:        for(i=0; s[i]; i++)
                    323:                if(c == s[i])
                    324:                        return((&m0)[i]);
                    325:        printf("%c/%s: bad mode\n", c, string);
                    326:        error = 1;
                    327:        return(0);
                    328: }
                    329: 
                    330: long
                    331: getnum()
                    332: {
                    333:        int i, c;
                    334:        long n;
                    335: 
                    336:        getstr();
                    337:        n = 0;
                    338:        i = 0;
                    339:        for(i=0; c=string[i]; i++) {
                    340:                if(c<'0' || c>'9') {
                    341:                        printf("%s: bad number\n", string);
                    342:                        error = 1;
                    343:                        return((long)0);
                    344:                }
                    345:                n = n*10 + (c-'0');
                    346:        }
                    347:        return(n);
                    348: }
                    349: 
                    350: getstr()
                    351: {
                    352:        int i, c;
                    353: 
                    354: loop:
                    355:        switch(c=getch()) {
                    356: 
                    357:        case ' ':
                    358:        case '\t':
                    359:        case '\n':
                    360:                goto loop;
                    361: 
                    362:        case '\0':
                    363:                printf("EOF\n");
                    364:                exit(1);
                    365: 
                    366:        case ':':
                    367:                while(getch() != '\n');
                    368:                goto loop;
                    369: 
                    370:        }
                    371:        i = 0;
                    372: 
                    373:        do {
                    374:                string[i++] = c;
                    375:                c = getch();
                    376:        } while(c!=' '&&c!='\t'&&c!='\n'&&c!='\0');
                    377:        string[i] = '\0';
                    378: }
                    379: 
                    380: rdfs(bno, bf)
                    381: daddr_t bno;
                    382: char *bf;
                    383: {
                    384:        int n;
                    385: 
                    386:        lseek(fsi, bno*BSIZE(0), 0);
                    387:        n = read(fsi, bf, BSIZE(0));
                    388:        if(n != BSIZE(0)) {
                    389:                printf("read error: %ld\n", bno);
                    390:                exit(1);
                    391:        }
                    392: }
                    393: 
                    394: wtfs(bno, bf)
                    395: daddr_t bno;
                    396: char *bf;
                    397: {
                    398:        int n;
                    399: 
                    400:        lseek(fso, bno*BSIZE(0), 0);
                    401:        n = write(fso, bf, BSIZE(0));
                    402:        if(n != BSIZE(0)) {
                    403:                printf("write error: %D\n", bno);
                    404:                exit(1);
                    405:        }
                    406: }
                    407: 
                    408: daddr_t
                    409: alloc()
                    410: {
                    411:        int i;
                    412:        daddr_t bno;
                    413: 
                    414:        filsys.s_tfree--;
                    415:        bno = filsys.s_free[--filsys.s_nfree];
                    416:        if(bno == 0) {
                    417:                printf("out of free space\n");
                    418:                exit(1);
                    419:        }
                    420:        if(filsys.s_nfree <= 0) {
                    421:                rdfs(bno, (char *)&fbuf);
                    422:                filsys.s_nfree = fbuf.df_nfree;
                    423:                for(i=0; i<NICFREE; i++)
                    424:                        filsys.s_free[i] = fbuf.df_free[i];
                    425:        }
                    426:        return(bno);
                    427: }
                    428: 
                    429: bfree(bno)
                    430: daddr_t bno;
                    431: {
                    432:        int i;
                    433: 
                    434:        if (bno)
                    435:                filsys.s_tfree++;
                    436:        if(filsys.s_nfree >= NICFREE) {
                    437:                fbuf.df_nfree = filsys.s_nfree;
                    438:                for(i=0; i<NICFREE; i++)
                    439:                        fbuf.df_free[i] = filsys.s_free[i];
                    440:                wtfs(bno, (char *)&fbuf);
                    441:                filsys.s_nfree = 0;
                    442:        }
                    443:        filsys.s_free[filsys.s_nfree++] = bno;
                    444: }
                    445: 
                    446: entry(inum, str, adbc, db, aibc, ib)
                    447: ino_t inum;
                    448: char *str;
                    449: int *adbc, *aibc;
                    450: char *db;
                    451: daddr_t *ib;
                    452: {
                    453:        struct direct *dp;
                    454:        int i;
                    455: 
                    456:        dp = (struct direct *)db;
                    457:        dp += *adbc;
                    458:        (*adbc)++;
                    459:        dp->d_ino = inum;
                    460:        for(i=0; i<DIRSIZ; i++)
                    461:                dp->d_name[i] = 0;
                    462:        for(i=0; i<DIRSIZ; i++)
                    463:                if((dp->d_name[i] = str[i]) == 0)
                    464:                        break;
                    465:        if(*adbc >= NDIRECT)
                    466:                newblk(adbc, db, aibc, ib);
                    467: }
                    468: 
                    469: newblk(adbc, db, aibc, ib)
                    470: int *adbc, *aibc;
                    471: char *db;
                    472: daddr_t *ib;
                    473: {
                    474:        int i;
                    475:        daddr_t bno;
                    476: 
                    477:        bno = alloc();
                    478:        wtfs(bno, db);
                    479:        for(i=0; i<BSIZE(0); i++)
                    480:                db[i] = 0;
                    481:        *adbc = 0;
                    482:        ib[*aibc] = bno;
                    483:        (*aibc)++;
                    484:        if(*aibc >= NINDIR(0)) {
                    485:                printf("indirect block full\n");
                    486:                error = 1;
                    487:                *aibc = 0;
                    488:        }
                    489: }
                    490: 
                    491: getch()
                    492: {
                    493: 
                    494: #ifndef STANDALONE
                    495:        if(charp)
                    496: #endif
                    497:                return(*charp++);
                    498: #ifndef STANDALONE
                    499:        return(getc(fin));
                    500: #endif
                    501: }
                    502: 
                    503: bflist()
                    504: {
                    505:        struct inode in;
                    506:        daddr_t ib[NINDIR(0)];
                    507:        int ibc;
                    508:        char flg[MAXFN];
                    509:        int adr[MAXFN];
                    510:        int i, j;
                    511:        daddr_t f, d;
                    512: 
                    513:        for(i=0; i<f_n; i++)
                    514:                flg[i] = 0;
                    515:        i = 0;
                    516:        for(j=0; j<f_n; j++) {
                    517:                while(flg[i])
                    518:                        i = (i+1)%f_n;
                    519:                adr[j] = i+1;
                    520:                flg[i]++;
                    521:                i = (i+f_m)%f_n;
                    522:        }
                    523: 
                    524:        ino++;
                    525:        in.i_number = ino;
                    526:        in.i_mode = IFREG;
                    527:        in.i_uid = 0;
                    528:        in.i_gid = 0;
                    529:        in.i_nlink = 0;
                    530:        in.i_size = 0;
                    531:        for(i=0; i<NADDR; i++)
                    532:                in.i_un.i_addr[i] = (daddr_t)0;
                    533: 
                    534:        for(i=0; i<NINDIR(0); i++)
                    535:                ib[i] = (daddr_t)0;
                    536:        ibc = 0;
                    537:        bfree((daddr_t)0);
                    538:        d = filsys.s_fsize-1;
                    539:        while(d%f_n)
                    540:                d++;
                    541:        for(; d > 0; d -= f_n)
                    542:        for(i=0; i<f_n; i++) {
                    543:                f = d - adr[i];
                    544:                if(f < filsys.s_fsize && f >= filsys.s_isize)
                    545:                        if(badblk(f)) {
                    546:                                if(ibc >= NINDIR(0)) {
                    547:                                        printf("too many bad blocks\n");
                    548:                                        error = 1;
                    549:                                        ibc = 0;
                    550:                                }
                    551:                                ib[ibc] = f;
                    552:                                ibc++;
                    553:                        } else
                    554:                                bfree(f);
                    555:        }
                    556:        iput(&in, &ibc, ib);
                    557: }
                    558: 
                    559: iput(ip, aibc, ib)
                    560: struct inode *ip;
                    561: int *aibc;
                    562: daddr_t *ib;
                    563: {
                    564:        struct dinode *dp;
                    565:        daddr_t d;
                    566:        int i;
                    567: 
                    568:        filsys.s_tinode--;
                    569:        d = itod(0,ip->i_number);
                    570:        if(d >= filsys.s_isize) {
                    571:                if(error == 0)
                    572:                        printf("ilist too small\n");
                    573:                error = 1;
                    574:                return;
                    575:        }
                    576:        rdfs(d, buf);
                    577:        dp = (struct dinode *)buf;
                    578:        dp += itoo(0,ip->i_number);
                    579: 
                    580:        dp->di_mode = ip->i_mode;
                    581:        dp->di_nlink = ip->i_nlink;
                    582:        dp->di_uid = ip->i_uid;
                    583:        dp->di_gid = ip->i_gid;
                    584:        dp->di_size = ip->i_size;
                    585:        dp->di_atime = utime;
                    586:        dp->di_mtime = utime;
                    587:        dp->di_ctime = utime;
                    588: 
                    589:        switch(ip->i_mode&IFMT) {
                    590: 
                    591:        case IFDIR:
                    592:        case IFREG:
                    593:                for(i=0; i<*aibc; i++) {
                    594:                        if(i >= LADDR)
                    595:                                break;
                    596:                        ip->i_un.i_addr[i] = ib[i];
                    597:                }
                    598:                if(*aibc >= LADDR) {
                    599:                        ip->i_un.i_addr[LADDR] = alloc();
                    600:                        for(i=0; i<NINDIR(0)-LADDR; i++) {
                    601:                                ib[i] = ib[i+LADDR];
                    602:                                ib[i+LADDR] = (daddr_t)0;
                    603:                        }
                    604:                        wtfs(ip->i_un.i_addr[LADDR], (char *)ib);
                    605:                }
                    606: 
                    607:        case IFBLK:
                    608:        case IFCHR:
                    609:                ltol3(dp->di_addr, ip->i_un.i_addr, NADDR);
                    610:                break;
                    611: 
                    612:        default:
                    613:                printf("bad mode %o\n", ip->i_mode);
                    614:                exit(1);
                    615:        }
                    616:        wtfs(d, buf);
                    617: }
                    618: 
                    619: badblk(bno)
                    620: daddr_t bno;
                    621: {
                    622: 
                    623:        return(0);
                    624: }

unix.superglobalmegacorp.com

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