|
|
1.1 ! root 1: /* ! 2: * Copyright (c) 1983 Regents of the University of California. ! 3: * All rights reserved. The Berkeley software License Agreement ! 4: * specifies the terms and conditions for redistribution. ! 5: */ ! 6: ! 7: #ifndef lint ! 8: char copyright[] = ! 9: "@(#) Copyright (c) 1980 Regents of the University of California.\n\ ! 10: All rights reserved.\n"; ! 11: #endif not lint ! 12: ! 13: #ifndef lint ! 14: static char sccsid[] = "@(#)mkproto.c 5.4 (Berkeley) 5/31/88"; ! 15: #endif not lint ! 16: ! 17: /* ! 18: * Make a file system prototype. ! 19: * usage: mkproto filsys proto ! 20: */ ! 21: #include <stdio.h> ! 22: #include <sys/param.h> ! 23: #include <sys/inode.h> ! 24: #include <sys/fs.h> ! 25: #include <sys/dir.h> ! 26: ! 27: union { ! 28: struct fs fs; ! 29: char fsx[SBSIZE]; ! 30: } ufs; ! 31: #define sblock ufs.fs ! 32: union { ! 33: struct cg cg; ! 34: char cgx[MAXBSIZE]; ! 35: } ucg; ! 36: #define acg ucg.cg ! 37: struct fs *fs; ! 38: struct csum *fscs; ! 39: int fso, fsi; ! 40: FILE *proto; ! 41: char token[BUFSIZ]; ! 42: int errs; ! 43: long dev_bsize = 1; ! 44: int ino = 10; ! 45: long getnum(); ! 46: char *strcpy(); ! 47: ! 48: main(argc, argv) ! 49: int argc; ! 50: char *argv[]; ! 51: { ! 52: int i; ! 53: char *calloc(); ! 54: ! 55: if (argc != 3) { ! 56: fprintf(stderr, "usage: mkproto filsys proto\n"); ! 57: exit(1); ! 58: } ! 59: fso = open(argv[1], 1); ! 60: fsi = open(argv[1], 0); ! 61: if (fso < 0 || fsi < 0) { ! 62: perror(argv[1]); ! 63: exit(1); ! 64: } ! 65: fs = &sblock; ! 66: rdfs(SBOFF, SBSIZE, (char *)fs); ! 67: dev_bsize = fs->fs_fsize / fsbtodb(fs, 1); ! 68: fscs = (struct csum *)calloc(1, (u_int)fs->fs_cssize); ! 69: for (i = 0; i < fs->fs_cssize; i += fs->fs_bsize) ! 70: rdfs(fsbtodb(fs, fs->fs_csaddr + numfrags(fs, i)), ! 71: (int)(fs->fs_cssize - i < fs->fs_bsize ? ! 72: fs->fs_cssize - i : fs->fs_bsize), ! 73: ((char *)fscs) + i); ! 74: proto = fopen(argv[2], "r"); ! 75: descend((struct inode *)0); ! 76: wtfs(SBOFF / dev_bsize, SBSIZE, (char *)fs); ! 77: for (i = 0; i < fs->fs_cssize; i += fs->fs_bsize) ! 78: wtfs(fsbtodb(&sblock, fs->fs_csaddr + numfrags(&sblock, i)), ! 79: (int)(fs->fs_cssize - i < fs->fs_bsize ? ! 80: fs->fs_cssize - i : fs->fs_bsize), ! 81: ((char *)fscs) + i); ! 82: exit(errs); ! 83: } ! 84: ! 85: descend(par) ! 86: struct inode *par; ! 87: { ! 88: struct inode in; ! 89: int ibc = 0; ! 90: int i, f, c; ! 91: struct dinode *dip, inos[MAXBSIZE / sizeof (struct dinode)]; ! 92: daddr_t ib[MAXBSIZE / sizeof (daddr_t)]; ! 93: char buf[MAXBSIZE]; ! 94: ! 95: getstr(); ! 96: in.i_mode = gmode(token[0], "-bcd", IFREG, IFBLK, IFCHR, IFDIR); ! 97: in.i_mode |= gmode(token[1], "-u", 0, ISUID, 0, 0); ! 98: in.i_mode |= gmode(token[2], "-g", 0, ISGID, 0, 0); ! 99: for (i = 3; i < 6; i++) { ! 100: c = token[i]; ! 101: if (c < '0' || c > '7') { ! 102: printf("%c/%s: bad octal mode digit\n", c, token); ! 103: errs++; ! 104: c = 0; ! 105: } ! 106: in.i_mode |= (c-'0')<<(15-3*i); ! 107: } ! 108: in.i_uid = getnum(); in.i_gid = getnum(); ! 109: for (i = 0; i < fs->fs_bsize; i++) ! 110: buf[i] = 0; ! 111: for (i = 0; i < NINDIR(fs); i++) ! 112: ib[i] = (daddr_t)0; ! 113: in.i_nlink = 1; ! 114: in.i_size = 0; ! 115: for (i = 0; i < NDADDR; i++) ! 116: in.i_db[i] = (daddr_t)0; ! 117: for (i = 0; i < NIADDR; i++) ! 118: in.i_ib[i] = (daddr_t)0; ! 119: if (par != (struct inode *)0) { ! 120: ialloc(&in); ! 121: } else { ! 122: par = ∈ ! 123: i = itod(fs, ROOTINO); ! 124: rdfs(fsbtodb(fs, i), fs->fs_bsize, (char *)inos); ! 125: dip = &inos[ROOTINO % INOPB(fs)]; ! 126: in.i_number = ROOTINO; ! 127: in.i_nlink = dip->di_nlink; ! 128: in.i_size = dip->di_size; ! 129: in.i_db[0] = dip->di_db[0]; ! 130: rdfs(fsbtodb(fs, in.i_db[0]), fs->fs_bsize, buf); ! 131: } ! 132: ! 133: switch (in.i_mode&IFMT) { ! 134: ! 135: case IFREG: ! 136: getstr(); ! 137: f = open(token, 0); ! 138: if (f < 0) { ! 139: printf("%s: cannot open\n", token); ! 140: errs++; ! 141: break; ! 142: } ! 143: while ((i = read(f, buf, (int)fs->fs_bsize)) > 0) { ! 144: in.i_size += i; ! 145: newblk(buf, &ibc, ib, (int)blksize(fs, &in, ibc)); ! 146: } ! 147: close(f); ! 148: break; ! 149: ! 150: case IFBLK: ! 151: case IFCHR: ! 152: /* ! 153: * special file ! 154: * content is maj/min types ! 155: */ ! 156: ! 157: i = getnum() & 0377; ! 158: f = getnum() & 0377; ! 159: in.i_rdev = (i << 8) | f; ! 160: break; ! 161: ! 162: case IFDIR: ! 163: /* ! 164: * directory ! 165: * put in extra links ! 166: * call recursively until ! 167: * name of "$" found ! 168: */ ! 169: ! 170: if (in.i_number != ROOTINO) { ! 171: par->i_nlink++; ! 172: in.i_nlink++; ! 173: entry(&in, in.i_number, ".", buf); ! 174: entry(&in, par->i_number, "..", buf); ! 175: } ! 176: for (;;) { ! 177: getstr(); ! 178: if (token[0]=='$' && token[1]=='\0') ! 179: break; ! 180: entry(&in, (ino_t)(ino+1), token, buf); ! 181: descend(&in); ! 182: } ! 183: if (in.i_number != ROOTINO) ! 184: newblk(buf, &ibc, ib, (int)blksize(fs, &in, 0)); ! 185: else ! 186: wtfs(fsbtodb(fs, in.i_db[0]), (int)fs->fs_bsize, buf); ! 187: break; ! 188: } ! 189: iput(&in, &ibc, ib); ! 190: } ! 191: ! 192: /*ARGSUSED*/ ! 193: gmode(c, s, m0, m1, m2, m3) ! 194: char c, *s; ! 195: { ! 196: int i; ! 197: ! 198: for (i = 0; s[i]; i++) ! 199: if (c == s[i]) ! 200: return((&m0)[i]); ! 201: printf("%c/%s: bad mode\n", c, token); ! 202: errs++; ! 203: return(0); ! 204: } ! 205: ! 206: long ! 207: getnum() ! 208: { ! 209: int i, c; ! 210: long n; ! 211: ! 212: getstr(); ! 213: n = 0; ! 214: i = 0; ! 215: for (i = 0; c=token[i]; i++) { ! 216: if (c<'0' || c>'9') { ! 217: printf("%s: bad number\n", token); ! 218: errs++; ! 219: return((long)0); ! 220: } ! 221: n = n*10 + (c-'0'); ! 222: } ! 223: return(n); ! 224: } ! 225: ! 226: getstr() ! 227: { ! 228: int i, c; ! 229: ! 230: loop: ! 231: switch (c = getc(proto)) { ! 232: ! 233: case ' ': ! 234: case '\t': ! 235: case '\n': ! 236: goto loop; ! 237: ! 238: case EOF: ! 239: printf("Unexpected EOF\n"); ! 240: exit(1); ! 241: ! 242: case ':': ! 243: while (getc(proto) != '\n') ! 244: ; ! 245: goto loop; ! 246: ! 247: } ! 248: i = 0; ! 249: do { ! 250: token[i++] = c; ! 251: c = getc(proto); ! 252: } while (c != ' ' && c != '\t' && c != '\n' && c != '\0'); ! 253: token[i] = 0; ! 254: } ! 255: ! 256: entry(ip, inum, str, buf) ! 257: struct inode *ip; ! 258: ino_t inum; ! 259: char *str; ! 260: char *buf; ! 261: { ! 262: register struct direct *dp, *odp; ! 263: int oldsize, newsize, spacefree; ! 264: ! 265: odp = dp = (struct direct *)buf; ! 266: while ((int)dp - (int)buf < ip->i_size) { ! 267: odp = dp; ! 268: dp = (struct direct *)((int)dp + dp->d_reclen); ! 269: } ! 270: if (odp != dp) ! 271: oldsize = DIRSIZ(odp); ! 272: else ! 273: oldsize = 0; ! 274: spacefree = odp->d_reclen - oldsize; ! 275: dp = (struct direct *)((int)odp + oldsize); ! 276: dp->d_ino = inum; ! 277: dp->d_namlen = strlen(str); ! 278: newsize = DIRSIZ(dp); ! 279: if (spacefree >= newsize) { ! 280: odp->d_reclen = oldsize; ! 281: dp->d_reclen = spacefree; ! 282: } else { ! 283: dp = (struct direct *)((int)odp + odp->d_reclen); ! 284: if ((int)dp - (int)buf >= fs->fs_bsize) { ! 285: printf("directory too large\n"); ! 286: exit(1); ! 287: } ! 288: dp->d_ino = inum; ! 289: dp->d_namlen = strlen(str); ! 290: dp->d_reclen = DIRBLKSIZ; ! 291: } ! 292: strcpy(dp->d_name, str); ! 293: ip->i_size = (int)dp - (int)buf + newsize; ! 294: } ! 295: ! 296: newblk(buf, aibc, ib, size) ! 297: int *aibc; ! 298: char *buf; ! 299: daddr_t *ib; ! 300: int size; ! 301: { ! 302: int i; ! 303: daddr_t bno, alloc(); ! 304: ! 305: bno = alloc(size); ! 306: wtfs(fsbtodb(fs, bno), (int)fs->fs_bsize, buf); ! 307: for (i = 0; i < fs->fs_bsize; i++) ! 308: buf[i] = 0; ! 309: ib[(*aibc)++] = bno; ! 310: if (*aibc >= NINDIR(fs)) { ! 311: printf("indirect block full\n"); ! 312: errs++; ! 313: *aibc = 0; ! 314: } ! 315: } ! 316: ! 317: iput(ip, aibc, ib) ! 318: struct inode *ip; ! 319: int *aibc; ! 320: daddr_t *ib; ! 321: { ! 322: daddr_t d, alloc(); ! 323: int i; ! 324: struct dinode buf[MAXBSIZE / sizeof (struct dinode)]; ! 325: time_t time(); ! 326: ! 327: ip->i_atime = ip->i_mtime = ip->i_ctime = time((time_t *)NULL); ! 328: switch (ip->i_mode&IFMT) { ! 329: ! 330: case IFDIR: ! 331: case IFREG: ! 332: for (i = 0; i < *aibc; i++) { ! 333: if (i >= NDADDR) ! 334: break; ! 335: ip->i_db[i] = ib[i]; ! 336: } ! 337: if (*aibc > NDADDR) { ! 338: ip->i_ib[0] = alloc((int)fs->fs_bsize); ! 339: for (i = 0; i < NINDIR(fs) - NDADDR; i++) { ! 340: ib[i] = ib[i+NDADDR]; ! 341: ib[i+NDADDR] = (daddr_t)0; ! 342: } ! 343: wtfs(fsbtodb(fs, ip->i_ib[0]), ! 344: (int)fs->fs_bsize, (char *)ib); ! 345: } ! 346: break; ! 347: ! 348: case IFBLK: ! 349: case IFCHR: ! 350: break; ! 351: ! 352: default: ! 353: printf("bad mode %o\n", ip->i_mode); ! 354: exit(1); ! 355: } ! 356: d = fsbtodb(fs, itod(fs, ip->i_number)); ! 357: rdfs(d, (int)fs->fs_bsize, (char *)buf); ! 358: buf[itoo(fs, ip->i_number)].di_ic = ip->i_ic; ! 359: wtfs(d, (int)fs->fs_bsize, (char *)buf); ! 360: } ! 361: ! 362: daddr_t ! 363: alloc(size) ! 364: int size; ! 365: { ! 366: int i, frag; ! 367: daddr_t d; ! 368: static int cg = 0; ! 369: ! 370: again: ! 371: rdfs(fsbtodb(&sblock, cgtod(&sblock, cg)), (int)sblock.fs_cgsize, ! 372: (char *)&acg); ! 373: if (!cg_chkmagic(&acg)) { ! 374: printf("cg %d: bad magic number\n", cg); ! 375: return (0); ! 376: } ! 377: if (acg.cg_cs.cs_nbfree == 0) { ! 378: cg++; ! 379: if (cg >= fs->fs_ncg) { ! 380: printf("ran out of space\n"); ! 381: return (0); ! 382: } ! 383: goto again; ! 384: } ! 385: for (d = 0; d < acg.cg_ndblk; d += sblock.fs_frag) ! 386: if (isblock(&sblock, (u_char *)cg_blksfree(&acg), ! 387: d / sblock.fs_frag)) ! 388: goto goth; ! 389: printf("internal error: can't find block in cyl %d\n", cg); ! 390: return (0); ! 391: goth: ! 392: clrblock(&sblock, (u_char *)cg_blksfree(&acg), d / sblock.fs_frag); ! 393: acg.cg_cs.cs_nbfree--; ! 394: sblock.fs_cstotal.cs_nbfree--; ! 395: fscs[cg].cs_nbfree--; ! 396: cg_blktot(&acg)[cbtocylno(&sblock, d)]--; ! 397: cg_blks(&sblock, &acg, cbtocylno(&sblock, d))[cbtorpos(&sblock, d)]--; ! 398: if (size != sblock.fs_bsize) { ! 399: frag = howmany(size, sblock.fs_fsize); ! 400: fscs[cg].cs_nffree += sblock.fs_frag - frag; ! 401: sblock.fs_cstotal.cs_nffree += sblock.fs_frag - frag; ! 402: acg.cg_cs.cs_nffree += sblock.fs_frag - frag; ! 403: acg.cg_frsum[sblock.fs_frag - frag]++; ! 404: for (i = frag; i < sblock.fs_frag; i++) ! 405: setbit(cg_blksfree(&acg), d + i); ! 406: } ! 407: wtfs(fsbtodb(&sblock, cgtod(&sblock, cg)), (int)sblock.fs_cgsize, ! 408: (char *)&acg); ! 409: return (acg.cg_cgx * fs->fs_fpg + d); ! 410: } ! 411: ! 412: /* ! 413: * Allocate an inode on the disk ! 414: */ ! 415: ialloc(ip) ! 416: register struct inode *ip; ! 417: { ! 418: int c; ! 419: ! 420: ip->i_number = ++ino; ! 421: c = itog(&sblock, ip->i_number); ! 422: rdfs(fsbtodb(&sblock, cgtod(&sblock, c)), (int)sblock.fs_cgsize, ! 423: (char *)&acg); ! 424: if (!cg_chkmagic(&acg)) { ! 425: printf("cg %d: bad magic number\n", c); ! 426: exit(1); ! 427: } ! 428: if (ip->i_mode & IFDIR) { ! 429: acg.cg_cs.cs_ndir++; ! 430: sblock.fs_cstotal.cs_ndir++; ! 431: fscs[c].cs_ndir++; ! 432: } ! 433: acg.cg_cs.cs_nifree--; ! 434: setbit(cg_inosused(&acg), ip->i_number); ! 435: wtfs(fsbtodb(&sblock, cgtod(&sblock, c)), (int)sblock.fs_cgsize, ! 436: (char *)&acg); ! 437: sblock.fs_cstotal.cs_nifree--; ! 438: fscs[c].cs_nifree--; ! 439: if(ip->i_number >= sblock.fs_ipg * sblock.fs_ncg) { ! 440: printf("fsinit: inode value out of range (%lu).\n", ! 441: ip->i_number); ! 442: exit(1); ! 443: } ! 444: /* return (ip->i_number); */ ! 445: } ! 446: ! 447: /* ! 448: * read a block from the file system ! 449: */ ! 450: rdfs(bno, size, bf) ! 451: int bno, size; ! 452: char *bf; ! 453: { ! 454: int n; ! 455: off_t lseek(); ! 456: ! 457: if (lseek(fsi, bno * dev_bsize, 0) < 0) { ! 458: printf("seek error: %d\n", bno); ! 459: perror("rdfs"); ! 460: exit(1); ! 461: } ! 462: n = read(fsi, bf, size); ! 463: if(n != size) { ! 464: printf("read error: %d\n", bno); ! 465: perror("rdfs"); ! 466: exit(1); ! 467: } ! 468: } ! 469: ! 470: /* ! 471: * write a block to the file system ! 472: */ ! 473: wtfs(bno, size, bf) ! 474: int bno, size; ! 475: char *bf; ! 476: { ! 477: int n; ! 478: off_t lseek(); ! 479: ! 480: if (lseek(fso, bno * dev_bsize, 0) < 0) { ! 481: printf("seek error: %d\n", bno); ! 482: perror("wtfs"); ! 483: exit(1); ! 484: } ! 485: n = write(fso, bf, size); ! 486: if(n != size) { ! 487: printf("write error: %d\n", bno); ! 488: perror("wtfs"); ! 489: exit(1); ! 490: } ! 491: } ! 492: /* ! 493: * check if a block is available ! 494: */ ! 495: isblock(fs, cp, h) ! 496: struct fs *fs; ! 497: unsigned char *cp; ! 498: int h; ! 499: { ! 500: unsigned char mask; ! 501: ! 502: switch (fs->fs_frag) { ! 503: case 8: ! 504: return (cp[h] == 0xff); ! 505: case 4: ! 506: mask = 0x0f << ((h & 0x1) << 2); ! 507: return ((cp[h >> 1] & mask) == mask); ! 508: case 2: ! 509: mask = 0x03 << ((h & 0x3) << 1); ! 510: return ((cp[h >> 2] & mask) == mask); ! 511: case 1: ! 512: mask = 0x01 << (h & 0x7); ! 513: return ((cp[h >> 3] & mask) == mask); ! 514: default: ! 515: fprintf(stderr, "isblock bad fs_frag %ld\n", fs->fs_frag); ! 516: return (0); ! 517: } ! 518: /*NOTREACHED*/ ! 519: } ! 520: ! 521: /* ! 522: * take a block out of the map ! 523: */ ! 524: clrblock(fs, cp, h) ! 525: struct fs *fs; ! 526: unsigned char *cp; ! 527: int h; ! 528: { ! 529: switch ((fs)->fs_frag) { ! 530: case 8: ! 531: cp[h] = 0; ! 532: return; ! 533: case 4: ! 534: cp[h >> 1] &= ~(0x0f << ((h & 0x1) << 2)); ! 535: return; ! 536: case 2: ! 537: cp[h >> 2] &= ~(0x03 << ((h & 0x3) << 1)); ! 538: return; ! 539: case 1: ! 540: cp[h >> 3] &= ~(0x01 << (h & 0x7)); ! 541: return; ! 542: default: ! 543: fprintf(stderr, "clrblock bad fs_frag %ld\n", fs->fs_frag); ! 544: return; ! 545: } ! 546: } ! 547:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.