1*9403Smckusick static char *sccsid = "@(#)traverse.c 1.12 (Berkeley) 12/02/82"; 25329Smckusic 31426Sroot #include "dump.h" 41426Sroot 51426Sroot pass(fn, map) 64702Smckusic int (*fn)(); 75329Smckusic char *map; 81426Sroot { 94702Smckusic struct dinode *dp; 101426Sroot int bits; 114702Smckusic ino_t maxino; 121426Sroot 135329Smckusic maxino = sblock->fs_ipg * sblock->fs_ncg - 1; 144702Smckusic for (ino = 0; ino < maxino; ) { 155329Smckusic 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); 405329Smckusic if ((ip->di_mtime >= spcl.c_ddate || ip->di_ctime >= spcl.c_ddate) && 415329Smckusic !BIT(ino, nodmap)) { 421426Sroot BIS(ino, nodmap); 436288Smckusick if (f != IFREG && f != IFDIR && f != IFLNK) { 441426Sroot esize += 1; 451426Sroot return; 461426Sroot } 471426Sroot est(ip); 481426Sroot } 491426Sroot } 501426Sroot 511426Sroot add(ip) 525329Smckusic register struct dinode *ip; 531426Sroot { 545329Smckusic register int i; 551426Sroot 561426Sroot if(BIT(ino, nodmap)) 571426Sroot return; 581426Sroot nsubdir = 0; 591426Sroot dadded = 0; 605329Smckusic for (i = 0; i < NDADDR; i++) { 615329Smckusic if (ip->di_db[i] != 0) 625329Smckusic dsrch(ip->di_db[i], dblksize(sblock, ip, i)); 635329Smckusic } 645329Smckusic for (i = 0; i < NIADDR; i++) { 655329Smckusic if (ip->di_ib[i] != 0) 665329Smckusic indir(ip->di_ib[i], i); 675329Smckusic } 681426Sroot if(dadded) { 691426Sroot nadded++; 705329Smckusic if (!BIT(ino, nodmap)) { 715329Smckusic BIS(ino, nodmap); 725329Smckusic est(ip); 735329Smckusic } 741426Sroot } 751426Sroot if(nsubdir == 0) 761426Sroot if(!BIT(ino, nodmap)) 771426Sroot BIC(ino, dirmap); 781426Sroot } 791426Sroot 805329Smckusic indir(d, n) 815329Smckusic daddr_t d; 825329Smckusic int n; 835329Smckusic { 845329Smckusic register i; 855329Smckusic daddr_t idblk[MAXNINDIR]; 865329Smckusic 875329Smckusic bread(fsbtodb(sblock, d), (char *)idblk, sblock->fs_bsize); 885329Smckusic if(n <= 0) { 895329Smckusic for(i=0; i < NINDIR(sblock); i++) { 905329Smckusic d = idblk[i]; 915329Smckusic if(d != 0) 925329Smckusic dsrch(d, sblock->fs_bsize); 935329Smckusic } 945329Smckusic } else { 955329Smckusic n--; 965329Smckusic for(i=0; i < NINDIR(sblock); i++) { 975329Smckusic d = idblk[i]; 985329Smckusic if(d != 0) 995329Smckusic indir(d, n); 1005329Smckusic } 1015329Smckusic } 1025329Smckusic } 1035329Smckusic 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; 1196288Smckusick if ((i != IFDIR && i != IFREG && i != IFLNK) || ip->di_size == 0) { 1201426Sroot spclrec(); 1211426Sroot return; 1221426Sroot } 1235329Smckusic if (ip->di_size > NDADDR * sblock->fs_bsize) 1245329Smckusic i = NDADDR * sblock->fs_frag; 1254777Smckusic else 1265329Smckusic i = howmany(ip->di_size, sblock->fs_fsize); 1274777Smckusic blksout(&ip->di_db[0], i); 1285329Smckusic 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; 1445329Smckusic daddr_t idblk[MAXNINDIR]; 1451426Sroot 1464777Smckusic if (blk != 0) 1475329Smckusic bread(fsbtodb(sblock, blk), (char *)idblk, sblock->fs_bsize); 1484777Smckusic else 1495329Smckusic blkclr(idblk, sblock->fs_bsize); 1504777Smckusic if (lvl <= 0) { 1515329Smckusic if (*size < NINDIR(sblock) * sblock->fs_bsize) 1525329Smckusic cnt = howmany(*size, sblock->fs_fsize); 1534777Smckusic else 1545329Smckusic cnt = NINDIR(sblock) * sblock->fs_frag; 1555329Smckusic *size -= NINDIR(sblock) * sblock->fs_bsize; 1564777Smckusic blksout(&idblk[0], cnt); 1574777Smckusic return; 1581426Sroot } 1594777Smckusic lvl--; 1605329Smckusic 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 { 1715329Smckusic int i, j, count, blks, tbperdb; 1724777Smckusic 173*9403Smckusick blks = howmany(frags * sblock->fs_fsize, TP_BSIZE); 1748537Smckusick tbperdb = sblock->fs_bsize / TP_BSIZE; 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++) 1815329Smckusic 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(); 1875329Smckusic for (j = i; j < count; j += tbperdb) 1885329Smckusic if (blkp[j / tbperdb] != 0) 1895329Smckusic if (j + tbperdb <= count) 1905329Smckusic dmpblk(blkp[j / tbperdb], 1915329Smckusic sblock->fs_bsize); 1924777Smckusic else 1935329Smckusic dmpblk(blkp[j / tbperdb], 1944777Smckusic (count - j) * TP_BSIZE); 1954777Smckusic spcl.c_type = TS_ADDR; 1964777Smckusic } 1974777Smckusic } 1984777Smckusic 1991426Sroot bitmap(map, typ) 2005329Smckusic char *map; 2011426Sroot { 2021426Sroot register i, n; 2031426Sroot char *cp; 2041426Sroot 2051426Sroot n = -1; 2065329Smckusic for (i = 0; i < msiz; i++) 2071426Sroot if(map[i]) 2081426Sroot n = i; 2095329Smckusic if (n < 0) 2101426Sroot return; 2115329Smckusic n++; 2121426Sroot spcl.c_type = typ; 2135329Smckusic spcl.c_count = howmany(n * sizeof(map[0]), TP_BSIZE); 2141426Sroot spclrec(); 2155329Smckusic 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; 2248368Smckusick spcl.c_magic = NFS_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 2345329Smckusic dsrch(d, size) 2354777Smckusic daddr_t d; 2365329Smckusic int size; 2371426Sroot { 2385942Smckusic register struct direct *dp; 2395942Smckusic long loc; 2405942Smckusic char dblk[MAXBSIZE]; 2411426Sroot 2421426Sroot if(dadded) 2431426Sroot return; 2445942Smckusic bread(fsbtodb(sblock, d), dblk, size); 2455942Smckusic for (loc = 0; loc < size; ) { 2465942Smckusic dp = (struct direct *)(dblk + loc); 2475942Smckusic if (dp->d_reclen == 0) 2485942Smckusic break; 2495942Smckusic loc += dp->d_reclen; 2505942Smckusic if(dp->d_ino == 0) 2511426Sroot continue; 2525942Smckusic if(dp->d_name[0] == '.') { 2535942Smckusic if(dp->d_name[1] == '\0') 2541426Sroot continue; 2555942Smckusic if(dp->d_name[1] == '.' && dp->d_name[2] == '\0') 2561426Sroot continue; 2571426Sroot } 2585942Smckusic if(BIT(dp->d_ino, nodmap)) { 2591426Sroot dadded++; 2601426Sroot return; 2611426Sroot } 2625942Smckusic if(BIT(dp->d_ino, dirmap)) 2631426Sroot nsubdir++; 2641426Sroot } 2651426Sroot } 2661426Sroot 2674702Smckusic struct dinode * 2684702Smckusic getino(ino) 2694702Smckusic daddr_t ino; 2704702Smckusic { 2714702Smckusic static daddr_t minino, maxino; 2725329Smckusic static struct dinode itab[MAXINOPB]; 2734702Smckusic 2744702Smckusic if (ino >= minino && ino < maxino) { 2754702Smckusic return (&itab[ino - minino]); 2764702Smckusic } 2775386Smckusic bread(fsbtodb(sblock, itod(sblock, ino)), itab, sblock->fs_bsize); 2785329Smckusic minino = ino - (ino % INOPB(sblock)); 2795329Smckusic maxino = minino + INOPB(sblock); 2804702Smckusic return (&itab[ino - minino]); 2814702Smckusic } 2824702Smckusic 2831426Sroot int breaderrors = 0; 2841426Sroot #define BREADEMAX 32 2851426Sroot 2861426Sroot bread(da, ba, c) 2871426Sroot daddr_t da; 2881426Sroot char *ba; 2891426Sroot int c; 2901426Sroot { 2911426Sroot register n; 2921426Sroot register regc; 2931426Sroot 2945329Smckusic if (lseek(fi, (long)(da * DEV_BSIZE), 0) < 0){ 2951426Sroot msg("bread: lseek fails\n"); 2961426Sroot } 2971426Sroot regc = c; /* put c someplace safe; it gets clobbered */ 2981426Sroot n = read(fi, ba, c); 2995329Smckusic if (n != c || regc != c) { 3001426Sroot msg("(This should not happen)bread from %s [block %d]: c=0x%x, regc=0x%x, &c=0x%x, n=0x%x\n", 3011426Sroot disk, da, c, regc, &c, n); 3021426Sroot #ifdef ERNIE 3031426Sroot msg("Notify Robert Henry of this error.\n"); 3041426Sroot #endif 3051426Sroot if (++breaderrors > BREADEMAX){ 3061426Sroot msg("More than %d block read errors from %d\n", 3071426Sroot BREADEMAX, disk); 3081426Sroot broadcast("DUMP IS AILING!\n"); 3091426Sroot msg("This is an unrecoverable error.\n"); 3101426Sroot if (!query("Do you want to attempt to continue?")){ 3111426Sroot dumpabort(); 3121426Sroot /*NOTREACHED*/ 3131426Sroot } else 3141426Sroot breaderrors = 0; 3151426Sroot } 3161426Sroot } 3171426Sroot } 3181426Sroot 3194777Smckusic blkclr(cp, size) 3204777Smckusic char *cp; 3214777Smckusic long size; 3224777Smckusic { 3234777Smckusic asm("movc5 $0,(r0),$0,8(ap),*4(ap)"); 3244777Smckusic } 325