xref: /csrg-svn/sbin/dump/traverse.c (revision 4777)
1*4777Smckusic static	char *sccsid = "@(#)traverse.c	1.3 (Berkeley) 11/07/81";
21426Sroot #include "dump.h"
31426Sroot 
44702Smckusic struct	fs	sblock;
51426Sroot 
61426Sroot pass(fn, map)
74702Smckusic 	int (*fn)();
84702Smckusic 	short *map;
91426Sroot {
104702Smckusic 	struct dinode *dp;
111426Sroot 	int bits;
124702Smckusic 	ino_t maxino;
131426Sroot 
141426Sroot 	sync();
154702Smckusic 	bread(SBLOCK, &sblock, sizeof sblock);
164702Smckusic 	if (sblock.fs_magic != FS_MAGIC) {
174702Smckusic 		msg("bad sblock magic number\n");
184702Smckusic 		dumpabort();
194702Smckusic 	}
204702Smckusic 	maxino = sblock.fs_ipg * sblock.fs_ncg;
214702Smckusic 	for (ino = 0; ino < maxino; ) {
224702Smckusic 		if((ino % MLEN) == 0) {
234702Smckusic 			bits = ~0;
244702Smckusic 			if(map != NULL)
254702Smckusic 				bits = *map++;
261426Sroot 		}
274702Smckusic 		ino++;
284702Smckusic 		if(bits & 1) {
294702Smckusic 			dp = getino(ino);
304702Smckusic 			(*fn)(dp);
314702Smckusic 		}
324702Smckusic 		bits >>= 1;
331426Sroot 	}
341426Sroot }
351426Sroot 
36*4777Smckusic icat(dp, fn1)
374702Smckusic 	register struct	dinode	*dp;
38*4777Smckusic 	int (*fn1)();
391426Sroot {
404702Smckusic 	register int i;
411426Sroot 
424702Smckusic 	for (i = 0; i < NDADDR; i++) {
434702Smckusic 		if (dp->di_db[i] != 0)
444702Smckusic 			(*fn1)(dp->di_db[i]);
451426Sroot 	}
464702Smckusic 	for (i = 0; i < NIADDR; i++) {
474702Smckusic 		if (dp->di_ib[i] != 0)
48*4777Smckusic 			indir(dp->di_ib[i], fn1, i);
494702Smckusic 	}
501426Sroot }
511426Sroot 
52*4777Smckusic indir(d, fn1, n)
53*4777Smckusic 	daddr_t d;
54*4777Smckusic 	int (*fn1)();
55*4777Smckusic 	int n;
561426Sroot {
571426Sroot 	register i;
581426Sroot 	daddr_t	idblk[NINDIR];
591426Sroot 
601426Sroot 	bread(d, (char *)idblk, sizeof(idblk));
611426Sroot 	if(n <= 0) {
621426Sroot 		for(i=0; i<NINDIR; i++) {
631426Sroot 			d = idblk[i];
641426Sroot 			if(d != 0)
651426Sroot 				(*fn1)(d);
661426Sroot 		}
671426Sroot 	} else {
681426Sroot 		n--;
691426Sroot 		for(i=0; i<NINDIR; i++) {
701426Sroot 			d = idblk[i];
711426Sroot 			if(d != 0)
72*4777Smckusic 				indir(d, fn1, n);
731426Sroot 		}
741426Sroot 	}
751426Sroot }
761426Sroot 
771426Sroot mark(ip)
78*4777Smckusic 	struct dinode *ip;
791426Sroot {
801426Sroot 	register f;
811426Sroot 
821426Sroot 	f = ip->di_mode & IFMT;
831426Sroot 	if(f == 0)
841426Sroot 		return;
851426Sroot 	BIS(ino, clrmap);
861426Sroot 	if(f == IFDIR)
871426Sroot 		BIS(ino, dirmap);
881426Sroot 	if(ip->di_mtime >= spcl.c_ddate ||
891426Sroot 	   ip->di_ctime >= spcl.c_ddate) {
901426Sroot 		BIS(ino, nodmap);
911426Sroot 		if (f != IFREG){
921426Sroot 			esize += 1;
931426Sroot 			return;
941426Sroot 		}
951426Sroot 		est(ip);
961426Sroot 	}
971426Sroot }
981426Sroot 
991426Sroot add(ip)
100*4777Smckusic 	struct dinode *ip;
1011426Sroot {
1021426Sroot 
1031426Sroot 	if(BIT(ino, nodmap))
1041426Sroot 		return;
1051426Sroot 	nsubdir = 0;
1061426Sroot 	dadded = 0;
107*4777Smckusic 	icat(ip, dsrch);
1081426Sroot 	if(dadded) {
1091426Sroot 		BIS(ino, nodmap);
1101426Sroot 		est(ip);
1111426Sroot 		nadded++;
1121426Sroot 	}
1131426Sroot 	if(nsubdir == 0)
1141426Sroot 		if(!BIT(ino, nodmap))
1151426Sroot 			BIC(ino, dirmap);
1161426Sroot }
1171426Sroot 
1181426Sroot dump(ip)
119*4777Smckusic 	struct dinode *ip;
1201426Sroot {
121*4777Smckusic 	register int i;
122*4777Smckusic 	long size;
1231426Sroot 
1241426Sroot 	if(newtape) {
1251426Sroot 		newtape = 0;
1261426Sroot 		bitmap(nodmap, TS_BITS);
1271426Sroot 	}
1281426Sroot 	BIC(ino, nodmap);
1291426Sroot 	spcl.c_dinode = *ip;
1301426Sroot 	spcl.c_type = TS_INODE;
1311426Sroot 	spcl.c_count = 0;
1321426Sroot 	i = ip->di_mode & IFMT;
133*4777Smckusic 	if ((i != IFDIR && i != IFREG) || ip->di_size == 0) {
1341426Sroot 		spclrec();
1351426Sroot 		return;
1361426Sroot 	}
137*4777Smckusic 	if (ip->di_size > NDADDR * BSIZE)
138*4777Smckusic 		i = NDADDR * FRAG;
139*4777Smckusic 	else
140*4777Smckusic 		i = howmany(ip->di_size, FSIZE);
141*4777Smckusic 	blksout(&ip->di_db[0], i);
142*4777Smckusic 	size = ip->di_size - NDADDR * BSIZE;
143*4777Smckusic 	if (size <= 0)
144*4777Smckusic 		return;
145*4777Smckusic 	for (i = 0; i < NIADDR; i++) {
146*4777Smckusic 		dmpindir(ip->di_ib[i], i, &size);
147*4777Smckusic 		if (size <= 0)
148*4777Smckusic 			return;
149*4777Smckusic 	}
1501426Sroot }
1511426Sroot 
152*4777Smckusic dmpindir(blk, lvl, size)
153*4777Smckusic 	daddr_t blk;
154*4777Smckusic 	int lvl;
155*4777Smckusic 	long *size;
1561426Sroot {
157*4777Smckusic 	int i, cnt;
158*4777Smckusic 	daddr_t idblk[NINDIR];
1591426Sroot 
160*4777Smckusic 	if (blk != 0)
161*4777Smckusic 		bread(blk, (char *)idblk, sizeof(idblk));
162*4777Smckusic 	else
163*4777Smckusic 		blkclr(idblk, sizeof(idblk));
164*4777Smckusic 	if (lvl <= 0) {
165*4777Smckusic 		if (*size < NINDIR * BSIZE)
166*4777Smckusic 			cnt = howmany(*size, TP_BSIZE);
167*4777Smckusic 		else
168*4777Smckusic 			cnt = NINDIR * BLKING * FRAG;
169*4777Smckusic 		*size -= NINDIR * BSIZE;
170*4777Smckusic 		blksout(&idblk[0], cnt);
171*4777Smckusic 		return;
1721426Sroot 	}
173*4777Smckusic 	lvl--;
174*4777Smckusic 	for (i = 0; i < NINDIR; i++) {
175*4777Smckusic 		dmpindir(idblk[i], lvl, size);
176*4777Smckusic 		if (*size <= 0)
177*4777Smckusic 			return;
178*4777Smckusic 	}
1791426Sroot }
1801426Sroot 
181*4777Smckusic blksout(blkp, frags)
182*4777Smckusic 	daddr_t *blkp;
183*4777Smckusic 	int frags;
184*4777Smckusic {
185*4777Smckusic 	int i, j, count, blks;
186*4777Smckusic 
187*4777Smckusic 	blks = frags * BLKING;
188*4777Smckusic 	for (i = 0; i < blks; i += TP_NINDIR) {
189*4777Smckusic 		if (i + TP_NINDIR > blks)
190*4777Smckusic 			count = blks;
191*4777Smckusic 		else
192*4777Smckusic 			count = i + TP_NINDIR;
193*4777Smckusic 		for (j = i; j < count; j++)
194*4777Smckusic 			if (blkp[j / (BLKING * FRAG)] != 0)
195*4777Smckusic 				spcl.c_addr[j - i] = 1;
196*4777Smckusic 			else
197*4777Smckusic 				spcl.c_addr[j - i] = 0;
198*4777Smckusic 		spcl.c_count = count - i;
199*4777Smckusic 		spclrec();
200*4777Smckusic 		for (j = i; j < count; j += (BLKING * FRAG))
201*4777Smckusic 			if (blkp[j / (BLKING * FRAG)] != 0)
202*4777Smckusic 				if (j + (BLKING * FRAG) <= count)
203*4777Smckusic 					dmpblk(blkp[j / (BLKING * FRAG)],
204*4777Smckusic 					    BSIZE);
205*4777Smckusic 				else
206*4777Smckusic 					dmpblk(blkp[j / (BLKING * FRAG)],
207*4777Smckusic 					    (count - j) * TP_BSIZE);
208*4777Smckusic 		spcl.c_type = TS_ADDR;
209*4777Smckusic 	}
210*4777Smckusic }
211*4777Smckusic 
2121426Sroot bitmap(map, typ)
213*4777Smckusic 	short *map;
2141426Sroot {
2151426Sroot 	register i, n;
2161426Sroot 	char *cp;
2171426Sroot 
2181426Sroot 	n = -1;
2191426Sroot 	for(i=0; i<MSIZ; i++)
2201426Sroot 		if(map[i])
2211426Sroot 			n = i;
2221426Sroot 	if(n < 0)
2231426Sroot 		return;
2241426Sroot 	spcl.c_type = typ;
225*4777Smckusic 	spcl.c_count = (n*sizeof(map[0]) + TP_BSIZE)/TP_BSIZE;
2261426Sroot 	spclrec();
2271426Sroot 	cp = (char *)map;
2281426Sroot 	for(i=0; i<spcl.c_count; i++) {
2291426Sroot 		taprec(cp);
230*4777Smckusic 		cp += TP_BSIZE;
2311426Sroot 	}
2321426Sroot }
2331426Sroot 
2341426Sroot spclrec()
2351426Sroot {
236*4777Smckusic 	register int s, i, *ip;
2371426Sroot 
2381426Sroot 	spcl.c_inumber = ino;
2391426Sroot 	spcl.c_magic = MAGIC;
2401426Sroot 	spcl.c_checksum = 0;
2411426Sroot 	ip = (int *)&spcl;
2421426Sroot 	s = 0;
243*4777Smckusic 	for(i = 0; i < sizeof(union u_spcl)/sizeof(int); i++)
2441426Sroot 		s += *ip++;
2451426Sroot 	spcl.c_checksum = CHECKSUM - s;
2461426Sroot 	taprec((char *)&spcl);
2471426Sroot }
2481426Sroot 
2491426Sroot dsrch(d)
250*4777Smckusic 	daddr_t d;
2511426Sroot {
2521426Sroot 	register char *cp;
2531426Sroot 	register i;
2541426Sroot 	register ino_t in;
2551426Sroot 	struct direct dblk[DIRPB];
2561426Sroot 
2571426Sroot 	if(dadded)
2581426Sroot 		return;
2591426Sroot 	bread(d, (char *)dblk, sizeof(dblk));
2601426Sroot 	for(i=0; i<DIRPB; i++) {
2611426Sroot 		in = dblk[i].d_ino;
2621426Sroot 		if(in == 0)
2631426Sroot 			continue;
2641426Sroot 		cp = dblk[i].d_name;
2651426Sroot 		if(cp[0] == '.') {
2661426Sroot 			if(cp[1] == '\0')
2671426Sroot 				continue;
2681426Sroot 			if(cp[1] == '.' && cp[2] == '\0')
2691426Sroot 				continue;
2701426Sroot 		}
2711426Sroot 		if(BIT(in, nodmap)) {
2721426Sroot 			dadded++;
2731426Sroot 			return;
2741426Sroot 		}
2751426Sroot 		if(BIT(in, dirmap))
2761426Sroot 			nsubdir++;
2771426Sroot 	}
2781426Sroot }
2791426Sroot 
2804702Smckusic struct dinode *
2814702Smckusic getino(ino)
2824702Smckusic 	daddr_t ino;
2834702Smckusic {
2844702Smckusic 	static daddr_t minino, maxino;
2854702Smckusic 	static struct dinode itab[INOPB];
2864702Smckusic 
2874702Smckusic 	if (ino >= minino && ino < maxino) {
2884702Smckusic 		return (&itab[ino - minino]);
2894702Smckusic 	}
2904702Smckusic 	bread(itod(ino, &sblock), itab, BSIZE);
2914702Smckusic 	minino = ino - (ino % INOPB);
2924702Smckusic 	maxino = minino + INOPB;
2934702Smckusic 	return (&itab[ino - minino]);
2944702Smckusic }
2954702Smckusic 
2961426Sroot int	breaderrors = 0;
2971426Sroot #define	BREADEMAX 32
2981426Sroot 
2991426Sroot bread(da, ba, c)
3001426Sroot 	daddr_t da;
3011426Sroot 	char *ba;
3021426Sroot 	int	c;
3031426Sroot {
3041426Sroot 	register n;
3051426Sroot 	register	regc;
3061426Sroot 
3074702Smckusic 	if (lseek(fi, (long)(da*FSIZE), 0) < 0){
3081426Sroot 		msg("bread: lseek fails\n");
3091426Sroot 	}
3101426Sroot 	regc = c;	/* put c someplace safe; it gets clobbered */
3111426Sroot 	n = read(fi, ba, c);
3121426Sroot 	if(n != c || regc != c){
3131426Sroot 		msg("(This should not happen)bread from %s [block %d]: c=0x%x, regc=0x%x, &c=0x%x, n=0x%x\n",
3141426Sroot 			disk, da, c, regc, &c, n);
3151426Sroot #ifdef ERNIE
3161426Sroot 		msg("Notify Robert Henry of this error.\n");
3171426Sroot #endif
3181426Sroot 		if (++breaderrors > BREADEMAX){
3191426Sroot 			msg("More than %d block read errors from %d\n",
3201426Sroot 				BREADEMAX, disk);
3211426Sroot 			broadcast("DUMP IS AILING!\n");
3221426Sroot 			msg("This is an unrecoverable error.\n");
3231426Sroot 			if (!query("Do you want to attempt to continue?")){
3241426Sroot 				dumpabort();
3251426Sroot 				/*NOTREACHED*/
3261426Sroot 			} else
3271426Sroot 				breaderrors = 0;
3281426Sroot 		}
3291426Sroot 	}
3301426Sroot }
3311426Sroot 
3321426Sroot CLR(map)
333*4777Smckusic 	register short *map;
3341426Sroot {
3351426Sroot 	register n;
3361426Sroot 
3371426Sroot 	n = MSIZ;
3381426Sroot 	do
3391426Sroot 		*map++ = 0;
3401426Sroot 	while(--n);
3411426Sroot }
3421426Sroot 
343*4777Smckusic blkclr(cp, size)
344*4777Smckusic 	char *cp;
345*4777Smckusic 	long size;
346*4777Smckusic {
347*4777Smckusic 	asm("movc5	$0,(r0),$0,8(ap),*4(ap)");
348*4777Smckusic }
349