Annotation of 43BSD/etc/fsck/pass1.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[] = "@(#)pass1.c    5.3 (Berkeley) 5/13/86";
                      9: #endif not lint
                     10: 
                     11: #include <sys/param.h>
                     12: #include <sys/inode.h>
                     13: #include <sys/fs.h>
                     14: #include "fsck.h"
                     15: 
                     16: static daddr_t badblk;
                     17: static daddr_t dupblk;
                     18: int pass1check();
                     19: 
                     20: pass1()
                     21: {
                     22:        register int c, i, j;
                     23:        register DINODE *dp;
                     24:        struct zlncnt *zlnp;
                     25:        int ndb, partial, cgd;
                     26:        struct inodesc idesc;
                     27:        ino_t inumber;
                     28: 
                     29:        /*
                     30:         * Set file system reserved blocks in used block map.
                     31:         */
                     32:        for (c = 0; c < sblock.fs_ncg; c++) {
                     33:                cgd = cgdmin(&sblock, c);
                     34:                if (c == 0) {
                     35:                        i = cgbase(&sblock, c);
                     36:                        cgd += howmany(sblock.fs_cssize, sblock.fs_fsize);
                     37:                } else
                     38:                        i = cgsblock(&sblock, c);
                     39:                for (; i < cgd; i++)
                     40:                        setbmap(i);
                     41:        }
                     42:        /*
                     43:         * Find all allocated blocks.
                     44:         */
                     45:        bzero((char *)&idesc, sizeof(struct inodesc));
                     46:        idesc.id_type = ADDR;
                     47:        idesc.id_func = pass1check;
                     48:        inumber = 0;
                     49:        n_files = n_blks = 0;
                     50:        for (c = 0; c < sblock.fs_ncg; c++) {
                     51:                for (i = 0; i < sblock.fs_ipg; i++, inumber++) {
                     52:                        if (inumber < ROOTINO)
                     53:                                continue;
                     54:                        dp = ginode(inumber);
                     55:                        if (!ALLOC(dp)) {
                     56:                                if (bcmp((char *)dp->di_db, (char *)zino.di_db,
                     57:                                        NDADDR * sizeof(daddr_t)) ||
                     58:                                    bcmp((char *)dp->di_ib, (char *)zino.di_ib,
                     59:                                        NIADDR * sizeof(daddr_t)) ||
                     60:                                    dp->di_mode || dp->di_size) {
                     61:                                        pfatal("PARTIALLY ALLOCATED INODE I=%u",
                     62:                                                inumber);
                     63:                                        if (reply("CLEAR") == 1) {
                     64:                                                zapino(dp);
                     65:                                                inodirty();
                     66:                                        }
                     67:                                }
                     68:                                statemap[inumber] = USTATE;
                     69:                                continue;
                     70:                        }
                     71:                        lastino = inumber;
                     72:                        if (dp->di_size < 0) {
                     73:                                if (debug)
                     74:                                        printf("bad size %d:", dp->di_size);
                     75:                                goto unknown;
                     76:                        }
                     77:                        if (!preen && (dp->di_mode & IFMT) == IFMT &&
                     78:                            reply("HOLD BAD BLOCK") == 1) {
                     79:                                dp->di_size = sblock.fs_fsize;
                     80:                                dp->di_mode = IFREG|0600;
                     81:                                inodirty();
                     82:                        }
                     83:                        ndb = howmany(dp->di_size, sblock.fs_bsize);
                     84:                        if (SPECIAL(dp))
                     85:                                ndb++;
                     86:                        for (j = ndb; j < NDADDR; j++)
                     87:                                if (dp->di_db[j] != 0) {
                     88:                                        if (debug)
                     89:                                                printf("bad direct addr: %d\n",
                     90:                                                        dp->di_db[j]);
                     91:                                        goto unknown;
                     92:                                }
                     93:                        for (j = 0, ndb -= NDADDR; ndb > 0; j++)
                     94:                                ndb /= NINDIR(&sblock);
                     95:                        for (; j < NIADDR; j++)
                     96:                                if (dp->di_ib[j] != 0) {
                     97:                                        if (debug)
                     98:                                                printf("bad indirect addr: %d\n",
                     99:                                                        dp->di_ib[j]);
                    100:                                        goto unknown;
                    101:                                }
                    102:                        if (ftypeok(dp) == 0)
                    103:                                goto unknown;
                    104:                        n_files++;
                    105:                        lncntp[inumber] = dp->di_nlink;
                    106:                        if (dp->di_nlink <= 0) {
                    107:                                zlnp = (struct zlncnt *)malloc(sizeof *zlnp);
                    108:                                if (zlnp == NULL) {
                    109:                                        pfatal("LINK COUNT TABLE OVERFLOW");
                    110:                                        if (reply("CONTINUE") == 0)
                    111:                                                errexit("");
                    112:                                } else {
                    113:                                        zlnp->zlncnt = inumber;
                    114:                                        zlnp->next = zlnhead;
                    115:                                        zlnhead = zlnp;
                    116:                                }
                    117:                        }
                    118:                        statemap[inumber] = DIRCT(dp) ? DSTATE : FSTATE;
                    119:                        badblk = dupblk = 0; maxblk = 0;
                    120:                        idesc.id_number = inumber;
                    121:                        (void)ckinode(dp, &idesc);
                    122:                        idesc.id_entryno *= btodb(sblock.fs_fsize);
                    123:                        if (dp->di_blocks != idesc.id_entryno) {
                    124:                                pwarn("INCORRECT BLOCK COUNT I=%u (%ld should be %ld)",
                    125:                                    inumber, dp->di_blocks, idesc.id_entryno);
                    126:                                if (preen)
                    127:                                        printf(" (CORRECTED)\n");
                    128:                                else if (reply("CORRECT") == 0)
                    129:                                        continue;
                    130:                                dp->di_blocks = idesc.id_entryno;
                    131:                                inodirty();
                    132:                        }
                    133:                        continue;
                    134:        unknown:
                    135:                        pfatal("UNKNOWN FILE TYPE I=%u", inumber);
                    136:                        statemap[inumber] = FCLEAR;
                    137:                        if (reply("CLEAR") == 1) {
                    138:                                statemap[inumber] = USTATE;
                    139:                                zapino(dp);
                    140:                                inodirty();
                    141:                        }
                    142:                }
                    143:        }
                    144: }
                    145: 
                    146: pass1check(idesc)
                    147:        register struct inodesc *idesc;
                    148: {
                    149:        int res = KEEPON;
                    150:        int anyout, nfrags;
                    151:        daddr_t blkno = idesc->id_blkno;
                    152:        register struct dups *dlp;
                    153:        struct dups *new;
                    154: 
                    155:        if ((anyout = outrange(blkno, idesc->id_numfrags)) != 0) {
                    156:                blkerr(idesc->id_number, "BAD", blkno);
                    157:                if (++badblk >= MAXBAD) {
                    158:                        pwarn("EXCESSIVE BAD BLKS I=%u",
                    159:                                idesc->id_number);
                    160:                        if (preen)
                    161:                                printf(" (SKIPPING)\n");
                    162:                        else if (reply("CONTINUE") == 0)
                    163:                                errexit("");
                    164:                        return (STOP);
                    165:                }
                    166:        }
                    167:        for (nfrags = idesc->id_numfrags; nfrags > 0; blkno++, nfrags--) {
                    168:                if (anyout && outrange(blkno, 1)) {
                    169:                        res = SKIP;
                    170:                } else if (!getbmap(blkno)) {
                    171:                        n_blks++;
                    172:                        setbmap(blkno);
                    173:                } else {
                    174:                        blkerr(idesc->id_number, "DUP", blkno);
                    175:                        if (++dupblk >= MAXDUP) {
                    176:                                pwarn("EXCESSIVE DUP BLKS I=%u",
                    177:                                        idesc->id_number);
                    178:                                if (preen)
                    179:                                        printf(" (SKIPPING)\n");
                    180:                                else if (reply("CONTINUE") == 0)
                    181:                                        errexit("");
                    182:                                return (STOP);
                    183:                        }
                    184:                        new = (struct dups *)malloc(sizeof(struct dups));
                    185:                        if (new == NULL) {
                    186:                                pfatal("DUP TABLE OVERFLOW.");
                    187:                                if (reply("CONTINUE") == 0)
                    188:                                        errexit("");
                    189:                                return (STOP);
                    190:                        }
                    191:                        new->dup = blkno;
                    192:                        if (muldup == 0) {
                    193:                                duplist = muldup = new;
                    194:                                new->next = 0;
                    195:                        } else {
                    196:                                new->next = muldup->next;
                    197:                                muldup->next = new;
                    198:                        }
                    199:                        for (dlp = duplist; dlp != muldup; dlp = dlp->next)
                    200:                                if (dlp->dup == blkno)
                    201:                                        break;
                    202:                        if (dlp == muldup && dlp->dup != blkno)
                    203:                                muldup = new;
                    204:                }
                    205:                /*
                    206:                 * count the number of blocks found in id_entryno
                    207:                 */
                    208:                idesc->id_entryno++;
                    209:        }
                    210:        return (res);
                    211: }

unix.superglobalmegacorp.com

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