summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ufs-fsck/pass2.c61
1 files changed, 60 insertions, 1 deletions
diff --git a/ufs-fsck/pass2.c b/ufs-fsck/pass2.c
index cb874712..7c00e44c 100644
--- a/ufs-fsck/pass2.c
+++ b/ufs-fsck/pass2.c
@@ -23,6 +23,10 @@
starting at root and mark those we find in inodetype with DIR_REF. */
pass2 ()
{
+ int nd;
+ struct dirinfo *dnp;
+ struct dinode dino, *di = &dino;
+
switch (statemap [ROOTINO])
{
default:
@@ -62,5 +66,60 @@ pass2 ()
statemap[ROOTINO] != DIR_REF;
+ /* Sort inpsort */
+ qsort (dirsorted, dirarrayused, sizeof (struct dirinfo *), sortfunc);
+
+ /* Check basic integrity of each directory */
+ for (nd = 0; nd < dirarrayused; nd++)
+ {
+ dnp = dirsorted[nd];
+
+ if (dnp->i_isize == 0)
+ continue;
+ if (dnp->i_isize % DIRBLKSIZ)
+ {
+ getpathname (pathbuf, dnp->i_number, dnp->i_number);
+ pwarn ("DIRECTORY %s: LENGTH %d NOT MULTIPLE OF %d",
+ pathbuf, dnp->i_isize, DIRBLKSIZ);
+ if (preen || reply ("ADJUST"))
+ {
+ if (preen)
+ printf (" (ADJUSTED)");
+ getinode (number, &dino);
+ dino.di_size = roundup (dnp->i_isize, DIRBLKSIZ);
+ write_inode (number, &dino);
+ }
+ }
+ bzero (di, sizeof (struct dinode));
+ di->di_size = dnp->i_isize;
+ bcopy (dnp->i_blks, di->di_db, dnp->i_numblks);
+
+ datablocks_iterate (dp, checkdirblock);
+ }
-
+ /* At this point for each directory:
+ If this directory is an entry in another directory, then i_parent is
+ set to that nodes directory.
+ If this directory has a `..' entry, then i_dotdot is set to that link.
+ Check to see that `..' is set correctly. */
+ for (nd = 0; nd < dirarrayused; nd++)
+ {
+ dnp = dirsorted[nd];
+ if (dnp->i_parent == 0 || dnp->i_isize == 0)
+ continue;
+
+ if (dnp->i_dotdot == dnp->i_parent
+ || dnp->i_dotdot == -1)
+ continue;
+
+ if (dnp->i_dotdot == 0)
+ {
+ dnp->i_dotdot = dnp->i_parent;
+
+ fileerror (dnp->i_parent, dnp->i_number, "MISSING `..'");
+ if (reply ("FIX"))
+ {
+ makeentry (dnp->i_number, dnp->i_parent, "..");
+
+
+