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