|
|
1.1.1.2 ! root 1: /* ! 2: * Copyright (c) 1980 Regents of the University of California. ! 3: * All rights reserved. The Berkeley software License Agreement ! 4: * specifies the terms and conditions for redistribution. ! 5: */ ! 6: ! 7: #ifndef lint ! 8: static char sccsid[] = "@(#)dumptraverse.c 5.2 (Berkeley) 8/5/85"; ! 9: #endif not lint 1.1 root 10: 11: #include "dump.h" 12: 13: pass(fn, map) 14: int (*fn)(); 15: char *map; 16: { 17: struct dinode *dp; 18: int bits; 19: ino_t maxino; 20: 21: maxino = sblock->fs_ipg * sblock->fs_ncg - 1; 22: for (ino = 0; ino < maxino; ) { 23: if((ino % NBBY) == 0) { 24: bits = ~0; 25: if(map != NULL) 26: bits = *map++; 27: } 28: ino++; 29: if(bits & 1) { 30: dp = getino(ino); 31: (*fn)(dp); 32: } 33: bits >>= 1; 34: } 35: } 36: 37: mark(ip) 38: struct dinode *ip; 39: { 40: register f; 41: 42: f = ip->di_mode & IFMT; 43: if(f == 0) 44: return; 45: BIS(ino, clrmap); 46: if(f == IFDIR) 47: BIS(ino, dirmap); 48: if ((ip->di_mtime >= spcl.c_ddate || ip->di_ctime >= spcl.c_ddate) && 49: !BIT(ino, nodmap)) { 50: BIS(ino, nodmap); 51: if (f != IFREG && f != IFDIR && f != IFLNK) { 52: esize += 1; 53: return; 54: } 55: est(ip); 56: } 57: } 58: 59: add(ip) 60: register struct dinode *ip; 61: { 62: register int i; 63: long filesize; 64: 65: if(BIT(ino, nodmap)) 66: return; 67: nsubdir = 0; 68: dadded = 0; 69: filesize = ip->di_size; 70: for (i = 0; i < NDADDR; i++) { 71: if (ip->di_db[i] != 0) 72: dsrch(ip->di_db[i], dblksize(sblock, ip, i), filesize); 73: filesize -= sblock->fs_bsize; 74: } 75: for (i = 0; i < NIADDR; i++) { 76: if (ip->di_ib[i] != 0) 77: indir(ip->di_ib[i], i, &filesize); 78: } 79: if(dadded) { 80: nadded++; 81: if (!BIT(ino, nodmap)) { 82: BIS(ino, nodmap); 83: est(ip); 84: } 85: } 86: if(nsubdir == 0) 87: if(!BIT(ino, nodmap)) 88: BIC(ino, dirmap); 89: } 90: 91: indir(d, n, filesize) 92: daddr_t d; 93: int n, *filesize; 94: { 95: register i; 96: daddr_t idblk[MAXNINDIR]; 97: 98: bread(fsbtodb(sblock, d), (char *)idblk, sblock->fs_bsize); 99: if(n <= 0) { 100: for(i=0; i < NINDIR(sblock); i++) { 101: d = idblk[i]; 102: if(d != 0) 103: dsrch(d, sblock->fs_bsize, *filesize); 104: *filesize -= sblock->fs_bsize; 105: } 106: } else { 107: n--; 108: for(i=0; i < NINDIR(sblock); i++) { 109: d = idblk[i]; 110: if(d != 0) 111: indir(d, n, filesize); 112: } 113: } 114: } 115: 116: dirdump(ip) 117: struct dinode *ip; 118: { 119: /* watchout for dir inodes deleted and maybe reallocated */ 120: if ((ip->di_mode & IFMT) != IFDIR) 121: return; 122: dump(ip); 123: } 124: 125: dump(ip) 126: struct dinode *ip; 127: { 128: register int i; 129: long size; 130: 131: if(newtape) { 132: newtape = 0; 133: bitmap(nodmap, TS_BITS); 134: } 135: BIC(ino, nodmap); 136: spcl.c_dinode = *ip; 137: spcl.c_type = TS_INODE; 138: spcl.c_count = 0; 139: i = ip->di_mode & IFMT; 140: if (i == 0) /* free inode */ 141: return; 142: if ((i != IFDIR && i != IFREG && i != IFLNK) || ip->di_size == 0) { 143: spclrec(); 144: return; 145: } 146: if (ip->di_size > NDADDR * sblock->fs_bsize) 147: i = NDADDR * sblock->fs_frag; 148: else 149: i = howmany(ip->di_size, sblock->fs_fsize); 150: blksout(&ip->di_db[0], i); 151: size = ip->di_size - NDADDR * sblock->fs_bsize; 152: if (size <= 0) 153: return; 154: for (i = 0; i < NIADDR; i++) { 155: dmpindir(ip->di_ib[i], i, &size); 156: if (size <= 0) 157: return; 158: } 159: } 160: 161: dmpindir(blk, lvl, size) 162: daddr_t blk; 163: int lvl; 164: long *size; 165: { 166: int i, cnt; 167: daddr_t idblk[MAXNINDIR]; 168: 169: if (blk != 0) 170: bread(fsbtodb(sblock, blk), (char *)idblk, sblock->fs_bsize); 171: else 172: bzero(idblk, sblock->fs_bsize); 173: if (lvl <= 0) { 174: if (*size < NINDIR(sblock) * sblock->fs_bsize) 175: cnt = howmany(*size, sblock->fs_fsize); 176: else 177: cnt = NINDIR(sblock) * sblock->fs_frag; 178: *size -= NINDIR(sblock) * sblock->fs_bsize; 179: blksout(&idblk[0], cnt); 180: return; 181: } 182: lvl--; 183: for (i = 0; i < NINDIR(sblock); i++) { 184: dmpindir(idblk[i], lvl, size); 185: if (*size <= 0) 186: return; 187: } 188: } 189: 190: blksout(blkp, frags) 191: daddr_t *blkp; 192: int frags; 193: { 194: int i, j, count, blks, tbperdb; 195: 196: blks = howmany(frags * sblock->fs_fsize, TP_BSIZE); 197: tbperdb = sblock->fs_bsize / TP_BSIZE; 198: for (i = 0; i < blks; i += TP_NINDIR) { 199: if (i + TP_NINDIR > blks) 200: count = blks; 201: else 202: count = i + TP_NINDIR; 203: for (j = i; j < count; j++) 204: if (blkp[j / tbperdb] != 0) 205: spcl.c_addr[j - i] = 1; 206: else 207: spcl.c_addr[j - i] = 0; 208: spcl.c_count = count - i; 209: spclrec(); 210: for (j = i; j < count; j += tbperdb) 211: if (blkp[j / tbperdb] != 0) 212: if (j + tbperdb <= count) 213: dmpblk(blkp[j / tbperdb], 214: sblock->fs_bsize); 215: else 216: dmpblk(blkp[j / tbperdb], 217: (count - j) * TP_BSIZE); 218: spcl.c_type = TS_ADDR; 219: } 220: } 221: 222: bitmap(map, typ) 223: char *map; 224: { 1.1.1.2 ! root 225: register i; 1.1 root 226: char *cp; 227: 228: spcl.c_type = typ; 229: spcl.c_count = howmany(msiz * sizeof(map[0]), TP_BSIZE); 230: spclrec(); 231: for (i = 0, cp = map; i < spcl.c_count; i++, cp += TP_BSIZE) 232: taprec(cp); 233: } 234: 235: spclrec() 236: { 237: register int s, i, *ip; 238: 239: spcl.c_inumber = ino; 240: spcl.c_magic = NFS_MAGIC; 241: spcl.c_checksum = 0; 242: ip = (int *)&spcl; 243: s = 0; 1.1.1.2 ! root 244: i = sizeof(union u_spcl) / (4*sizeof(int)); ! 245: while (--i >= 0) { ! 246: s += *ip++; s += *ip++; ! 247: s += *ip++; s += *ip++; ! 248: } 1.1 root 249: spcl.c_checksum = CHECKSUM - s; 250: taprec((char *)&spcl); 251: } 252: 253: dsrch(d, size, filesize) 254: daddr_t d; 255: int size, filesize; 256: { 257: register struct direct *dp; 258: long loc; 259: char dblk[MAXBSIZE]; 260: 261: if(dadded) 262: return; 263: if (filesize > size) 264: filesize = size; 265: bread(fsbtodb(sblock, d), dblk, filesize); 266: for (loc = 0; loc < filesize; ) { 267: dp = (struct direct *)(dblk + loc); 268: if (dp->d_reclen == 0) { 269: msg("corrupted directory, inumber %d\n", ino); 270: break; 271: } 272: loc += dp->d_reclen; 273: if(dp->d_ino == 0) 274: continue; 275: if(dp->d_name[0] == '.') { 276: if(dp->d_name[1] == '\0') 277: continue; 278: if(dp->d_name[1] == '.' && dp->d_name[2] == '\0') 279: continue; 280: } 281: if(BIT(dp->d_ino, nodmap)) { 282: dadded++; 283: return; 284: } 285: if(BIT(dp->d_ino, dirmap)) 286: nsubdir++; 287: } 288: } 289: 290: struct dinode * 291: getino(ino) 292: daddr_t ino; 293: { 294: static daddr_t minino, maxino; 295: static struct dinode itab[MAXINOPB]; 296: 297: if (ino >= minino && ino < maxino) { 298: return (&itab[ino - minino]); 299: } 300: bread(fsbtodb(sblock, itod(sblock, ino)), itab, sblock->fs_bsize); 301: minino = ino - (ino % INOPB(sblock)); 302: maxino = minino + INOPB(sblock); 303: return (&itab[ino - minino]); 304: } 305: 306: int breaderrors = 0; 307: #define BREADEMAX 32 308: 309: bread(da, ba, cnt) 310: daddr_t da; 311: char *ba; 312: int cnt; 313: { 314: int n; 315: 316: loop: 317: if (lseek(fi, (long)(da * DEV_BSIZE), 0) < 0){ 318: msg("bread: lseek fails\n"); 319: } 320: n = read(fi, ba, cnt); 321: if (n == cnt) 322: return; 323: if (da + (cnt / DEV_BSIZE) > fsbtodb(sblock, sblock->fs_size)) { 324: /* 325: * Trying to read the final fragment. 326: * 327: * NB - dump only works in TP_BSIZE blocks, hence 328: * rounds DEV_BSIZE fragments up to TP_BSIZE pieces. 329: * It should be smarter about not actually trying to 330: * read more than it can get, but for the time being 331: * we punt and scale back the read only when it gets 332: * us into trouble. (mkm 9/25/83) 333: */ 334: cnt -= DEV_BSIZE; 335: goto loop; 336: } 337: msg("(This should not happen)bread from %s [block %d]: count=%d, got=%d\n", 338: disk, da, cnt, n); 339: if (++breaderrors > BREADEMAX){ 340: msg("More than %d block read errors from %d\n", 341: BREADEMAX, disk); 342: broadcast("DUMP IS AILING!\n"); 343: msg("This is an unrecoverable error.\n"); 344: if (!query("Do you want to attempt to continue?")){ 345: dumpabort(); 346: /*NOTREACHED*/ 347: } else 348: breaderrors = 0; 349: } 350: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.