diff options
Diffstat (limited to 'ufs-fsck/pass2.c')
-rw-r--r-- | ufs-fsck/pass2.c | 61 |
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, ".."); + + + |