pass4.c revision 297886
1210284Sjmallett/* 2232812Sjmallett * Copyright (c) 1980, 1986, 1993 3215990Sjmallett * The Regents of the University of California. All rights reserved. 4210284Sjmallett * 5210284Sjmallett * Redistribution and use in source and binary forms, with or without 6215990Sjmallett * modification, are permitted provided that the following conditions 7215990Sjmallett * are met: 8215990Sjmallett * 1. Redistributions of source code must retain the above copyright 9210284Sjmallett * notice, this list of conditions and the following disclaimer. 10215990Sjmallett * 2. Redistributions in binary form must reproduce the above copyright 11215990Sjmallett * notice, this list of conditions and the following disclaimer in the 12210284Sjmallett * documentation and/or other materials provided with the distribution. 13215990Sjmallett * 4. Neither the name of the University nor the names of its contributors 14215990Sjmallett * may be used to endorse or promote products derived from this software 15215990Sjmallett * without specific prior written permission. 16215990Sjmallett * 17215990Sjmallett * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 18232812Sjmallett * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19215990Sjmallett * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20215990Sjmallett * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 21215990Sjmallett * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 22215990Sjmallett * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 23215990Sjmallett * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 24215990Sjmallett * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 25215990Sjmallett * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 26215990Sjmallett * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 27215990Sjmallett * SUCH DAMAGE. 28215990Sjmallett */ 29232812Sjmallett 30215990Sjmallett#if 0 31215990Sjmallett#ifndef lint 32215990Sjmallettstatic const char sccsid[] = "@(#)pass4.c 8.4 (Berkeley) 4/28/95"; 33215990Sjmallett#endif /* not lint */ 34215990Sjmallett#endif 35215990Sjmallett#include <sys/cdefs.h> 36215990Sjmallett__FBSDID("$FreeBSD: head/sbin/fsck_ffs/pass4.c 297886 2016-04-12 22:55:47Z pfg $"); 37215990Sjmallett 38210284Sjmallett#include <sys/param.h> 39210284Sjmallett 40210284Sjmallett#include <ufs/ufs/dinode.h> 41210284Sjmallett#include <ufs/ffs/fs.h> 42210284Sjmallett 43210284Sjmallett#include <err.h> 44210284Sjmallett#include <stdint.h> 45215990Sjmallett#include <string.h> 46210284Sjmallett 47210284Sjmallett#include "fsck.h" 48210284Sjmallett 49210284Sjmallettvoid 50210284Sjmallettpass4(void) 51232812Sjmallett{ 52210284Sjmallett ino_t inumber; 53210284Sjmallett union dinode *dp; 54210284Sjmallett struct inodesc idesc; 55210284Sjmallett int i, n, cg; 56210284Sjmallett 57215990Sjmallett memset(&idesc, 0, sizeof(struct inodesc)); 58215990Sjmallett idesc.id_type = ADDR; 59215990Sjmallett idesc.id_func = pass4check; 60215990Sjmallett for (cg = 0; cg < sblock.fs_ncg; cg++) { 61215990Sjmallett if (got_siginfo) { 62215990Sjmallett printf("%s: phase 4: cyl group %d of %d (%d%%)\n", 63215990Sjmallett cdevname, cg, sblock.fs_ncg, 64210284Sjmallett cg * 100 / sblock.fs_ncg); 65210284Sjmallett got_siginfo = 0; 66210284Sjmallett } 67210284Sjmallett if (got_sigalarm) { 68210284Sjmallett setproctitle("%s p4 %d%%", cdevname, 69210284Sjmallett cg * 100 / sblock.fs_ncg); 70210284Sjmallett got_sigalarm = 0; 71210284Sjmallett } 72210284Sjmallett inumber = cg * sblock.fs_ipg; 73210284Sjmallett for (i = 0; i < inostathead[cg].il_numalloced; i++, inumber++) { 74210284Sjmallett if (inumber < ROOTINO) 75215990Sjmallett continue; 76210284Sjmallett idesc.id_number = inumber; 77210284Sjmallett switch (inoinfo(inumber)->ino_state) { 78210284Sjmallett 79210284Sjmallett case FZLINK: 80215990Sjmallett case DZLINK: 81210284Sjmallett if (inoinfo(inumber)->ino_linkcnt == 0) { 82210284Sjmallett clri(&idesc, "UNREF", 1); 83210284Sjmallett break; 84210284Sjmallett } 85210284Sjmallett /* fall through */ 86210284Sjmallett 87210284Sjmallett case FSTATE: 88210284Sjmallett case DFOUND: 89210284Sjmallett n = inoinfo(inumber)->ino_linkcnt; 90210284Sjmallett if (n) { 91210284Sjmallett adjust(&idesc, (short)n); 92210284Sjmallett break; 93210284Sjmallett } 94210284Sjmallett break; 95210284Sjmallett 96210284Sjmallett case DSTATE: 97210284Sjmallett clri(&idesc, "UNREF", 1); 98210284Sjmallett break; 99210284Sjmallett 100210284Sjmallett case DCLEAR: 101210284Sjmallett /* if on snapshot, already cleared */ 102210284Sjmallett if (cursnapshot != 0) 103210284Sjmallett break; 104210284Sjmallett dp = ginode(inumber); 105210284Sjmallett if (DIP(dp, di_size) == 0) { 106210284Sjmallett clri(&idesc, "ZERO LENGTH", 1); 107210284Sjmallett break; 108210284Sjmallett } 109210284Sjmallett /* fall through */ 110210284Sjmallett case FCLEAR: 111210284Sjmallett clri(&idesc, "BAD/DUP", 1); 112210284Sjmallett break; 113210284Sjmallett 114210284Sjmallett case USTATE: 115210284Sjmallett break; 116210284Sjmallett 117210284Sjmallett default: 118210284Sjmallett errx(EEXIT, "BAD STATE %d FOR INODE I=%ju", 119210284Sjmallett inoinfo(inumber)->ino_state, 120210284Sjmallett (uintmax_t)inumber); 121210284Sjmallett } 122210284Sjmallett } 123210284Sjmallett } 124210284Sjmallett} 125210284Sjmallett 126210284Sjmallettint 127210284Sjmallettpass4check(struct inodesc *idesc) 128210284Sjmallett{ 129210284Sjmallett struct dups *dlp; 130210284Sjmallett int nfrags, res = KEEPON; 131210284Sjmallett ufs2_daddr_t blkno = idesc->id_blkno; 132210284Sjmallett 133210284Sjmallett for (nfrags = idesc->id_numfrags; nfrags > 0; blkno++, nfrags--) { 134210284Sjmallett if (chkrange(blkno, 1)) { 135210284Sjmallett res = SKIP; 136210284Sjmallett } else if (testbmap(blkno)) { 137217214Sjmallett for (dlp = duplist; dlp; dlp = dlp->next) { 138210284Sjmallett if (dlp->dup != blkno) 139217214Sjmallett continue; 140217214Sjmallett dlp->dup = duplist->dup; 141217214Sjmallett dlp = duplist; 142217214Sjmallett duplist = duplist->next; 143217214Sjmallett free((char *)dlp); 144217214Sjmallett break; 145217214Sjmallett } 146217214Sjmallett if (dlp == NULL) { 147217214Sjmallett clrbmap(blkno); 148217214Sjmallett n_blks--; 149217214Sjmallett } 150217214Sjmallett } 151210284Sjmallett } 152210284Sjmallett return (res); 153210284Sjmallett} 154210284Sjmallett