Annotation of 43BSDReno/sbin/fsck/pass1.c, revision 1.1.1.1

1.1       root        1: /*
                      2:  * Copyright (c) 1980, 1986 The Regents of the University of California.
                      3:  * All rights reserved.
                      4:  *
                      5:  * Redistribution and use in source and binary forms are permitted provided
                      6:  * that: (1) source distributions retain this entire copyright notice and
                      7:  * comment, and (2) distributions including binaries display the following
                      8:  * acknowledgement:  ``This product includes software developed by the
                      9:  * University of California, Berkeley and its contributors'' in the
                     10:  * documentation or other materials provided with the distribution and in
                     11:  * all advertising materials mentioning features or use of this software.
                     12:  * Neither the name of the University nor the names of its contributors may
                     13:  * be used to endorse or promote products derived from this software without
                     14:  * specific prior written permission.
                     15:  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
                     16:  * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
                     17:  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
                     18:  */
                     19: 
                     20: #ifndef lint
                     21: static char sccsid[] = "@(#)pass1.c    5.15 (Berkeley) 7/20/90";
                     22: #endif /* not lint */
                     23: 
                     24: #include <sys/param.h>
                     25: #include <ufs/dinode.h>
                     26: #include <ufs/fs.h>
                     27: #include <stdlib.h>
                     28: #include <string.h>
                     29: #include "fsck.h"
                     30: 
                     31: static daddr_t badblk;
                     32: static daddr_t dupblk;
                     33: int pass1check();
                     34: struct dinode *getnextinode();
                     35: 
                     36: pass1()
                     37: {
                     38:        register int c, i, j;
                     39:        register struct dinode *dp;
                     40:        struct zlncnt *zlnp;
                     41:        int ndb, cgd;
                     42:        struct inodesc idesc;
                     43:        ino_t inumber;
                     44: 
                     45:        /*
                     46:         * Set file system reserved blocks in used block map.
                     47:         */
                     48:        for (c = 0; c < sblock.fs_ncg; c++) {
                     49:                cgd = cgdmin(&sblock, c);
                     50:                if (c == 0) {
                     51:                        i = cgbase(&sblock, c);
                     52:                        cgd += howmany(sblock.fs_cssize, sblock.fs_fsize);
                     53:                } else
                     54:                        i = cgsblock(&sblock, c);
                     55:                for (; i < cgd; i++)
                     56:                        setbmap(i);
                     57:        }
                     58:        /*
                     59:         * Find all allocated blocks.
                     60:         */
                     61:        bzero((char *)&idesc, sizeof(struct inodesc));
                     62:        idesc.id_type = ADDR;
                     63:        idesc.id_func = pass1check;
                     64:        inumber = 0;
                     65:        n_files = n_blks = 0;
                     66:        resetinodebuf();
                     67:        for (c = 0; c < sblock.fs_ncg; c++) {
                     68:                for (i = 0; i < sblock.fs_ipg; i++, inumber++) {
                     69:                        if (inumber < ROOTINO)
                     70:                                continue;
                     71:                        dp = getnextinode(inumber);
                     72:                        if ((dp->di_mode & IFMT) == 0) {
                     73:                                if (bcmp((char *)dp->di_db, (char *)zino.di_db,
                     74:                                        NDADDR * sizeof(daddr_t)) ||
                     75:                                    bcmp((char *)dp->di_ib, (char *)zino.di_ib,
                     76:                                        NIADDR * sizeof(daddr_t)) ||
                     77:                                    dp->di_mode || dp->di_size) {
                     78:                                        pfatal("PARTIALLY ALLOCATED INODE I=%lu",
                     79:                                                inumber);
                     80:                                        if (reply("CLEAR") == 1) {
                     81:                                                dp = ginode(inumber);
                     82:                                                clearinode(dp);
                     83:                                                inodirty();
                     84:                                        }
                     85:                                }
                     86:                                statemap[inumber] = USTATE;
                     87:                                continue;
                     88:                        }
                     89:                        lastino = inumber;
                     90:                        if (/* dp->di_size < 0 || */
                     91:                            dp->di_size + sblock.fs_bsize - 1 < dp->di_size) {
                     92:                                if (debug)
                     93:                                        printf("bad size %lu:", dp->di_size);
                     94:                                goto unknown;
                     95:                        }
                     96:                        if (!preen && (dp->di_mode & IFMT) == IFMT &&
                     97:                            reply("HOLD BAD BLOCK") == 1) {
                     98:                                dp = ginode(inumber);
                     99:                                dp->di_size = sblock.fs_fsize;
                    100:                                dp->di_mode = IFREG|0600;
                    101:                                inodirty();
                    102:                        }
                    103:                        ndb = howmany(dp->di_size, sblock.fs_bsize);
                    104:                        if (ndb < 0) {
                    105:                                if (debug)
                    106:                                        printf("bad size %lu ndb %d:",
                    107:                                                dp->di_size, ndb);
                    108:                                goto unknown;
                    109:                        }
                    110:                        if ((dp->di_mode & IFMT) == IFBLK ||
                    111:                            (dp->di_mode & IFMT) == IFCHR)
                    112:                                ndb++;
                    113:                        for (j = ndb; j < NDADDR; j++)
                    114:                                if (dp->di_db[j] != 0) {
                    115:                                        if (debug)
                    116:                                                printf("bad direct addr: %ld\n",
                    117:                                                        dp->di_db[j]);
                    118:                                        goto unknown;
                    119:                                }
                    120:                        for (j = 0, ndb -= NDADDR; ndb > 0; j++)
                    121:                                ndb /= NINDIR(&sblock);
                    122:                        for (; j < NIADDR; j++)
                    123:                                if (dp->di_ib[j] != 0) {
                    124:                                        if (debug)
                    125:                                                printf("bad indirect addr: %ld\n",
                    126:                                                        dp->di_ib[j]);
                    127:                                        goto unknown;
                    128:                                }
                    129:                        if (ftypeok(dp) == 0)
                    130:                                goto unknown;
                    131:                        n_files++;
                    132:                        lncntp[inumber] = dp->di_nlink;
                    133:                        if (dp->di_nlink <= 0) {
                    134:                                zlnp = (struct zlncnt *)malloc(sizeof *zlnp);
                    135:                                if (zlnp == NULL) {
                    136:                                        pfatal("LINK COUNT TABLE OVERFLOW");
                    137:                                        if (reply("CONTINUE") == 0)
                    138:                                                errexit("");
                    139:                                } else {
                    140:                                        zlnp->zlncnt = inumber;
                    141:                                        zlnp->next = zlnhead;
                    142:                                        zlnhead = zlnp;
                    143:                                }
                    144:                        }
                    145:                        if ((dp->di_mode & IFMT) == IFDIR) {
                    146:                                if (dp->di_size == 0)
                    147:                                        statemap[inumber] = DCLEAR;
                    148:                                else
                    149:                                        statemap[inumber] = DSTATE;
                    150:                                cacheino(dp, inumber);
                    151:                        } else
                    152:                                statemap[inumber] = FSTATE;
                    153:                        badblk = dupblk = 0;
                    154:                        idesc.id_number = inumber;
                    155:                        (void)ckinode(dp, &idesc);
                    156:                        idesc.id_entryno *= btodb(sblock.fs_fsize);
                    157:                        if (dp->di_blocks != idesc.id_entryno) {
                    158:                                pwarn("INCORRECT BLOCK COUNT I=%lu (%ld should be %ld)",
                    159:                                    inumber, dp->di_blocks, idesc.id_entryno);
                    160:                                if (preen)
                    161:                                        printf(" (CORRECTED)\n");
                    162:                                else if (reply("CORRECT") == 0)
                    163:                                        continue;
                    164:                                dp = ginode(inumber);
                    165:                                dp->di_blocks = idesc.id_entryno;
                    166:                                inodirty();
                    167:                        }
                    168:                        continue;
                    169:        unknown:
                    170:                        pfatal("UNKNOWN FILE TYPE I=%lu", inumber);
                    171:                        statemap[inumber] = FCLEAR;
                    172:                        if (reply("CLEAR") == 1) {
                    173:                                statemap[inumber] = USTATE;
                    174:                                dp = ginode(inumber);
                    175:                                clearinode(dp);
                    176:                                inodirty();
                    177:                        }
                    178:                }
                    179:        }
                    180:        freeinodebuf();
                    181: }
                    182: 
                    183: pass1check(idesc)
                    184:        register struct inodesc *idesc;
                    185: {
                    186:        int res = KEEPON;
                    187:        int anyout, nfrags;
                    188:        daddr_t blkno = idesc->id_blkno;
                    189:        register struct dups *dlp;
                    190:        struct dups *new;
                    191: 
                    192:        if ((anyout = chkrange(blkno, idesc->id_numfrags)) != 0) {
                    193:                blkerror(idesc->id_number, "BAD", blkno);
                    194:                if (++badblk >= MAXBAD) {
                    195:                        pwarn("EXCESSIVE BAD BLKS I=%lu",
                    196:                                idesc->id_number);
                    197:                        if (preen)
                    198:                                printf(" (SKIPPING)\n");
                    199:                        else if (reply("CONTINUE") == 0)
                    200:                                errexit("");
                    201:                        return (STOP);
                    202:                }
                    203:        }
                    204:        for (nfrags = idesc->id_numfrags; nfrags > 0; blkno++, nfrags--) {
                    205:                if (anyout && chkrange(blkno, 1)) {
                    206:                        res = SKIP;
                    207:                } else if (!testbmap(blkno)) {
                    208:                        n_blks++;
                    209:                        setbmap(blkno);
                    210:                } else {
                    211:                        blkerror(idesc->id_number, "DUP", blkno);
                    212:                        if (++dupblk >= MAXDUP) {
                    213:                                pwarn("EXCESSIVE DUP BLKS I=%lu",
                    214:                                        idesc->id_number);
                    215:                                if (preen)
                    216:                                        printf(" (SKIPPING)\n");
                    217:                                else if (reply("CONTINUE") == 0)
                    218:                                        errexit("");
                    219:                                return (STOP);
                    220:                        }
                    221:                        new = (struct dups *)malloc(sizeof(struct dups));
                    222:                        if (new == NULL) {
                    223:                                pfatal("DUP TABLE OVERFLOW.");
                    224:                                if (reply("CONTINUE") == 0)
                    225:                                        errexit("");
                    226:                                return (STOP);
                    227:                        }
                    228:                        new->dup = blkno;
                    229:                        if (muldup == 0) {
                    230:                                duplist = muldup = new;
                    231:                                new->next = 0;
                    232:                        } else {
                    233:                                new->next = muldup->next;
                    234:                                muldup->next = new;
                    235:                        }
                    236:                        for (dlp = duplist; dlp != muldup; dlp = dlp->next)
                    237:                                if (dlp->dup == blkno)
                    238:                                        break;
                    239:                        if (dlp == muldup && dlp->dup != blkno)
                    240:                                muldup = new;
                    241:                }
                    242:                /*
                    243:                 * count the number of blocks found in id_entryno
                    244:                 */
                    245:                idesc->id_entryno++;
                    246:        }
                    247:        return (res);
                    248: }

unix.superglobalmegacorp.com

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