save block pointers of directories as they are encountered in pass1
authorKirk McKusick <mckusick@ucbvax.Berkeley.EDU>
Fri, 2 Feb 1990 15:36:24 +0000 (07:36 -0800)
committerKirk McKusick <mckusick@ucbvax.Berkeley.EDU>
Fri, 2 Feb 1990 15:36:24 +0000 (07:36 -0800)
so that they do not have to be reread when descending in pass2

SCCS-vsn: sbin/fsck/main.c 5.18
SCCS-vsn: sbin/fsck/utilities.c 5.22
SCCS-vsn: sbin/fsck/pass1.c 5.10
SCCS-vsn: sbin/fsck/dir.c 5.11
SCCS-vsn: sbin/fsck/inode.c 5.12
SCCS-vsn: sbin/fsck/fsck.h 5.11
SCCS-vsn: sbin/fsck/pass3.c 5.7

usr/src/sbin/fsck/dir.c
usr/src/sbin/fsck/fsck.h
usr/src/sbin/fsck/inode.c
usr/src/sbin/fsck/main.c
usr/src/sbin/fsck/pass1.c
usr/src/sbin/fsck/pass3.c
usr/src/sbin/fsck/utilities.c

index 6191d14..cfd74a6 100644 (file)
@@ -16,7 +16,7 @@
  */
 
 #ifndef lint
  */
 
 #ifndef lint
-static char sccsid[] = "@(#)dir.c      5.10 (Berkeley) %G%";
+static char sccsid[] = "@(#)dir.c      5.11 (Berkeley) %G%";
 #endif /* not lint */
 
 #include <sys/param.h>
 #endif /* not lint */
 
 #include <sys/param.h>
@@ -49,7 +49,7 @@ descend(parentino, inumber)
        if (statemap[inumber] != DSTATE)
                errexit("BAD INODE %d TO DESCEND", statemap[inumber]);
        statemap[inumber] = DFOUND;
        if (statemap[inumber] != DSTATE)
                errexit("BAD INODE %d TO DESCEND", statemap[inumber]);
        statemap[inumber] = DFOUND;
-       dp = ginode(inumber);
+       dp = getcacheino(inumber);
        if (dp->di_size == 0) {
                direrror(inumber, "ZERO LENGTH DIRECTORY");
                if (reply("REMOVE") == 1)
        if (dp->di_size == 0) {
                direrror(inumber, "ZERO LENGTH DIRECTORY");
                if (reply("REMOVE") == 1)
@@ -59,8 +59,11 @@ descend(parentino, inumber)
        if (dp->di_size < MINDIRSIZE) {
                direrror(inumber, "DIRECTORY TOO SHORT");
                dp->di_size = MINDIRSIZE;
        if (dp->di_size < MINDIRSIZE) {
                direrror(inumber, "DIRECTORY TOO SHORT");
                dp->di_size = MINDIRSIZE;
-               if (reply("FIX") == 1)
+               if (reply("FIX") == 1) {
+                       dp = ginode(inumber);
+                       dp->di_size = MINDIRSIZE;
                        inodirty();
                        inodirty();
+               }
        }
        if ((dp->di_size & (DIRBLKSIZ - 1)) != 0) {
                pwarn("DIRECTORY %s: LENGTH %d NOT MULTIPLE OF %d",
        }
        if ((dp->di_size & (DIRBLKSIZ - 1)) != 0) {
                pwarn("DIRECTORY %s: LENGTH %d NOT MULTIPLE OF %d",
@@ -68,8 +71,11 @@ descend(parentino, inumber)
                dp->di_size = roundup(dp->di_size, DIRBLKSIZ);
                if (preen)
                        printf(" (ADJUSTED)\n");
                dp->di_size = roundup(dp->di_size, DIRBLKSIZ);
                if (preen)
                        printf(" (ADJUSTED)\n");
-               if (preen || reply("ADJUST") == 1)
+               if (preen || reply("ADJUST") == 1) {
+                       dp = ginode(inumber);
+                       dp->di_size = roundup(dp->di_size, DIRBLKSIZ);
                        inodirty();
                        inodirty();
+               }
        }
        curino.id_type = DATA;
        curino.id_func = parentino->id_func;
        }
        curino.id_type = DATA;
        curino.id_func = parentino->id_func;
index 373473f..ab33b2c 100644 (file)
@@ -14,7 +14,7 @@
  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
  *
  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
  *
- *     @(#)fsck.h      5.10 (Berkeley) %G%
+ *     @(#)fsck.h      5.11 (Berkeley) %G%
  */
 
 #define        MAXDUP          10       /* limit on dup blks (per inode) */
  */
 
 #define        MAXDUP          10       /* limit on dup blks (per inode) */
@@ -176,6 +176,7 @@ struct      dinode zino;
 
 time_t time();
 struct dinode *ginode();
 
 time_t time();
 struct dinode *ginode();
+struct dinode *getcacheino();
 struct bufarea *getblk();
 ino_t allocino();
 int findino();
 struct bufarea *getblk();
 ino_t allocino();
 int findino();
index dffd09d..5539398 100644 (file)
@@ -16,7 +16,7 @@
  */
 
 #ifndef lint
  */
 
 #ifndef lint
-static char sccsid[] = "@(#)inode.c    5.11 (Berkeley) %G%";
+static char sccsid[] = "@(#)inode.c    5.12 (Berkeley) %G%";
 #endif /* not lint */
 
 #include <sys/param.h>
 #endif /* not lint */
 
 #include <sys/param.h>
@@ -27,6 +27,17 @@ static char sccsid[] = "@(#)inode.c  5.11 (Berkeley) %G%";
 #include "fsck.h"
 
 struct bufarea *pbp = 0;
 #include "fsck.h"
 
 struct bufarea *pbp = 0;
+/*
+ * Inode cache data structures.
+ */
+struct inoinfo {
+       struct  inoinfo *i_next;        /* next entry in hash chain */
+       ino_t   i_number;               /* inode number of this entry */
+       size_t  i_size;                 /* size of inode */
+       u_int   i_numblks;              /* size of block array */
+       daddr_t i_blks[1];              /* actually longer */
+} **inphead;
+long hashsize;
 
 ckinode(dp, idesc)
        struct dinode *dp;
 
 ckinode(dp, idesc)
        struct dinode *dp;
@@ -188,6 +199,73 @@ ginode(inumber)
        return (&pbp->b_un.b_dinode[inumber % INOPB(&sblock)]);
 }
 
        return (&pbp->b_un.b_dinode[inumber % INOPB(&sblock)]);
 }
 
+cacheino(dp, inumber)
+       register struct dinode *dp;
+       ino_t inumber;
+{
+       register struct inoinfo *inp;
+       struct inoinfo **inpp;
+       unsigned int blks;
+
+       if (inphead == NULL) {
+               hashsize = sblock.fs_cstotal.cs_ndir;
+               inphead = (struct inoinfo **)malloc(hashsize * sizeof(daddr_t));
+               if (inphead == NULL)
+                       return;
+               bzero((char *)inphead, hashsize * sizeof(daddr_t));
+       }
+       blks = howmany(dp->di_size, sblock.fs_bsize);
+       if (blks > NDADDR)
+               blks = NDADDR + NIADDR;
+       inp = (struct inoinfo *)
+               malloc(sizeof(*inp) + (blks - 1) * sizeof(daddr_t));
+       if (inp == NULL)
+               return;
+       inpp = &inphead[inumber % hashsize];
+       inp->i_next = *inpp;
+       *inpp = inp;
+       inp->i_number = inumber;
+       inp->i_size = dp->di_size;
+       inp->i_numblks = blks * sizeof(daddr_t);
+       bcopy((char *)&dp->di_db[0], (char *)&inp->i_blks[0], inp->i_numblks);
+}
+
+struct dinode *
+getcacheino(inumber)
+       ino_t inumber;
+{
+       register struct inoinfo *inp;
+       static struct dinode dino;
+       register struct dinode *dp = &dino;
+
+       for (inp = inphead[inumber % hashsize]; inp; inp = inp->i_next) {
+               if (inp->i_number != inumber)
+                       continue;
+               dp->di_size = inp->i_size;
+               bcopy((char *)&inp->i_blks[0], (char *)&dp->di_db[0],
+                       inp->i_numblks);
+               return (dp);
+       }
+       return (ginode(inumber));
+}
+
+inocleanup()
+{
+       register struct inoinfo *inp, **inpp;
+       struct inoinfo *inpnext;
+
+       if (inphead == NULL)
+               return;
+       for (inpp = &inphead[hashsize - 1]; inpp >= inphead; inpp--) {
+               for (inp = *inpp; inp; inp = inpnext) {
+                       inpnext = inp->i_next;
+                       free(inp);
+               }
+       }
+       free(inphead);
+       inphead = NULL;
+}
+       
 inodirty()
 {
        
 inodirty()
 {
        
index fd6b7f5..bdde2ab 100644 (file)
@@ -22,7 +22,7 @@ char copyright[] =
 #endif /* not lint */
 
 #ifndef lint
 #endif /* not lint */
 
 #ifndef lint
-static char sccsid[] = "@(#)main.c     5.17 (Berkeley) %G%";
+static char sccsid[] = "@(#)main.c     5.18 (Berkeley) %G%";
 #endif /* not lint */
 
 #include <sys/param.h>
 #endif /* not lint */
 
 #include <sys/param.h>
@@ -405,6 +405,7 @@ checkfilesys(filesys)
        }
        zlnhead = (struct zlncnt *)0;
        duplist = (struct dups *)0;
        }
        zlnhead = (struct zlncnt *)0;
        duplist = (struct dups *)0;
+       inocleanup();
        if (fsmodified) {
                (void)time(&sblock.fs_time);
                sbdirty();
        if (fsmodified) {
                (void)time(&sblock.fs_time);
                sbdirty();
index ec676a5..aadff78 100644 (file)
@@ -16,7 +16,7 @@
  */
 
 #ifndef lint
  */
 
 #ifndef lint
-static char sccsid[] = "@(#)pass1.c    5.9 (Berkeley) %G%";
+static char sccsid[] = "@(#)pass1.c    5.10 (Berkeley) %G%";
 #endif /* not lint */
 
 #include <sys/param.h>
 #endif /* not lint */
 
 #include <sys/param.h>
@@ -134,8 +134,11 @@ pass1()
                                        zlnhead = zlnp;
                                }
                        }
                                        zlnhead = zlnp;
                                }
                        }
-                       statemap[inumber] =
-                           (dp->di_mode & IFMT) == IFDIR ? DSTATE : FSTATE;
+                       if ((dp->di_mode & IFMT) == IFDIR) {
+                               statemap[inumber] = DSTATE;
+                               cacheino(dp, inumber);
+                       } else
+                               statemap[inumber] = FSTATE;
                        badblk = dupblk = 0;
                        idesc.id_number = inumber;
                        (void)ckinode(dp, &idesc);
                        badblk = dupblk = 0;
                        idesc.id_number = inumber;
                        (void)ckinode(dp, &idesc);
index 76f17bf..0e053ae 100644 (file)
@@ -16,7 +16,7 @@
  */
 
 #ifndef lint
  */
 
 #ifndef lint
-static char sccsid[] = "@(#)pass3.c    5.6 (Berkeley) %G%";
+static char sccsid[] = "@(#)pass3.c    5.7 (Berkeley) %G%";
 #endif /* not lint */
 
 #include <sys/param.h>
 #endif /* not lint */
 
 #include <sys/param.h>
@@ -48,7 +48,7 @@ pass3()
                                orphan = idesc.id_parent;
                                if (orphan < ROOTINO || orphan > maxino)
                                        break;
                                orphan = idesc.id_parent;
                                if (orphan < ROOTINO || orphan > maxino)
                                        break;
-                               dp = ginode(orphan);
+                               dp = getcacheino(orphan);
                                idesc.id_parent = 0;
                                idesc.id_number = orphan;
                                if ((ckinode(dp, &idesc) & FOUND) == 0)
                                idesc.id_parent = 0;
                                idesc.id_number = orphan;
                                if ((ckinode(dp, &idesc) & FOUND) == 0)
index 2596af4..ad466f2 100644 (file)
@@ -16,7 +16,7 @@
  */
 
 #ifndef lint
  */
 
 #ifndef lint
-static char sccsid[] = "@(#)utilities.c        5.21 (Berkeley) %G%";
+static char sccsid[] = "@(#)utilities.c        5.22 (Berkeley) %G%";
 #endif /* not lint */
 
 #include <sys/param.h>
 #endif /* not lint */
 
 #include <sys/param.h>
@@ -374,14 +374,14 @@ getpathname(namebuf, curdir, ino)
                idesc.id_number = ino;
                idesc.id_func = findino;
                idesc.id_name = "..";
                idesc.id_number = ino;
                idesc.id_func = findino;
                idesc.id_name = "..";
-               if ((ckinode(ginode(ino), &idesc) & FOUND) == 0)
+               if ((ckinode(getcacheino(ino), &idesc) & FOUND) == 0)
                        break;
        namelookup:
                idesc.id_number = idesc.id_parent;
                idesc.id_parent = ino;
                idesc.id_func = findname;
                idesc.id_name = namebuf;
                        break;
        namelookup:
                idesc.id_number = idesc.id_parent;
                idesc.id_parent = ino;
                idesc.id_func = findname;
                idesc.id_name = namebuf;
-               if ((ckinode(ginode(idesc.id_number), &idesc) & FOUND) == 0)
+               if ((ckinode(getcacheino(idesc.id_number), &idesc)&FOUND) == 0)
                        break;
                len = strlen(namebuf);
                cp -= len;
                        break;
                len = strlen(namebuf);
                cp -= len;