Annotation of cci/usr/src/etc/dump/dumptraverse.c, revision 1.1.1.2

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

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.