|
|
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.