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