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