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