xref: /csrg-svn/sbin/dump/traverse.c (revision 8368)
1*8368Smckusick static	char *sccsid = "@(#)traverse.c	1.9 (Berkeley) 10/07/82";
25329Smckusic 
31426Sroot #include "dump.h"
46883Ssam #include <dir.h>
51426Sroot 
61426Sroot pass(fn, map)
74702Smckusic 	int (*fn)();
85329Smckusic 	char *map;
91426Sroot {
104702Smckusic 	struct dinode *dp;
111426Sroot 	int bits;
124702Smckusic 	ino_t maxino;
131426Sroot 
145329Smckusic 	maxino = sblock->fs_ipg * sblock->fs_ncg - 1;
154702Smckusic 	for (ino = 0; ino < maxino; ) {
165329Smckusic 		if((ino % NBBY) == 0) {
174702Smckusic 			bits = ~0;
184702Smckusic 			if(map != NULL)
194702Smckusic 				bits = *map++;
201426Sroot 		}
214702Smckusic 		ino++;
224702Smckusic 		if(bits & 1) {
234702Smckusic 			dp = getino(ino);
244702Smckusic 			(*fn)(dp);
254702Smckusic 		}
264702Smckusic 		bits >>= 1;
271426Sroot 	}
281426Sroot }
291426Sroot 
301426Sroot mark(ip)
314777Smckusic 	struct dinode *ip;
321426Sroot {
331426Sroot 	register f;
341426Sroot 
351426Sroot 	f = ip->di_mode & IFMT;
361426Sroot 	if(f == 0)
371426Sroot 		return;
381426Sroot 	BIS(ino, clrmap);
391426Sroot 	if(f == IFDIR)
401426Sroot 		BIS(ino, dirmap);
415329Smckusic 	if ((ip->di_mtime >= spcl.c_ddate || ip->di_ctime >= spcl.c_ddate) &&
425329Smckusic 	    !BIT(ino, nodmap)) {
431426Sroot 		BIS(ino, nodmap);
446288Smckusick 		if (f != IFREG && f != IFDIR && f != IFLNK) {
451426Sroot 			esize += 1;
461426Sroot 			return;
471426Sroot 		}
481426Sroot 		est(ip);
491426Sroot 	}
501426Sroot }
511426Sroot 
521426Sroot add(ip)
535329Smckusic 	register struct	dinode	*ip;
541426Sroot {
555329Smckusic 	register int i;
561426Sroot 
571426Sroot 	if(BIT(ino, nodmap))
581426Sroot 		return;
591426Sroot 	nsubdir = 0;
601426Sroot 	dadded = 0;
615329Smckusic 	for (i = 0; i < NDADDR; i++) {
625329Smckusic 		if (ip->di_db[i] != 0)
635329Smckusic 			dsrch(ip->di_db[i], dblksize(sblock, ip, i));
645329Smckusic 	}
655329Smckusic 	for (i = 0; i < NIADDR; i++) {
665329Smckusic 		if (ip->di_ib[i] != 0)
675329Smckusic 			indir(ip->di_ib[i], i);
685329Smckusic 	}
691426Sroot 	if(dadded) {
701426Sroot 		nadded++;
715329Smckusic 		if (!BIT(ino, nodmap)) {
725329Smckusic 			BIS(ino, nodmap);
735329Smckusic 			est(ip);
745329Smckusic 		}
751426Sroot 	}
761426Sroot 	if(nsubdir == 0)
771426Sroot 		if(!BIT(ino, nodmap))
781426Sroot 			BIC(ino, dirmap);
791426Sroot }
801426Sroot 
815329Smckusic indir(d, n)
825329Smckusic 	daddr_t d;
835329Smckusic 	int n;
845329Smckusic {
855329Smckusic 	register i;
865329Smckusic 	daddr_t	idblk[MAXNINDIR];
875329Smckusic 
885329Smckusic 	bread(fsbtodb(sblock, d), (char *)idblk, sblock->fs_bsize);
895329Smckusic 	if(n <= 0) {
905329Smckusic 		for(i=0; i < NINDIR(sblock); i++) {
915329Smckusic 			d = idblk[i];
925329Smckusic 			if(d != 0)
935329Smckusic 				dsrch(d, sblock->fs_bsize);
945329Smckusic 		}
955329Smckusic 	} else {
965329Smckusic 		n--;
975329Smckusic 		for(i=0; i < NINDIR(sblock); i++) {
985329Smckusic 			d = idblk[i];
995329Smckusic 			if(d != 0)
1005329Smckusic 				indir(d, n);
1015329Smckusic 		}
1025329Smckusic 	}
1035329Smckusic }
1045329Smckusic 
1051426Sroot dump(ip)
1064777Smckusic 	struct dinode *ip;
1071426Sroot {
1084777Smckusic 	register int i;
1094777Smckusic 	long size;
1101426Sroot 
1111426Sroot 	if(newtape) {
1121426Sroot 		newtape = 0;
1131426Sroot 		bitmap(nodmap, TS_BITS);
1141426Sroot 	}
1151426Sroot 	BIC(ino, nodmap);
1161426Sroot 	spcl.c_dinode = *ip;
1171426Sroot 	spcl.c_type = TS_INODE;
1181426Sroot 	spcl.c_count = 0;
1191426Sroot 	i = ip->di_mode & IFMT;
1206288Smckusick 	if ((i != IFDIR && i != IFREG && i != IFLNK) || ip->di_size == 0) {
1211426Sroot 		spclrec();
1221426Sroot 		return;
1231426Sroot 	}
1245329Smckusic 	if (ip->di_size > NDADDR * sblock->fs_bsize)
1255329Smckusic 		i = NDADDR * sblock->fs_frag;
1264777Smckusic 	else
1275329Smckusic 		i = howmany(ip->di_size, sblock->fs_fsize);
1284777Smckusic 	blksout(&ip->di_db[0], i);
1295329Smckusic 	size = ip->di_size - NDADDR * sblock->fs_bsize;
1304777Smckusic 	if (size <= 0)
1314777Smckusic 		return;
1324777Smckusic 	for (i = 0; i < NIADDR; i++) {
1334777Smckusic 		dmpindir(ip->di_ib[i], i, &size);
1344777Smckusic 		if (size <= 0)
1354777Smckusic 			return;
1364777Smckusic 	}
1371426Sroot }
1381426Sroot 
1394777Smckusic dmpindir(blk, lvl, size)
1404777Smckusic 	daddr_t blk;
1414777Smckusic 	int lvl;
1424777Smckusic 	long *size;
1431426Sroot {
1444777Smckusic 	int i, cnt;
1455329Smckusic 	daddr_t idblk[MAXNINDIR];
1461426Sroot 
1474777Smckusic 	if (blk != 0)
1485329Smckusic 		bread(fsbtodb(sblock, blk), (char *)idblk, sblock->fs_bsize);
1494777Smckusic 	else
1505329Smckusic 		blkclr(idblk, sblock->fs_bsize);
1514777Smckusic 	if (lvl <= 0) {
1525329Smckusic 		if (*size < NINDIR(sblock) * sblock->fs_bsize)
1535329Smckusic 			cnt = howmany(*size, sblock->fs_fsize);
1544777Smckusic 		else
1555329Smckusic 			cnt = NINDIR(sblock) * sblock->fs_frag;
1565329Smckusic 		*size -= NINDIR(sblock) * sblock->fs_bsize;
1574777Smckusic 		blksout(&idblk[0], cnt);
1584777Smckusic 		return;
1591426Sroot 	}
1604777Smckusic 	lvl--;
1615329Smckusic 	for (i = 0; i < NINDIR(sblock); i++) {
1624777Smckusic 		dmpindir(idblk[i], lvl, size);
1634777Smckusic 		if (*size <= 0)
1644777Smckusic 			return;
1654777Smckusic 	}
1661426Sroot }
1671426Sroot 
1684777Smckusic blksout(blkp, frags)
1694777Smckusic 	daddr_t *blkp;
1704777Smckusic 	int frags;
1714777Smckusic {
1725329Smckusic 	int i, j, count, blks, tbperdb;
1734777Smckusic 
1745329Smckusic 	blks = frags * BLKING(sblock);
1755329Smckusic 	tbperdb = BLKING(sblock) * sblock->fs_frag;
1764777Smckusic 	for (i = 0; i < blks; i += TP_NINDIR) {
1774777Smckusic 		if (i + TP_NINDIR > blks)
1784777Smckusic 			count = blks;
1794777Smckusic 		else
1804777Smckusic 			count = i + TP_NINDIR;
1814777Smckusic 		for (j = i; j < count; j++)
1825329Smckusic 			if (blkp[j / tbperdb] != 0)
1834777Smckusic 				spcl.c_addr[j - i] = 1;
1844777Smckusic 			else
1854777Smckusic 				spcl.c_addr[j - i] = 0;
1864777Smckusic 		spcl.c_count = count - i;
1874777Smckusic 		spclrec();
1885329Smckusic 		for (j = i; j < count; j += tbperdb)
1895329Smckusic 			if (blkp[j / tbperdb] != 0)
1905329Smckusic 				if (j + tbperdb <= count)
1915329Smckusic 					dmpblk(blkp[j / tbperdb],
1925329Smckusic 					    sblock->fs_bsize);
1934777Smckusic 				else
1945329Smckusic 					dmpblk(blkp[j / tbperdb],
1954777Smckusic 					    (count - j) * TP_BSIZE);
1964777Smckusic 		spcl.c_type = TS_ADDR;
1974777Smckusic 	}
1984777Smckusic }
1994777Smckusic 
2001426Sroot bitmap(map, typ)
2015329Smckusic 	char *map;
2021426Sroot {
2031426Sroot 	register i, n;
2041426Sroot 	char *cp;
2051426Sroot 
2061426Sroot 	n = -1;
2075329Smckusic 	for (i = 0; i < msiz; i++)
2081426Sroot 		if(map[i])
2091426Sroot 			n = i;
2105329Smckusic 	if (n < 0)
2111426Sroot 		return;
2125329Smckusic 	n++;
2131426Sroot 	spcl.c_type = typ;
2145329Smckusic 	spcl.c_count = howmany(n * sizeof(map[0]), TP_BSIZE);
2151426Sroot 	spclrec();
2165329Smckusic 	for (i = 0, cp = map; i < spcl.c_count; i++, cp += TP_BSIZE)
2171426Sroot 		taprec(cp);
2181426Sroot }
2191426Sroot 
2201426Sroot spclrec()
2211426Sroot {
2224777Smckusic 	register int s, i, *ip;
2231426Sroot 
2241426Sroot 	spcl.c_inumber = ino;
225*8368Smckusick 	spcl.c_magic = NFS_MAGIC;
2261426Sroot 	spcl.c_checksum = 0;
2271426Sroot 	ip = (int *)&spcl;
2281426Sroot 	s = 0;
2294777Smckusic 	for(i = 0; i < sizeof(union u_spcl)/sizeof(int); i++)
2301426Sroot 		s += *ip++;
2311426Sroot 	spcl.c_checksum = CHECKSUM - s;
2321426Sroot 	taprec((char *)&spcl);
2331426Sroot }
2341426Sroot 
2355329Smckusic dsrch(d, size)
2364777Smckusic 	daddr_t d;
2375329Smckusic 	int size;
2381426Sroot {
2395942Smckusic 	register struct direct *dp;
2405942Smckusic 	long loc;
2415942Smckusic 	char dblk[MAXBSIZE];
2421426Sroot 
2431426Sroot 	if(dadded)
2441426Sroot 		return;
2455942Smckusic 	bread(fsbtodb(sblock, d), dblk, size);
2465942Smckusic 	for (loc = 0; loc < size; ) {
2475942Smckusic 		dp = (struct direct *)(dblk + loc);
2485942Smckusic 		if (dp->d_reclen == 0)
2495942Smckusic 			break;
2505942Smckusic 		loc += dp->d_reclen;
2515942Smckusic 		if(dp->d_ino == 0)
2521426Sroot 			continue;
2535942Smckusic 		if(dp->d_name[0] == '.') {
2545942Smckusic 			if(dp->d_name[1] == '\0')
2551426Sroot 				continue;
2565942Smckusic 			if(dp->d_name[1] == '.' && dp->d_name[2] == '\0')
2571426Sroot 				continue;
2581426Sroot 		}
2595942Smckusic 		if(BIT(dp->d_ino, nodmap)) {
2601426Sroot 			dadded++;
2611426Sroot 			return;
2621426Sroot 		}
2635942Smckusic 		if(BIT(dp->d_ino, dirmap))
2641426Sroot 			nsubdir++;
2651426Sroot 	}
2661426Sroot }
2671426Sroot 
2684702Smckusic struct dinode *
2694702Smckusic getino(ino)
2704702Smckusic 	daddr_t ino;
2714702Smckusic {
2724702Smckusic 	static daddr_t minino, maxino;
2735329Smckusic 	static struct dinode itab[MAXINOPB];
2744702Smckusic 
2754702Smckusic 	if (ino >= minino && ino < maxino) {
2764702Smckusic 		return (&itab[ino - minino]);
2774702Smckusic 	}
2785386Smckusic 	bread(fsbtodb(sblock, itod(sblock, ino)), itab, sblock->fs_bsize);
2795329Smckusic 	minino = ino - (ino % INOPB(sblock));
2805329Smckusic 	maxino = minino + INOPB(sblock);
2814702Smckusic 	return (&itab[ino - minino]);
2824702Smckusic }
2834702Smckusic 
2841426Sroot int	breaderrors = 0;
2851426Sroot #define	BREADEMAX 32
2861426Sroot 
2871426Sroot bread(da, ba, c)
2881426Sroot 	daddr_t da;
2891426Sroot 	char *ba;
2901426Sroot 	int	c;
2911426Sroot {
2921426Sroot 	register n;
2931426Sroot 	register	regc;
2941426Sroot 
2955329Smckusic 	if (lseek(fi, (long)(da * DEV_BSIZE), 0) < 0){
2961426Sroot 		msg("bread: lseek fails\n");
2971426Sroot 	}
2981426Sroot 	regc = c;	/* put c someplace safe; it gets clobbered */
2991426Sroot 	n = read(fi, ba, c);
3005329Smckusic 	if (n != c || regc != c) {
3011426Sroot 		msg("(This should not happen)bread from %s [block %d]: c=0x%x, regc=0x%x, &c=0x%x, n=0x%x\n",
3021426Sroot 			disk, da, c, regc, &c, n);
3031426Sroot #ifdef ERNIE
3041426Sroot 		msg("Notify Robert Henry of this error.\n");
3051426Sroot #endif
3061426Sroot 		if (++breaderrors > BREADEMAX){
3071426Sroot 			msg("More than %d block read errors from %d\n",
3081426Sroot 				BREADEMAX, disk);
3091426Sroot 			broadcast("DUMP IS AILING!\n");
3101426Sroot 			msg("This is an unrecoverable error.\n");
3111426Sroot 			if (!query("Do you want to attempt to continue?")){
3121426Sroot 				dumpabort();
3131426Sroot 				/*NOTREACHED*/
3141426Sroot 			} else
3151426Sroot 				breaderrors = 0;
3161426Sroot 		}
3171426Sroot 	}
3181426Sroot }
3191426Sroot 
3204777Smckusic blkclr(cp, size)
3214777Smckusic 	char *cp;
3224777Smckusic 	long size;
3234777Smckusic {
3244777Smckusic 	asm("movc5	$0,(r0),$0,8(ap),*4(ap)");
3254777Smckusic }
326