Annotation of 43BSD/etc/dump/dumptraverse.c, revision 1.1.1.1

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

unix.superglobalmegacorp.com

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