112d93969Sdist /*
212d93969Sdist * Copyright (c) 1980 Regents of the University of California.
312d93969Sdist * All rights reserved. The Berkeley software License Agreement
412d93969Sdist * specifies the terms and conditions for redistribution.
512d93969Sdist */
612d93969Sdist
704d02f54Ssam #ifndef lint
812d93969Sdist char copyright[] =
912d93969Sdist "@(#) Copyright (c) 1980 Regents of the University of California.\n\
1012d93969Sdist All rights reserved.\n";
1112d93969Sdist #endif not lint
1212d93969Sdist
1312d93969Sdist #ifndef lint
14*d4c43c37Sbostic static char sccsid[] = "@(#)dcheck.c 5.4 (Berkeley) 07/30/89";
1512d93969Sdist #endif not lint
1612d93969Sdist
1756c871baSmckusick /*
1856c871baSmckusick * dcheck - check directory consistency
1956c871baSmckusick */
2056c871baSmckusick #define NB 10
219b43ab0cSmckusic #define MAXNINDIR (MAXBSIZE / sizeof (daddr_t))
2256c871baSmckusick
23b257f55fSmckusick #include <sys/param.h>
24*d4c43c37Sbostic #include <sys/time.h>
25*d4c43c37Sbostic #include <sys/vnode.h>
26*d4c43c37Sbostic #include <ufs/inode.h>
27*d4c43c37Sbostic #include <ufs/fs.h>
2804d02f54Ssam #include <sys/dir.h>
29a405466cSmckusic #include <stdio.h>
3056c871baSmckusick
3156c871baSmckusick union {
3256c871baSmckusick struct fs fs;
33c4a51231Smckusick char pad[SBSIZE];
3456c871baSmckusick } fsun;
3556c871baSmckusick #define sblock fsun.fs
3656c871baSmckusick
37a405466cSmckusic struct dirstuff {
38a405466cSmckusic int loc;
39a405466cSmckusic struct dinode *ip;
40a405466cSmckusic char dbuf[MAXBSIZE];
41a405466cSmckusic };
42a405466cSmckusic
43c4a51231Smckusick struct dinode itab[MAXBSIZE / sizeof(struct dinode)];
445ba00738Smckusic struct dinode *gip;
4556c871baSmckusick ino_t ilist[NB];
4656c871baSmckusick
4756c871baSmckusick int fi;
4856c871baSmckusick ino_t ino;
4956c871baSmckusick ino_t *ecount;
5056c871baSmckusick int headpr;
5156c871baSmckusick int nfiles;
52397eaf9bSmckusick long dev_bsize = 1;
5356c871baSmckusick
5456c871baSmckusick int nerror;
5556c871baSmckusick daddr_t bmap();
5656c871baSmckusick long atol();
5756c871baSmckusick char *malloc();
5856c871baSmckusick
main(argc,argv)5956c871baSmckusick main(argc, argv)
6056c871baSmckusick char *argv[];
6156c871baSmckusick {
6256c871baSmckusick register i;
6356c871baSmckusick long n;
6456c871baSmckusick
6556c871baSmckusick while (--argc) {
6656c871baSmckusick argv++;
6756c871baSmckusick if (**argv=='-')
6856c871baSmckusick switch ((*argv)[1]) {
6956c871baSmckusick
7056c871baSmckusick case 'i':
7156c871baSmckusick for(i=0; i<NB; i++) {
7256c871baSmckusick n = atol(argv[1]);
7356c871baSmckusick if(n == 0)
7456c871baSmckusick break;
7556c871baSmckusick ilist[i] = n;
7656c871baSmckusick argv++;
7756c871baSmckusick argc--;
7856c871baSmckusick }
7956c871baSmckusick ilist[i] = 0;
8056c871baSmckusick continue;
8156c871baSmckusick
8256c871baSmckusick default:
8356c871baSmckusick printf("Bad flag %c\n", (*argv)[1]);
8456c871baSmckusick nerror++;
8556c871baSmckusick }
8656c871baSmckusick check(*argv);
8756c871baSmckusick }
8856c871baSmckusick return(nerror);
8956c871baSmckusick }
9056c871baSmckusick
check(file)9156c871baSmckusick check(file)
9256c871baSmckusick char *file;
9356c871baSmckusick {
9456c871baSmckusick register i, j, c;
9556c871baSmckusick
9656c871baSmckusick fi = open(file, 0);
9756c871baSmckusick if(fi < 0) {
9856c871baSmckusick printf("cannot open %s\n", file);
9956c871baSmckusick nerror++;
10056c871baSmckusick return;
10156c871baSmckusick }
10256c871baSmckusick headpr = 0;
10356c871baSmckusick printf("%s:\n", file);
10456c871baSmckusick sync();
105397eaf9bSmckusick bread(SBOFF, (char *)&sblock, SBSIZE);
10656c871baSmckusick if (sblock.fs_magic != FS_MAGIC) {
10756c871baSmckusick printf("%s: not a file system\n", file);
10856c871baSmckusick nerror++;
10956c871baSmckusick return;
11056c871baSmckusick }
111397eaf9bSmckusick dev_bsize = sblock.fs_fsize / fsbtodb(&sblock, 1);
11256c871baSmckusick nfiles = sblock.fs_ipg * sblock.fs_ncg;
11356c871baSmckusick ecount = (ino_t *)malloc((nfiles+1) * sizeof (*ecount));
11456c871baSmckusick if (ecount == 0) {
11556c871baSmckusick printf("%s: not enough core for %d files\n", file, nfiles);
11656c871baSmckusick exit(04);
11756c871baSmckusick }
11856c871baSmckusick for (i = 0; i<=nfiles; i++)
11956c871baSmckusick ecount[i] = 0;
12056c871baSmckusick ino = 0;
12156c871baSmckusick for (c = 0; c < sblock.fs_ncg; c++) {
122c4a51231Smckusick for (i = 0;
123c4a51231Smckusick i < sblock.fs_ipg / INOPF(&sblock);
124c4a51231Smckusick i += sblock.fs_frag) {
125c4a51231Smckusick bread(fsbtodb(&sblock, cgimin(&sblock, c) + i),
126c4a51231Smckusick (char *)itab, sblock.fs_bsize);
127c4a51231Smckusick for (j = 0; j < INOPB(&sblock); j++) {
12856c871baSmckusick pass1(&itab[j]);
12956c871baSmckusick ino++;
13056c871baSmckusick }
13156c871baSmckusick }
132c4a51231Smckusick }
13356c871baSmckusick ino = 0;
13456c871baSmckusick for (c = 0; c < sblock.fs_ncg; c++) {
135c4a51231Smckusick for (i = 0;
136c4a51231Smckusick i < sblock.fs_ipg / INOPF(&sblock);
137c4a51231Smckusick i += sblock.fs_frag) {
138c4a51231Smckusick bread(fsbtodb(&sblock, cgimin(&sblock, c) + i),
139c4a51231Smckusick (char *)itab, sblock.fs_bsize);
140c4a51231Smckusick for (j = 0; j < INOPB(&sblock); j++) {
14156c871baSmckusick pass2(&itab[j]);
14256c871baSmckusick ino++;
14356c871baSmckusick }
14456c871baSmckusick }
145c4a51231Smckusick }
14656c871baSmckusick free(ecount);
14756c871baSmckusick }
14856c871baSmckusick
pass1(ip)14956c871baSmckusick pass1(ip)
15056c871baSmckusick register struct dinode *ip;
15156c871baSmckusick {
152a405466cSmckusic register struct direct *dp;
153a405466cSmckusic struct dirstuff dirp;
15456c871baSmckusick int k;
15556c871baSmckusick
15656c871baSmckusick if((ip->di_mode&IFMT) != IFDIR)
15756c871baSmckusick return;
158a405466cSmckusic dirp.loc = 0;
159a405466cSmckusic dirp.ip = ip;
1605ba00738Smckusic gip = ip;
161a405466cSmckusic for (dp = readdir(&dirp); dp != NULL; dp = readdir(&dirp)) {
162a405466cSmckusic if(dp->d_ino == 0)
16356c871baSmckusick continue;
164a405466cSmckusic if(dp->d_ino > nfiles || dp->d_ino < ROOTINO) {
165a405466cSmckusic printf("%d bad; %d/%s\n",
166a405466cSmckusic dp->d_ino, ino, dp->d_name);
16756c871baSmckusick nerror++;
16856c871baSmckusick continue;
16956c871baSmckusick }
17056c871baSmckusick for (k = 0; ilist[k] != 0; k++)
171a405466cSmckusic if (ilist[k] == dp->d_ino) {
172a405466cSmckusic printf("%d arg; %d/%s\n",
173a405466cSmckusic dp->d_ino, ino, dp->d_name);
17456c871baSmckusick nerror++;
17556c871baSmckusick }
176a405466cSmckusic ecount[dp->d_ino]++;
17756c871baSmckusick }
17856c871baSmckusick }
17956c871baSmckusick
pass2(ip)18056c871baSmckusick pass2(ip)
18156c871baSmckusick register struct dinode *ip;
18256c871baSmckusick {
18356c871baSmckusick register i;
18456c871baSmckusick
18556c871baSmckusick i = ino;
18656c871baSmckusick if ((ip->di_mode&IFMT)==0 && ecount[i]==0)
18756c871baSmckusick return;
18856c871baSmckusick if (ip->di_nlink==ecount[i] && ip->di_nlink!=0)
18956c871baSmckusick return;
19056c871baSmckusick if (headpr==0) {
19156c871baSmckusick printf(" entries link cnt\n");
19256c871baSmckusick headpr++;
19356c871baSmckusick }
19456c871baSmckusick printf("%u\t%d\t%d\n", ino,
19556c871baSmckusick ecount[i], ip->di_nlink);
19656c871baSmckusick }
19756c871baSmckusick
198a405466cSmckusic /*
199a405466cSmckusic * get next entry in a directory.
200a405466cSmckusic */
201a405466cSmckusic struct direct *
readdir(dirp)202a405466cSmckusic readdir(dirp)
203a405466cSmckusic register struct dirstuff *dirp;
204a405466cSmckusic {
205a405466cSmckusic register struct direct *dp;
206a405466cSmckusic daddr_t lbn, d;
207a405466cSmckusic
208a405466cSmckusic for(;;) {
209a405466cSmckusic if (dirp->loc >= dirp->ip->di_size)
210a405466cSmckusic return NULL;
21142e3eb1bSmckusic if ((lbn = lblkno(&sblock, dirp->loc)) == 0) {
212a405466cSmckusic d = bmap(lbn);
213a405466cSmckusic if(d == 0)
214a405466cSmckusic return NULL;
215a405466cSmckusic bread(fsbtodb(&sblock, d), dirp->dbuf,
216a405466cSmckusic dblksize(&sblock, dirp->ip, lbn));
217a405466cSmckusic }
218a405466cSmckusic dp = (struct direct *)
21942e3eb1bSmckusic (dirp->dbuf + blkoff(&sblock, dirp->loc));
220a405466cSmckusic dirp->loc += dp->d_reclen;
221a405466cSmckusic if (dp->d_ino == 0)
222a405466cSmckusic continue;
223a405466cSmckusic return (dp);
224a405466cSmckusic }
225a405466cSmckusic }
226a405466cSmckusic
bread(bno,buf,cnt)22756c871baSmckusick bread(bno, buf, cnt)
22856c871baSmckusick daddr_t bno;
22956c871baSmckusick char *buf;
23056c871baSmckusick {
23156c871baSmckusick register i;
23256c871baSmckusick
233397eaf9bSmckusick lseek(fi, bno * dev_bsize, 0);
23456c871baSmckusick if (read(fi, buf, cnt) != cnt) {
23556c871baSmckusick printf("read error %d\n", bno);
2369b43ab0cSmckusic for(i=0; i < cnt; i++)
23756c871baSmckusick buf[i] = 0;
23856c871baSmckusick }
23956c871baSmckusick }
24056c871baSmckusick
24156c871baSmckusick daddr_t
bmap(i)24256c871baSmckusick bmap(i)
24356c871baSmckusick {
2449b43ab0cSmckusic daddr_t ibuf[MAXNINDIR];
24556c871baSmckusick
24656c871baSmckusick if(i < NDADDR)
2475ba00738Smckusic return(gip->di_db[i]);
24856c871baSmckusick i -= NDADDR;
2499b43ab0cSmckusic if(i > NINDIR(&sblock)) {
25056c871baSmckusick printf("%u - huge directory\n", ino);
25156c871baSmckusick return((daddr_t)0);
25256c871baSmckusick }
2539b43ab0cSmckusic bread(fsbtodb(&sblock, gip->di_ib[0]), (char *)ibuf, sizeof(ibuf));
25456c871baSmckusick return(ibuf[i]);
25556c871baSmckusick }
256