xref: /illumos-gate/usr/src/cmd/fs.d/ufs/fsck/pass5.c (revision 7c478bd9)
1 /*
2  * Copyright 2003 Sun Microsystems, Inc.  All rights reserved.
3  * Use is subject to license terms.
4  */
5 
6 /*	Copyright (c) 1983, 1984, 1985, 1986, 1987, 1988, 1989 AT&T	*/
7 /*	  All Rights Reserved  	*/
8 
9 /*
10  * Copyright (c) 1980, 1986, 1990 The Regents of the University of California.
11  * All rights reserved.
12  *
13  * Redistribution and use in source and binary forms are permitted
14  * provided that: (1) source distributions retain this entire copyright
15  * notice and comment, and (2) distributions including binaries display
16  * the following acknowledgement:  ``This product includes software
17  * developed by the University of California, Berkeley and its contributors''
18  * in the documentation or other materials provided with the distribution
19  * and in all advertising materials mentioning features or use of this
20  * software. Neither the name of the University nor the names of its
21  * contributors may be used to endorse or promote products derived
22  * from this software without specific prior written permission.
23  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
24  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
25  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
26  */
27 
28 #pragma ident	"%Z%%M%	%I%	%E% SMI"
29 
30 #include <sys/param.h>
31 #include <sys/sysmacros.h>
32 #include <sys/mntent.h>
33 
34 #define	bcopy(f, t, n)    memcpy(t, f, n)
35 #define	bzero(s, n)	memset(s, 0, n)
36 #define	bcmp(s, d, n)	memcmp(s, d, n)
37 
38 #define	index(s, r)	strchr(s, r)
39 #define	rindex(s, r)	strrchr(s, r)
40 
41 #include <sys/fs/ufs_fs.h>
42 #include <sys/vnode.h>
43 #include <sys/fs/ufs_inode.h>
44 #include "fsck.h"
45 
46 pass5()
47 {
48 	int32_t c, blk, frags, savednrpos, savednpsect;
49 	size_t	basesize, sumsize, mapsize;
50 	struct fs *fs = &sblock;
51 	struct cg *cg = &cgrp;
52 	diskaddr_t dbase, dmax;
53 	diskaddr_t d;
54 	uint64_t i, j;
55 	struct csum *cs;
56 	time_t now;
57 	struct csum cstotal;
58 	struct inodesc idesc;
59 	char buf[MAXBSIZE];
60 	struct cg *newcg = (struct cg *)buf;
61 	struct ocg *ocg = (struct ocg *)buf;
62 
63 	bzero((char *)newcg, (size_t)fs->fs_cgsize);
64 	newcg->cg_niblk = fs->fs_ipg;
65 	switch (fs->fs_postblformat) {
66 
67 	case FS_42POSTBLFMT:
68 		basesize = (char *)(&ocg->cg_btot[0]) - (char *)(&ocg->cg_link);
69 		sumsize = &ocg->cg_iused[0] - (char *)(&ocg->cg_btot[0]);
70 		mapsize = &ocg->cg_free[howmany(fs->fs_fpg, NBBY)] -
71 			(uchar_t *)&ocg->cg_iused[0];
72 		ocg->cg_magic = CG_MAGIC;
73 		savednrpos = fs->fs_nrpos;
74 		fs->fs_nrpos = 8;
75 		fs->fs_trackskew = 0;
76 		if ((fs->fs_npsect < 0) || (fs->fs_npsect > fs->fs_spc)) {
77 			/* Migration aid from fs_state */
78 			fs->fs_npsect = fs->fs_nsect;
79 		}
80 		savednpsect = fs->fs_npsect;
81 		fs->fs_npsect = fs->fs_nsect;
82 		break;
83 
84 	case FS_DYNAMICPOSTBLFMT:
85 		newcg->cg_btotoff =
86 			&newcg->cg_space[0] - (uchar_t *)(&newcg->cg_link);
87 		newcg->cg_boff =
88 			newcg->cg_btotoff + fs->fs_cpg * sizeof (long);
89 		newcg->cg_iusedoff = newcg->cg_boff +
90 			fs->fs_cpg * fs->fs_nrpos * sizeof (short);
91 		newcg->cg_freeoff =
92 			newcg->cg_iusedoff + howmany(fs->fs_ipg, NBBY);
93 		newcg->cg_nextfreeoff = newcg->cg_freeoff +
94 			howmany(fs->fs_cpg * fs->fs_spc / NSPF(fs),
95 				NBBY);
96 		newcg->cg_magic = CG_MAGIC;
97 		basesize = &newcg->cg_space[0] - (uchar_t *)(&newcg->cg_link);
98 		sumsize = newcg->cg_iusedoff - newcg->cg_btotoff;
99 		mapsize = newcg->cg_nextfreeoff - newcg->cg_iusedoff;
100 		break;
101 
102 	default:
103 		pfatal("UNKNOWN ROTATIONAL TABLE FORMAT %d\n",
104 			fs->fs_postblformat);
105 		errexit("");
106 	}
107 
108 	bzero((char *)&idesc, sizeof (struct inodesc));
109 	idesc.id_type = ADDR;
110 	bzero((char *)&cstotal, sizeof (struct csum));
111 	(void) time(&now);
112 
113 	/*
114 	 * If the last fragments in the file system don't make up a
115 	 * full file system block, mark the bits in the blockmap
116 	 * that correspond to those missing fragments as "allocated",
117 	 * so that the last block doesn't get counted as a free block
118 	 * and those missing fragments don't get counted as free frags.
119 	 */
120 	j = blknum(fs, (uint64_t)fs->fs_size + fs->fs_frag - 1);
121 	for (i = fs->fs_size; i < j; i++)
122 		setbmap(i);
123 	for (c = 0; c < fs->fs_ncg; c++) {
124 		getblk(&cgblk, (diskaddr_t)cgtod(fs, c), fs->fs_cgsize);
125 		if (!cg_chkmagic(cg))
126 			pfatal("CG %d: BAD MAGIC NUMBER\n", c);
127 		dbase = cgbase(fs, c);
128 		dmax = dbase + fs->fs_fpg;
129 		if (dmax > fs->fs_size)
130 			dmax = fs->fs_size;
131 		if (now > cg->cg_time)
132 			newcg->cg_time = cg->cg_time;
133 		else
134 			newcg->cg_time = now;
135 		newcg->cg_cgx = c;
136 		if (c == fs->fs_ncg - 1)
137 			newcg->cg_ncyl = fs->fs_ncyl % fs->fs_cpg;
138 		else
139 			newcg->cg_ncyl = fs->fs_cpg;
140 		newcg->cg_niblk = sblock.fs_ipg;
141 		newcg->cg_ndblk = dmax - dbase;
142 		newcg->cg_cs.cs_ndir = 0;
143 		newcg->cg_cs.cs_nffree = 0;
144 		newcg->cg_cs.cs_nbfree = 0;
145 		newcg->cg_cs.cs_nifree = fs->fs_ipg;
146 		if ((cg->cg_rotor >= 0) && (cg->cg_rotor < newcg->cg_ndblk))
147 			newcg->cg_rotor = cg->cg_rotor;
148 		else
149 			newcg->cg_rotor = 0;
150 		if ((cg->cg_frotor >= 0) && (cg->cg_frotor < newcg->cg_ndblk))
151 			newcg->cg_frotor = cg->cg_frotor;
152 		else
153 			newcg->cg_frotor = 0;
154 		if ((cg->cg_irotor >= 0) && (cg->cg_irotor < newcg->cg_niblk))
155 			newcg->cg_irotor = cg->cg_irotor;
156 		else
157 			newcg->cg_irotor = 0;
158 		bzero((char *)&newcg->cg_frsum[0], sizeof (newcg->cg_frsum));
159 		bzero((char *)&cg_blktot(newcg)[0], sumsize + mapsize);
160 		if (fs->fs_postblformat == FS_42POSTBLFMT)
161 			ocg->cg_magic = CG_MAGIC;
162 		j = fs->fs_ipg * c;
163 		for (i = 0; i < fs->fs_ipg; j++, i++) {
164 			switch (statemap[j]) {
165 
166 			case USTATE:
167 				break;
168 
169 			case DSTATE:
170 			case DCLEAR:
171 			case DFOUND:
172 				newcg->cg_cs.cs_ndir++;
173 				/* fall through */
174 
175 			case FSTATE:
176 			case FCLEAR:
177 			case SSTATE:
178 			case SCLEAR:
179 				newcg->cg_cs.cs_nifree--;
180 				setbit(cg_inosused(newcg), i);
181 				break;
182 
183 			default:
184 				if (j < UFSROOTINO)
185 					break;
186 				errexit("BAD STATE %d FOR INODE I=%d",
187 				    statemap[j], j);
188 			}
189 		}
190 		if (c == 0)
191 			for (i = 0; i < UFSROOTINO; i++) {
192 				setbit(cg_inosused(newcg), i);
193 				newcg->cg_cs.cs_nifree--;
194 			}
195 		for (i = 0, d = dbase;
196 		    d < dmax;
197 		    d += fs->fs_frag, i += fs->fs_frag) {
198 			frags = 0;
199 			for (j = 0; j < fs->fs_frag; j++) {
200 				if (testbmap(d + j))
201 					continue;
202 				setbit(cg_blksfree(newcg), i + j);
203 				frags++;
204 			}
205 			if (frags == fs->fs_frag) {
206 				newcg->cg_cs.cs_nbfree++;
207 				j = cbtocylno(fs, i);
208 				cg_blktot(newcg)[j]++;
209 				cg_blks(fs, newcg, j)[cbtorpos(fs, i)]++;
210 			} else if (frags > 0) {
211 				newcg->cg_cs.cs_nffree += frags;
212 				blk = blkmap(fs, cg_blksfree(newcg), i);
213 				fragacct(fs, blk, newcg->cg_frsum, 1);
214 			}
215 		}
216 /*
217  *		for (frags = d; d < dmax; d++) {
218  *			if (getbmap(d))
219  *				continue;
220  *			setbit(newcg->cg_free, d - dbase);
221  *			newcg->cg_cs.cs_nffree++;
222  *		}
223  *		if (frags != d) {
224  *			blk = blkmap(&sblock, newcg->cg_free, (frags - dbase));
225  *			fragacct(&sblock, blk, newcg->cg_frsum, 1);
226  *		}
227  */
228 		cstotal.cs_nffree += newcg->cg_cs.cs_nffree;
229 		cstotal.cs_nbfree += newcg->cg_cs.cs_nbfree;
230 		cstotal.cs_nifree += newcg->cg_cs.cs_nifree;
231 		cstotal.cs_ndir += newcg->cg_cs.cs_ndir;
232 
233 		cs = &fs->fs_cs(fs, c);
234 		if (bcmp((char *)&newcg->cg_cs, (char *)cs,
235 		    sizeof (*cs)) != 0 &&
236 		    dofix(&idesc, "FREE BLK COUNT(S) WRONG IN SUPERBLK")) {
237 			bcopy((char *)&newcg->cg_cs, (char *)cs, sizeof (*cs));
238 			sbdirty();
239 		}
240 		if (cvtflag) {
241 			bcopy((char *)newcg, (char *)cg, (size_t)fs->fs_cgsize);
242 			cgdirty();
243 			continue;
244 		}
245 		if ((bcmp((char *)newcg, (char *)cg, (size_t)basesize) != 0 ||
246 		    bcmp((char *)&cg_blktot(newcg)[0],
247 			    (char *)&cg_blktot(cg)[0], sumsize) != 0) &&
248 		    dofix(&idesc, "SUMMARY INFORMATION BAD")) {
249 			bcopy((char *)newcg, (char *)cg, (size_t)basesize);
250 			bcopy((char *)&cg_blktot(newcg)[0],
251 			    (char *)&cg_blktot(cg)[0], sumsize);
252 			cgdirty();
253 		}
254 		if (bcmp(cg_inosused(newcg),
255 			    cg_inosused(cg), mapsize) != 0 &&
256 		    dofix(&idesc, "BLK(S) MISSING IN BIT MAPS")) {
257 			bcopy(cg_inosused(newcg), cg_inosused(cg), mapsize);
258 			cgdirty();
259 		}
260 
261 		cs = &sblock.fs_cs(&sblock, c);
262 		if (bcmp((char *)&newcg->cg_cs, (char *)cs,
263 		    sizeof (*cs)) != 0 &&
264 		    dofix(&idesc, "FREE BLK COUNT(S) WRONG IN SUPERBLK")) {
265 	/*
266 	 *		bcopy((char *)&newcg->cg_cs, (char *)cs, sizeof (*cs));
267 	 *		sbdirty();
268 	 */
269 		}
270 
271 	}
272 	if (fs->fs_postblformat == FS_42POSTBLFMT) {
273 		fs->fs_nrpos = savednrpos;
274 		fs->fs_npsect = savednpsect;
275 	}
276 	if ((fflag || !(islog && islogok)) &&
277 	    bcmp((char *)&cstotal, (char *)&fs->fs_cstotal,
278 	    sizeof (struct csum)) != 0 &&
279 	    dofix(&idesc, "FREE BLK COUNT(S) WRONG IN SUPERBLK")) {
280 		bcopy((char *)&cstotal, (char *)&fs->fs_cstotal,
281 			sizeof (struct csum));
282 		fs->fs_ronly = 0;
283 		fs->fs_fmod = 0;
284 		sbdirty();
285 	}
286 }
287