|
|
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 = ∈ ! 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: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.