xref: /csrg-svn/sbin/dump/traverse.c (revision 5329)
1*5329Smckusic static	char *sccsid = "@(#)traverse.c	1.4 (Berkeley) 01/05/82";
2*5329Smckusic 
31426Sroot #include "dump.h"
41426Sroot 
51426Sroot pass(fn, map)
64702Smckusic 	int (*fn)();
7*5329Smckusic 	char *map;
81426Sroot {
94702Smckusic 	struct dinode *dp;
101426Sroot 	int bits;
114702Smckusic 	ino_t maxino;
121426Sroot 
13*5329Smckusic 	maxino = sblock->fs_ipg * sblock->fs_ncg - 1;
144702Smckusic 	for (ino = 0; ino < maxino; ) {
15*5329Smckusic 		if((ino % NBBY) == 0) {
164702Smckusic 			bits = ~0;
174702Smckusic 			if(map != NULL)
184702Smckusic 				bits = *map++;
191426Sroot 		}
204702Smckusic 		ino++;
214702Smckusic 		if(bits & 1) {
224702Smckusic 			dp = getino(ino);
234702Smckusic 			(*fn)(dp);
244702Smckusic 		}
254702Smckusic 		bits >>= 1;
261426Sroot 	}
271426Sroot }
281426Sroot 
291426Sroot mark(ip)
304777Smckusic 	struct dinode *ip;
311426Sroot {
321426Sroot 	register f;
331426Sroot 
341426Sroot 	f = ip->di_mode & IFMT;
351426Sroot 	if(f == 0)
361426Sroot 		return;
371426Sroot 	BIS(ino, clrmap);
381426Sroot 	if(f == IFDIR)
391426Sroot 		BIS(ino, dirmap);
40*5329Smckusic 	if ((ip->di_mtime >= spcl.c_ddate || ip->di_ctime >= spcl.c_ddate) &&
41*5329Smckusic 	    !BIT(ino, nodmap)) {
421426Sroot 		BIS(ino, nodmap);
43*5329Smckusic 		if (f != IFREG && f != IFDIR) {
441426Sroot 			esize += 1;
451426Sroot 			return;
461426Sroot 		}
471426Sroot 		est(ip);
481426Sroot 	}
491426Sroot }
501426Sroot 
511426Sroot add(ip)
52*5329Smckusic 	register struct	dinode	*ip;
531426Sroot {
54*5329Smckusic 	register int i;
551426Sroot 
561426Sroot 	if(BIT(ino, nodmap))
571426Sroot 		return;
581426Sroot 	nsubdir = 0;
591426Sroot 	dadded = 0;
60*5329Smckusic 	for (i = 0; i < NDADDR; i++) {
61*5329Smckusic 		if (ip->di_db[i] != 0)
62*5329Smckusic 			dsrch(ip->di_db[i], dblksize(sblock, ip, i));
63*5329Smckusic 	}
64*5329Smckusic 	for (i = 0; i < NIADDR; i++) {
65*5329Smckusic 		if (ip->di_ib[i] != 0)
66*5329Smckusic 			indir(ip->di_ib[i], i);
67*5329Smckusic 	}
681426Sroot 	if(dadded) {
691426Sroot 		nadded++;
70*5329Smckusic 		if (!BIT(ino, nodmap)) {
71*5329Smckusic 			BIS(ino, nodmap);
72*5329Smckusic 			est(ip);
73*5329Smckusic 		}
741426Sroot 	}
751426Sroot 	if(nsubdir == 0)
761426Sroot 		if(!BIT(ino, nodmap))
771426Sroot 			BIC(ino, dirmap);
781426Sroot }
791426Sroot 
80*5329Smckusic indir(d, n)
81*5329Smckusic 	daddr_t d;
82*5329Smckusic 	int n;
83*5329Smckusic {
84*5329Smckusic 	register i;
85*5329Smckusic 	daddr_t	idblk[MAXNINDIR];
86*5329Smckusic 
87*5329Smckusic 	bread(fsbtodb(sblock, d), (char *)idblk, sblock->fs_bsize);
88*5329Smckusic 	if(n <= 0) {
89*5329Smckusic 		for(i=0; i < NINDIR(sblock); i++) {
90*5329Smckusic 			d = idblk[i];
91*5329Smckusic 			if(d != 0)
92*5329Smckusic 				dsrch(d, sblock->fs_bsize);
93*5329Smckusic 		}
94*5329Smckusic 	} else {
95*5329Smckusic 		n--;
96*5329Smckusic 		for(i=0; i < NINDIR(sblock); i++) {
97*5329Smckusic 			d = idblk[i];
98*5329Smckusic 			if(d != 0)
99*5329Smckusic 				indir(d, n);
100*5329Smckusic 		}
101*5329Smckusic 	}
102*5329Smckusic }
103*5329Smckusic 
1041426Sroot dump(ip)
1054777Smckusic 	struct dinode *ip;
1061426Sroot {
1074777Smckusic 	register int i;
1084777Smckusic 	long size;
1091426Sroot 
1101426Sroot 	if(newtape) {
1111426Sroot 		newtape = 0;
1121426Sroot 		bitmap(nodmap, TS_BITS);
1131426Sroot 	}
1141426Sroot 	BIC(ino, nodmap);
1151426Sroot 	spcl.c_dinode = *ip;
1161426Sroot 	spcl.c_type = TS_INODE;
1171426Sroot 	spcl.c_count = 0;
1181426Sroot 	i = ip->di_mode & IFMT;
1194777Smckusic 	if ((i != IFDIR && i != IFREG) || ip->di_size == 0) {
1201426Sroot 		spclrec();
1211426Sroot 		return;
1221426Sroot 	}
123*5329Smckusic 	if (ip->di_size > NDADDR * sblock->fs_bsize)
124*5329Smckusic 		i = NDADDR * sblock->fs_frag;
1254777Smckusic 	else
126*5329Smckusic 		i = howmany(ip->di_size, sblock->fs_fsize);
1274777Smckusic 	blksout(&ip->di_db[0], i);
128*5329Smckusic 	size = ip->di_size - NDADDR * sblock->fs_bsize;
1294777Smckusic 	if (size <= 0)
1304777Smckusic 		return;
1314777Smckusic 	for (i = 0; i < NIADDR; i++) {
1324777Smckusic 		dmpindir(ip->di_ib[i], i, &size);
1334777Smckusic 		if (size <= 0)
1344777Smckusic 			return;
1354777Smckusic 	}
1361426Sroot }
1371426Sroot 
1384777Smckusic dmpindir(blk, lvl, size)
1394777Smckusic 	daddr_t blk;
1404777Smckusic 	int lvl;
1414777Smckusic 	long *size;
1421426Sroot {
1434777Smckusic 	int i, cnt;
144*5329Smckusic 	daddr_t idblk[MAXNINDIR];
1451426Sroot 
1464777Smckusic 	if (blk != 0)
147*5329Smckusic 		bread(fsbtodb(sblock, blk), (char *)idblk, sblock->fs_bsize);
1484777Smckusic 	else
149*5329Smckusic 		blkclr(idblk, sblock->fs_bsize);
1504777Smckusic 	if (lvl <= 0) {
151*5329Smckusic 		if (*size < NINDIR(sblock) * sblock->fs_bsize)
152*5329Smckusic 			cnt = howmany(*size, sblock->fs_fsize);
1534777Smckusic 		else
154*5329Smckusic 			cnt = NINDIR(sblock) * sblock->fs_frag;
155*5329Smckusic 		*size -= NINDIR(sblock) * sblock->fs_bsize;
1564777Smckusic 		blksout(&idblk[0], cnt);
1574777Smckusic 		return;
1581426Sroot 	}
1594777Smckusic 	lvl--;
160*5329Smckusic 	for (i = 0; i < NINDIR(sblock); i++) {
1614777Smckusic 		dmpindir(idblk[i], lvl, size);
1624777Smckusic 		if (*size <= 0)
1634777Smckusic 			return;
1644777Smckusic 	}
1651426Sroot }
1661426Sroot 
1674777Smckusic blksout(blkp, frags)
1684777Smckusic 	daddr_t *blkp;
1694777Smckusic 	int frags;
1704777Smckusic {
171*5329Smckusic 	int i, j, count, blks, tbperdb;
1724777Smckusic 
173*5329Smckusic 	blks = frags * BLKING(sblock);
174*5329Smckusic 	tbperdb = BLKING(sblock) * sblock->fs_frag;
1754777Smckusic 	for (i = 0; i < blks; i += TP_NINDIR) {
1764777Smckusic 		if (i + TP_NINDIR > blks)
1774777Smckusic 			count = blks;
1784777Smckusic 		else
1794777Smckusic 			count = i + TP_NINDIR;
1804777Smckusic 		for (j = i; j < count; j++)
181*5329Smckusic 			if (blkp[j / tbperdb] != 0)
1824777Smckusic 				spcl.c_addr[j - i] = 1;
1834777Smckusic 			else
1844777Smckusic 				spcl.c_addr[j - i] = 0;
1854777Smckusic 		spcl.c_count = count - i;
1864777Smckusic 		spclrec();
187*5329Smckusic 		for (j = i; j < count; j += tbperdb)
188*5329Smckusic 			if (blkp[j / tbperdb] != 0)
189*5329Smckusic 				if (j + tbperdb <= count)
190*5329Smckusic 					dmpblk(blkp[j / tbperdb],
191*5329Smckusic 					    sblock->fs_bsize);
1924777Smckusic 				else
193*5329Smckusic 					dmpblk(blkp[j / tbperdb],
1944777Smckusic 					    (count - j) * TP_BSIZE);
1954777Smckusic 		spcl.c_type = TS_ADDR;
1964777Smckusic 	}
1974777Smckusic }
1984777Smckusic 
1991426Sroot bitmap(map, typ)
200*5329Smckusic 	char *map;
2011426Sroot {
2021426Sroot 	register i, n;
2031426Sroot 	char *cp;
2041426Sroot 
2051426Sroot 	n = -1;
206*5329Smckusic 	for (i = 0; i < msiz; i++)
2071426Sroot 		if(map[i])
2081426Sroot 			n = i;
209*5329Smckusic 	if (n < 0)
2101426Sroot 		return;
211*5329Smckusic 	n++;
2121426Sroot 	spcl.c_type = typ;
213*5329Smckusic 	spcl.c_count = howmany(n * sizeof(map[0]), TP_BSIZE);
2141426Sroot 	spclrec();
215*5329Smckusic 	for (i = 0, cp = map; i < spcl.c_count; i++, cp += TP_BSIZE)
2161426Sroot 		taprec(cp);
2171426Sroot }
2181426Sroot 
2191426Sroot spclrec()
2201426Sroot {
2214777Smckusic 	register int s, i, *ip;
2221426Sroot 
2231426Sroot 	spcl.c_inumber = ino;
2241426Sroot 	spcl.c_magic = MAGIC;
2251426Sroot 	spcl.c_checksum = 0;
2261426Sroot 	ip = (int *)&spcl;
2271426Sroot 	s = 0;
2284777Smckusic 	for(i = 0; i < sizeof(union u_spcl)/sizeof(int); i++)
2291426Sroot 		s += *ip++;
2301426Sroot 	spcl.c_checksum = CHECKSUM - s;
2311426Sroot 	taprec((char *)&spcl);
2321426Sroot }
2331426Sroot 
234*5329Smckusic dsrch(d, size)
2354777Smckusic 	daddr_t d;
236*5329Smckusic 	int size;
2371426Sroot {
2381426Sroot 	register char *cp;
2391426Sroot 	register i;
2401426Sroot 	register ino_t in;
241*5329Smckusic 	struct direct dblk[MAXDIRPB];
2421426Sroot 
2431426Sroot 	if(dadded)
2441426Sroot 		return;
245*5329Smckusic 	bread(fsbtodb(sblock, d), (char *)dblk, size);
246*5329Smckusic 	for(i=0; i < DIRPB(sblock); i++) {
2471426Sroot 		in = dblk[i].d_ino;
2481426Sroot 		if(in == 0)
2491426Sroot 			continue;
2501426Sroot 		cp = dblk[i].d_name;
2511426Sroot 		if(cp[0] == '.') {
2521426Sroot 			if(cp[1] == '\0')
2531426Sroot 				continue;
2541426Sroot 			if(cp[1] == '.' && cp[2] == '\0')
2551426Sroot 				continue;
2561426Sroot 		}
2571426Sroot 		if(BIT(in, nodmap)) {
2581426Sroot 			dadded++;
2591426Sroot 			return;
2601426Sroot 		}
2611426Sroot 		if(BIT(in, dirmap))
2621426Sroot 			nsubdir++;
2631426Sroot 	}
2641426Sroot }
2651426Sroot 
2664702Smckusic struct dinode *
2674702Smckusic getino(ino)
2684702Smckusic 	daddr_t ino;
2694702Smckusic {
2704702Smckusic 	static daddr_t minino, maxino;
271*5329Smckusic 	static struct dinode itab[MAXINOPB];
2724702Smckusic 
2734702Smckusic 	if (ino >= minino && ino < maxino) {
2744702Smckusic 		return (&itab[ino - minino]);
2754702Smckusic 	}
276*5329Smckusic 	bread(fsbtodb(sblock, itod(ino, sblock)), itab, sblock->fs_bsize);
277*5329Smckusic 	minino = ino - (ino % INOPB(sblock));
278*5329Smckusic 	maxino = minino + INOPB(sblock);
2794702Smckusic 	return (&itab[ino - minino]);
2804702Smckusic }
2814702Smckusic 
2821426Sroot int	breaderrors = 0;
2831426Sroot #define	BREADEMAX 32
2841426Sroot 
2851426Sroot bread(da, ba, c)
2861426Sroot 	daddr_t da;
2871426Sroot 	char *ba;
2881426Sroot 	int	c;
2891426Sroot {
2901426Sroot 	register n;
2911426Sroot 	register	regc;
2921426Sroot 
293*5329Smckusic 	if (lseek(fi, (long)(da * DEV_BSIZE), 0) < 0){
2941426Sroot 		msg("bread: lseek fails\n");
2951426Sroot 	}
2961426Sroot 	regc = c;	/* put c someplace safe; it gets clobbered */
2971426Sroot 	n = read(fi, ba, c);
298*5329Smckusic 	if (n != c || regc != c) {
2991426Sroot 		msg("(This should not happen)bread from %s [block %d]: c=0x%x, regc=0x%x, &c=0x%x, n=0x%x\n",
3001426Sroot 			disk, da, c, regc, &c, n);
3011426Sroot #ifdef ERNIE
3021426Sroot 		msg("Notify Robert Henry of this error.\n");
3031426Sroot #endif
3041426Sroot 		if (++breaderrors > BREADEMAX){
3051426Sroot 			msg("More than %d block read errors from %d\n",
3061426Sroot 				BREADEMAX, disk);
3071426Sroot 			broadcast("DUMP IS AILING!\n");
3081426Sroot 			msg("This is an unrecoverable error.\n");
3091426Sroot 			if (!query("Do you want to attempt to continue?")){
3101426Sroot 				dumpabort();
3111426Sroot 				/*NOTREACHED*/
3121426Sroot 			} else
3131426Sroot 				breaderrors = 0;
3141426Sroot 		}
3151426Sroot 	}
3161426Sroot }
3171426Sroot 
3184777Smckusic blkclr(cp, size)
3194777Smckusic 	char *cp;
3204777Smckusic 	long size;
3214777Smckusic {
3224777Smckusic 	asm("movc5	$0,(r0),$0,8(ap),*4(ap)");
3234777Smckusic }
324