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