pass3.c revision 92839
1258210Srpaulo/*
2258210Srpaulo * Copyright (c) 1980, 1986, 1993
3327595Sian *	The Regents of the University of California.  All rights reserved.
4258210Srpaulo *
5258210Srpaulo * Redistribution and use in source and binary forms, with or without
6258210Srpaulo * modification, are permitted provided that the following conditions
7258210Srpaulo * are met:
8258210Srpaulo * 1. Redistributions of source code must retain the above copyright
9258210Srpaulo *    notice, this list of conditions and the following disclaimer.
10258210Srpaulo * 2. Redistributions in binary form must reproduce the above copyright
11258210Srpaulo *    notice, this list of conditions and the following disclaimer in the
12258210Srpaulo *    documentation and/or other materials provided with the distribution.
13258210Srpaulo * 3. All advertising materials mentioning features or use of this software
14258210Srpaulo *    must display the following acknowledgement:
15258210Srpaulo *	This product includes software developed by the University of
16258210Srpaulo *	California, Berkeley and its contributors.
17258210Srpaulo * 4. Neither the name of the University nor the names of its contributors
18258210Srpaulo *    may be used to endorse or promote products derived from this software
19258210Srpaulo *    without specific prior written permission.
20258210Srpaulo *
21258210Srpaulo * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
22258210Srpaulo * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23258210Srpaulo * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24258210Srpaulo * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
25258210Srpaulo * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26258210Srpaulo * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27258210Srpaulo * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28258210Srpaulo * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29258210Srpaulo * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30327595Sian * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31327595Sian * SUCH DAMAGE.
32327595Sian */
33258210Srpaulo
34258210Srpaulo#ifndef lint
35327595Sian#if 0
36258210Srpaulostatic const char sccsid[] = "@(#)pass3.c	8.2 (Berkeley) 4/27/95";
37258210Srpaulo#endif
38258210Srpaulostatic const char rcsid[] =
39258210Srpaulo  "$FreeBSD: head/sbin/fsck_ffs/pass3.c 92839 2002-03-20 22:57:10Z imp $";
40258210Srpaulo#endif /* not lint */
41258210Srpaulo
42327595Sian#include <sys/param.h>
43327595Sian
44258210Srpaulo#include <ufs/ufs/dinode.h>
45258210Srpaulo#include <ufs/ufs/dir.h>
46258210Srpaulo#include <ufs/ffs/fs.h>
47258210Srpaulo
48258210Srpaulo#include <string.h>
49258210Srpaulo
50327595Sian#include "fsck.h"
51258210Srpaulo
52258210Srpaulovoid
53258210Srpaulopass3(void)
54258210Srpaulo{
55258210Srpaulo	struct inoinfo *inp;
56258210Srpaulo	int loopcnt, inpindex, state;
57258210Srpaulo	ino_t orphan;
58258210Srpaulo	struct inodesc idesc;
59258210Srpaulo	char namebuf[MAXNAMLEN+1];
60258210Srpaulo
61258210Srpaulo	for (inpindex = inplast - 1; inpindex >= 0; inpindex--) {
62258210Srpaulo		if (got_siginfo) {
63258210Srpaulo			printf("%s: phase 3: dir %d of %d (%d%%)\n", cdevname,
64258210Srpaulo			    (int)(inplast - inpindex - 1), (int)inplast,
65258210Srpaulo			    (int)((inplast - inpindex - 1) * 100 / inplast));
66258210Srpaulo			got_siginfo = 0;
67258210Srpaulo		}
68258210Srpaulo		inp = inpsort[inpindex];
69327595Sian		state = inoinfo(inp->i_number)->ino_state;
70327595Sian		if (inp->i_number == ROOTINO ||
71327595Sian		    (inp->i_parent != 0 && state != DSTATE))
72327595Sian			continue;
73258210Srpaulo		if (state == DCLEAR)
74258210Srpaulo			continue;
75258210Srpaulo		/*
76258210Srpaulo		 * If we are running with soft updates and we come
77258210Srpaulo		 * across unreferenced directories, we just leave
78258210Srpaulo		 * them in DSTATE which will cause them to be pitched
79327595Sian		 * in pass 4.
80327595Sian		 */
81327595Sian		if ((preen || bkgrdflag) &&
82327595Sian		    resolved && usedsoftdep && state == DSTATE) {
83258210Srpaulo			if (inp->i_dotdot >= ROOTINO)
84327595Sian				inoinfo(inp->i_dotdot)->ino_linkcnt++;
85327595Sian			continue;
86327595Sian		}
87327595Sian		for (loopcnt = 0; ; loopcnt++) {
88327595Sian			orphan = inp->i_number;
89327595Sian			if (inp->i_parent == 0 ||
90283138Srpaulo			    inoinfo(inp->i_parent)->ino_state != DSTATE ||
91327595Sian			    loopcnt > countdirs)
92327595Sian				break;
93327595Sian			inp = getinoinfo(inp->i_parent);
94327595Sian		}
95327595Sian		if (loopcnt <= countdirs) {
96327595Sian			if (linkup(orphan, inp->i_dotdot, NULL)) {
97327595Sian				inp->i_parent = inp->i_dotdot = lfdir;
98327595Sian				inoinfo(lfdir)->ino_linkcnt--;
99327595Sian			}
100327595Sian			inoinfo(orphan)->ino_state = DFOUND;
101327595Sian			propagate();
102327595Sian			continue;
103327595Sian		}
104327595Sian		pfatal("ORPHANED DIRECTORY LOOP DETECTED I=%lu",
105327595Sian		    (u_long)orphan);
106327595Sian		if (reply("RECONNECT") == 0)
107327595Sian			continue;
108327595Sian		memset(&idesc, 0, sizeof(struct inodesc));
109327595Sian		idesc.id_type = DATA;
110327595Sian		idesc.id_number = inp->i_parent;
111327595Sian		idesc.id_parent = orphan;
112327595Sian		idesc.id_func = findname;
113327595Sian		idesc.id_name = namebuf;
114327595Sian		if ((ckinode(ginode(inp->i_parent), &idesc) & FOUND) == 0)
115327595Sian			pfatal("COULD NOT FIND NAME IN PARENT DIRECTORY");
116327595Sian		if (linkup(orphan, inp->i_parent, namebuf)) {
117327595Sian			idesc.id_func = clearentry;
118327595Sian			if (ckinode(ginode(inp->i_parent), &idesc) & FOUND)
119327595Sian				inoinfo(orphan)->ino_linkcnt++;
120327595Sian			inp->i_parent = inp->i_dotdot = lfdir;
121327595Sian			inoinfo(lfdir)->ino_linkcnt--;
122327595Sian		}
123327595Sian		inoinfo(orphan)->ino_state = DFOUND;
124258210Srpaulo		propagate();
125258210Srpaulo	}
126258210Srpaulo}
127327595Sian