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