check in temporary version with compatibility hacks
[unix-history] / usr / src / sbin / fsck / pass1.c
index 3cc8cdc..9ec72f2 100644 (file)
@@ -1,28 +1,32 @@
 /*
 /*
- * Copyright (c) 1980 Regents of the University of California.
- * All rights reserved.  The Berkeley software License Agreement
- * specifies the terms and conditions for redistribution.
+ * Copyright (c) 1980, 1986 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * %sccs.include.redist.c%
  */
 
 #ifndef lint
  */
 
 #ifndef lint
-static char sccsid[] = "@(#)pass1.c    5.2 (Berkeley) %G%";
-#endif not lint
+static char sccsid[] = "@(#)pass1.c    5.17 (Berkeley) %G%";
+#endif /* not lint */
 
 #include <sys/param.h>
 
 #include <sys/param.h>
-#include <sys/inode.h>
-#include <sys/fs.h>
+#include <ufs/ufs/dinode.h>
+#include <ufs/ffs/fs.h>
+#include <stdlib.h>
+#include <string.h>
 #include "fsck.h"
 
 static daddr_t badblk;
 static daddr_t dupblk;
 int pass1check();
 #include "fsck.h"
 
 static daddr_t badblk;
 static daddr_t dupblk;
 int pass1check();
+struct dinode *getnextinode();
 
 pass1()
 {
        register int c, i, j;
 
 pass1()
 {
        register int c, i, j;
-       register DINODE *dp;
+       register struct dinode *dp;
        struct zlncnt *zlnp;
        struct zlncnt *zlnp;
-       int ndb, partial, cgd;
+       int ndb, cgd;
        struct inodesc idesc;
        ino_t inumber;
 
        struct inodesc idesc;
        ino_t inumber;
 
@@ -47,21 +51,23 @@ pass1()
        idesc.id_func = pass1check;
        inumber = 0;
        n_files = n_blks = 0;
        idesc.id_func = pass1check;
        inumber = 0;
        n_files = n_blks = 0;
+       resetinodebuf();
        for (c = 0; c < sblock.fs_ncg; c++) {
                for (i = 0; i < sblock.fs_ipg; i++, inumber++) {
                        if (inumber < ROOTINO)
                                continue;
        for (c = 0; c < sblock.fs_ncg; c++) {
                for (i = 0; i < sblock.fs_ipg; i++, inumber++) {
                        if (inumber < ROOTINO)
                                continue;
-                       dp = ginode(inumber);
-                       if (!ALLOC(dp)) {
+                       dp = getnextinode(inumber);
+                       if ((dp->di_mode & IFMT) == 0) {
                                if (bcmp((char *)dp->di_db, (char *)zino.di_db,
                                        NDADDR * sizeof(daddr_t)) ||
                                    bcmp((char *)dp->di_ib, (char *)zino.di_ib,
                                        NIADDR * sizeof(daddr_t)) ||
                                    dp->di_mode || dp->di_size) {
                                if (bcmp((char *)dp->di_db, (char *)zino.di_db,
                                        NDADDR * sizeof(daddr_t)) ||
                                    bcmp((char *)dp->di_ib, (char *)zino.di_ib,
                                        NIADDR * sizeof(daddr_t)) ||
                                    dp->di_mode || dp->di_size) {
-                                       pfatal("PARTIALLY ALLOCATED INODE I=%u",
+                                       pfatal("PARTIALLY ALLOCATED INODE I=%lu",
                                                inumber);
                                        if (reply("CLEAR") == 1) {
                                                inumber);
                                        if (reply("CLEAR") == 1) {
-                                               zapino(dp);
+                                               dp = ginode(inumber);
+                                               clearinode(dp);
                                                inodirty();
                                        }
                                }
                                                inodirty();
                                        }
                                }
@@ -69,18 +75,33 @@ pass1()
                                continue;
                        }
                        lastino = inumber;
                                continue;
                        }
                        lastino = inumber;
-                       if (dp->di_size < 0) {
+                       if (/* dp->di_size < 0 || */
+                           dp->di_size + sblock.fs_bsize - 1 < dp->di_size) {
                                if (debug)
                                if (debug)
-                                       printf("bad size %d:", dp->di_size);
+                                       printf("bad size %lu:", dp->di_size);
                                goto unknown;
                        }
                                goto unknown;
                        }
+                       if (!preen && (dp->di_mode & IFMT) == IFMT &&
+                           reply("HOLD BAD BLOCK") == 1) {
+                               dp = ginode(inumber);
+                               dp->di_size = sblock.fs_fsize;
+                               dp->di_mode = IFREG|0600;
+                               inodirty();
+                       }
                        ndb = howmany(dp->di_size, sblock.fs_bsize);
                        ndb = howmany(dp->di_size, sblock.fs_bsize);
-                       if (SPECIAL(dp))
+                       if (ndb < 0) {
+                               if (debug)
+                                       printf("bad size %lu ndb %d:",
+                                               dp->di_size, ndb);
+                               goto unknown;
+                       }
+                       if ((dp->di_mode & IFMT) == IFBLK ||
+                           (dp->di_mode & IFMT) == IFCHR)
                                ndb++;
                        for (j = ndb; j < NDADDR; j++)
                                if (dp->di_db[j] != 0) {
                                        if (debug)
                                ndb++;
                        for (j = ndb; j < NDADDR; j++)
                                if (dp->di_db[j] != 0) {
                                        if (debug)
-                                               printf("bad direct addr: %d\n",
+                                               printf("bad direct addr: %ld\n",
                                                        dp->di_db[j]);
                                        goto unknown;
                                }
                                                        dp->di_db[j]);
                                        goto unknown;
                                }
@@ -89,16 +110,11 @@ pass1()
                        for (; j < NIADDR; j++)
                                if (dp->di_ib[j] != 0) {
                                        if (debug)
                        for (; j < NIADDR; j++)
                                if (dp->di_ib[j] != 0) {
                                        if (debug)
-                                               printf("bad indirect addr: %d\n",
+                                               printf("bad indirect addr: %ld\n",
                                                        dp->di_ib[j]);
                                        goto unknown;
                                }
                                                        dp->di_ib[j]);
                                        goto unknown;
                                }
-                       if (!preen && (dp->di_mode & IFMT) == IFMT &&
-                           reply("HOLD BAD BLOCK") == 1) {
-                               dp->di_size = sblock.fs_fsize;
-                               dp->di_mode = IFREG|0600;
-                               inodirty();
-                       } else if (ftypeok(dp) == 0)
+                       if (ftypeok(dp) == 0)
                                goto unknown;
                        n_files++;
                        lncntp[inumber] = dp->di_nlink;
                                goto unknown;
                        n_files++;
                        lncntp[inumber] = dp->di_nlink;
@@ -114,32 +130,42 @@ pass1()
                                        zlnhead = zlnp;
                                }
                        }
                                        zlnhead = zlnp;
                                }
                        }
-                       statemap[inumber] = DIRCT(dp) ? DSTATE : FSTATE;
-                       badblk = dupblk = 0; maxblk = 0;
+                       if ((dp->di_mode & IFMT) == IFDIR) {
+                               if (dp->di_size == 0)
+                                       statemap[inumber] = DCLEAR;
+                               else
+                                       statemap[inumber] = DSTATE;
+                               cacheino(dp, inumber);
+                       } else
+                               statemap[inumber] = FSTATE;
+                       badblk = dupblk = 0;
                        idesc.id_number = inumber;
                        (void)ckinode(dp, &idesc);
                        idesc.id_entryno *= btodb(sblock.fs_fsize);
                        if (dp->di_blocks != idesc.id_entryno) {
                        idesc.id_number = inumber;
                        (void)ckinode(dp, &idesc);
                        idesc.id_entryno *= btodb(sblock.fs_fsize);
                        if (dp->di_blocks != idesc.id_entryno) {
-                               pwarn("INCORRECT BLOCK COUNT I=%u (%ld should be %ld)",
+                               pwarn("INCORRECT BLOCK COUNT I=%lu (%ld should be %ld)",
                                    inumber, dp->di_blocks, idesc.id_entryno);
                                if (preen)
                                        printf(" (CORRECTED)\n");
                                else if (reply("CORRECT") == 0)
                                        continue;
                                    inumber, dp->di_blocks, idesc.id_entryno);
                                if (preen)
                                        printf(" (CORRECTED)\n");
                                else if (reply("CORRECT") == 0)
                                        continue;
+                               dp = ginode(inumber);
                                dp->di_blocks = idesc.id_entryno;
                                inodirty();
                        }
                        continue;
        unknown:
                                dp->di_blocks = idesc.id_entryno;
                                inodirty();
                        }
                        continue;
        unknown:
-                       pfatal("UNKNOWN FILE TYPE I=%u", inumber);
+                       pfatal("UNKNOWN FILE TYPE I=%lu", inumber);
                        statemap[inumber] = FCLEAR;
                        if (reply("CLEAR") == 1) {
                                statemap[inumber] = USTATE;
                        statemap[inumber] = FCLEAR;
                        if (reply("CLEAR") == 1) {
                                statemap[inumber] = USTATE;
-                               zapino(dp);
+                               dp = ginode(inumber);
+                               clearinode(dp);
                                inodirty();
                        }
                }
        }
                                inodirty();
                        }
                }
        }
+       freeinodebuf();
 }
 
 pass1check(idesc)
 }
 
 pass1check(idesc)
@@ -151,10 +177,10 @@ pass1check(idesc)
        register struct dups *dlp;
        struct dups *new;
 
        register struct dups *dlp;
        struct dups *new;
 
-       if ((anyout = outrange(blkno, idesc->id_numfrags)) != 0) {
-               blkerr(idesc->id_number, "BAD", blkno);
-               if (++badblk >= MAXBAD) {
-                       pwarn("EXCESSIVE BAD BLKS I=%u",
+       if ((anyout = chkrange(blkno, idesc->id_numfrags)) != 0) {
+               blkerror(idesc->id_number, "BAD", blkno);
+               if (badblk++ >= MAXBAD) {
+                       pwarn("EXCESSIVE BAD BLKS I=%lu",
                                idesc->id_number);
                        if (preen)
                                printf(" (SKIPPING)\n");
                                idesc->id_number);
                        if (preen)
                                printf(" (SKIPPING)\n");
@@ -164,15 +190,15 @@ pass1check(idesc)
                }
        }
        for (nfrags = idesc->id_numfrags; nfrags > 0; blkno++, nfrags--) {
                }
        }
        for (nfrags = idesc->id_numfrags; nfrags > 0; blkno++, nfrags--) {
-               if (anyout && outrange(blkno, 1)) {
+               if (anyout && chkrange(blkno, 1)) {
                        res = SKIP;
                        res = SKIP;
-               } else if (!getbmap(blkno)) {
+               } else if (!testbmap(blkno)) {
                        n_blks++;
                        setbmap(blkno);
                } else {
                        n_blks++;
                        setbmap(blkno);
                } else {
-                       blkerr(idesc->id_number, "DUP", blkno);
-                       if (++dupblk >= MAXDUP) {
-                               pwarn("EXCESSIVE DUP BLKS I=%u",
+                       blkerror(idesc->id_number, "DUP", blkno);
+                       if (dupblk++ >= MAXDUP) {
+                               pwarn("EXCESSIVE DUP BLKS I=%lu",
                                        idesc->id_number);
                                if (preen)
                                        printf(" (SKIPPING)\n");
                                        idesc->id_number);
                                if (preen)
                                        printf(" (SKIPPING)\n");