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: }

Defined functions

add defined in line 58; used 1 times
bitmap defined in line 221; used 2 times
blksout defined in line 189; used 2 times
bread defined in line 308; used 6 times
dirdump defined in line 115; used 1 times
dmpindir defined in line 160; used 2 times
dsrch defined in line 252; used 3 times
dump defined in line 124; used 2 times
getino defined in line 289; used 2 times
indir defined in line 90; used 2 times
mark defined in line 34; used 1 times
pass defined in line 13; used 4 times
spclrec defined in line 234; used 6 times

Defined variables

breaderrors defined in line 305; used 2 times
sccsid defined in line 8; never used

Defined macros

BREADEMAX defined in line 306; used 2 times
Last modified: 1986-05-02
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 1623
Valid CSS Valid XHTML 1.0 Strict