pass4.c revision 136281
1234353Sdim/* 2218885Sdim * Copyright (c) 1980, 1986, 1993 3218885Sdim * The Regents of the University of California. All rights reserved. 4218885Sdim * 5218885Sdim * Redistribution and use in source and binary forms, with or without 6218885Sdim * modification, are permitted provided that the following conditions 7218885Sdim * are met: 8218885Sdim * 1. Redistributions of source code must retain the above copyright 9218885Sdim * notice, this list of conditions and the following disclaimer. 10218885Sdim * 2. Redistributions in binary form must reproduce the above copyright 11218885Sdim * notice, this list of conditions and the following disclaimer in the 12218885Sdim * documentation and/or other materials provided with the distribution. 13218885Sdim * 4. Neither the name of the University nor the names of its contributors 14218885Sdim * may be used to endorse or promote products derived from this software 15218885Sdim * without specific prior written permission. 16218885Sdim * 17218885Sdim * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 18249423Sdim * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19218885Sdim * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20218885Sdim * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 21218885Sdim * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 22218885Sdim * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 23218885Sdim * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 24218885Sdim * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 25218885Sdim * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 26218885Sdim * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 27218885Sdim * SUCH DAMAGE. 28218885Sdim */ 29218885Sdim 30249423Sdim#if 0 31249423Sdim#ifndef lint 32218885Sdimstatic const char sccsid[] = "@(#)pass4.c 8.4 (Berkeley) 4/28/95"; 33218885Sdim#endif /* not lint */ 34218885Sdim#endif 35249423Sdim#include <sys/cdefs.h> 36249423Sdim__FBSDID("$FreeBSD: head/sbin/fsck_ffs/pass4.c 136281 2004-10-08 20:44:47Z truckman $"); 37249423Sdim 38218885Sdim#include <sys/param.h> 39218885Sdim 40218885Sdim#include <ufs/ufs/dinode.h> 41218885Sdim#include <ufs/ffs/fs.h> 42218885Sdim 43218885Sdim#include <err.h> 44218885Sdim#include <string.h> 45218885Sdim 46249423Sdim#include "fsck.h" 47218885Sdim 48218885Sdimvoid 49218885Sdimpass4(void) 50249423Sdim{ 51249423Sdim ino_t inumber; 52249423Sdim union dinode *dp; 53218885Sdim struct inodesc idesc; 54243830Sdim int i, n, cg; 55243830Sdim 56243830Sdim memset(&idesc, 0, sizeof(struct inodesc)); 57243830Sdim idesc.id_type = ADDR; 58243830Sdim idesc.id_func = pass4check; 59249423Sdim for (cg = 0; cg < sblock.fs_ncg; cg++) { 60249423Sdim if (got_siginfo) { 61249423Sdim printf("%s: phase 4: cyl group %d of %d (%d%%)\n", 62249423Sdim cdevname, cg, sblock.fs_ncg, 63243830Sdim cg * 100 / sblock.fs_ncg); 64243830Sdim got_siginfo = 0; 65243830Sdim } 66243830Sdim if (got_sigalarm) { 67243830Sdim setproctitle("%s p4 %d%%", cdevname, 68218885Sdim cg * 100 / sblock.fs_ncg); 69218885Sdim got_sigalarm = 0; 70218885Sdim } 71218885Sdim inumber = cg * sblock.fs_ipg; 72218885Sdim for (i = 0; i < inostathead[cg].il_numalloced; i++, inumber++) { 73218885Sdim if (inumber < ROOTINO) 74218885Sdim continue; 75218885Sdim idesc.id_number = inumber; 76218885Sdim switch (inoinfo(inumber)->ino_state) { 77218885Sdim 78218885Sdim case FZLINK: 79218885Sdim case DZLINK: 80218885Sdim if (inoinfo(inumber)->ino_linkcnt == 0) { 81218885Sdim clri(&idesc, "UNREF", 1); 82218885Sdim break; 83218885Sdim } 84218885Sdim /* fall through */ 85218885Sdim 86218885Sdim case FSTATE: 87218885Sdim case DFOUND: 88218885Sdim n = inoinfo(inumber)->ino_linkcnt; 89218885Sdim if (n) { 90218885Sdim adjust(&idesc, (short)n); 91218885Sdim break; 92218885Sdim } 93218885Sdim break; 94218885Sdim 95218885Sdim case DSTATE: 96218885Sdim clri(&idesc, "UNREF", 1); 97263508Sdim break; 98263508Sdim 99263508Sdim case DCLEAR: 100263508Sdim dp = ginode(inumber); 101263508Sdim if (DIP(dp, di_size) == 0) { 102263508Sdim clri(&idesc, "ZERO LENGTH", 1); 103263508Sdim break; 104263508Sdim } 105263508Sdim /* fall through */ 106263508Sdim case FCLEAR: 107218885Sdim clri(&idesc, "BAD/DUP", 1); 108218885Sdim break; 109218885Sdim 110218885Sdim case USTATE: 111218885Sdim break; 112218885Sdim 113218885Sdim default: 114218885Sdim errx(EEXIT, "BAD STATE %d FOR INODE I=%d", 115218885Sdim inoinfo(inumber)->ino_state, inumber); 116218885Sdim } 117218885Sdim } 118218885Sdim } 119218885Sdim} 120218885Sdim 121218885Sdimint 122218885Sdimpass4check(struct inodesc *idesc) 123218885Sdim{ 124218885Sdim struct dups *dlp; 125218885Sdim int nfrags, res = KEEPON; 126218885Sdim ufs2_daddr_t blkno = idesc->id_blkno; 127218885Sdim 128218885Sdim for (nfrags = idesc->id_numfrags; nfrags > 0; blkno++, nfrags--) { 129218885Sdim if (chkrange(blkno, 1)) { 130218885Sdim res = SKIP; 131218885Sdim } else if (testbmap(blkno)) { 132218885Sdim for (dlp = duplist; dlp; dlp = dlp->next) { 133218885Sdim if (dlp->dup != blkno) 134218885Sdim continue; 135218885Sdim dlp->dup = duplist->dup; 136218885Sdim dlp = duplist; 137218885Sdim duplist = duplist->next; 138218885Sdim free((char *)dlp); 139218885Sdim break; 140218885Sdim } 141218885Sdim if (dlp == 0) { 142218885Sdim clrbmap(blkno); 143218885Sdim n_blks--; 144218885Sdim } 145218885Sdim } 146218885Sdim } 147218885Sdim return (res); 148218885Sdim} 149218885Sdim