|
|
1.1 root 1: #include "fs.h"
2: #include "sys/fblk.h"
3: enum {Byte=8}; /* number of bits per byte */
4: int btypes[NADDR] = {Data, Data, Data, Data, Data, Data, Data, Data, Data, Data,
5: Ind, Ind2, Ind3};
6: int dtypes[NADDR] = {First, Other, Other, Other, Other, Other, Other, Other,
7: Other, Other, Ind, Ind2, Ind3};
8:
9: firstsuper()
10: { int i;
11: if(bread(1, (char *)&sblk, 1)) {
12: perror("superblock");
13: fatal("couldn't read superblock of %s\n", file);
14: }
15: inopb = bsize / sizeof(struct dinode);
16: ninode = (sblk.s_isize-2) * inopb + 1;
17: fblk = sblk.s_isize;
18: pblk = sblk.s_fsize;
19: if(bsize >= 4096 && BITMAP*Byte*sizeof(long)+fblk < pblk) {
20: i = (pblk + (bsize*Byte-1))/(bsize*Byte);
21: lblk = pblk - i;
22: }
23: else
24: lblk = pblk;
25: if(flags['v'])
26: pmesg("ninode %d isize %d lblk %d pblk %d\n", ninode, fblk, lblk,
27: pblk);
28: if(ninode < 2 || lblk <= fblk || pblk < lblk)
29: fatal("absurd(%d inodes, lblk=%d, pblk=%d)\n", ninode, fblk, pblk);
30: /* allocate all the space */
31: buf = (char *) malloc(buflen = fblk * bsize);
32: if(!buf) /* we've been too greedy, cache this stuff FIX*/
33: fatal("couldn't alloc %d bytes for buffers\n", buflen);
34: imap = (im *) malloc(ninode*sizeof(im));
35: bmap = (bm *) malloc(pblk*sizeof(bm));
36: dmap = (dm *) malloc((dmaplen = 1000)*sizeof(dm));
37: if(!imap || !bmap || !dmap)
38: fatal("couldn't alloc imap, bmap, or dmap\n");
39: memset((char *)imap, 0, ninode*sizeof(im));
40: memset((char *)bmap, 0, pblk*sizeof(bm));
41: if(flags['v'])
42: pmesg("alloc: %d for bufs, %d for imap, %d for bmap\n", buflen,
43: ninode*sizeof(im), pblk*sizeof(bm));
44: timer("alloc");
45: if(bread(0, buf, fblk)) /* fragile, FIX */
46: fatal("couldn't read inodes\n");
47: bmap[0].type = Boot;
48: bmap[1].type = Sblock;
49: for(i = 2; i < fblk; i++)
50: bmap[i].type = Inode;
51: /* and, if necessary, the extra bitmaps */
52: if(pblk > lblk) {
53: freeb = (char *) malloc(bsize * (pblk-lblk));
54: if(!freeb || bread(lblk, freeb, pblk-lblk))
55: fatal("couldn't read bitmap blocks\n");
56: for(i = lblk; i < pblk; i++)
57: bmap[i].type = Bits;
58: }
59: }
60:
61: scaninodes()
62: { register int ino, *lp, *p;
63: register struct dinode *dp;
64: register im *ip;
65: register bm *bp;
66: int addr[NADDR], *ty, last;
67: ino = 0;
68: ip = imap+1;
69: dp = (struct dinode *) (buf+2*bsize);
70: for(ino = 1; ino < ninode; ino++, dp++, ip++) {
71: switch(dp->di_mode & IFMT) {
72: default:
73: pmesg("ino %d weird mode 0%o\n", ino, dp->di_mode);
74: ip->type = Weird;
75: continue;
76: case IFDIR:
77: ip->type = Dir;
78: ty = dtypes;
79: break;
80: case IFCHR:
81: ip->type = Chr;
82: continue;
83: case IFBLK:
84: ip->type = Blk;
85: continue;
86: case IFREG:
87: ip->type = Reg;
88: ty = btypes;
89: break;
90: case IFLNK:
91: ty = btypes;
92: ip->type = Lnk;
93: if(dp->di_size > bsize || dp->di_size == 0)
94: inoerr(Elinksize, ino);
95: break;
96: case 0:
97: if(!dp->di_mode && !dp->di_size && !dp->di_nlink)
98: ip->type = Unalloc;
99: else
100: ip->type = Weird;
101: continue;
102: }
103: /* now look through the blocks in the inode */
104: l3tol(addr, dp->di_addr, NADDR);
105: p = addr;
106: lp = addr + NADDR;
107: for(last = -1; p < lp; p++) {
108: if(*p == 0)
109: continue;
110: if(*p < fblk || *p >= lblk) {
111: inoerr(Ebadaddr, ino, *p);
112: continue;
113: }
114: bp = bmap + *p;
115: if(bp->ino)
116: dupblock(bp, bp->type, 0);
117: bp->ino = ino;
118: bp->type = ty[p-addr];
119: blkcnts[bp->type]++;
120: last = p-addr;
121: switch(last) {
122: case 10: /* indirect */
123: bp->bnum = NADDR-3;
124: continue;
125: case 11:
126: bp->bnum = bsize/sizeof(long) + NADDR-3;
127: continue;
128: /* hard to tell if triple blocks are an error, so... */
129: case 12:
130: if(bsize >= 4096)
131: bp->type = Other, inoerr(Etriple, ino, *p);
132: else
133: bp->bnum = (bsize/sizeof(long)) *
134: (bsize/sizeof(long) + 1) + NADDR-3;
135: continue;
136: }
137: }
138: if(ip->type == Dir && (addr[0] < fblk || addr[0] >= lblk))
139: direrror(Efirst, ino);
140: ip->last = last;
141: }
142: }
143:
144: indblocks(old, new)
145: register old;
146: { register int *p, *ep;
147: register bm *bp, *obp, *mx = bmap + lblk;
148: int nty, delta, last;
149:
150: switch(old) {
151: default:
152: delta = 1;
153: break;
154: case Ind2:
155: delta = bsize/sizeof(long);
156: break;
157: case Ind3:
158: delta = bsize/sizeof(long) * bsize/sizeof(long);
159: break;
160: }
161: ep = (int *)(buf+bsize);
162: for(obp = bmap+1; obp < mx; obp++) {
163: if(obp->type != old)
164: continue;
165: if(bread(obp-bmap, buf, 1)) {
166: pmesg("ino %d block %d couldn't read\n", obp->ino,
167: obp-bmap);
168: obp->type = Ioerr;
169: inoerr(Ebadread, obp->ino, obp-bmap);
170: continue;
171: }
172: nty = obp->type == Dir && new == Data? Other: new;
173: for(last = -1, p = (long *)buf; p < ep; p++) {
174: if(*p == 0)
175: continue;
176: if(*p < fblk || *p >= lblk) {
177: inoerr(Ebadaddr, bmap[obp-bmap].ino);
178: break;
179: }
180: bp = bmap + *p;
181: if(bp->ino)
182: dupblock(bp, obp->type, new);
183: last = bp->bnum = obp->bnum + delta*(p-(long *)buf);
184: bp->ino = obp->ino;
185: bp->type = nty;
186: blkcnts[nty]++;
187: }
188: if(last == -1)
189: pmesg("ino %d had ind block (%d) all 0\n", obp->ino,
190: obp-bmap);
191: if(imap[obp->ino].last < last)
192: imap[obp->ino].last = last;
193: }
194: }
195:
196: dochecks()
197: { int i, j, k;
198: im *ip = imap + ROOTINO;
199: struct dinode *dp = (struct dinode *)(buf + 2*bsize);
200: for(i = ROOTINO, dp += i-1; i < ninode; i++, ip++, dp++) {
201: j = dp->di_nlink;
202: if(ip->type != Unalloc && ip->nrefs == 0 && j == 0)
203: inoerr(Enullable, i, 0);
204: else if(ip->nrefs != j)
205: inoerr(Elinkcnt, i, ip->nrefs-j);
206: switch(ip->type) {
207: case Dir:
208: if(dp->di_size < 32) /* no room for . and .. */
209: direrror(Eshortdir, i, dp->di_size);
210: case Lnk: case Reg:
211: k = ip->last;
212: if(dp->di_size == 0 && k == -1)
213: continue;
214: j = (dp->di_size-1)/bsize;
215: if(j == k)
216: continue;
217: if(j < k) /* blks after end */
218: inoerr(Eshort, i, k);
219: if(j > k) /* ends with holes */
220: inoerr(Ehole, i, k);
221: }
222: }
223: dirtree();
224: }
225:
226: checksuper()
227: { register int i, cnt, j, k;
228: bm *bp;
229: int last;
230: if(!sblk.U.B.S_valid)
231: supererr(Einvalid, 0, 0);
232: for(cnt = i = 0; i < NICINOD && i < sblk.s_ninode; i++) {
233: j = sblk.s_inode[i];
234: if(j == 0) /* really? */
235: continue;
236: if(j >= ninode || imap[j].type != Unalloc) {
237: supererr(Esuperino, j, 0);
238: break;
239: }
240: cnt++;
241: }
242: if(i >= NICINOD && cnt != sblk.s_ninode)
243: supererr(Esuperino, 0, cnt);
244: for(i = 1, cnt = 0; i < ninode; i++)
245: if(imap[i].type == Unalloc)
246: cnt++;
247: tinode = cnt;
248: if(cnt != sblk.s_tinode)
249: supererr(Esuperino, cnt, sblk.s_tinode);
250: if(bsize < 4096) { /* there should be a file system type FIX */
251: ch1free();
252: return;
253: }
254: if(pblk > lblk) {
255: chbitmap();
256: return;
257: }
258: cnt = fblk;
259: bp = bmap + cnt;
260: for(i = 0; i < BITMAP; i++, cnt += 32) {
261: k = sblk.U.B.S_bfree[i];
262: for(j = 0; j < 32; j++, bp++) {
263: if((k & (1<<j)) == 0) {
264: continue;
265: }
266: if(cnt+j >= lblk) {
267: supererr(Esuperfree, cnt+j, 0);
268: return;
269: }
270: if(bp->type == Unk) {
271: bp->type = Free;
272: blkcnts[Free]++;
273: }
274: else {
275: supererr(Esuperfree, cnt+j, bp->type);
276: return;
277: }
278: }
279: }
280: for(i = 1, bp = bmap + i; i < pblk; i++, bp++)
281: if(bp->type == Unk) {
282: supererr(Efreelist, i, bp->type);
283: return;
284: }
285: tfree = blkcnts[Free];
286: if(tfree != sblk.s_tfree)
287: supererr(Efreelist, sblk.s_tfree, tfree);
288: }
289:
290: chbitmap()
291: { register long *p;
292: register int i, k, j;
293: register bm *bp = bmap;
294: for(i = 0, p = (long *)freeb; i < pblk; i += 32, p++) {
295: k = *p;
296: for(j = 0; j < 32; j++, bp++) {
297: if((k & (1 << j)) == 0)
298: continue;
299: if(i+j >= lblk) {
300: supererr(Esuperfree, i+j, 0);
301: continue;
302: }
303: if(bp->type == Unk) {
304: bp->type = Free;
305: blkcnts[Free]++;
306: }
307: else {
308: supererr(Esuperfree, i+j, bp->type);
309: return;
310: }
311: }
312: }
313: for(i = 1, bp = bmap + i; i < pblk; i++, bp++)
314: if(bp->type == Unk) {
315: supererr(Efreelist, i, bp->type);
316: return;
317: }
318: tfree = blkcnts[Free];
319: if(tfree != sblk.s_tfree)
320: supererr(Efreelist, sblk.s_tfree, tfree);
321: }
322:
323: ch1free()
324: { int i, j, k;
325: daddr_t *p;
326: /* these could be unified if S_nfree were an int, not a short */
327: for(i = 0; i < sblk.U.R.S_nfree; i++) {
328: j = sblk.U.R.S_free[i];
329: if(j >= fblk && j < lblk && !bmap[j].ino) {
330: if(bmap[j].type)
331: adderr(Edup, j, 0);
332: bmap[j].type = Free;
333: blkcnts[Free]++;
334: }
335: else if(j)
336: inoerr(Ebadaddr, 0, j);
337: }
338: if((j = sblk.U.R.S_free[0]) == 0)
339: return;
340: loop:
341: if(bread(j, buf, 1)) {
342: pmesg("couldn't read free blk %d\n", j);
343: bmap[j].type = Ioerr;
344: exitcode = 1;
345: return;
346: }
347: k = ((struct fblk *)buf)->df_nfree;
348: for(p = ((struct fblk *)buf)->df_free, i = 0; i < k; i++) {
349: j = p[i];
350: if(j >= fblk && j < lblk && !bmap[j].ino) {
351: if(bmap[j].type)
352: adderr(Edup, j, 0);
353: bmap[j].type = Free;
354: blkcnts[Free]++;
355: }
356: else if(j)
357: inoerr(Ebadaddr, 0, j);
358: }
359: if(j = p[0])
360: goto loop;
361: }
362:
363: report()
364: { int i, cnts[32], j, k;
365: for(i = 0; i < iptr; i++) {
366: j = iarg[i];
367: if(j < 1 || j >= ninode) {
368: pmesg("arg ino %d out of range\n", j);
369: continue;
370: }
371: pmesg("arg ino %s\n", prino(j));
372: if(imap[j].type == Dir) {
373: for(k = 0; k < pblk; k++)
374: if(bmap[k].ino == j && bmap[k].type == First)
375: pmesg(" (first blk %d)\n", k);
376: }
377: }
378: for(i = 0; i < bptr; i++) {
379: j = barg[i];
380: if(j < 0 || j > pblk) {
381: pmesg("arg blk %d out of range\n", j);
382: continue;
383: }
384: pmesg("arg blk %d(%s) %s\n", j, btype(bmap[j].type),
385: prino(bmap[j].ino));
386: }
387: if(!flags['v'])
388: return;
389: pmesg("dmapptr %d erptr %d\n", dmapptr, erptr);
390: pmesg("\tinodes:\n");
391: for(i = 0; i < 32; i++)
392: cnts[i] = 0;
393: for(i = 1; i < ninode; i++)
394: cnts[imap[i].type]++;
395: for(i = 0; i < 32; i++)
396: if(cnts[i])
397: pmesg("%s %d\n", itype(i), cnts[i]);
398: pmesg("\tblocks:\n");
399: for(i = 0; i < 32; i++)
400: if(blkcnts[i])
401: pmesg("%s %d\n", btype(i), blkcnts[i]);
402: rpterrs();
403: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.