122489Sdist /*
222489Sdist * Copyright (c) 1980 Regents of the University of California.
322489Sdist * All rights reserved. The Berkeley software License Agreement
422489Sdist * specifies the terms and conditions for redistribution.
522489Sdist */
622489Sdist
713550Ssam #ifndef lint
822489Sdist char copyright[] =
922489Sdist "@(#) Copyright (c) 1980 Regents of the University of California.\n\
1022489Sdist All rights reserved.\n";
1122489Sdist #endif not lint
1222489Sdist
1322489Sdist #ifndef lint
14*38504Sbostic static char sccsid[] = "@(#)dcheck.c 5.4 (Berkeley) 07/30/89";
1522489Sdist #endif not lint
1622489Sdist
174238Smckusick /*
184238Smckusick * dcheck - check directory consistency
194238Smckusick */
204238Smckusick #define NB 10
215348Smckusic #define MAXNINDIR (MAXBSIZE / sizeof (daddr_t))
224238Smckusick
236493Smckusick #include <sys/param.h>
24*38504Sbostic #include <sys/time.h>
25*38504Sbostic #include <sys/vnode.h>
26*38504Sbostic #include <ufs/inode.h>
27*38504Sbostic #include <ufs/fs.h>
2813550Ssam #include <sys/dir.h>
295946Smckusic #include <stdio.h>
304238Smckusick
314238Smckusick union {
324238Smckusick struct fs fs;
3334151Smckusick char pad[SBSIZE];
344238Smckusick } fsun;
354238Smckusick #define sblock fsun.fs
364238Smckusick
375946Smckusic struct dirstuff {
385946Smckusic int loc;
395946Smckusic struct dinode *ip;
405946Smckusic char dbuf[MAXBSIZE];
415946Smckusic };
425946Smckusic
4334151Smckusick struct dinode itab[MAXBSIZE / sizeof(struct dinode)];
444253Smckusic struct dinode *gip;
454238Smckusick ino_t ilist[NB];
464238Smckusick
474238Smckusick int fi;
484238Smckusick ino_t ino;
494238Smckusick ino_t *ecount;
504238Smckusick int headpr;
514238Smckusick int nfiles;
5230558Smckusick long dev_bsize = 1;
534238Smckusick
544238Smckusick int nerror;
554238Smckusick daddr_t bmap();
564238Smckusick long atol();
574238Smckusick char *malloc();
584238Smckusick
main(argc,argv)594238Smckusick main(argc, argv)
604238Smckusick char *argv[];
614238Smckusick {
624238Smckusick register i;
634238Smckusick long n;
644238Smckusick
654238Smckusick while (--argc) {
664238Smckusick argv++;
674238Smckusick if (**argv=='-')
684238Smckusick switch ((*argv)[1]) {
694238Smckusick
704238Smckusick case 'i':
714238Smckusick for(i=0; i<NB; i++) {
724238Smckusick n = atol(argv[1]);
734238Smckusick if(n == 0)
744238Smckusick break;
754238Smckusick ilist[i] = n;
764238Smckusick argv++;
774238Smckusick argc--;
784238Smckusick }
794238Smckusick ilist[i] = 0;
804238Smckusick continue;
814238Smckusick
824238Smckusick default:
834238Smckusick printf("Bad flag %c\n", (*argv)[1]);
844238Smckusick nerror++;
854238Smckusick }
864238Smckusick check(*argv);
874238Smckusick }
884238Smckusick return(nerror);
894238Smckusick }
904238Smckusick
check(file)914238Smckusick check(file)
924238Smckusick char *file;
934238Smckusick {
944238Smckusick register i, j, c;
954238Smckusick
964238Smckusick fi = open(file, 0);
974238Smckusick if(fi < 0) {
984238Smckusick printf("cannot open %s\n", file);
994238Smckusick nerror++;
1004238Smckusick return;
1014238Smckusick }
1024238Smckusick headpr = 0;
1034238Smckusick printf("%s:\n", file);
1044238Smckusick sync();
10530558Smckusick bread(SBOFF, (char *)&sblock, SBSIZE);
1064238Smckusick if (sblock.fs_magic != FS_MAGIC) {
1074238Smckusick printf("%s: not a file system\n", file);
1084238Smckusick nerror++;
1094238Smckusick return;
1104238Smckusick }
11130558Smckusick dev_bsize = sblock.fs_fsize / fsbtodb(&sblock, 1);
1124238Smckusick nfiles = sblock.fs_ipg * sblock.fs_ncg;
1134238Smckusick ecount = (ino_t *)malloc((nfiles+1) * sizeof (*ecount));
1144238Smckusick if (ecount == 0) {
1154238Smckusick printf("%s: not enough core for %d files\n", file, nfiles);
1164238Smckusick exit(04);
1174238Smckusick }
1184238Smckusick for (i = 0; i<=nfiles; i++)
1194238Smckusick ecount[i] = 0;
1204238Smckusick ino = 0;
1214238Smckusick for (c = 0; c < sblock.fs_ncg; c++) {
12234151Smckusick for (i = 0;
12334151Smckusick i < sblock.fs_ipg / INOPF(&sblock);
12434151Smckusick i += sblock.fs_frag) {
12534151Smckusick bread(fsbtodb(&sblock, cgimin(&sblock, c) + i),
12634151Smckusick (char *)itab, sblock.fs_bsize);
12734151Smckusick for (j = 0; j < INOPB(&sblock); j++) {
12834151Smckusick pass1(&itab[j]);
12934151Smckusick ino++;
13034151Smckusick }
1314238Smckusick }
1324238Smckusick }
1334238Smckusick ino = 0;
1344238Smckusick for (c = 0; c < sblock.fs_ncg; c++) {
13534151Smckusick for (i = 0;
13634151Smckusick i < sblock.fs_ipg / INOPF(&sblock);
13734151Smckusick i += sblock.fs_frag) {
13834151Smckusick bread(fsbtodb(&sblock, cgimin(&sblock, c) + i),
13934151Smckusick (char *)itab, sblock.fs_bsize);
14034151Smckusick for (j = 0; j < INOPB(&sblock); j++) {
14134151Smckusick pass2(&itab[j]);
14234151Smckusick ino++;
14334151Smckusick }
1444238Smckusick }
1454238Smckusick }
1464238Smckusick free(ecount);
1474238Smckusick }
1484238Smckusick
pass1(ip)1494238Smckusick pass1(ip)
1505946Smckusic register struct dinode *ip;
1514238Smckusick {
1525946Smckusic register struct direct *dp;
1535946Smckusic struct dirstuff dirp;
1544238Smckusick int k;
1554238Smckusick
1564238Smckusick if((ip->di_mode&IFMT) != IFDIR)
1574238Smckusick return;
1585946Smckusic dirp.loc = 0;
1595946Smckusic dirp.ip = ip;
1604253Smckusic gip = ip;
1615946Smckusic for (dp = readdir(&dirp); dp != NULL; dp = readdir(&dirp)) {
1625946Smckusic if(dp->d_ino == 0)
1635946Smckusic continue;
1645946Smckusic if(dp->d_ino > nfiles || dp->d_ino < ROOTINO) {
1655946Smckusic printf("%d bad; %d/%s\n",
1665946Smckusic dp->d_ino, ino, dp->d_name);
1675946Smckusic nerror++;
1685946Smckusic continue;
1695946Smckusic }
1705946Smckusic for (k = 0; ilist[k] != 0; k++)
1715946Smckusic if (ilist[k] == dp->d_ino) {
1725946Smckusic printf("%d arg; %d/%s\n",
1735946Smckusic dp->d_ino, ino, dp->d_name);
1744238Smckusick nerror++;
1754238Smckusick }
1765946Smckusic ecount[dp->d_ino]++;
1774238Smckusick }
1784238Smckusick }
1794238Smckusick
pass2(ip)1804238Smckusick pass2(ip)
1814238Smckusick register struct dinode *ip;
1824238Smckusick {
1834238Smckusick register i;
1844238Smckusick
1854238Smckusick i = ino;
1864238Smckusick if ((ip->di_mode&IFMT)==0 && ecount[i]==0)
1874238Smckusick return;
1884238Smckusick if (ip->di_nlink==ecount[i] && ip->di_nlink!=0)
1894238Smckusick return;
1904238Smckusick if (headpr==0) {
1914238Smckusick printf(" entries link cnt\n");
1924238Smckusick headpr++;
1934238Smckusick }
1944238Smckusick printf("%u\t%d\t%d\n", ino,
1954238Smckusick ecount[i], ip->di_nlink);
1964238Smckusick }
1974238Smckusick
1985946Smckusic /*
1995946Smckusic * get next entry in a directory.
2005946Smckusic */
2015946Smckusic struct direct *
readdir(dirp)2025946Smckusic readdir(dirp)
2035946Smckusic register struct dirstuff *dirp;
2045946Smckusic {
2055946Smckusic register struct direct *dp;
2065946Smckusic daddr_t lbn, d;
2075946Smckusic
2085946Smckusic for(;;) {
2095946Smckusic if (dirp->loc >= dirp->ip->di_size)
2105946Smckusic return NULL;
2115957Smckusic if ((lbn = lblkno(&sblock, dirp->loc)) == 0) {
2125946Smckusic d = bmap(lbn);
2135946Smckusic if(d == 0)
2145946Smckusic return NULL;
2155946Smckusic bread(fsbtodb(&sblock, d), dirp->dbuf,
2165946Smckusic dblksize(&sblock, dirp->ip, lbn));
2175946Smckusic }
2185946Smckusic dp = (struct direct *)
2195957Smckusic (dirp->dbuf + blkoff(&sblock, dirp->loc));
2205946Smckusic dirp->loc += dp->d_reclen;
2215946Smckusic if (dp->d_ino == 0)
2225946Smckusic continue;
2235946Smckusic return (dp);
2245946Smckusic }
2255946Smckusic }
2265946Smckusic
bread(bno,buf,cnt)2274238Smckusick bread(bno, buf, cnt)
2284238Smckusick daddr_t bno;
2294238Smckusick char *buf;
2304238Smckusick {
2314238Smckusick register i;
2324238Smckusick
23330558Smckusick lseek(fi, bno * dev_bsize, 0);
2344238Smckusick if (read(fi, buf, cnt) != cnt) {
2354238Smckusick printf("read error %d\n", bno);
2365326Smckusic for(i=0; i < cnt; i++)
2374238Smckusick buf[i] = 0;
2384238Smckusick }
2394238Smckusick }
2404238Smckusick
2414238Smckusick daddr_t
bmap(i)2424238Smckusick bmap(i)
2434238Smckusick {
2445326Smckusic daddr_t ibuf[MAXNINDIR];
2454238Smckusick
2464238Smckusick if(i < NDADDR)
2474253Smckusic return(gip->di_db[i]);
2484238Smckusick i -= NDADDR;
2495326Smckusic if(i > NINDIR(&sblock)) {
2504238Smckusick printf("%u - huge directory\n", ino);
2514238Smckusick return((daddr_t)0);
2524238Smckusick }
2535326Smckusic bread(fsbtodb(&sblock, gip->di_ib[0]), (char *)ibuf, sizeof(ibuf));
2544238Smckusick return(ibuf[i]);
2554238Smckusick }
256