|
|
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: int temp; ! 310: struct dinode buf[MAXBSIZE / sizeof (struct dinode)]; ! 311: ! 312: ip->i_atime = ip->i_mtime = ip->i_ctime = time((long *)0); ! 313: switch (ip->i_mode&IFMT) { ! 314: ! 315: case IFDIR: ! 316: case IFREG: ! 317: for (i = 0; i < *aibc; i++) { ! 318: if (i >= NDADDR) ! 319: break; ! 320: ip->i_db[i] = ib[i]; ! 321: } ! 322: if (*aibc > NDADDR) { ! 323: ip->i_ib[0] = alloc((int)fs->fs_bsize); ! 324: for (i = 0; i < NINDIR(fs) - NDADDR; i++) { ! 325: ib[i] = ib[i+NDADDR]; ! 326: ib[i+NDADDR] = (daddr_t)0; ! 327: } ! 328: wtfs(fsbtodb(fs, ip->i_ib[0]), ! 329: (int)fs->fs_bsize, (char *)ib); ! 330: } ! 331: break; ! 332: ! 333: case IFBLK: ! 334: case IFCHR: ! 335: break; ! 336: ! 337: default: ! 338: printf("bad mode %o\n", ip->i_mode); ! 339: exit(1); ! 340: } ! 341: d = fsbtodb(fs, itod(fs, ip->i_number)); ! 342: rdfs(d, (int)fs->fs_bsize, (char *)buf); ! 343: temp = itoo(fs, ip->i_number); ! 344: buf[temp].di_ic = ip->i_ic; ! 345: wtfs(d, (int)fs->fs_bsize, (char *)buf); ! 346: } ! 347: ! 348: daddr_t ! 349: alloc(size) ! 350: int size; ! 351: { ! 352: int i, frag; ! 353: daddr_t d; ! 354: static int cg = 0; ! 355: ! 356: again: ! 357: rdfs(fsbtodb(&sblock, cgtod(&sblock, cg)), (int)sblock.fs_cgsize, ! 358: (char *)&acg); ! 359: if (acg.cg_magic != CG_MAGIC) { ! 360: printf("cg %d: bad magic number\n", cg); ! 361: return (0); ! 362: } ! 363: if (acg.cg_cs.cs_nbfree == 0) { ! 364: cg++; ! 365: if (cg >= fs->fs_ncg) { ! 366: printf("ran out of space\n"); ! 367: return (0); ! 368: } ! 369: goto again; ! 370: } ! 371: for (d = 0; d < acg.cg_ndblk; d += sblock.fs_frag) ! 372: if (isblock(&sblock, (u_char *)acg.cg_free, d / sblock.fs_frag)) ! 373: goto goth; ! 374: printf("internal error: can't find block in cyl %d\n", cg); ! 375: return (0); ! 376: goth: ! 377: clrblock(&sblock, (u_char *)acg.cg_free, d / sblock.fs_frag); ! 378: acg.cg_cs.cs_nbfree--; ! 379: sblock.fs_cstotal.cs_nbfree--; ! 380: fscs[cg].cs_nbfree--; ! 381: acg.cg_btot[cbtocylno(&sblock, d)]--; ! 382: acg.cg_b[cbtocylno(&sblock, d)][cbtorpos(&sblock, d)]--; ! 383: if (size != sblock.fs_bsize) { ! 384: frag = howmany(size, sblock.fs_fsize); ! 385: fscs[cg].cs_nffree += sblock.fs_frag - frag; ! 386: sblock.fs_cstotal.cs_nffree += sblock.fs_frag - frag; ! 387: acg.cg_cs.cs_nffree += sblock.fs_frag - frag; ! 388: acg.cg_frsum[sblock.fs_frag - frag]++; ! 389: for (i = frag; i < sblock.fs_frag; i++) ! 390: setbit(acg.cg_free, d + i); ! 391: } ! 392: wtfs(fsbtodb(&sblock, cgtod(&sblock, cg)), (int)sblock.fs_cgsize, ! 393: (char *)&acg); ! 394: return (acg.cg_cgx * fs->fs_fpg + d); ! 395: } ! 396: ! 397: /* ! 398: * Allocate an inode on the disk ! 399: */ ! 400: ialloc(ip) ! 401: register struct inode *ip; ! 402: { ! 403: struct dinode buf[MAXBSIZE / sizeof (struct dinode)]; ! 404: daddr_t d; ! 405: int c; ! 406: ! 407: ip->i_number = ++ino; ! 408: c = itog(&sblock, ip->i_number); ! 409: rdfs(fsbtodb(&sblock, cgtod(&sblock, c)), (int)sblock.fs_cgsize, ! 410: (char *)&acg); ! 411: if (acg.cg_magic != CG_MAGIC) { ! 412: printf("cg %d: bad magic number\n", c); ! 413: exit(1); ! 414: } ! 415: if (ip->i_mode & IFDIR) { ! 416: acg.cg_cs.cs_ndir++; ! 417: sblock.fs_cstotal.cs_ndir++; ! 418: fscs[c].cs_ndir++; ! 419: } ! 420: acg.cg_cs.cs_nifree--; ! 421: setbit(acg.cg_iused, ip->i_number); ! 422: wtfs(fsbtodb(&sblock, cgtod(&sblock, c)), (int)sblock.fs_cgsize, ! 423: (char *)&acg); ! 424: sblock.fs_cstotal.cs_nifree--; ! 425: fscs[c].cs_nifree--; ! 426: if(ip->i_number >= sblock.fs_ipg * sblock.fs_ncg) { ! 427: printf("fsinit: inode value out of range (%d).\n", ! 428: ip->i_number); ! 429: exit(1); ! 430: } ! 431: return (ip->i_number); ! 432: } ! 433: ! 434: /* ! 435: * read a block from the file system ! 436: */ ! 437: rdfs(bno, size, bf) ! 438: int bno, size; ! 439: char *bf; ! 440: { ! 441: int n; ! 442: ! 443: if (lseek(fsi, bno * DEV_BSIZE, 0) < 0) { ! 444: printf("seek error: %ld\n", bno); ! 445: perror("rdfs"); ! 446: exit(1); ! 447: } ! 448: n = read(fsi, bf, size); ! 449: if(n != size) { ! 450: printf("read error: %ld\n", bno); ! 451: perror("rdfs"); ! 452: exit(1); ! 453: } ! 454: } ! 455: ! 456: /* ! 457: * write a block to the file system ! 458: */ ! 459: wtfs(bno, size, bf) ! 460: int bno, size; ! 461: char *bf; ! 462: { ! 463: int n; ! 464: ! 465: lseek(fso, bno * DEV_BSIZE, 0); ! 466: if (lseek(fso, bno * DEV_BSIZE, 0) < 0) { ! 467: printf("seek error: %ld\n", bno); ! 468: perror("wtfs"); ! 469: exit(1); ! 470: } ! 471: n = write(fso, bf, size); ! 472: if(n != size) { ! 473: printf("write error: %D\n", bno); ! 474: perror("wtfs"); ! 475: exit(1); ! 476: } ! 477: } ! 478: /* ! 479: * check if a block is available ! 480: */ ! 481: isblock(fs, cp, h) ! 482: struct fs *fs; ! 483: unsigned char *cp; ! 484: int h; ! 485: { ! 486: unsigned char mask; ! 487: ! 488: switch (fs->fs_frag) { ! 489: case 8: ! 490: return (cp[h] == 0xff); ! 491: case 4: ! 492: mask = 0x0f << ((h & 0x1) << 2); ! 493: return ((cp[h >> 1] & mask) == mask); ! 494: case 2: ! 495: mask = 0x03 << ((h & 0x3) << 1); ! 496: return ((cp[h >> 2] & mask) == mask); ! 497: case 1: ! 498: mask = 0x01 << (h & 0x7); ! 499: return ((cp[h >> 3] & mask) == mask); ! 500: default: ! 501: fprintf(stderr, "isblock bad fs_frag %d\n", fs->fs_frag); ! 502: return (0); ! 503: } ! 504: /*NOTREACHED*/ ! 505: } ! 506: ! 507: /* ! 508: * take a block out of the map ! 509: */ ! 510: clrblock(fs, cp, h) ! 511: struct fs *fs; ! 512: unsigned char *cp; ! 513: int h; ! 514: { ! 515: switch ((fs)->fs_frag) { ! 516: case 8: ! 517: cp[h] = 0; ! 518: return; ! 519: case 4: ! 520: cp[h >> 1] &= ~(0x0f << ((h & 0x1) << 2)); ! 521: return; ! 522: case 2: ! 523: cp[h >> 2] &= ~(0x03 << ((h & 0x3) << 1)); ! 524: return; ! 525: case 1: ! 526: cp[h >> 3] &= ~(0x01 << (h & 0x7)); ! 527: return; ! 528: default: ! 529: fprintf(stderr, "clrblock bad fs_frag %d\n", fs->fs_frag); ! 530: return; ! 531: } ! 532: } ! 533:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.