Annotation of cci/usr/src/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: dirdump(ip)
                    109:        struct dinode *ip;
                    110: {
                    111:        /* watchout for dir inodes deleted and maybe reallocated */
                    112:        if ((ip->di_mode & IFMT) != IFDIR)
                    113:                return;
                    114:        dump(ip);
                    115: }
                    116: 
                    117: dump(ip)
                    118:        struct dinode *ip;
                    119: {
                    120:        register int i;
                    121:        long size;
                    122: 
                    123:        if(newtape) {
                    124:                newtape = 0;
                    125:                bitmap(nodmap, TS_BITS);
                    126:        }
                    127:        BIC(ino, nodmap);
                    128:        spcl.c_dinode = *ip;
                    129:        spcl.c_type = TS_INODE;
                    130:        spcl.c_count = 0;
                    131:        i = ip->di_mode & IFMT;
                    132:        if (i == 0) /* free inode */
                    133:                return;
                    134:        if ((i != IFDIR && i != IFREG && i != IFLNK) || ip->di_size == 0) {
                    135:                spclrec();
                    136:                return;
                    137:        }
                    138:        if (ip->di_size > NDADDR * sblock->fs_bsize)
                    139:                i = NDADDR * sblock->fs_frag;
                    140:        else
                    141:                i = howmany(ip->di_size, sblock->fs_fsize);
                    142:        blksout(&ip->di_db[0], i);
                    143:        size = ip->di_size - NDADDR * sblock->fs_bsize;
                    144:        if (size <= 0)
                    145:                return;
                    146:        for (i = 0; i < NIADDR; i++) {
                    147:                dmpindir(ip->di_ib[i], i, &size);
                    148:                if (size <= 0)
                    149:                        return;
                    150:        }
                    151: }
                    152: 
                    153: dmpindir(blk, lvl, size)
                    154:        daddr_t blk;
                    155:        int lvl;
                    156:        long *size;
                    157: {
                    158:        int i, cnt;
                    159:        daddr_t idblk[MAXNINDIR];
                    160: 
                    161:        if (blk != 0)
                    162:                bread(fsbtodb(sblock, blk), (char *)idblk, sblock->fs_bsize);
                    163:        else
                    164:                bzero(idblk, sblock->fs_bsize);
                    165:        if (lvl <= 0) {
                    166:                if (*size < NINDIR(sblock) * sblock->fs_bsize)
                    167:                        cnt = howmany(*size, sblock->fs_fsize);
                    168:                else
                    169:                        cnt = NINDIR(sblock) * sblock->fs_frag;
                    170:                *size -= NINDIR(sblock) * sblock->fs_bsize;
                    171:                blksout(&idblk[0], cnt);
                    172:                return;
                    173:        }
                    174:        lvl--;
                    175:        for (i = 0; i < NINDIR(sblock); i++) {
                    176:                dmpindir(idblk[i], lvl, size);
                    177:                if (*size <= 0)
                    178:                        return;
                    179:        }
                    180: }
                    181: 
                    182: blksout(blkp, frags)
                    183:        daddr_t *blkp;
                    184:        int frags;
                    185: {
                    186:        int i, j, count, blks, tbperdb;
                    187: 
                    188:        blks = howmany(frags * sblock->fs_fsize, TP_BSIZE);
                    189:        tbperdb = sblock->fs_bsize / TP_BSIZE;
                    190:        for (i = 0; i < blks; i += TP_NINDIR) {
                    191:                if (i + TP_NINDIR > blks)
                    192:                        count = blks;
                    193:                else
                    194:                        count = i + TP_NINDIR;
                    195:                for (j = i; j < count; j++)
                    196:                        if (blkp[j / tbperdb] != 0)
                    197:                                spcl.c_addr[j - i] = 1;
                    198:                        else
                    199:                                spcl.c_addr[j - i] = 0;
                    200:                spcl.c_count = count - i;
                    201:                spclrec();
                    202:                for (j = i; j < count; j += tbperdb)
                    203:                        if (blkp[j / tbperdb] != 0)
                    204:                                if (j + tbperdb <= count)
                    205:                                        dmpblk(blkp[j / tbperdb],
                    206:                                            sblock->fs_bsize);
                    207:                                else
                    208:                                        dmpblk(blkp[j / tbperdb],
                    209:                                            (count - j) * TP_BSIZE);
                    210:                spcl.c_type = TS_ADDR;
                    211:        }
                    212: }
                    213: 
                    214: bitmap(map, typ)
                    215:        char *map;
                    216: {
                    217:        register i, n;
                    218:        char *cp;
                    219: 
                    220:        spcl.c_type = typ;
                    221:        spcl.c_count = howmany(msiz * sizeof(map[0]), TP_BSIZE);
                    222:        spclrec();
                    223:        for (i = 0, cp = map; i < spcl.c_count; i++, cp += TP_BSIZE)
                    224:                taprec(cp);
                    225: }
                    226: 
                    227: spclrec()
                    228: {
                    229:        register int s, i, *ip;
                    230: 
                    231:        spcl.c_inumber = ino;
                    232:        spcl.c_magic = NFS_MAGIC;
                    233:        spcl.c_checksum = 0;
                    234:        ip = (int *)&spcl;
                    235:        s = 0;
                    236:        for(i = 0; i < sizeof(union u_spcl)/sizeof(int); i++)
                    237:                s += *ip++;
                    238:        spcl.c_checksum = CHECKSUM - s;
                    239:        taprec((char *)&spcl);
                    240: }
                    241: 
                    242: dsrch(d, size, filesize)
                    243:        daddr_t d;
                    244:        int size, filesize;
                    245: {
                    246:        register struct direct *dp;
                    247:        long loc;
                    248:        char dblk[MAXBSIZE];
                    249: 
                    250:        if(dadded)
                    251:                return;
                    252:        if (filesize > size)
                    253:                filesize = size;
                    254:        bread(fsbtodb(sblock, d), dblk, filesize);
                    255:        for (loc = 0; loc < filesize; ) {
                    256:                dp = (struct direct *)(dblk + loc);
                    257:                if (dp->d_reclen == 0) {
                    258:                        msg("corrupted directory, inumber %d\n", ino);
                    259:                        break;
                    260:                }
                    261:                loc += dp->d_reclen;
                    262:                if(dp->d_ino == 0)
                    263:                        continue;
                    264:                if(dp->d_name[0] == '.') {
                    265:                        if(dp->d_name[1] == '\0')
                    266:                                continue;
                    267:                        if(dp->d_name[1] == '.' && dp->d_name[2] == '\0')
                    268:                                continue;
                    269:                }
                    270:                if(BIT(dp->d_ino, nodmap)) {
                    271:                        dadded++;
                    272:                        return;
                    273:                }
                    274:                if(BIT(dp->d_ino, dirmap))
                    275:                        nsubdir++;
                    276:        }
                    277: }
                    278: 
                    279: struct dinode *
                    280: getino(ino)
                    281:        daddr_t ino;
                    282: {
                    283:        static daddr_t minino, maxino;
                    284:        static struct dinode itab[MAXINOPB];
                    285: 
                    286:        if (ino >= minino && ino < maxino) {
                    287:                return (&itab[ino - minino]);
                    288:        }
                    289:        bread(fsbtodb(sblock, itod(sblock, ino)), itab, sblock->fs_bsize);
                    290:        minino = ino - (ino % INOPB(sblock));
                    291:        maxino = minino + INOPB(sblock);
                    292:        return (&itab[ino - minino]);
                    293: }
                    294: 
                    295: int    breaderrors = 0;                
                    296: #define        BREADEMAX 32
                    297: 
                    298: bread(da, ba, cnt)
                    299:        daddr_t da;
                    300:        char *ba;
                    301:        int     cnt;    
                    302: {
                    303:        int n;
                    304: 
                    305: loop:
                    306:        if (lseek(fi, (long)(da * DEV_BSIZE), 0) < 0){
                    307:                msg("bread: lseek fails\n");
                    308:        }
                    309:        n = read(fi, ba, cnt);
                    310:        if (n == cnt)
                    311:                return;
                    312:        if (da + (cnt / DEV_BSIZE) > fsbtodb(sblock, sblock->fs_size)) {
                    313:                /*
                    314:                 * Trying to read the final fragment.
                    315:                 *
                    316:                 * NB - dump only works in TP_BSIZE blocks, hence
                    317:                 * rounds DEV_BSIZE fragments up to TP_BSIZE pieces.
                    318:                 * It should be smarter about not actually trying to
                    319:                 * read more than it can get, but for the time being
                    320:                 * we punt and scale back the read only when it gets
                    321:                 * us into trouble. (mkm 9/25/83)
                    322:                 */
                    323:                cnt -= DEV_BSIZE;
                    324:                goto loop;
                    325:        }
                    326:        msg("(This should not happen)bread from %s [block %d]: count=%d, got=%d\n",
                    327:                disk, da, cnt, n);
                    328:        if (++breaderrors > BREADEMAX){
                    329:                msg("More than %d block read errors from %d\n",
                    330:                        BREADEMAX, disk);
                    331:                broadcast("DUMP IS AILING!\n");
                    332:                msg("This is an unrecoverable error.\n");
                    333:                if (!query("Do you want to attempt to continue?")){
                    334:                        dumpabort();
                    335:                        /*NOTREACHED*/
                    336:                } else
                    337:                        breaderrors = 0;
                    338:        }
                    339: }

unix.superglobalmegacorp.com

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