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

Defined functions

alloc defined in line 400; used 3 times
badblk defined in line 610; used 1 times
bflist defined in line 494; used 1 times
bfree defined in line 421; used 2 times
cfile defined in line 197; used 2 times
entry defined in line 437; used 3 times
getch defined in line 482; used 3 times
getnum defined in line 322; used 7 times
getstr defined in line 342; used 5 times
gmode defined in line 309; used 3 times
iput defined in line 550; used 2 times
main defined in line 52; never used
newblk defined in line 460; used 3 times
rdfs defined in line 372; used 2 times
wtfs defined in line 386; used 7 times

Defined variables

buf defined in line 30; used 7 times
charp defined in line 29; used 3 times
error defined in line 47; used 9 times
f_m defined in line 46; used 7 times
f_n defined in line 45; used 14 times
fin defined in line 25; used 5 times
fsi defined in line 27; used 6 times
fso defined in line 28; used 6 times
fsys defined in line 43; used 5 times
head defined in line 36; used 5 times
ino defined in line 48; used 6 times
proto defined in line 44; used 5 times
string defined in line 38; used 19 times
utime defined in line 21; used 5 times

Defined macros

LADDR defined in line 8; used 7 times
MAXFN defined in line 9; used 5 times
NDIRECT defined in line 7; used 1 times
NINDIR defined in line 6; used 7 times
NIPB defined in line 5; used 5 times
itoo defined in line 10; used 1 times
Last modified: 1979-01-10
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 1704
Valid CSS Valid XHTML 1.0 Strict