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