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