diff options
Diffstat (limited to 'sbin/fsck/dir.c')
-rw-r--r-- | sbin/fsck/dir.c | 87 |
1 files changed, 28 insertions, 59 deletions
diff --git a/sbin/fsck/dir.c b/sbin/fsck/dir.c index 71e8a05b9139b..91b507fa2b13a 100644 --- a/sbin/fsck/dir.c +++ b/sbin/fsck/dir.c @@ -36,11 +36,10 @@ static const char sccsid[] = "@(#)dir.c 8.8 (Berkeley) 4/28/95"; #endif static const char rcsid[] = - "$Id: dir.c,v 1.12 1998/09/23 05:37:35 nate Exp $"; + "$Id: dir.c,v 1.11 1998/06/28 19:23:02 bde Exp $"; #endif /* not lint */ #include <sys/param.h> -#include <sys/time.h> #include <ufs/ufs/dinode.h> #include <ufs/ufs/dir.h> @@ -89,9 +88,9 @@ propagate() inp = *inpp; if (inp->i_parent == 0) continue; - if (inoinfo(inp->i_parent)->ino_state == DFOUND && - inoinfo(inp->i_number)->ino_state == DSTATE) { - inoinfo(inp->i_number)->ino_state = DFOUND; + if (statemap[inp->i_parent] == DFOUND && + statemap[inp->i_number] == DSTATE) { + statemap[inp->i_number] = DFOUND; change++; } } @@ -124,8 +123,6 @@ dirscan(idesc) idesc->id_loc = 0; for (dp = fsck_readdir(idesc); dp != NULL; dp = fsck_readdir(idesc)) { dsize = dp->d_reclen; - if (dsize > sizeof(dbuf)) - dsize = sizeof(dbuf); memmove(dbuf, dp, (size_t)dsize); # if (BYTE_ORDER == LITTLE_ENDIAN) if (!newinofmt) { @@ -238,7 +235,8 @@ dircheck(idesc, dp) int spaceleft; spaceleft = DIRBLKSIZ - (idesc->id_loc % DIRBLKSIZ); - if (dp->d_reclen == 0 || + if (dp->d_ino >= maxino || + dp->d_reclen == 0 || dp->d_reclen > spaceleft || (dp->d_reclen & 0x3) != 0) return (0); @@ -308,40 +306,13 @@ adjust(idesc, lcnt) register struct inodesc *idesc; int lcnt; { - struct dinode *dp; - int saveresolved; + register struct dinode *dp; dp = ginode(idesc->id_number); if (dp->di_nlink == lcnt) { - /* - * If we have not hit any unresolved problems, are running - * in preen mode, and are on a filesystem using soft updates, - * then just toss any partially allocated files. - */ - if (resolved && preen && usedsoftdep) { - clri(idesc, "UNREF", 1); - return; - } else { - /* - * The filesystem can be marked clean even if - * a file is not linked up, but is cleared. - * Hence, resolved should not be cleared when - * linkup is answered no, but clri is answered yes. - */ - saveresolved = resolved; - if (linkup(idesc->id_number, (ino_t)0, NULL) == 0) { - resolved = saveresolved; - clri(idesc, "UNREF", 0); - return; - } - /* - * Account for the new reference created by linkup(). - */ - dp = ginode(idesc->id_number); - lcnt--; - } - } - if (lcnt != 0) { + if (linkup(idesc->id_number, (ino_t)0) == 0) + clri(idesc, "UNREF", 0); + } else { pwarn("LINK COUNT %s", (lfdir == idesc->id_number) ? lfname : ((dp->di_mode & IFMT) == IFDIR ? "DIR" : "FILE")); pinode(idesc->id_number); @@ -384,7 +355,7 @@ mkentry(idesc) dirp->d_ino = idesc->id_parent; /* ino to be entered is in id_parent */ dirp->d_reclen = newent.d_reclen; if (newinofmt) - dirp->d_type = inoinfo(idesc->id_parent)->ino_type; + dirp->d_type = typemap[idesc->id_parent]; else dirp->d_type = 0; dirp->d_namlen = newent.d_namlen; @@ -417,17 +388,16 @@ chgino(idesc) return (KEEPON); dirp->d_ino = idesc->id_parent; if (newinofmt) - dirp->d_type = inoinfo(idesc->id_parent)->ino_type; + dirp->d_type = typemap[idesc->id_parent]; else dirp->d_type = 0; return (ALTERED|STOP); } int -linkup(orphan, parentdir, name) +linkup(orphan, parentdir) ino_t orphan; ino_t parentdir; - char *name; { register struct dinode *dp; int lostdir; @@ -440,7 +410,7 @@ linkup(orphan, parentdir, name) lostdir = (dp->di_mode & IFMT) == IFDIR; pwarn("UNREF %s ", lostdir ? "DIR" : "FILE"); pinode(orphan); - if (preen && dp->di_size == 0) + if ((preen || usedsoftdep) && dp->di_size == 0) return (0); if (preen) printf(" (RECONNECTED)\n"); @@ -461,7 +431,6 @@ linkup(orphan, parentdir, name) lfdir = allocdir(ROOTINO, (ino_t)0, lfmode); if (lfdir != 0) { if (makeentry(ROOTINO, lfdir, lfname) != 0) { - numdirs++; if (preen) printf(" (CREATED)\n"); } else { @@ -497,21 +466,21 @@ linkup(orphan, parentdir, name) idesc.id_type = ADDR; idesc.id_func = pass4check; idesc.id_number = oldlfdir; - adjust(&idesc, inoinfo(oldlfdir)->ino_linkcnt + 1); - inoinfo(oldlfdir)->ino_linkcnt = 0; + adjust(&idesc, lncntp[oldlfdir] + 1); + lncntp[oldlfdir] = 0; dp = ginode(lfdir); } - if (inoinfo(lfdir)->ino_state != DFOUND) { + if (statemap[lfdir] != DFOUND) { pfatal("SORRY. NO lost+found DIRECTORY\n\n"); return (0); } (void)lftempname(tempname, orphan); - if (makeentry(lfdir, orphan, (name ? name : tempname)) == 0) { + if (makeentry(lfdir, orphan, tempname) == 0) { pfatal("SORRY. NO SPACE IN lost+found DIRECTORY"); printf("\n\n"); return (0); } - inoinfo(orphan)->ino_linkcnt--; + lncntp[orphan]--; if (lostdir) { if ((changeino(orphan, "..", lfdir) & ALTERED) == 0 && parentdir != (ino_t)-1) @@ -519,7 +488,7 @@ linkup(orphan, parentdir, name) dp = ginode(lfdir); dp->di_nlink++; inodirty(); - inoinfo(lfdir)->ino_linkcnt++; + lncntp[lfdir]++; pwarn("DIR I=%lu CONNECTED. ", orphan); if (parentdir != (ino_t)-1) { printf("PARENT WAS I=%lu\n", (u_long)parentdir); @@ -530,7 +499,8 @@ linkup(orphan, parentdir, name) * fixes the parent link count so that fsck does * not need to be rerun. */ - inoinfo(parentdir)->ino_linkcnt++; + lncntp[parentdir]++; + } if (preen == 0) printf("\n"); @@ -688,20 +658,19 @@ allocdir(parent, request, mode) dp->di_nlink = 2; inodirty(); if (ino == ROOTINO) { - inoinfo(ino)->ino_linkcnt = dp->di_nlink; + lncntp[ino] = dp->di_nlink; cacheino(dp, ino); return(ino); } - if (inoinfo(parent)->ino_state != DSTATE && - inoinfo(parent)->ino_state != DFOUND) { + if (statemap[parent] != DSTATE && statemap[parent] != DFOUND) { freeino(ino); return (0); } cacheino(dp, ino); - inoinfo(ino)->ino_state = inoinfo(parent)->ino_state; - if (inoinfo(ino)->ino_state == DSTATE) { - inoinfo(ino)->ino_linkcnt = dp->di_nlink; - inoinfo(parent)->ino_linkcnt++; + statemap[ino] = statemap[parent]; + if (statemap[ino] == DSTATE) { + lncntp[ino] = dp->di_nlink; + lncntp[parent]++; } dp = ginode(parent); dp->di_nlink++; |