|
|
1.1 root 1: /*
2: * Copyright (c) 1980 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[] = "@(#)dcheck.c 5.4 (Berkeley) 7/30/89";
15: #endif not lint
16:
17: /*
18: * dcheck - check directory consistency
19: */
20: #define NB 10
21: #define MAXNINDIR (MAXBSIZE / sizeof (daddr_t))
22:
23: #include <sys/param.h>
24: #include <sys/time.h>
25: #include <sys/vnode.h>
26: #include <ufs/inode.h>
27: #include <ufs/fs.h>
28: #include <sys/dir.h>
29: #include <stdio.h>
30:
31: union {
32: struct fs fs;
33: char pad[SBSIZE];
34: } fsun;
35: #define sblock fsun.fs
36:
37: struct dirstuff {
38: int loc;
39: struct dinode *ip;
40: char dbuf[MAXBSIZE];
41: };
42:
43: struct dinode itab[MAXBSIZE / sizeof(struct dinode)];
44: struct dinode *gip;
45: ino_t ilist[NB];
46:
47: int fi;
48: ino_t ino;
49: ino_t *ecount;
50: int headpr;
51: int nfiles;
52: long dev_bsize = 1;
53:
54: int nerror;
55: daddr_t bmap();
56: long atol();
57: char *malloc();
58:
59: main(argc, argv)
60: char *argv[];
61: {
62: register i;
63: long n;
64:
65: while (--argc) {
66: argv++;
67: if (**argv=='-')
68: switch ((*argv)[1]) {
69:
70: case 'i':
71: for(i=0; i<NB; i++) {
72: n = atol(argv[1]);
73: if(n == 0)
74: break;
75: ilist[i] = n;
76: argv++;
77: argc--;
78: }
79: ilist[i] = 0;
80: continue;
81:
82: default:
83: printf("Bad flag %c\n", (*argv)[1]);
84: nerror++;
85: }
86: check(*argv);
87: }
88: return(nerror);
89: }
90:
91: check(file)
92: char *file;
93: {
94: register i, j, c;
95:
96: fi = open(file, 0);
97: if(fi < 0) {
98: printf("cannot open %s\n", file);
99: nerror++;
100: return;
101: }
102: headpr = 0;
103: printf("%s:\n", file);
104: sync();
105: bread(SBOFF, (char *)&sblock, SBSIZE);
106: if (sblock.fs_magic != FS_MAGIC) {
107: printf("%s: not a file system\n", file);
108: nerror++;
109: return;
110: }
111: dev_bsize = sblock.fs_fsize / fsbtodb(&sblock, 1);
112: nfiles = sblock.fs_ipg * sblock.fs_ncg;
113: ecount = (ino_t *)malloc((nfiles+1) * sizeof (*ecount));
114: if (ecount == 0) {
115: printf("%s: not enough core for %d files\n", file, nfiles);
116: exit(04);
117: }
118: for (i = 0; i<=nfiles; i++)
119: ecount[i] = 0;
120: ino = 0;
121: for (c = 0; c < sblock.fs_ncg; c++) {
122: for (i = 0;
123: i < sblock.fs_ipg / INOPF(&sblock);
124: i += sblock.fs_frag) {
125: bread(fsbtodb(&sblock, cgimin(&sblock, c) + i),
126: (char *)itab, sblock.fs_bsize);
127: for (j = 0; j < INOPB(&sblock); j++) {
128: pass1(&itab[j]);
129: ino++;
130: }
131: }
132: }
133: ino = 0;
134: for (c = 0; c < sblock.fs_ncg; c++) {
135: for (i = 0;
136: i < sblock.fs_ipg / INOPF(&sblock);
137: i += sblock.fs_frag) {
138: bread(fsbtodb(&sblock, cgimin(&sblock, c) + i),
139: (char *)itab, sblock.fs_bsize);
140: for (j = 0; j < INOPB(&sblock); j++) {
141: pass2(&itab[j]);
142: ino++;
143: }
144: }
145: }
146: free(ecount);
147: }
148:
149: pass1(ip)
150: register struct dinode *ip;
151: {
152: register struct direct *dp;
153: struct dirstuff dirp;
154: int k;
155:
156: if((ip->di_mode&IFMT) != IFDIR)
157: return;
158: dirp.loc = 0;
159: dirp.ip = ip;
160: gip = ip;
161: for (dp = readdir(&dirp); dp != NULL; dp = readdir(&dirp)) {
162: if(dp->d_ino == 0)
163: continue;
164: if(dp->d_ino > nfiles || dp->d_ino < ROOTINO) {
165: printf("%d bad; %d/%s\n",
166: dp->d_ino, ino, dp->d_name);
167: nerror++;
168: continue;
169: }
170: for (k = 0; ilist[k] != 0; k++)
171: if (ilist[k] == dp->d_ino) {
172: printf("%d arg; %d/%s\n",
173: dp->d_ino, ino, dp->d_name);
174: nerror++;
175: }
176: ecount[dp->d_ino]++;
177: }
178: }
179:
180: pass2(ip)
181: register struct dinode *ip;
182: {
183: register i;
184:
185: i = ino;
186: if ((ip->di_mode&IFMT)==0 && ecount[i]==0)
187: return;
188: if (ip->di_nlink==ecount[i] && ip->di_nlink!=0)
189: return;
190: if (headpr==0) {
191: printf(" entries link cnt\n");
192: headpr++;
193: }
194: printf("%u\t%d\t%d\n", ino,
195: ecount[i], ip->di_nlink);
196: }
197:
198: /*
199: * get next entry in a directory.
200: */
201: struct direct *
202: readdir(dirp)
203: register struct dirstuff *dirp;
204: {
205: register struct direct *dp;
206: daddr_t lbn, d;
207:
208: for(;;) {
209: if (dirp->loc >= dirp->ip->di_size)
210: return NULL;
211: if ((lbn = lblkno(&sblock, dirp->loc)) == 0) {
212: d = bmap(lbn);
213: if(d == 0)
214: return NULL;
215: bread(fsbtodb(&sblock, d), dirp->dbuf,
216: dblksize(&sblock, dirp->ip, lbn));
217: }
218: dp = (struct direct *)
219: (dirp->dbuf + blkoff(&sblock, dirp->loc));
220: dirp->loc += dp->d_reclen;
221: if (dp->d_ino == 0)
222: continue;
223: return (dp);
224: }
225: }
226:
227: bread(bno, buf, cnt)
228: daddr_t bno;
229: char *buf;
230: {
231: register i;
232:
233: lseek(fi, bno * dev_bsize, 0);
234: if (read(fi, buf, cnt) != cnt) {
235: printf("read error %d\n", bno);
236: for(i=0; i < cnt; i++)
237: buf[i] = 0;
238: }
239: }
240:
241: daddr_t
242: bmap(i)
243: {
244: daddr_t ibuf[MAXNINDIR];
245:
246: if(i < NDADDR)
247: return(gip->di_db[i]);
248: i -= NDADDR;
249: if(i > NINDIR(&sblock)) {
250: printf("%u - huge directory\n", ino);
251: return((daddr_t)0);
252: }
253: bread(fsbtodb(&sblock, gip->di_ib[0]), (char *)ibuf, sizeof(ibuf));
254: return(ibuf[i]);
255: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.