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

Defined functions

alloc defined in line 438; used 3 times
badblk defined in line 650; used 1 times
bflist defined in line 533; used 1 times
bfree defined in line 459; used 2 times
cfile defined in line 223; used 2 times
entry defined in line 476; used 6 times
getch defined in line 521; used 3 times
getnum defined in line 355; used 7 times
getstr defined in line 375; used 5 times
gmode defined in line 342; used 3 times
iput defined in line 589; used 3 times
main defined in line 59; never used
mklost defined in line 656; used 1 times
newblk defined in line 499; used 4 times
rdfs defined in line 410; used 2 times
wtfs defined in line 424; used 7 times

Defined variables

buf defined in line 37; used 17 times
charp defined in line 36; used 3 times
error defined in line 54; used 9 times
f_m defined in line 53; used 12 times
f_n defined in line 52; used 20 times
fin defined in line 31; used 5 times
fsi defined in line 34; used 6 times
fso defined in line 35; used 6 times
fsys defined in line 50; used 5 times
head defined in line 43; used 5 times
ino defined in line 55; used 8 times
module defined in line 32; used 1 times
  • in line 88
proto defined in line 51; used 5 times
sccsid defined in line 2; never used
string defined in line 45; used 19 times
utime defined in line 27; used 5 times

Defined macros

CLSIZE defined in line 128; used 1 times
LADDR defined in line 26; used 7 times
MAXFN defined in line 12; used 6 times
NDIRECT defined in line 11; used 1 times
NINDIR defined in line 10; used 9 times
NIPB defined in line 9; used 5 times
itoo defined in line 14; used 1 times
Last modified: 1983-07-26
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 2455
Valid CSS Valid XHTML 1.0 Strict