Annotation of researchv9/cmd/mkfs.c, revision 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.