1 /*
2  * pass5.c --- check block and inode bitmaps against on-disk bitmaps
3  *
4  * Copyright (C) 1993, 1994, 1995, 1996, 1997 Theodore Ts'o.
5  *
6  * %Begin-Header%
7  * This file may be redistributed under the terms of the GNU Public
8  * License.
9  * %End-Header%
10  *
11  */
12 
13 #include <stdint.h>
14 #include <sys/types.h>
15 #include <sys/stat.h>
16 #include <sys/ioctl.h>
17 #include <fcntl.h>
18 #include <errno.h>
19 
20 #include "e2fsck.h"
21 #include "problem.h"
22 
23 #define DIV_ROUND_UP(n,d) (((n) + (d) - 1) / (d))
24 
25 static void check_block_bitmaps(e2fsck_t ctx);
26 static void check_inode_bitmaps(e2fsck_t ctx);
27 static void check_inode_end(e2fsck_t ctx);
28 static void check_block_end(e2fsck_t ctx);
29 
e2fsck_pass5(e2fsck_t ctx)30 void e2fsck_pass5(e2fsck_t ctx)
31 {
32 #ifdef RESOURCE_TRACK
33 	struct resource_track	rtrack;
34 #endif
35 	struct problem_context	pctx;
36 
37 #ifdef MTRACE
38 	mtrace_print("Pass 5");
39 #endif
40 
41 	init_resource_track(&rtrack, ctx->fs->io);
42 	clear_problem_context(&pctx);
43 
44 	if (!(ctx->options & E2F_OPT_PREEN))
45 		fix_problem(ctx, PR_5_PASS_HEADER, &pctx);
46 
47 	if (ctx->progress)
48 		if ((ctx->progress)(ctx, 5, 0, ctx->fs->group_desc_count*2))
49 			return;
50 
51 	e2fsck_read_bitmaps(ctx);
52 
53 	check_block_bitmaps(ctx);
54 	if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
55 		return;
56 	check_inode_bitmaps(ctx);
57 	if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
58 		return;
59 	check_inode_end(ctx);
60 	if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
61 		return;
62 	check_block_end(ctx);
63 	if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
64 		return;
65 
66 	ext2fs_free_inode_bitmap(ctx->inode_used_map);
67 	ctx->inode_used_map = 0;
68 	ext2fs_free_inode_bitmap(ctx->inode_dir_map);
69 	ctx->inode_dir_map = 0;
70 	ext2fs_free_block_bitmap(ctx->block_found_map);
71 	ctx->block_found_map = 0;
72 
73 	print_resource_track(ctx, _("Pass 5"), &rtrack, ctx->fs->io);
74 }
75 
e2fsck_discard_blocks(e2fsck_t ctx,blk64_t start,blk64_t count)76 static void e2fsck_discard_blocks(e2fsck_t ctx, blk64_t start,
77 				  blk64_t count)
78 {
79 	ext2_filsys fs = ctx->fs;
80 
81 	/*
82 	 * If the filesystem has changed it means that there was an corruption
83 	 * which should be repaired, but in some cases just one e2fsck run is
84 	 * not enough to fix the problem, hence it is not safe to run discard
85 	 * in this case.
86 	 */
87 	if (ext2fs_test_changed(fs))
88 		ctx->options &= ~E2F_OPT_DISCARD;
89 
90 	if ((ctx->options & E2F_OPT_DISCARD) &&
91 	    (io_channel_discard(fs->io, start, count)))
92 		ctx->options &= ~E2F_OPT_DISCARD;
93 }
94 
95 /*
96  * This will try to discard number 'count' inodes starting at
97  * inode number 'start' within the 'group'. Note that 'start'
98  * is 1-based, it means that we need to adjust it by -1 in this
99  * function to compute right offset in the particular inode table.
100  */
e2fsck_discard_inodes(e2fsck_t ctx,dgrp_t group,ext2_ino_t start,int count)101 static void e2fsck_discard_inodes(e2fsck_t ctx, dgrp_t group,
102 				  ext2_ino_t start, int count)
103 {
104 	ext2_filsys fs = ctx->fs;
105 	blk64_t blk, num;
106 
107 	/*
108 	 * Sanity check for 'start'
109 	 */
110 	if ((start < 1) || (start > EXT2_INODES_PER_GROUP(fs->super))) {
111 		printf("PROGRAMMING ERROR: Got start %d outside of group %d!"
112 		       " Disabling discard\n",
113 			start, group);
114 		ctx->options &= ~E2F_OPT_DISCARD;
115 	}
116 
117 	/*
118 	 * Do not attempt to discard if E2F_OPT_DISCARD is not set. And also
119 	 * skip the discard on this group if discard does not zero data.
120 	 * The reason is that if the inode table is not zeroed discard would
121 	 * no help us since we need to zero it anyway, or if the inode table
122 	 * is zeroed then the read after discard would not be deterministic
123 	 * anyway and we would not be able to assume that this inode table
124 	 * was zeroed anymore so we would have to zero it again, which does
125 	 * not really make sense.
126 	 */
127 	if (!(ctx->options & E2F_OPT_DISCARD) ||
128 	    !io_channel_discard_zeroes_data(fs->io))
129 		return;
130 
131 	/*
132 	 * Start is inode number within the group which starts
133 	 * counting from 1, so we need to adjust it.
134 	 */
135 	start -= 1;
136 
137 	/*
138 	 * We can discard only blocks containing only unused
139 	 * inodes in the table.
140 	 */
141 	blk = DIV_ROUND_UP(start,
142 		EXT2_INODES_PER_BLOCK(fs->super));
143 	count -= (blk * EXT2_INODES_PER_BLOCK(fs->super) - start);
144 	blk += ext2fs_inode_table_loc(fs, group);
145 	num = count / EXT2_INODES_PER_BLOCK(fs->super);
146 
147 	if (num > 0)
148 		e2fsck_discard_blocks(ctx, blk, num);
149 }
150 
151 #define NO_BLK ((blk64_t) -1)
152 
print_bitmap_problem(e2fsck_t ctx,problem_t problem,struct problem_context * pctx)153 static void print_bitmap_problem(e2fsck_t ctx, problem_t problem,
154 			    struct problem_context *pctx)
155 {
156 	switch (problem) {
157 	case PR_5_BLOCK_UNUSED:
158 		if (pctx->blk == pctx->blk2)
159 			pctx->blk2 = 0;
160 		else
161 			problem = PR_5_BLOCK_RANGE_UNUSED;
162 		break;
163 	case PR_5_BLOCK_USED:
164 		if (pctx->blk == pctx->blk2)
165 			pctx->blk2 = 0;
166 		else
167 			problem = PR_5_BLOCK_RANGE_USED;
168 		break;
169 	case PR_5_INODE_UNUSED:
170 		if (pctx->ino == pctx->ino2)
171 			pctx->ino2 = 0;
172 		else
173 			problem = PR_5_INODE_RANGE_UNUSED;
174 		break;
175 	case PR_5_INODE_USED:
176 		if (pctx->ino == pctx->ino2)
177 			pctx->ino2 = 0;
178 		else
179 			problem = PR_5_INODE_RANGE_USED;
180 		break;
181 	}
182 	fix_problem(ctx, problem, pctx);
183 	pctx->blk = pctx->blk2 = NO_BLK;
184 	pctx->ino = pctx->ino2 = 0;
185 }
186 
187 /* Just to be more succint */
188 #define B2C(x)	EXT2FS_B2C(fs, (x))
189 #define EQ_CLSTR(x, y) (B2C(x) == B2C(y))
190 #define LE_CLSTR(x, y) (B2C(x) <= B2C(y))
191 #define GE_CLSTR(x, y) (B2C(x) >= B2C(y))
192 
check_block_bitmaps(e2fsck_t ctx)193 static void check_block_bitmaps(e2fsck_t ctx)
194 {
195 	ext2_filsys fs = ctx->fs;
196 	blk64_t	i;
197 	unsigned int	*free_array;
198 	dgrp_t		g, group = 0;
199 	unsigned int	blocks = 0;
200 	blk64_t	free_blocks = 0;
201 	blk64_t first_free = ext2fs_blocks_count(fs->super);
202 	unsigned int	group_free = 0;
203 	int	actual, bitmap;
204 	struct problem_context	pctx;
205 	problem_t	problem, save_problem;
206 	int		fixit, had_problem;
207 	errcode_t	retval;
208 	int		csum_flag;
209 	int		skip_group = 0;
210 	int	old_desc_blocks = 0;
211 	int	count = 0;
212 	int	cmp_block = 0;
213 	int	redo_flag = 0;
214 	blk64_t	super_blk, old_desc_blk, new_desc_blk;
215 	char *actual_buf, *bitmap_buf;
216 
217 	actual_buf = (char *) e2fsck_allocate_memory(ctx, fs->blocksize,
218 						     "actual bitmap buffer");
219 	bitmap_buf = (char *) e2fsck_allocate_memory(ctx, fs->blocksize,
220 						     "bitmap block buffer");
221 
222 	clear_problem_context(&pctx);
223 	free_array = (unsigned int *) e2fsck_allocate_memory(ctx,
224 	    fs->group_desc_count * sizeof(unsigned int), "free block count array");
225 
226 	if ((B2C(fs->super->s_first_data_block) <
227 	     ext2fs_get_block_bitmap_start2(ctx->block_found_map)) ||
228 	    (B2C(ext2fs_blocks_count(fs->super)-1) >
229 	     ext2fs_get_block_bitmap_end2(ctx->block_found_map))) {
230 		pctx.num = 1;
231 		pctx.blk = B2C(fs->super->s_first_data_block);
232 		pctx.blk2 = B2C(ext2fs_blocks_count(fs->super) - 1);
233 		pctx.ino = ext2fs_get_block_bitmap_start2(ctx->block_found_map);
234 		pctx.ino2 = ext2fs_get_block_bitmap_end2(ctx->block_found_map);
235 		fix_problem(ctx, PR_5_BMAP_ENDPOINTS, &pctx);
236 
237 		ctx->flags |= E2F_FLAG_ABORT; /* fatal */
238 		goto errout;
239 	}
240 
241 	if ((B2C(fs->super->s_first_data_block) <
242 	     ext2fs_get_block_bitmap_start2(fs->block_map)) ||
243 	    (B2C(ext2fs_blocks_count(fs->super)-1) >
244 	     ext2fs_get_block_bitmap_end2(fs->block_map))) {
245 		pctx.num = 2;
246 		pctx.blk = B2C(fs->super->s_first_data_block);
247 		pctx.blk2 = B2C(ext2fs_blocks_count(fs->super) - 1);
248 		pctx.ino = ext2fs_get_block_bitmap_start2(fs->block_map);
249 		pctx.ino2 = ext2fs_get_block_bitmap_end2(fs->block_map);
250 		fix_problem(ctx, PR_5_BMAP_ENDPOINTS, &pctx);
251 
252 		ctx->flags |= E2F_FLAG_ABORT; /* fatal */
253 		goto errout;
254 	}
255 
256 	csum_flag = EXT2_HAS_RO_COMPAT_FEATURE(fs->super,
257 					       EXT4_FEATURE_RO_COMPAT_GDT_CSUM);
258 redo_counts:
259 	had_problem = 0;
260 	save_problem = 0;
261 	pctx.blk = pctx.blk2 = NO_BLK;
262 	if (csum_flag &&
263 	    (ext2fs_bg_flags_test(fs, group, EXT2_BG_BLOCK_UNINIT)))
264 		skip_group++;
265 	for (i = B2C(fs->super->s_first_data_block);
266 	     i < ext2fs_blocks_count(fs->super);
267 	     i += EXT2FS_CLUSTER_RATIO(fs)) {
268 		int first_block_in_bg = (B2C(i) -
269 					 B2C(fs->super->s_first_data_block)) %
270 			fs->super->s_clusters_per_group == 0;
271 		int n, nbytes = fs->super->s_clusters_per_group / 8;
272 
273 		actual = ext2fs_fast_test_block_bitmap2(ctx->block_found_map, i);
274 
275 		/*
276 		 * Try to optimize pass5 by extracting a bitmap block
277 		 * as expected from what we have on disk, and then
278 		 * comparing the two.  If they are identical, then
279 		 * update the free block counts and go on to the next
280 		 * block group.  This is much faster than doing the
281 		 * individual bit-by-bit comparison.  The one downside
282 		 * is that this doesn't work if we are asking e2fsck
283 		 * to do a discard operation.
284 		 */
285 		if (!first_block_in_bg ||
286 		    (group == (int)fs->group_desc_count - 1) ||
287 		    (ctx->options & E2F_OPT_DISCARD))
288 			goto no_optimize;
289 
290 		retval = ext2fs_get_block_bitmap_range2(ctx->block_found_map,
291 				B2C(i), fs->super->s_clusters_per_group,
292 				actual_buf);
293 		if (retval)
294 			goto no_optimize;
295 		if (ext2fs_bg_flags_test(fs, group, EXT2_BG_BLOCK_UNINIT))
296 			memset(bitmap_buf, 0, nbytes);
297 		else {
298 			retval = ext2fs_get_block_bitmap_range2(fs->block_map,
299 					B2C(i), fs->super->s_clusters_per_group,
300 					bitmap_buf);
301 			if (retval)
302 				goto no_optimize;
303 		}
304 		if (memcmp(actual_buf, bitmap_buf, nbytes) != 0)
305 			goto no_optimize;
306 		n = ext2fs_bitcount(actual_buf, nbytes);
307 		group_free = fs->super->s_clusters_per_group - n;
308 		free_blocks += group_free;
309 		i += EXT2FS_C2B(fs, fs->super->s_clusters_per_group - 1);
310 		goto next_group;
311 	no_optimize:
312 
313 		if (skip_group) {
314 			if (first_block_in_bg) {
315 				super_blk = 0;
316 				old_desc_blk = 0;
317 				new_desc_blk = 0;
318 				ext2fs_super_and_bgd_loc2(fs, group, &super_blk,
319 					 &old_desc_blk, &new_desc_blk, 0);
320 
321 				if (fs->super->s_feature_incompat &
322 						EXT2_FEATURE_INCOMPAT_META_BG)
323 					old_desc_blocks =
324 						fs->super->s_first_meta_bg;
325 				else
326 					old_desc_blocks = fs->desc_blocks +
327 					fs->super->s_reserved_gdt_blocks;
328 
329 				count = 0;
330 				cmp_block = fs->super->s_clusters_per_group;
331 				if (group == (int)fs->group_desc_count - 1)
332 					cmp_block = EXT2FS_NUM_B2C(fs,
333 						    ext2fs_group_blocks_count(fs, group));
334 			}
335 
336 			bitmap = 0;
337 			if (EQ_CLSTR(i, super_blk) ||
338 			    (old_desc_blk && old_desc_blocks &&
339 			     GE_CLSTR(i, old_desc_blk) &&
340 			     LE_CLSTR(i, old_desc_blk + old_desc_blocks-1)) ||
341 			    (new_desc_blk && EQ_CLSTR(i, new_desc_blk)) ||
342 			    EQ_CLSTR(i, ext2fs_block_bitmap_loc(fs, group)) ||
343 			    EQ_CLSTR(i, ext2fs_inode_bitmap_loc(fs, group)) ||
344 			    (GE_CLSTR(i, ext2fs_inode_table_loc(fs, group)) &&
345 			     LE_CLSTR(i, (ext2fs_inode_table_loc(fs, group) +
346 					  fs->inode_blocks_per_group - 1)))) {
347 				bitmap = 1;
348 				actual = (actual != 0);
349 				count++;
350 				cmp_block--;
351 			} else if ((EXT2FS_B2C(fs, i) - count -
352 				    EXT2FS_B2C(fs, fs->super->s_first_data_block)) %
353 				   fs->super->s_clusters_per_group == 0) {
354 				/*
355 				 * When the compare data blocks in block bitmap
356 				 * are 0, count the free block,
357 				 * skip the current block group.
358 				 */
359 				if (ext2fs_test_block_bitmap_range2(
360 					    ctx->block_found_map,
361 					    EXT2FS_B2C(fs, i),
362 					    cmp_block)) {
363 					/*
364 					 * -1 means to skip the current block
365 					 * group.
366 					 */
367 					blocks = fs->super->s_clusters_per_group - 1;
368 					group_free = cmp_block;
369 					free_blocks += cmp_block;
370 					/*
371 					 * The current block group's last block
372 					 * is set to i.
373 					 */
374 					i += EXT2FS_C2B(fs, cmp_block - 1);
375 					bitmap = 1;
376 					goto do_counts;
377 				}
378 			}
379 		} else if (redo_flag)
380 			bitmap = actual;
381 		else
382 			bitmap = ext2fs_fast_test_block_bitmap2(fs->block_map, i);
383 
384 		if (!actual == !bitmap)
385 			goto do_counts;
386 
387 		if (!actual && bitmap) {
388 			/*
389 			 * Block not used, but marked in use in the bitmap.
390 			 */
391 			problem = PR_5_BLOCK_UNUSED;
392 		} else {
393 			/*
394 			 * Block used, but not marked in use in the bitmap.
395 			 */
396 			problem = PR_5_BLOCK_USED;
397 
398 			if (skip_group) {
399 				struct problem_context pctx2;
400 				pctx2.blk = i;
401 				pctx2.group = group;
402 				if (fix_problem(ctx, PR_5_BLOCK_UNINIT,&pctx2)){
403 					ext2fs_bg_flags_clear(fs, group, EXT2_BG_BLOCK_UNINIT);
404 					skip_group = 0;
405 				}
406 			}
407 		}
408 		if (pctx.blk == NO_BLK) {
409 			pctx.blk = pctx.blk2 = i;
410 			save_problem = problem;
411 		} else {
412 			if ((problem == save_problem) &&
413 			    (pctx.blk2 == i - EXT2FS_CLUSTER_RATIO(fs)))
414 				pctx.blk2 += EXT2FS_CLUSTER_RATIO(fs);
415 			else {
416 				print_bitmap_problem(ctx, save_problem, &pctx);
417 				pctx.blk = pctx.blk2 = i;
418 				save_problem = problem;
419 			}
420 		}
421 		ctx->flags |= E2F_FLAG_PROG_SUPPRESS;
422 		had_problem++;
423 
424 		/*
425 		 * If there a problem we should turn off the discard so we
426 		 * do not compromise the filesystem.
427 		 */
428 		ctx->options &= ~E2F_OPT_DISCARD;
429 
430 	do_counts:
431 		if (!bitmap) {
432 			group_free++;
433 			free_blocks++;
434 			if (first_free > i)
435 				first_free = i;
436 		} else if (i > first_free) {
437 			e2fsck_discard_blocks(ctx, first_free,
438 					      (i - first_free));
439 			first_free = ext2fs_blocks_count(fs->super);
440 		}
441 		blocks ++;
442 		if ((blocks == fs->super->s_clusters_per_group) ||
443 		    (EXT2FS_B2C(fs, i) ==
444 		     EXT2FS_B2C(fs, ext2fs_blocks_count(fs->super)-1))) {
445 			/*
446 			 * If the last block of this group is free, then we can
447 			 * discard it as well.
448 			 */
449 			if (!bitmap && i >= first_free)
450 				e2fsck_discard_blocks(ctx, first_free,
451 						      (i - first_free) + 1);
452 		next_group:
453 			first_free = ext2fs_blocks_count(fs->super);
454 
455 			free_array[group] = group_free;
456 			group ++;
457 			blocks = 0;
458 			group_free = 0;
459 			skip_group = 0;
460 			if (ctx->progress)
461 				if ((ctx->progress)(ctx, 5, group,
462 						    fs->group_desc_count*2))
463 					goto errout;
464 			if (csum_flag &&
465 			    (i != ext2fs_blocks_count(fs->super)-1) &&
466 			    ext2fs_bg_flags_test(fs, group,
467 						EXT2_BG_BLOCK_UNINIT))
468 				skip_group++;
469 		}
470 	}
471 	if (pctx.blk != NO_BLK)
472 		print_bitmap_problem(ctx, save_problem, &pctx);
473 	if (had_problem)
474 		fixit = end_problem_latch(ctx, PR_LATCH_BBITMAP);
475 	else
476 		fixit = -1;
477 	ctx->flags &= ~E2F_FLAG_PROG_SUPPRESS;
478 
479 	if (fixit == 1) {
480 		ext2fs_free_block_bitmap(fs->block_map);
481 		retval = ext2fs_copy_bitmap(ctx->block_found_map,
482 						  &fs->block_map);
483 		if (retval) {
484 			clear_problem_context(&pctx);
485 			fix_problem(ctx, PR_5_COPY_BBITMAP_ERROR, &pctx);
486 			ctx->flags |= E2F_FLAG_ABORT;
487 			goto errout;
488 		}
489 		ext2fs_set_bitmap_padding(fs->block_map);
490 		ext2fs_mark_bb_dirty(fs);
491 
492 		/* Redo the counts */
493 		blocks = 0; free_blocks = 0; group_free = 0; group = 0;
494 		memset(free_array, 0, fs->group_desc_count * sizeof(int));
495 		redo_flag++;
496 		goto redo_counts;
497 	} else if (fixit == 0)
498 		ext2fs_unmark_valid(fs);
499 
500 	for (g = 0; g < fs->group_desc_count; g++) {
501 		if (free_array[g] != ext2fs_bg_free_blocks_count(fs, g)) {
502 			pctx.group = g;
503 			pctx.blk = ext2fs_bg_free_blocks_count(fs, g);
504 			pctx.blk2 = free_array[g];
505 
506 			if (fix_problem(ctx, PR_5_FREE_BLOCK_COUNT_GROUP,
507 					&pctx)) {
508 				ext2fs_bg_free_blocks_count_set(fs, g, free_array[g]);
509 				ext2fs_mark_super_dirty(fs);
510 			} else
511 				ext2fs_unmark_valid(fs);
512 		}
513 	}
514 	free_blocks = EXT2FS_C2B(fs, free_blocks);
515 	if (free_blocks != ext2fs_free_blocks_count(fs->super)) {
516 		pctx.group = 0;
517 		pctx.blk = ext2fs_free_blocks_count(fs->super);
518 		pctx.blk2 = free_blocks;
519 
520 		if (fix_problem(ctx, PR_5_FREE_BLOCK_COUNT, &pctx)) {
521 			ext2fs_free_blocks_count_set(fs->super, free_blocks);
522 			ext2fs_mark_super_dirty(fs);
523 		}
524 	}
525 errout:
526 	ext2fs_free_mem(&free_array);
527 	ext2fs_free_mem(&actual_buf);
528 	ext2fs_free_mem(&bitmap_buf);
529 }
530 
check_inode_bitmaps(e2fsck_t ctx)531 static void check_inode_bitmaps(e2fsck_t ctx)
532 {
533 	ext2_filsys fs = ctx->fs;
534 	ext2_ino_t	i;
535 	unsigned int	free_inodes = 0;
536 	int		group_free = 0;
537 	int		dirs_count = 0;
538 	dgrp_t		group = 0;
539 	unsigned int	inodes = 0;
540 	ext2_ino_t	*free_array;
541 	ext2_ino_t	*dir_array;
542 	int		actual, bitmap;
543 	errcode_t	retval;
544 	struct problem_context	pctx;
545 	problem_t	problem, save_problem;
546 	int		fixit, had_problem;
547 	int		csum_flag;
548 	int		skip_group = 0;
549 	int		redo_flag = 0;
550 	ext2_ino_t		first_free = fs->super->s_inodes_per_group + 1;
551 
552 	clear_problem_context(&pctx);
553 	free_array = (ext2_ino_t *) e2fsck_allocate_memory(ctx,
554 	    fs->group_desc_count * sizeof(ext2_ino_t), "free inode count array");
555 
556 	dir_array = (ext2_ino_t *) e2fsck_allocate_memory(ctx,
557 	   fs->group_desc_count * sizeof(ext2_ino_t), "directory count array");
558 
559 	if ((1 < ext2fs_get_inode_bitmap_start2(ctx->inode_used_map)) ||
560 	    (fs->super->s_inodes_count >
561 	     ext2fs_get_inode_bitmap_end2(ctx->inode_used_map))) {
562 		pctx.num = 3;
563 		pctx.blk = 1;
564 		pctx.blk2 = fs->super->s_inodes_count;
565 		pctx.ino = ext2fs_get_inode_bitmap_start2(ctx->inode_used_map);
566 		pctx.ino2 = ext2fs_get_inode_bitmap_end2(ctx->inode_used_map);
567 		fix_problem(ctx, PR_5_BMAP_ENDPOINTS, &pctx);
568 
569 		ctx->flags |= E2F_FLAG_ABORT; /* fatal */
570 		goto errout;
571 	}
572 	if ((1 < ext2fs_get_inode_bitmap_start2(fs->inode_map)) ||
573 	    (fs->super->s_inodes_count >
574 	     ext2fs_get_inode_bitmap_end2(fs->inode_map))) {
575 		pctx.num = 4;
576 		pctx.blk = 1;
577 		pctx.blk2 = fs->super->s_inodes_count;
578 		pctx.ino = ext2fs_get_inode_bitmap_start2(fs->inode_map);
579 		pctx.ino2 = ext2fs_get_inode_bitmap_end2(fs->inode_map);
580 		fix_problem(ctx, PR_5_BMAP_ENDPOINTS, &pctx);
581 
582 		ctx->flags |= E2F_FLAG_ABORT; /* fatal */
583 		goto errout;
584 	}
585 
586 	csum_flag = EXT2_HAS_RO_COMPAT_FEATURE(fs->super,
587 					       EXT4_FEATURE_RO_COMPAT_GDT_CSUM);
588 redo_counts:
589 	had_problem = 0;
590 	save_problem = 0;
591 	pctx.ino = pctx.ino2 = 0;
592 	if (csum_flag &&
593 	    (ext2fs_bg_flags_test(fs, group, EXT2_BG_INODE_UNINIT)))
594 		skip_group++;
595 
596 	/* Protect loop from wrap-around if inodes_count is maxed */
597 	for (i = 1; i <= fs->super->s_inodes_count && i > 0; i++) {
598 		bitmap = 0;
599 		if (skip_group &&
600 		    i % fs->super->s_inodes_per_group == 1) {
601 			/*
602 			 * Current inode is the first inode
603 			 * in the current block group.
604 			 */
605 			if (ext2fs_test_inode_bitmap_range(
606 				    ctx->inode_used_map, i,
607 				    fs->super->s_inodes_per_group)) {
608 				/*
609 				 * When the compared inodes in inodes bitmap
610 				 * are 0, count the free inode,
611 				 * skip the current block group.
612 				 */
613 				first_free = 1;
614 				inodes = fs->super->s_inodes_per_group - 1;
615 				group_free = inodes;
616 				free_inodes += inodes;
617 				i += inodes;
618 				skip_group = 0;
619 				goto do_counts;
620 			}
621 		}
622 
623 		actual = ext2fs_fast_test_inode_bitmap2(ctx->inode_used_map, i);
624 		if (redo_flag)
625 			bitmap = actual;
626 		else if (!skip_group)
627 			bitmap = ext2fs_fast_test_inode_bitmap2(fs->inode_map, i);
628 		if (!actual == !bitmap)
629 			goto do_counts;
630 
631 		if (!actual && bitmap) {
632 			/*
633 			 * Inode wasn't used, but marked in bitmap
634 			 */
635 			problem = PR_5_INODE_UNUSED;
636 		} else /* if (actual && !bitmap) */ {
637 			/*
638 			 * Inode used, but not in bitmap
639 			 */
640 			problem = PR_5_INODE_USED;
641 
642 			/* We should never hit this, because it means that
643 			 * inodes were marked in use that weren't noticed
644 			 * in pass1 or pass 2. It is easier to fix the problem
645 			 * than to kill e2fsck and leave the user stuck. */
646 			if (skip_group) {
647 				struct problem_context pctx2;
648 				pctx2.blk = i;
649 				pctx2.group = group;
650 				if (fix_problem(ctx, PR_5_INODE_UNINIT,&pctx2)){
651 					ext2fs_bg_flags_clear(fs, group, EXT2_BG_INODE_UNINIT);
652 					skip_group = 0;
653 				}
654 			}
655 		}
656 		if (pctx.ino == 0) {
657 			pctx.ino = pctx.ino2 = i;
658 			save_problem = problem;
659 		} else {
660 			if ((problem == save_problem) &&
661 			    (pctx.ino2 == i-1))
662 				pctx.ino2++;
663 			else {
664 				print_bitmap_problem(ctx, save_problem, &pctx);
665 				pctx.ino = pctx.ino2 = i;
666 				save_problem = problem;
667 			}
668 		}
669 		ctx->flags |= E2F_FLAG_PROG_SUPPRESS;
670 		had_problem++;
671 		/*
672 		 * If there a problem we should turn off the discard so we
673 		 * do not compromise the filesystem.
674 		 */
675 		ctx->options &= ~E2F_OPT_DISCARD;
676 
677 do_counts:
678 		inodes++;
679 		if (bitmap) {
680 			if (ext2fs_test_inode_bitmap2(ctx->inode_dir_map, i))
681 				dirs_count++;
682 			if (inodes > first_free) {
683 				e2fsck_discard_inodes(ctx, group, first_free,
684 						      inodes - first_free);
685 				first_free = fs->super->s_inodes_per_group + 1;
686 			}
687 		} else {
688 			group_free++;
689 			free_inodes++;
690 			if (first_free > inodes)
691 				first_free = inodes;
692 		}
693 
694 		if ((inodes == fs->super->s_inodes_per_group) ||
695 		    (i == fs->super->s_inodes_count)) {
696 			/*
697 			 * If the last inode is free, we can discard it as well.
698 			 */
699 			if (!bitmap && inodes >= first_free)
700 				e2fsck_discard_inodes(ctx, group, first_free,
701 						      inodes - first_free + 1);
702 			/*
703 			 * If discard zeroes data and the group inode table
704 			 * was not zeroed yet, set itable as zeroed
705 			 */
706 			if ((ctx->options & E2F_OPT_DISCARD) &&
707 			    io_channel_discard_zeroes_data(fs->io) &&
708 			    !(ext2fs_bg_flags_test(fs, group,
709 						   EXT2_BG_INODE_ZEROED))) {
710 				ext2fs_bg_flags_set(fs, group,
711 						    EXT2_BG_INODE_ZEROED);
712 				ext2fs_group_desc_csum_set(fs, group);
713 			}
714 
715 			first_free = fs->super->s_inodes_per_group + 1;
716 			free_array[group] = group_free;
717 			dir_array[group] = dirs_count;
718 			group ++;
719 			inodes = 0;
720 			skip_group = 0;
721 			group_free = 0;
722 			dirs_count = 0;
723 			if (ctx->progress)
724 				if ((ctx->progress)(ctx, 5,
725 					    group + fs->group_desc_count,
726 					    fs->group_desc_count*2))
727 					goto errout;
728 			if (csum_flag &&
729 			    (i != fs->super->s_inodes_count) &&
730 			    (ext2fs_bg_flags_test(fs, group, EXT2_BG_INODE_UNINIT)
731 			     ))
732 				skip_group++;
733 		}
734 	}
735 	if (pctx.ino)
736 		print_bitmap_problem(ctx, save_problem, &pctx);
737 
738 	if (had_problem)
739 		fixit = end_problem_latch(ctx, PR_LATCH_IBITMAP);
740 	else
741 		fixit = -1;
742 	ctx->flags &= ~E2F_FLAG_PROG_SUPPRESS;
743 
744 	if (fixit == 1) {
745 		ext2fs_free_inode_bitmap(fs->inode_map);
746 		retval = ext2fs_copy_bitmap(ctx->inode_used_map,
747 						  &fs->inode_map);
748 		if (retval) {
749 			clear_problem_context(&pctx);
750 			fix_problem(ctx, PR_5_COPY_IBITMAP_ERROR, &pctx);
751 			ctx->flags |= E2F_FLAG_ABORT;
752 			goto errout;
753 		}
754 		ext2fs_set_bitmap_padding(fs->inode_map);
755 		ext2fs_mark_ib_dirty(fs);
756 
757 		/* redo counts */
758 		inodes = 0; free_inodes = 0; group_free = 0;
759 		dirs_count = 0; group = 0;
760 		memset(free_array, 0, fs->group_desc_count * sizeof(int));
761 		memset(dir_array, 0, fs->group_desc_count * sizeof(int));
762 		redo_flag++;
763 		goto redo_counts;
764 	} else if (fixit == 0)
765 		ext2fs_unmark_valid(fs);
766 
767 	for (i = 0; i < fs->group_desc_count; i++) {
768 		if (free_array[i] != ext2fs_bg_free_inodes_count(fs, i)) {
769 			pctx.group = i;
770 			pctx.ino = ext2fs_bg_free_inodes_count(fs, i);
771 			pctx.ino2 = free_array[i];
772 			if (fix_problem(ctx, PR_5_FREE_INODE_COUNT_GROUP,
773 					&pctx)) {
774 				ext2fs_bg_free_inodes_count_set(fs, i, free_array[i]);
775 				ext2fs_mark_super_dirty(fs);
776 			} else
777 				ext2fs_unmark_valid(fs);
778 		}
779 		if (dir_array[i] != ext2fs_bg_used_dirs_count(fs, i)) {
780 			pctx.group = i;
781 			pctx.ino = ext2fs_bg_used_dirs_count(fs, i);
782 			pctx.ino2 = dir_array[i];
783 
784 			if (fix_problem(ctx, PR_5_FREE_DIR_COUNT_GROUP,
785 					&pctx)) {
786 				ext2fs_bg_used_dirs_count_set(fs, i, dir_array[i]);
787 				ext2fs_mark_super_dirty(fs);
788 			} else
789 				ext2fs_unmark_valid(fs);
790 		}
791 	}
792 	if (free_inodes != fs->super->s_free_inodes_count) {
793 		pctx.group = -1;
794 		pctx.ino = fs->super->s_free_inodes_count;
795 		pctx.ino2 = free_inodes;
796 
797 		if (fix_problem(ctx, PR_5_FREE_INODE_COUNT, &pctx)) {
798 			fs->super->s_free_inodes_count = free_inodes;
799 			ext2fs_mark_super_dirty(fs);
800 		}
801 	}
802 errout:
803 	ext2fs_free_mem(&free_array);
804 	ext2fs_free_mem(&dir_array);
805 }
806 
check_inode_end(e2fsck_t ctx)807 static void check_inode_end(e2fsck_t ctx)
808 {
809 	ext2_filsys fs = ctx->fs;
810 	ext2_ino_t	end, save_inodes_count, i;
811 	struct problem_context	pctx;
812 
813 	clear_problem_context(&pctx);
814 
815 	end = EXT2_INODES_PER_GROUP(fs->super) * fs->group_desc_count;
816 	pctx.errcode = ext2fs_fudge_inode_bitmap_end(fs->inode_map, end,
817 						     &save_inodes_count);
818 	if (pctx.errcode) {
819 		pctx.num = 1;
820 		fix_problem(ctx, PR_5_FUDGE_BITMAP_ERROR, &pctx);
821 		ctx->flags |= E2F_FLAG_ABORT; /* fatal */
822 		return;
823 	}
824 	if (save_inodes_count == end)
825 		return;
826 
827 	/* protect loop from wrap-around if end is maxed */
828 	for (i = save_inodes_count + 1; i <= end && i > save_inodes_count; i++) {
829 		if (!ext2fs_test_inode_bitmap(fs->inode_map, i)) {
830 			if (fix_problem(ctx, PR_5_INODE_BMAP_PADDING, &pctx)) {
831 				for (; i <= end; i++)
832 					ext2fs_mark_inode_bitmap(fs->inode_map,
833 								 i);
834 				ext2fs_mark_ib_dirty(fs);
835 			} else
836 				ext2fs_unmark_valid(fs);
837 			break;
838 		}
839 	}
840 
841 	pctx.errcode = ext2fs_fudge_inode_bitmap_end(fs->inode_map,
842 						     save_inodes_count, 0);
843 	if (pctx.errcode) {
844 		pctx.num = 2;
845 		fix_problem(ctx, PR_5_FUDGE_BITMAP_ERROR, &pctx);
846 		ctx->flags |= E2F_FLAG_ABORT; /* fatal */
847 		return;
848 	}
849 }
850 
check_block_end(e2fsck_t ctx)851 static void check_block_end(e2fsck_t ctx)
852 {
853 	ext2_filsys fs = ctx->fs;
854 	blk64_t	end, save_blocks_count, i;
855 	struct problem_context	pctx;
856 
857 	clear_problem_context(&pctx);
858 
859 	end = ext2fs_get_block_bitmap_start2(fs->block_map) +
860 		((blk64_t)EXT2_CLUSTERS_PER_GROUP(fs->super) * fs->group_desc_count) - 1;
861 	pctx.errcode = ext2fs_fudge_block_bitmap_end2(fs->block_map, end,
862 						     &save_blocks_count);
863 	if (pctx.errcode) {
864 		pctx.num = 3;
865 		fix_problem(ctx, PR_5_FUDGE_BITMAP_ERROR, &pctx);
866 		ctx->flags |= E2F_FLAG_ABORT; /* fatal */
867 		return;
868 	}
869 	if (save_blocks_count == end)
870 		return;
871 
872 	/* Protect loop from wrap-around if end is maxed */
873 	for (i = save_blocks_count + 1; i <= end && i > save_blocks_count; i++) {
874 		if (!ext2fs_test_block_bitmap2(fs->block_map,
875 					       EXT2FS_C2B(fs, i))) {
876 			if (fix_problem(ctx, PR_5_BLOCK_BMAP_PADDING, &pctx)) {
877 				for (; i <= end; i++)
878 					ext2fs_mark_block_bitmap2(fs->block_map,
879 							EXT2FS_C2B(fs, i));
880 				ext2fs_mark_bb_dirty(fs);
881 			} else
882 				ext2fs_unmark_valid(fs);
883 			break;
884 		}
885 	}
886 
887 	pctx.errcode = ext2fs_fudge_block_bitmap_end2(fs->block_map,
888 						     save_blocks_count, 0);
889 	if (pctx.errcode) {
890 		pctx.num = 4;
891 		fix_problem(ctx, PR_5_FUDGE_BITMAP_ERROR, &pctx);
892 		ctx->flags |= E2F_FLAG_ABORT; /* fatal */
893 		return;
894 	}
895 }
896 
897 
898 
899