xref: /openbsd-src/sbin/fsck_ffs/pass4.c (revision abbb35584eeb1f783012251d6de83bc7a1260d24)
1*abbb3558Sotto /*	$OpenBSD: pass4.c,v 1.26 2020/06/20 07:49:04 otto Exp $	*/
287304b87Stholo /*	$NetBSD: pass4.c,v 1.11 1996/09/27 22:45:17 christos Exp $	*/
3df930be7Sderaadt 
4df930be7Sderaadt /*
5df930be7Sderaadt  * Copyright (c) 1980, 1986, 1993
6df930be7Sderaadt  *	The Regents of the University of California.  All rights reserved.
7df930be7Sderaadt  *
8df930be7Sderaadt  * Redistribution and use in source and binary forms, with or without
9df930be7Sderaadt  * modification, are permitted provided that the following conditions
10df930be7Sderaadt  * are met:
11df930be7Sderaadt  * 1. Redistributions of source code must retain the above copyright
12df930be7Sderaadt  *    notice, this list of conditions and the following disclaimer.
13df930be7Sderaadt  * 2. Redistributions in binary form must reproduce the above copyright
14df930be7Sderaadt  *    notice, this list of conditions and the following disclaimer in the
15df930be7Sderaadt  *    documentation and/or other materials provided with the distribution.
161ef0d710Smillert  * 3. Neither the name of the University nor the names of its contributors
17df930be7Sderaadt  *    may be used to endorse or promote products derived from this software
18df930be7Sderaadt  *    without specific prior written permission.
19df930be7Sderaadt  *
20df930be7Sderaadt  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
21df930be7Sderaadt  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22df930be7Sderaadt  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23df930be7Sderaadt  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
24df930be7Sderaadt  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25df930be7Sderaadt  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
26df930be7Sderaadt  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27df930be7Sderaadt  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28df930be7Sderaadt  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29df930be7Sderaadt  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30df930be7Sderaadt  * SUCH DAMAGE.
31df930be7Sderaadt  */
32df930be7Sderaadt 
3378eb0b7eSderaadt #include <sys/param.h>	/* isset clrbit */
34df930be7Sderaadt #include <sys/time.h>
35df930be7Sderaadt #include <ufs/ufs/dinode.h>
36df930be7Sderaadt #include <ufs/ffs/fs.h>
37af9e537cSd #include <stdio.h>
38df930be7Sderaadt #include <stdlib.h>
39df930be7Sderaadt #include <string.h>
4087304b87Stholo 
4187304b87Stholo #include "fsutil.h"
42df930be7Sderaadt #include "fsck.h"
43df930be7Sderaadt #include "extern.h"
44df930be7Sderaadt 
45af9e537cSd static ino_t info_inumber;
46af9e537cSd 
47af9e537cSd static int
pass4_info(char * buf,size_t buflen)48379d1969Sderaadt pass4_info(char *buf, size_t buflen)
49af9e537cSd {
503b92bd08Sderaadt 	return (snprintf(buf, buflen, "phase 4, inode %llu/%llu",
513b92bd08Sderaadt 	    (unsigned long long)info_inumber,
523b92bd08Sderaadt 	    (unsigned long long)lastino) > 0);
53af9e537cSd }
54af9e537cSd 
55df930be7Sderaadt void
pass4(void)5660d6b16fSgluk pass4(void)
57df930be7Sderaadt {
58e073c79dSmpech 	ino_t inumber;
59e073c79dSmpech 	struct zlncnt *zlnp;
602fffe0e0Smillert 	union dinode *dp;
61df930be7Sderaadt 	struct inodesc idesc;
62*abbb3558Sotto 	int n, i;
63*abbb3558Sotto 	u_int c;
64df930be7Sderaadt 
65df930be7Sderaadt 	memset(&idesc, 0, sizeof(struct inodesc));
66df930be7Sderaadt 	idesc.id_type = ADDR;
67df930be7Sderaadt 	idesc.id_func = pass4check;
68af9e537cSd 	info_fn = pass4_info;
692fffe0e0Smillert 	for (c = 0; c < sblock.fs_ncg; c++) {
702fffe0e0Smillert 		inumber = c * sblock.fs_ipg;
714d91232bSotto 		for (i = 0; i < inostathead[c].il_numalloced; i++, inumber++) {
722fffe0e0Smillert 			if (inumber < ROOTINO)
732fffe0e0Smillert 				continue;
74df930be7Sderaadt 			idesc.id_number = inumber;
754aab0ea5Sotto 			switch (GET_ISTATE(inumber)) {
76df930be7Sderaadt 
77df930be7Sderaadt 			case FSTATE:
78df930be7Sderaadt 			case DFOUND:
794d91232bSotto 				n = ILNCOUNT(inumber);
802fffe0e0Smillert 				if (n) {
81df930be7Sderaadt 					adjust(&idesc, (short)n);
822fffe0e0Smillert 					break;
832fffe0e0Smillert 				}
84df930be7Sderaadt 				for (zlnp = zlnhead; zlnp; zlnp = zlnp->next)
85df930be7Sderaadt 					if (zlnp->zlncnt == inumber) {
86df930be7Sderaadt 						zlnp->zlncnt = zlnhead->zlncnt;
87df930be7Sderaadt 						zlnp = zlnhead;
88df930be7Sderaadt 						zlnhead = zlnhead->next;
89df930be7Sderaadt 						free((char *)zlnp);
90df930be7Sderaadt 						clri(&idesc, "UNREF", 1);
91df930be7Sderaadt 						break;
92df930be7Sderaadt 					}
93df930be7Sderaadt 				break;
94df930be7Sderaadt 
95df930be7Sderaadt 			case DSTATE:
96df930be7Sderaadt 				clri(&idesc, "UNREF", 1);
97df930be7Sderaadt 				break;
98df930be7Sderaadt 
99df930be7Sderaadt 			case DCLEAR:
100df930be7Sderaadt 				dp = ginode(inumber);
1012fffe0e0Smillert 				if (DIP(dp, di_size) == 0) {
102df930be7Sderaadt 					clri(&idesc, "ZERO LENGTH", 1);
103df930be7Sderaadt 					break;
104df930be7Sderaadt 				}
105898bdbabStedu 				/* FALLTHROUGH */
106df930be7Sderaadt 			case FCLEAR:
107df930be7Sderaadt 				clri(&idesc, "BAD/DUP", 1);
108df930be7Sderaadt 				break;
109df930be7Sderaadt 
110df930be7Sderaadt 			case USTATE:
111df930be7Sderaadt 				break;
112df930be7Sderaadt 
113df930be7Sderaadt 			default:
1143b92bd08Sderaadt 				errexit("BAD STATE %d FOR INODE I=%llu\n",
1153b92bd08Sderaadt 				    GET_ISTATE(inumber),
1163b92bd08Sderaadt 				    (unsigned long long)inumber);
117df930be7Sderaadt 			}
118df930be7Sderaadt 		}
1192fffe0e0Smillert 	}
120af9e537cSd 	info_fn = NULL;
121df930be7Sderaadt }
122df930be7Sderaadt 
123df930be7Sderaadt int
pass4check(struct inodesc * idesc)12460d6b16fSgluk pass4check(struct inodesc *idesc)
125df930be7Sderaadt {
126e073c79dSmpech 	struct dups *dlp;
127df930be7Sderaadt 	int nfrags, res = KEEPON;
1281abdbfdeSderaadt 	daddr_t blkno = idesc->id_blkno;
129df930be7Sderaadt 
130df930be7Sderaadt 	for (nfrags = idesc->id_numfrags; nfrags > 0; blkno++, nfrags--) {
131df930be7Sderaadt 		if (chkrange(blkno, 1)) {
132df930be7Sderaadt 			res = SKIP;
133df930be7Sderaadt 		} else if (testbmap(blkno)) {
134df930be7Sderaadt 			for (dlp = duplist; dlp; dlp = dlp->next) {
135df930be7Sderaadt 				if (dlp->dup != blkno)
136df930be7Sderaadt 					continue;
137df930be7Sderaadt 				dlp->dup = duplist->dup;
138df930be7Sderaadt 				dlp = duplist;
139df930be7Sderaadt 				duplist = duplist->next;
14060d6b16fSgluk 				free(dlp);
141df930be7Sderaadt 				break;
142df930be7Sderaadt 			}
143df930be7Sderaadt 			if (dlp == 0) {
144df930be7Sderaadt 				clrbmap(blkno);
145df930be7Sderaadt 				n_blks--;
146df930be7Sderaadt 			}
147df930be7Sderaadt 		}
148df930be7Sderaadt 	}
149df930be7Sderaadt 	return (res);
150df930be7Sderaadt }
151