Annotation of 3BSD/cmd/mkfs.c, revision 1.1.1.1

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

unix.superglobalmegacorp.com

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