|
|
1.1 ! root 1: /* ! 2: * make an empty bitmapped filesystem ! 3: */ ! 4: ! 5: #include <stdio.h> ! 6: #include <libc.h> ! 7: #include <sys/param.h> ! 8: #include <sys/stat.h> ! 9: #include <sys/filsys.h> ! 10: #include <sys/dir.h> ! 11: #include <sys/ino.h> ! 12: #include <sys/inode.h> ! 13: ! 14: #define ISBIT 0100 /* this is a bitmapped filesystem -- fake out macros */ ! 15: #define MAXSMALL (BITMAP*BITCELL) /* biggest in-superb fs */ ! 16: #define MAXINO 65536L /* ino_t is a short */ ! 17: ! 18: #define ICOUNT INOPB(ISBIT) ! 19: #define BCOUNT BSIZE(ISBIT) ! 20: ! 21: struct filsys sb; ! 22: union { ! 23: struct dinode ib[ICOUNT]; ! 24: struct direct db[BCOUNT/sizeof(struct direct)]; ! 25: long fb[BCOUNT/sizeof(long)]; ! 26: char bb[BCOUNT]; ! 27: } buf; ! 28: struct stat statbuf; ! 29: long where[NADDR]; ! 30: int cylsize = 40; ! 31: int space = 4; /* ok for comets, suboptimal elsewhere */ ! 32: ! 33: main(argc, argv) ! 34: char **argv; ! 35: { ! 36: int i, j; /* only for test read */ ! 37: daddr_t size, isize; ! 38: register daddr_t bno; ! 39: int fd; ! 40: register struct dinode *ip; ! 41: llong_t off; ! 42: long atol(); ! 43: extern llong_t Llmul(), ltoL(); ! 44: ! 45: if(argc < 3) { ! 46: fprintf(stderr, "%s: bit-dev no-of-4k-blocks [ space cylsize ]\n", argv[0]); ! 47: exit(1); ! 48: } ! 49: if (argc > 3) ! 50: space = atoi(argv[3]); ! 51: if (argc > 4) ! 52: cylsize = atoi(argv[4]); ! 53: fd = open(argv[1], 2); ! 54: if(fd < 0) { ! 55: perror(argv[1]); ! 56: exit(1); ! 57: } ! 58: if(fstat(fd, &statbuf) < 0) { ! 59: perror(argv[1]); ! 60: exit(1); ! 61: } ! 62: if(!BITFS(statbuf.st_rdev)) { /* doubtful */ ! 63: fprintf(stderr, "%s device %d, 0%o can't have a 4k filesystem\n", ! 64: argv[1], major(statbuf.st_rdev), minor(statbuf.st_rdev)); ! 65: exit(1); ! 66: } ! 67: size = atol(argv[2]); ! 68: if(size <= 3) { ! 69: fprintf(stderr, "size %ld too small\n", size); ! 70: exit(1); ! 71: } ! 72: off = Llmul(ltoL(size-1), BCOUNT); ! 73: llseek(fd, off, 0); ! 74: if((j = read(fd, buf.bb, BCOUNT)) != BCOUNT) { ! 75: fprintf(stderr, "size %ld too large (lseek [%d,%d], read %d)\n", ! 76: size, Lsign(off), Ltol(off), j); ! 77: exit(1); ! 78: } ! 79: isize = (size - 2)/(1 + ICOUNT); /* DOUBTFUL */ ! 80: if(isize * ICOUNT > MAXINO) ! 81: isize = MAXINO/ICOUNT; /* 65535 is largest short */ ! 82: fprintf(stderr, "%ld 4k blocks, %ld blocks of inodes, %d inodes\n", ! 83: size, isize - 2, ICOUNT * (isize - 2)); ! 84: /* zero out all inodes */ ! 85: lseek(fd, (off_t)((SUPERB+1) * BCOUNT), 0); ! 86: zerobuf(buf.bb); ! 87: for(bno = SUPERB+1; bno < isize; bno++) { ! 88: if (write(fd, (char *)buf.ib, BCOUNT) != BCOUNT) { ! 89: perror("inode write"); ! 90: exit(1); ! 91: } ! 92: } ! 93: /* next block has the root directory */ ! 94: where[0] = isize; ! 95: buf.db[0].d_ino = ROOTINO; ! 96: buf.db[0].d_name[0] = '.'; ! 97: buf.db[1].d_ino = ROOTINO; ! 98: buf.db[1].d_name[1] = buf.db[1].d_name[0] = '.'; ! 99: if (write(fd, (char *)buf.db, BCOUNT) != BCOUNT) { ! 100: perror("root dir write"); ! 101: exit(1); ! 102: } ! 103: /* now for its inode */ ! 104: zerobuf(buf.bb); ! 105: ip = &buf.ib[itoo(ISBIT, ROOTINO)]; ! 106: ip->di_mode = IFDIR | IREAD | IWRITE | IEXEC; ! 107: ip->di_mode |= (IREAD | IEXEC | IWRITE) >> 3; ! 108: ip->di_mode |= (IREAD | IEXEC | IWRITE) >> 6; ! 109: ip->di_nlink = 2; ! 110: ip->di_uid = ip->di_gid = 0; ! 111: ip->di_size = 2*sizeof(struct direct); ! 112: ltol3(ip->di_addr, where, 1); ! 113: ip->di_atime = ip->di_mtime = ! 114: ip->di_ctime = time((long *)0); ! 115: lseek(fd, (off_t)(itod(ISBIT, ROOTINO)*BCOUNT), 0); ! 116: if (write(fd, (char *)buf.ib, BCOUNT) != BCOUNT) { ! 117: perror("root inode write"); ! 118: exit(1); ! 119: } ! 120: /* and now the super block */ ! 121: sb.s_isize = isize; ! 122: sb.s_fsize = size; ! 123: sb.s_time = ip->di_atime; ! 124: sb.s_tfree = size - isize - 1; ! 125: sb.s_tinode = (isize - 2) * ICOUNT - 1; /* doubtful */ ! 126: sb.s_cylsize = cylsize; ! 127: sb.s_aspace = space; ! 128: if (size - isize <= MAXSMALL) ! 129: smallfree(); ! 130: else ! 131: largefree(fd); ! 132: sb.s_valid = 1; ! 133: lseek(fd, (off_t)(SUPERB * BCOUNT), 0); ! 134: if (write(fd, (char *)&sb, BCOUNT) != BCOUNT) { ! 135: perror("superblock write"); ! 136: exit(1); ! 137: } ! 138: exit(0); ! 139: } ! 140: ! 141: /* ! 142: * make the bitmap, if it all fits in the superblock ! 143: */ ! 144: smallfree() ! 145: { ! 146: register int i; ! 147: register daddr_t bno; ! 148: register daddr_t last; ! 149: ! 150: sb.U.N.S_flag = 0; ! 151: for(i = 0; i < BITMAP; i++) ! 152: sb.s_bfree[i] = 0; ! 153: last = sb.s_fsize - sb.s_isize; ! 154: BITALLOC(sb.s_bfree, 0); /* root */ ! 155: for (bno = 1; bno < last; bno++) ! 156: BITFREE(sb.s_bfree, bno); ! 157: } ! 158: ! 159: /* ! 160: * make the out-of-super-block bitmap ! 161: */ ! 162: #define BITSPERBLK (BCOUNT*NBBY) ! 163: ! 164: largefree(fd) ! 165: int fd; ! 166: { ! 167: daddr_t nblks, maxblk, firstblk, freeb; ! 168: register daddr_t bno; ! 169: register int bit; ! 170: ! 171: sb.U.N.S_flag = 1; ! 172: sb.U.N.S_bsize = BITSPERBLK; ! 173: nblks = (sb.s_fsize + BITSPERBLK-1)/BITSPERBLK; ! 174: if (nblks >= sizeof(sb.U.N.S_blk)/sizeof(sb.U.N.S_blk[0])) { ! 175: fprintf(stderr, "%ld blocks are too many\n", sb.s_fsize); ! 176: exit(1); ! 177: } ! 178: sb.s_tfree -= nblks; ! 179: firstblk = sb.s_isize + 1; /* root has first block */ ! 180: maxblk = sb.s_fsize - nblks; ! 181: freeb = maxblk; /* first block of bitmap */ ! 182: zerobuf(buf.bb); ! 183: for (bno = 0, bit = 0; bno < maxblk; bno++) { ! 184: if (bno >= firstblk) ! 185: BITFREE(buf.fb, bit); ! 186: /* else alloc, but map is already cleared */ ! 187: if (++bit == BITSPERBLK) { ! 188: lseek(fd, (off_t)freeb * BCOUNT, 0); ! 189: if (write(fd, (char *)buf.fb, BCOUNT) != BCOUNT) { ! 190: perror("freeblk write error"); ! 191: exit(1); ! 192: } ! 193: zerobuf(buf.bb); ! 194: freeb++; ! 195: bit = 0; ! 196: } ! 197: } ! 198: if (bit) { /* any leftovers? */ ! 199: lseek(fd, (off_t)freeb * BCOUNT, 0); ! 200: if (write(fd, (char *)buf.fb, BCOUNT) != BCOUNT) { ! 201: perror("freeblk write error"); ! 202: exit(1); ! 203: } ! 204: } ! 205: } ! 206: ! 207: zerobuf(b) ! 208: char *b; ! 209: { ! 210: memset(b, 0, BCOUNT); ! 211: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.