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

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

unix.superglobalmegacorp.com

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