GCC Code Coverage Report
Directory: ./ Exec Total Coverage
File: sbin/fsck_ffs/pass5.c Lines: 113 220 51.4 %
Date: 2017-11-07 Branches: 59 194 30.4 %

Line Branch Exec Source
1
/*	$OpenBSD: pass5.c,v 1.48 2015/01/20 18:22:21 deraadt Exp $	*/
2
/*	$NetBSD: pass5.c,v 1.16 1996/09/27 22:45:18 christos Exp $	*/
3
4
/*
5
 * Copyright (c) 1980, 1986, 1993
6
 *	The Regents of the University of California.  All rights reserved.
7
 *
8
 * Redistribution and use in source and binary forms, with or without
9
 * modification, are permitted provided that the following conditions
10
 * are met:
11
 * 1. Redistributions of source code must retain the above copyright
12
 *    notice, this list of conditions and the following disclaimer.
13
 * 2. Redistributions in binary form must reproduce the above copyright
14
 *    notice, this list of conditions and the following disclaimer in the
15
 *    documentation and/or other materials provided with the distribution.
16
 * 3. Neither the name of the University nor the names of its contributors
17
 *    may be used to endorse or promote products derived from this software
18
 *    without specific prior written permission.
19
 *
20
 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
21
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
24
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
26
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30
 * SUCH DAMAGE.
31
 */
32
33
#include <sys/param.h>	/* MAXBSIZE roundup setbit */
34
#include <sys/time.h>
35
#include <sys/lock.h>
36
#include <sys/ucred.h>
37
#include <ufs/ffs/fs.h>
38
#include <ufs/ufs/quota.h>
39
#include <ufs/ufs/inode.h>
40
#include <ufs/ffs/ffs_extern.h>
41
#include <stdio.h>
42
#include <string.h>
43
#include <limits.h>
44
45
#include "fsutil.h"
46
#include "fsck.h"
47
#include "extern.h"
48
49
#define MINIMUM(a, b)	(((a) < (b)) ? (a) : (b))
50
51
static int info_cg;
52
static int info_maxcg;
53
54
static int
55
pass5_info(char *buf, size_t buflen)
56
{
57
	return (snprintf(buf, buflen, "phase 5, cg %d/%d",
58
	    info_cg, info_maxcg) > 0);
59
}
60
61
void
62
pass5(void)
63
{
64
	int c, blk, frags, basesize, sumsize, mapsize, savednrpos=0;
65
	int inomapsize, blkmapsize;
66
16
	struct fs *fs = &sblock;
67
8
	struct cg *cg = &cgrp;
68
	daddr_t dbase, dmax;
69
	daddr_t d;
70
	long i, j, k, rewritecg = 0;
71
	struct csum *cs;
72
8
	struct csum_total cstotal;
73
8
	struct inodesc idesc[3];
74
8
	char buf[MAXBSIZE];
75
8
	struct cg *newcg = (struct cg *)buf;
76
8
	struct ocg *ocg = (struct ocg *)buf;
77
78
8
	memset(newcg, 0, (size_t)fs->fs_cgsize);
79
8
	if (cvtlevel >= 3) {
80
		if (fs->fs_maxcontig < 2 && fs->fs_contigsumsize > 0) {
81
			if (preen)
82
				pwarn("DELETING CLUSTERING MAPS\n");
83
			if (preen || reply("DELETE CLUSTERING MAPS")) {
84
				fs->fs_contigsumsize = 0;
85
				rewritecg = 1;
86
				sbdirty();
87
			}
88
		}
89
		if (fs->fs_maxcontig > 1) {
90
			char *doit = 0;
91
92
			if (fs->fs_contigsumsize < 1) {
93
				doit = "CREAT";
94
			} else if (fs->fs_contigsumsize < fs->fs_maxcontig &&
95
				   fs->fs_contigsumsize < FS_MAXCONTIG) {
96
				doit = "EXPAND";
97
			}
98
			if (doit) {
99
				i = fs->fs_contigsumsize;
100
				fs->fs_contigsumsize =
101
				    MINIMUM(fs->fs_maxcontig, FS_MAXCONTIG);
102
				if (CGSIZE(fs) > fs->fs_bsize) {
103
					pwarn("CANNOT %s CLUSTER MAPS\n", doit);
104
					fs->fs_contigsumsize = i;
105
				} else if (preen ||
106
				    reply("CREATE CLUSTER MAPS")) {
107
					if (preen)
108
						pwarn("%sING CLUSTER MAPS\n",
109
						    doit);
110
					fs->fs_cgsize =
111
					    fragroundup(fs, CGSIZE(fs));
112
					rewritecg = 1;
113
					sbdirty();
114
				}
115
			}
116
		}
117
	}
118
8
	switch ((int)fs->fs_postblformat) {
119
120
	case FS_42POSTBLFMT:
121
		basesize = (char *)(&ocg->cg_btot[0]) -
122
		    (char *)(&ocg->cg_firstfield);
123
		sumsize = &ocg->cg_iused[0] - (u_int8_t *)(&ocg->cg_btot[0]);
124
		mapsize = &ocg->cg_free[howmany(fs->fs_fpg, NBBY)] -
125
			(u_char *)&ocg->cg_iused[0];
126
		blkmapsize = howmany(fs->fs_fpg, NBBY);
127
		inomapsize = sizeof(ocg->cg_iused);
128
		ocg->cg_magic = CG_MAGIC;
129
		savednrpos = fs->fs_nrpos;
130
		fs->fs_nrpos = 8;
131
		break;
132
133
	case FS_DYNAMICPOSTBLFMT:
134
8
		if (sblock.fs_magic == FS_UFS2_MAGIC) {
135
			newcg->cg_iusedoff = sizeof(struct cg);
136
		} else {
137
8
			newcg->cg_btotoff = sizeof(struct cg);
138
8
			newcg->cg_boff = newcg->cg_btotoff +
139
8
			    fs->fs_cpg * sizeof(int32_t);
140
24
			newcg->cg_iusedoff = newcg->cg_boff + fs->fs_cpg *
141
16
			    fs->fs_nrpos * sizeof(int16_t);
142
		}
143
8
		inomapsize = howmany(fs->fs_ipg, CHAR_BIT);
144
8
		newcg->cg_freeoff = newcg->cg_iusedoff + inomapsize;
145
8
		blkmapsize = howmany(fs->fs_fpg, CHAR_BIT);
146
8
		newcg->cg_nextfreeoff = newcg->cg_freeoff + blkmapsize;
147
8
		if (fs->fs_contigsumsize > 0) {
148
			newcg->cg_clustersumoff = newcg->cg_nextfreeoff -
149
			    sizeof(int32_t);
150
			newcg->cg_clustersumoff =
151
			    roundup(newcg->cg_clustersumoff, sizeof(int32_t));
152
			newcg->cg_clusteroff = newcg->cg_clustersumoff +
153
			    (fs->fs_contigsumsize + 1) * sizeof(int32_t);
154
			newcg->cg_nextfreeoff = newcg->cg_clusteroff +
155
			    howmany(fragstoblks(fs, fs->fs_fpg), CHAR_BIT);
156
		}
157
8
		newcg->cg_magic = CG_MAGIC;
158
		basesize = sizeof(struct cg);
159
8
		sumsize = newcg->cg_iusedoff - newcg->cg_btotoff;
160
8
		mapsize = newcg->cg_nextfreeoff - newcg->cg_iusedoff;
161
8
		break;
162
163
	default:
164
		inomapsize = blkmapsize = sumsize = 0;
165
		errexit("UNKNOWN ROTATIONAL TABLE FORMAT %d\n",
166
			fs->fs_postblformat);
167
	}
168
8
	memset(&idesc[0], 0, sizeof idesc);
169
64
	for (i = 0; i < 3; i++)
170
24
		idesc[i].id_type = ADDR;
171
8
	memset(&cstotal, 0, sizeof(struct csum_total));
172
8
	dmax = blknum(fs, fs->fs_size + fs->fs_frag - 1);
173
16
	for (d = fs->fs_size; d < dmax; d++)
174
		setbmap(d);
175
8
	info_cg = 0;
176
8
	info_maxcg = fs->fs_ncg;
177
8
	info_fn = pass5_info;
178
40
	for (c = 0; c < fs->fs_ncg; c++) {
179
12
		info_cg = c;
180
12
		getblk(&cgblk, cgtod(fs, c), fs->fs_cgsize);
181

12
		if (!cg_chkmagic(cg))
182
			pfatal("CG %d: BAD MAGIC NUMBER\n", c);
183
12
		dbase = cgbase(fs, c);
184
12
		dmax = dbase + fs->fs_fpg;
185
12
		if (dmax > fs->fs_size)
186
1
			dmax = fs->fs_size;
187
12
		newcg->cg_time = cg->cg_time;
188
12
		newcg->cg_ffs2_time = cg->cg_ffs2_time;
189
12
		newcg->cg_cgx = c;
190
12
		if (c == fs->fs_ncg - 1)
191
8
			newcg->cg_ncyl = fs->fs_ncyl % fs->fs_cpg;
192
		else
193
4
			newcg->cg_ncyl = fs->fs_cpg;
194
12
		newcg->cg_ndblk = dmax - dbase;
195
12
		if (fs->fs_contigsumsize > 0)
196
			newcg->cg_nclusterblks = newcg->cg_ndblk / fs->fs_frag;
197
12
		newcg->cg_cs.cs_ndir = 0;
198
12
		newcg->cg_cs.cs_nffree = 0;
199
12
		newcg->cg_cs.cs_nbfree = 0;
200
12
		newcg->cg_cs.cs_nifree = fs->fs_ipg;
201
12
		if (cg->cg_rotor < newcg->cg_ndblk)
202
12
			newcg->cg_rotor = cg->cg_rotor;
203
		else
204
			newcg->cg_rotor = 0;
205

24
		if (cg->cg_frotor >= 0 && cg->cg_frotor < newcg->cg_ndblk)
206
12
			newcg->cg_frotor = cg->cg_frotor;
207
		else
208
			newcg->cg_frotor = 0;
209
12
		newcg->cg_irotor = 0;
210
12
		if (fs->fs_magic == FS_UFS1_MAGIC) {
211
12
			newcg->cg_initediblk = 0;
212
12
			newcg->cg_niblk = cg->cg_niblk;
213

24
			if (cg->cg_irotor >= 0 &&
214
12
			    cg->cg_irotor < fs->fs_ipg)
215
12
				newcg->cg_irotor = cg->cg_irotor;
216
		} else {
217
			newcg->cg_ncyl = 0;
218
			if ((unsigned)cg->cg_initediblk > fs->fs_ipg)
219
				newcg->cg_initediblk = fs->fs_ipg;
220
			else
221
				newcg->cg_initediblk = cg->cg_initediblk;
222
			newcg->cg_ffs2_niblk = fs->fs_ipg;
223
			if (cg->cg_irotor >= 0 &&
224
			    cg->cg_irotor < newcg->cg_ffs2_niblk)
225
				newcg->cg_irotor = cg->cg_irotor;
226
		}
227
12
		memset(&newcg->cg_frsum[0], 0, sizeof newcg->cg_frsum);
228
36
		memset(cg_inosused(newcg), 0, (size_t)(mapsize));
229
12
		if (fs->fs_postblformat == FS_42POSTBLFMT)
230
			ocg->cg_magic = CG_MAGIC;
231
12
		j = fs->fs_ipg * c;
232
72
		for (i = 0; i < inostathead[c].il_numalloced; j++, i++) {
233

56
			switch (GET_ISTATE(j)) {
234
235
			case USTATE:
236
				break;
237
238
			case DSTATE:
239
			case DCLEAR:
240
			case DFOUND:
241
8
				newcg->cg_cs.cs_ndir++;
242
				/* FALLTHROUGH */
243
244
			case FSTATE:
245
			case FCLEAR:
246
8
				newcg->cg_cs.cs_nifree--;
247
24
				setbit(cg_inosused(newcg), i);
248
8
				break;
249
250
			default:
251
16
				if (j < ROOTINO)
252
					break;
253
				errexit("BAD STATE %d FOR INODE I=%llu\n",
254
				    GET_ISTATE(j), (unsigned long long)j);
255
			}
256
		}
257
12
		if (c == 0)
258
48
			for (i = 0; i < ROOTINO; i++) {
259
48
				setbit(cg_inosused(newcg), i);
260
16
				newcg->cg_cs.cs_nifree--;
261
			}
262
9064
		for (i = 0, d = dbase;
263
4532
		     d < dmax;
264
4520
		     d += fs->fs_frag, i += fs->fs_frag) {
265
			frags = 0;
266
81360
			for (j = 0; j < fs->fs_frag; j++) {
267
36160
				if (testbmap(d + j))
268
					continue;
269
106056
				setbit(cg_blksfree(newcg), i + j);
270
35352
				frags++;
271
35352
			}
272
4520
			if (frags == fs->fs_frag) {
273
4405
				newcg->cg_cs.cs_nbfree++;
274
4405
				if (fs->fs_contigsumsize > 0)
275
					setbit(cg_clustersfree(newcg),
276
					    i / fs->fs_frag);
277
115
			} else if (frags > 0) {
278
16
				newcg->cg_cs.cs_nffree += frags;
279
48
				blk = blkmap(fs, cg_blksfree(newcg), i);
280
16
				ffs_fragacct(fs, blk, newcg->cg_frsum, 1);
281
16
			}
282
		}
283
12
		if (fs->fs_contigsumsize > 0) {
284
			int32_t *sump = cg_clustersum(newcg);
285
			u_char *mapp = cg_clustersfree(newcg);
286
			int map = *mapp++;
287
			int bit = 1;
288
			int run = 0;
289
290
			for (i = 0; i < newcg->cg_nclusterblks; i++) {
291
				if ((map & bit) != 0) {
292
					run++;
293
				} else if (run != 0) {
294
					if (run > fs->fs_contigsumsize)
295
						run = fs->fs_contigsumsize;
296
					sump[run]++;
297
					run = 0;
298
				}
299
				if ((i & (NBBY - 1)) != (NBBY - 1)) {
300
					bit <<= 1;
301
				} else {
302
					map = *mapp++;
303
					bit = 1;
304
				}
305
			}
306
			if (run != 0) {
307
				if (run > fs->fs_contigsumsize)
308
					run = fs->fs_contigsumsize;
309
				sump[run]++;
310
			}
311
		}
312
12
		cstotal.cs_nffree += newcg->cg_cs.cs_nffree;
313
12
		cstotal.cs_nbfree += newcg->cg_cs.cs_nbfree;
314
12
		cstotal.cs_nifree += newcg->cg_cs.cs_nifree;
315
12
		cstotal.cs_ndir += newcg->cg_cs.cs_ndir;
316
12
		cs = &fs->fs_cs(fs, c);
317

12
		if (memcmp(&newcg->cg_cs, cs, sizeof *cs) != 0 &&
318
		    dofix(&idesc[0], "FREE BLK COUNT(S) WRONG IN SUPERBLK")) {
319
			memcpy(cs, &newcg->cg_cs, sizeof *cs);
320
			sbdirty();
321
		}
322
12
		if (rewritecg) {
323
			memcpy(cg, newcg, (size_t)fs->fs_cgsize);
324
			cgdirty();
325
			continue;
326
		}
327

12
		if (memcmp(newcg, cg, basesize) &&
328
		    dofix(&idesc[2], "SUMMARY INFORMATION BAD")) {
329
			memcpy(cg, newcg, (size_t)basesize);
330
			cgdirty();
331
		}
332
12
		if (usedsoftdep) {
333
			for (i = 0; i < inomapsize; i++) {
334
				j = cg_inosused(newcg)[i];
335
				if ((cg_inosused(cg)[i] & j) == j)
336
					continue;
337
				for (k = 0; k < NBBY; k++) {
338
					if ((j & (1 << k)) == 0)
339
						continue;
340
					if (cg_inosused(cg)[i] & (1 << k))
341
						continue;
342
					pwarn("ALLOCATED INODE %lld MARKED FREE\n",
343
					      ((long long)c * fs->fs_ipg + i * 8) + k);
344
				}
345
			}
346
			for (i = 0; i < blkmapsize; i++) {
347
				j = cg_blksfree(cg)[i];
348
				if ((cg_blksfree(newcg)[i] & j) == j)
349
					continue;
350
				for (k = 0; k < NBBY; k++) {
351
					if ((j & (1 << k)) == 0)
352
						continue;
353
					if (cg_blksfree(newcg)[i] & (1 << k))
354
						continue;
355
					pwarn("ALLOCATED FRAG %lld MARKED FREE\n",
356
					      ((long long)c * fs->fs_fpg + i * 8) + k);
357
				}
358
			}
359
		}
360

60
		if (memcmp(cg_inosused(newcg), cg_inosused(cg),
361
12
			   mapsize) != 0 &&
362
		    dofix(&idesc[1], "BLK(S) MISSING IN BIT MAPS")) {
363
			memmove(cg_inosused(cg), cg_inosused(newcg),
364
				(size_t)mapsize);
365
			cgdirty();
366
		}
367
	}
368
8
	info_fn = NULL;
369
8
	if (fs->fs_postblformat == FS_42POSTBLFMT)
370
		fs->fs_nrpos = savednrpos;
371
372
	sumsize = sizeof(cstotal) - sizeof(cstotal.cs_spare);
373
8
	if (memcmp(&cstotal, &fs->fs_cstotal, sumsize) != 0
374
8
	    && dofix(&idesc[0], "FREE BLK COUNT(S) WRONG IN SUPERBLK")) {
375
		memcpy(&fs->fs_cstotal, &cstotal, sumsize);
376
		fs->fs_ronly = 0;
377
		fs->fs_fmod = 0;
378
		sbdirty();
379
	}
380
8
}