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