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