diff options
author | julian <julian@FreeBSD.org> | 1998-12-03 02:27:35 +0000 |
---|---|---|
committer | julian <julian@FreeBSD.org> | 1998-12-03 02:27:35 +0000 |
commit | c1ef9f83c919949e90841ae0990aa9a0273d6490 (patch) | |
tree | 766d55719160577172499b05ce54cc96670cf3c4 /sbin/fsck_ffs/pass3.c | |
parent | 1a5eceeafeb45fc95a5c9fe1830e0d3e349ec69a (diff) | |
download | FreeBSD-src-c1ef9f83c919949e90841ae0990aa9a0273d6490.zip FreeBSD-src-c1ef9f83c919949e90841ae0990aa9a0273d6490.tar.gz |
Reviewed by: Don Lewis <Don.Lewis@tsc.tdk.com>
Submitted by: Kirk McKusick <mckusick@McKusick.COM>
Obtained from: Mckusick, BSDI and a host of others
This exactly matches Kirks sources imported under the
Tag MCKUSICK2. These are as supplied by kirk with one small
change needed to compile under freeBSD.
Some FreeBSD patches will be added back, though many have been
added to Kirk's sources already.
Diffstat (limited to 'sbin/fsck_ffs/pass3.c')
-rw-r--r-- | sbin/fsck_ffs/pass3.c | 71 |
1 files changed, 55 insertions, 16 deletions
diff --git a/sbin/fsck_ffs/pass3.c b/sbin/fsck_ffs/pass3.c index 6524a11..6320755 100644 --- a/sbin/fsck_ffs/pass3.c +++ b/sbin/fsck_ffs/pass3.c @@ -32,45 +32,84 @@ */ #ifndef lint -#if 0 static const char sccsid[] = "@(#)pass3.c 8.2 (Berkeley) 4/27/95"; -#endif -static const char rcsid[] = - "$Id$"; #endif /* not lint */ #include <sys/param.h> +#include <sys/time.h> #include <ufs/ufs/dinode.h> +#include <ufs/ufs/dir.h> +#include <ufs/ffs/fs.h> + +#include <string.h> #include "fsck.h" void pass3() { - register struct inoinfo **inpp, *inp; + struct inoinfo *inp; + int loopcnt, inpindex, state; ino_t orphan; - int loopcnt; + struct inodesc idesc; + char namebuf[MAXNAMLEN+1]; - for (inpp = &inpsort[inplast - 1]; inpp >= inpsort; inpp--) { - inp = *inpp; + for (inpindex = inplast - 1; inpindex >= 0; inpindex--) { + inp = inpsort[inpindex]; + state = inoinfo(inp->i_number)->ino_state; if (inp->i_number == ROOTINO || - !(inp->i_parent == 0 || statemap[inp->i_number] == DSTATE)) + (inp->i_parent != 0 && state != DSTATE)) + continue; + if (state == DCLEAR) continue; - if (statemap[inp->i_number] == DCLEAR) + /* + * If we are running with soft updates and we come + * across unreferenced directories, we just leave + * them in DSTATE which will cause them to be pitched + * in pass 4. + */ + if (preen && resolved && usedsoftdep && state == DSTATE) { + if (inp->i_dotdot >= ROOTINO) + inoinfo(inp->i_dotdot)->ino_linkcnt++; continue; + } for (loopcnt = 0; ; loopcnt++) { orphan = inp->i_number; if (inp->i_parent == 0 || - statemap[inp->i_parent] != DSTATE || - loopcnt > numdirs) + inoinfo(inp->i_parent)->ino_state != DSTATE || + loopcnt > countdirs) break; inp = getinoinfo(inp->i_parent); } - (void)linkup(orphan, inp->i_dotdot); - inp->i_parent = inp->i_dotdot = lfdir; - lncntp[lfdir]--; - statemap[orphan] = DFOUND; + if (loopcnt <= countdirs) { + if (linkup(orphan, inp->i_dotdot, NULL)) { + inp->i_parent = inp->i_dotdot = lfdir; + inoinfo(lfdir)->ino_linkcnt--; + } + inoinfo(orphan)->ino_state = DFOUND; + propagate(); + continue; + } + pfatal("ORPHANED DIRECTORY LOOP DETECTED I=%lu", orphan); + if (reply("RECONNECT") == 0) + continue; + memset(&idesc, 0, sizeof(struct inodesc)); + idesc.id_type = DATA; + idesc.id_number = inp->i_parent; + idesc.id_parent = orphan; + idesc.id_func = findname; + idesc.id_name = namebuf; + if ((ckinode(ginode(inp->i_parent), &idesc) & FOUND) == 0) + pfatal("COULD NOT FIND NAME IN PARENT DIRECTORY"); + if (linkup(orphan, inp->i_parent, namebuf)) { + idesc.id_func = clearentry; + if (ckinode(ginode(inp->i_parent), &idesc) & FOUND) + inoinfo(orphan)->ino_linkcnt++; + inp->i_parent = inp->i_dotdot = lfdir; + inoinfo(lfdir)->ino_linkcnt--; + } + inoinfo(orphan)->ino_state = DFOUND; propagate(); } } |