pass3.c revision 136281
1166124Srafan/* 250276Speter * Copyright (c) 1980, 1986, 1993 3166124Srafan * The Regents of the University of California. All rights reserved. 450276Speter * 550276Speter * Redistribution and use in source and binary forms, with or without 650276Speter * modification, are permitted provided that the following conditions 750276Speter * are met: 850276Speter * 1. Redistributions of source code must retain the above copyright 950276Speter * notice, this list of conditions and the following disclaimer. 1050276Speter * 2. Redistributions in binary form must reproduce the above copyright 1150276Speter * notice, this list of conditions and the following disclaimer in the 1250276Speter * documentation and/or other materials provided with the distribution. 1350276Speter * 4. Neither the name of the University nor the names of its contributors 1450276Speter * may be used to endorse or promote products derived from this software 1550276Speter * without specific prior written permission. 1650276Speter * 1750276Speter * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 1850276Speter * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 1950276Speter * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 2050276Speter * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 2150276Speter * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 2250276Speter * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 2350276Speter * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 2450276Speter * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 2550276Speter * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 2650276Speter * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 2750276Speter * SUCH DAMAGE. 2850276Speter */ 2950276Speter 30166124Srafan#if 0 3150276Speter#ifndef lint 3250276Speterstatic const char sccsid[] = "@(#)pass3.c 8.2 (Berkeley) 4/27/95"; 3350276Speter#endif /* not lint */ 3450276Speter#endif 3550276Speter#include <sys/cdefs.h> 3650276Speter__FBSDID("$FreeBSD: head/sbin/fsck_ffs/pass3.c 136281 2004-10-08 20:44:47Z truckman $"); 3750276Speter 3850276Speter#include <sys/param.h> 39166124Srafan 4050276Speter#include <ufs/ufs/dinode.h> 4150276Speter#include <ufs/ufs/dir.h> 4250276Speter#include <ufs/ffs/fs.h> 43166124Srafan 44166124Srafan#include <string.h> 45166124Srafan 46166124Srafan#include "fsck.h" 4750276Speter 4850276Spetervoid 4950276Speterpass3(void) 5050276Speter{ 5150276Speter struct inoinfo *inp; 5250276Speter int loopcnt, inpindex, state; 5350276Speter ino_t orphan; 5450276Speter struct inodesc idesc; 5550276Speter char namebuf[MAXNAMLEN+1]; 5650276Speter 5750276Speter for (inpindex = inplast - 1; inpindex >= 0; inpindex--) { 5850276Speter if (got_siginfo) { 5950276Speter printf("%s: phase 3: dir %d of %d (%d%%)\n", cdevname, 6050276Speter (int)(inplast - inpindex - 1), (int)inplast, 6150276Speter (int)((inplast - inpindex - 1) * 100 / inplast)); 6250276Speter got_siginfo = 0; 6350276Speter } 6450276Speter if (got_sigalarm) { 6550276Speter setproctitle("%s p3 %d%%", cdevname, 6650276Speter (int)((inplast - inpindex - 1) * 100 / inplast)); 6750276Speter got_sigalarm = 0; 68166124Srafan } 69166124Srafan inp = inpsort[inpindex]; 70166124Srafan state = inoinfo(inp->i_number)->ino_state; 71166124Srafan if (inp->i_number == ROOTINO || 72166124Srafan (inp->i_parent != 0 && !S_IS_DUNFOUND(state))) 73166124Srafan continue; 74166124Srafan if (state == DCLEAR) 75166124Srafan continue; 7650276Speter /* 7750276Speter * If we are running with soft updates and we come 7850276Speter * across unreferenced directories, we just leave 7950276Speter * them in DSTATE which will cause them to be pitched 8050276Speter * in pass 4. 8162449Speter */ 8262449Speter if ((preen || bkgrdflag) && 8362449Speter resolved && usedsoftdep && S_IS_DUNFOUND(state)) { 8462449Speter if (inp->i_dotdot >= ROOTINO) 8562449Speter inoinfo(inp->i_dotdot)->ino_linkcnt++; 8662449Speter continue; 8762449Speter } 8862449Speter for (loopcnt = 0; ; loopcnt++) { 8950276Speter orphan = inp->i_number; 9050276Speter if (inp->i_parent == 0 || 9150276Speter !INO_IS_DUNFOUND(inp->i_parent) || 9250276Speter loopcnt > countdirs) 9350276Speter break; 9450276Speter inp = getinoinfo(inp->i_parent); 9550276Speter } 9650276Speter if (loopcnt <= countdirs) { 97166124Srafan if (linkup(orphan, inp->i_dotdot, NULL)) { 9850276Speter inp->i_parent = inp->i_dotdot = lfdir; 9950276Speter inoinfo(lfdir)->ino_linkcnt--; 10050276Speter } 101166124Srafan inoinfo(orphan)->ino_state = DFOUND; 10250276Speter propagate(); 103166124Srafan continue; 10450276Speter } 10550276Speter pfatal("ORPHANED DIRECTORY LOOP DETECTED I=%lu", 10650276Speter (u_long)orphan); 10750276Speter if (reply("RECONNECT") == 0) 10850276Speter continue; 10950276Speter memset(&idesc, 0, sizeof(struct inodesc)); 11050276Speter idesc.id_type = DATA; 11150276Speter idesc.id_number = inp->i_parent; 112166124Srafan idesc.id_parent = orphan; 113166124Srafan idesc.id_func = findname; 114166124Srafan idesc.id_name = namebuf; 115166124Srafan if ((ckinode(ginode(inp->i_parent), &idesc) & FOUND) == 0) 116166124Srafan pfatal("COULD NOT FIND NAME IN PARENT DIRECTORY"); 117166124Srafan if (linkup(orphan, inp->i_parent, namebuf)) { 118166124Srafan idesc.id_func = clearentry; 119166124Srafan if (ckinode(ginode(inp->i_parent), &idesc) & FOUND) 120166124Srafan inoinfo(orphan)->ino_linkcnt++; 121166124Srafan inp->i_parent = inp->i_dotdot = lfdir; 122166124Srafan inoinfo(lfdir)->ino_linkcnt--; 123166124Srafan } 124166124Srafan inoinfo(orphan)->ino_state = DFOUND; 125166124Srafan propagate(); 12650276Speter } 12750276Speter} 12850276Speter