blob: 7215a58d9051ffff91f4d5fd429d2a0793deeb91 [file] [log] [blame]
Theodore Ts'o3839e651997-04-26 13:21:57 +00001/*
2 * pass5.c --- check block and inode bitmaps against on-disk bitmaps
3 *
Theodore Ts'o21c84b71997-04-29 16:15:03 +00004 * 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%
Theodore Ts'o3839e651997-04-26 13:21:57 +000010 *
11 */
12
Theodore Ts'o3839e651997-04-26 13:21:57 +000013#include "e2fsck.h"
Theodore Ts'o1b6bf171997-10-03 17:48:10 +000014#include "problem.h"
Theodore Ts'o3839e651997-04-26 13:21:57 +000015
Theodore Ts'o1b6bf171997-10-03 17:48:10 +000016static void check_block_bitmaps(e2fsck_t ctx);
17static void check_inode_bitmaps(e2fsck_t ctx);
18static void check_inode_end(e2fsck_t ctx);
19static void check_block_end(e2fsck_t ctx);
Theodore Ts'o3839e651997-04-26 13:21:57 +000020
Theodore Ts'o08b21301997-11-03 19:42:40 +000021void e2fsck_pass5(e2fsck_t ctx)
Theodore Ts'o3839e651997-04-26 13:21:57 +000022{
Theodore Ts'o8bf191e1997-10-20 01:38:32 +000023#ifdef RESOURCE_TRACK
Theodore Ts'o3839e651997-04-26 13:21:57 +000024 struct resource_track rtrack;
Theodore Ts'o8bf191e1997-10-20 01:38:32 +000025#endif
Theodore Ts'o1b6bf171997-10-03 17:48:10 +000026 struct problem_context pctx;
Theodore Ts'o3839e651997-04-26 13:21:57 +000027
28#ifdef MTRACE
29 mtrace_print("Pass 5");
30#endif
31
Theodore Ts'o8bf191e1997-10-20 01:38:32 +000032#ifdef RESOURCE_TRACK
Theodore Ts'o3839e651997-04-26 13:21:57 +000033 init_resource_track(&rtrack);
Theodore Ts'o8bf191e1997-10-20 01:38:32 +000034#endif
Theodore Ts'o3839e651997-04-26 13:21:57 +000035
Theodore Ts'o1b6bf171997-10-03 17:48:10 +000036 clear_problem_context(&pctx);
Theodore Ts'o3839e651997-04-26 13:21:57 +000037
Theodore Ts'o1b6bf171997-10-03 17:48:10 +000038 if (!(ctx->options & E2F_OPT_PREEN))
39 fix_problem(ctx, PR_5_PASS_HEADER, &pctx);
Theodore Ts'o3839e651997-04-26 13:21:57 +000040
Theodore Ts'of8188ff1997-11-14 05:23:04 +000041 if (ctx->progress)
42 (ctx->progress)(ctx, 5, 0, 3);
43
44 e2fsck_read_bitmaps(ctx);
45
46 if (ctx->progress)
47 (ctx->progress)(ctx, 5, 2, 3);
Theodore Ts'o3839e651997-04-26 13:21:57 +000048
Theodore Ts'o1b6bf171997-10-03 17:48:10 +000049 check_block_bitmaps(ctx);
Theodore Ts'o08b21301997-11-03 19:42:40 +000050 if (ctx->flags & E2F_FLAG_ABORT)
51 return;
Theodore Ts'o1b6bf171997-10-03 17:48:10 +000052 check_inode_bitmaps(ctx);
Theodore Ts'o08b21301997-11-03 19:42:40 +000053 if (ctx->flags & E2F_FLAG_ABORT)
54 return;
Theodore Ts'o1b6bf171997-10-03 17:48:10 +000055 check_inode_end(ctx);
Theodore Ts'o08b21301997-11-03 19:42:40 +000056 if (ctx->flags & E2F_FLAG_ABORT)
57 return;
Theodore Ts'o1b6bf171997-10-03 17:48:10 +000058 check_block_end(ctx);
Theodore Ts'o08b21301997-11-03 19:42:40 +000059 if (ctx->flags & E2F_FLAG_ABORT)
60 return;
Theodore Ts'o3839e651997-04-26 13:21:57 +000061
Theodore Ts'of8188ff1997-11-14 05:23:04 +000062 if (ctx->progress)
63 (ctx->progress)(ctx, 5, 3, 3);
64
Theodore Ts'o1b6bf171997-10-03 17:48:10 +000065 ext2fs_free_inode_bitmap(ctx->inode_used_map);
66 ctx->inode_used_map = 0;
67 ext2fs_free_inode_bitmap(ctx->inode_dir_map);
68 ctx->inode_dir_map = 0;
69 ext2fs_free_block_bitmap(ctx->block_found_map);
70 ctx->block_found_map = 0;
71
Theodore Ts'o8bf191e1997-10-20 01:38:32 +000072#ifdef RESOURCE_TRACK
Theodore Ts'o1b6bf171997-10-03 17:48:10 +000073 if (ctx->options & E2F_OPT_TIME2)
74 print_resource_track("Pass 5", &rtrack);
Theodore Ts'o8bf191e1997-10-20 01:38:32 +000075#endif
Theodore Ts'o3839e651997-04-26 13:21:57 +000076}
77
Theodore Ts'o1b6bf171997-10-03 17:48:10 +000078static void check_block_bitmaps(e2fsck_t ctx)
Theodore Ts'o3839e651997-04-26 13:21:57 +000079{
Theodore Ts'o1b6bf171997-10-03 17:48:10 +000080 ext2_filsys fs = ctx->fs;
Theodore Ts'of3db3561997-04-26 13:34:30 +000081 blk_t i;
Theodore Ts'o3839e651997-04-26 13:21:57 +000082 int *free_array;
83 int group = 0;
84 int blocks = 0;
85 int free_blocks = 0;
86 int group_free = 0;
87 int actual, bitmap;
Theodore Ts'o1b6bf171997-10-03 17:48:10 +000088 struct problem_context pctx;
89 int problem, fixit;
90 errcode_t retval;
Theodore Ts'o3839e651997-04-26 13:21:57 +000091
Theodore Ts'o1b6bf171997-10-03 17:48:10 +000092 clear_problem_context(&pctx);
Theodore Ts'o54dc7ca1998-01-19 14:50:49 +000093 free_array = (int *) e2fsck_allocate_memory(ctx,
Theodore Ts'of8188ff1997-11-14 05:23:04 +000094 fs->group_desc_count * sizeof(int), "free block count array");
Theodore Ts'o50e1e101997-04-26 13:58:21 +000095
96 if ((fs->super->s_first_data_block <
Theodore Ts'o1b6bf171997-10-03 17:48:10 +000097 ext2fs_get_block_bitmap_start(ctx->block_found_map)) ||
Theodore Ts'o50e1e101997-04-26 13:58:21 +000098 (fs->super->s_blocks_count-1 >
Theodore Ts'o1b6bf171997-10-03 17:48:10 +000099 ext2fs_get_block_bitmap_end(ctx->block_found_map))) {
100 pctx.num = 1;
101 pctx.blk = fs->super->s_first_data_block;
102 pctx.blk2 = fs->super->s_blocks_count -1;
103 pctx.ino = ext2fs_get_block_bitmap_start(ctx->block_found_map);
104 pctx.ino2 = ext2fs_get_block_bitmap_end(ctx->block_found_map);
105 fix_problem(ctx, PR_5_BMAP_ENDPOINTS, &pctx);
Theodore Ts'o08b21301997-11-03 19:42:40 +0000106
107 ctx->flags |= E2F_FLAG_ABORT; /* fatal */
108 return;
Theodore Ts'o50e1e101997-04-26 13:58:21 +0000109 }
110
111 if ((fs->super->s_first_data_block <
112 ext2fs_get_block_bitmap_start(fs->block_map)) ||
113 (fs->super->s_blocks_count-1 >
114 ext2fs_get_block_bitmap_end(fs->block_map))) {
Theodore Ts'o1b6bf171997-10-03 17:48:10 +0000115 pctx.num = 2;
116 pctx.blk = fs->super->s_first_data_block;
117 pctx.blk2 = fs->super->s_blocks_count -1;
118 pctx.ino = ext2fs_get_block_bitmap_start(fs->block_map);
119 pctx.ino2 = ext2fs_get_block_bitmap_end(fs->block_map);
120 fix_problem(ctx, PR_5_BMAP_ENDPOINTS, &pctx);
Theodore Ts'o08b21301997-11-03 19:42:40 +0000121
122 ctx->flags |= E2F_FLAG_ABORT; /* fatal */
123 return;
Theodore Ts'o50e1e101997-04-26 13:58:21 +0000124 }
125
Theodore Ts'o1b6bf171997-10-03 17:48:10 +0000126redo_counts:
Theodore Ts'o3839e651997-04-26 13:21:57 +0000127 for (i = fs->super->s_first_data_block;
128 i < fs->super->s_blocks_count;
129 i++) {
Theodore Ts'o1b6bf171997-10-03 17:48:10 +0000130 actual = ext2fs_fast_test_block_bitmap(ctx->block_found_map, i);
Theodore Ts'o50e1e101997-04-26 13:58:21 +0000131 bitmap = ext2fs_fast_test_block_bitmap(fs->block_map, i);
Theodore Ts'o3839e651997-04-26 13:21:57 +0000132
133 if (actual == bitmap)
134 goto do_counts;
Theodore Ts'o1b6bf171997-10-03 17:48:10 +0000135
Theodore Ts'o3839e651997-04-26 13:21:57 +0000136 if (!actual && bitmap) {
137 /*
138 * Block not used, but marked in use in the bitmap.
139 */
Theodore Ts'o1b6bf171997-10-03 17:48:10 +0000140 problem = PR_5_UNUSED_BLOCK;
Theodore Ts'o3839e651997-04-26 13:21:57 +0000141 } else {
142 /*
143 * Block used, but not marked in use in the bitmap.
144 */
Theodore Ts'o1b6bf171997-10-03 17:48:10 +0000145 problem = PR_5_BLOCK_USED;
Theodore Ts'o3839e651997-04-26 13:21:57 +0000146 }
Theodore Ts'o1b6bf171997-10-03 17:48:10 +0000147 pctx.blk = i;
148 fix_problem(ctx, problem, &pctx);
149
Theodore Ts'o3839e651997-04-26 13:21:57 +0000150 do_counts:
151 if (!bitmap) {
152 group_free++;
153 free_blocks++;
154 }
155 blocks ++;
156 if ((blocks == fs->super->s_blocks_per_group) ||
157 (i == fs->super->s_blocks_count-1)) {
158 free_array[group] = group_free;
159 group ++;
160 blocks = 0;
161 group_free = 0;
162 }
163 }
Theodore Ts'o1b6bf171997-10-03 17:48:10 +0000164 fixit = end_problem_latch(ctx, PR_LATCH_BBITMAP);
165 if (fixit == 1) {
166 ext2fs_free_block_bitmap(fs->block_map);
167 retval = ext2fs_copy_bitmap(ctx->block_found_map,
168 &fs->block_map);
169 /* XXX check retval --- should never fail! */
170 ext2fs_set_bitmap_padding(fs->block_map);
171 ext2fs_mark_bb_dirty(fs);
172
173 /* Redo the counts */
174 blocks = 0; free_blocks = 0; group_free = 0; group = 0;
175 memset(free_array, 0, fs->group_desc_count * sizeof(int));
176 goto redo_counts;
177 } else if (fixit == 0)
178 ext2fs_unmark_valid(fs);
179
Theodore Ts'o3839e651997-04-26 13:21:57 +0000180 for (i = 0; i < fs->group_desc_count; i++) {
181 if (free_array[i] != fs->group_desc[i].bg_free_blocks_count) {
Theodore Ts'o1b6bf171997-10-03 17:48:10 +0000182 pctx.group = i;
183 pctx.blk = fs->group_desc[i].bg_free_blocks_count;
184 pctx.blk2 = free_array[i];
185
186 if (fix_problem(ctx, PR_5_FREE_BLOCK_COUNT_GROUP,
187 &pctx)) {
Theodore Ts'o3839e651997-04-26 13:21:57 +0000188 fs->group_desc[i].bg_free_blocks_count =
189 free_array[i];
190 ext2fs_mark_super_dirty(fs);
191 } else
192 ext2fs_unmark_valid(fs);
193 }
194 }
195 if (free_blocks != fs->super->s_free_blocks_count) {
Theodore Ts'o1b6bf171997-10-03 17:48:10 +0000196 pctx.group = 0;
197 pctx.blk = fs->super->s_free_blocks_count;
198 pctx.blk2 = free_blocks;
199
200 if (fix_problem(ctx, PR_5_FREE_BLOCK_COUNT, &pctx)) {
Theodore Ts'o3839e651997-04-26 13:21:57 +0000201 fs->super->s_free_blocks_count = free_blocks;
202 ext2fs_mark_super_dirty(fs);
203 } else
204 ext2fs_unmark_valid(fs);
205 }
Theodore Ts'o08b21301997-11-03 19:42:40 +0000206 ext2fs_free_mem((void **) &free_array);
Theodore Ts'o3839e651997-04-26 13:21:57 +0000207}
208
Theodore Ts'o1b6bf171997-10-03 17:48:10 +0000209static void check_inode_bitmaps(e2fsck_t ctx)
Theodore Ts'o3839e651997-04-26 13:21:57 +0000210{
Theodore Ts'o1b6bf171997-10-03 17:48:10 +0000211 ext2_filsys fs = ctx->fs;
Theodore Ts'of3db3561997-04-26 13:34:30 +0000212 ino_t i;
Theodore Ts'o3839e651997-04-26 13:21:57 +0000213 int free_inodes = 0;
214 int group_free = 0;
215 int dirs_count = 0;
216 int group = 0;
217 int inodes = 0;
218 int *free_array;
219 int *dir_array;
220 int actual, bitmap;
Theodore Ts'o1b6bf171997-10-03 17:48:10 +0000221 errcode_t retval;
222 struct problem_context pctx;
223 int problem, fixit;
Theodore Ts'o3839e651997-04-26 13:21:57 +0000224
Theodore Ts'o1b6bf171997-10-03 17:48:10 +0000225 clear_problem_context(&pctx);
Theodore Ts'o54dc7ca1998-01-19 14:50:49 +0000226 free_array = (int *) e2fsck_allocate_memory(ctx,
Theodore Ts'of8188ff1997-11-14 05:23:04 +0000227 fs->group_desc_count * sizeof(int), "free inode count array");
Theodore Ts'o3839e651997-04-26 13:21:57 +0000228
Theodore Ts'o54dc7ca1998-01-19 14:50:49 +0000229 dir_array = (int *) e2fsck_allocate_memory(ctx,
Theodore Ts'of8188ff1997-11-14 05:23:04 +0000230 fs->group_desc_count * sizeof(int), "directory count array");
Theodore Ts'o3839e651997-04-26 13:21:57 +0000231
Theodore Ts'o1b6bf171997-10-03 17:48:10 +0000232 if ((1 < ext2fs_get_inode_bitmap_start(ctx->inode_used_map)) ||
Theodore Ts'o50e1e101997-04-26 13:58:21 +0000233 (fs->super->s_inodes_count >
Theodore Ts'o1b6bf171997-10-03 17:48:10 +0000234 ext2fs_get_inode_bitmap_end(ctx->inode_used_map))) {
235 pctx.num = 3;
236 pctx.blk = 1;
237 pctx.blk2 = fs->super->s_inodes_count;
238 pctx.ino = ext2fs_get_inode_bitmap_start(ctx->inode_used_map);
239 pctx.ino2 = ext2fs_get_inode_bitmap_end(ctx->inode_used_map);
240 fix_problem(ctx, PR_5_BMAP_ENDPOINTS, &pctx);
Theodore Ts'o08b21301997-11-03 19:42:40 +0000241
242 ctx->flags |= E2F_FLAG_ABORT; /* fatal */
243 return;
Theodore Ts'o50e1e101997-04-26 13:58:21 +0000244 }
245 if ((1 < ext2fs_get_inode_bitmap_start(fs->inode_map)) ||
246 (fs->super->s_inodes_count >
247 ext2fs_get_inode_bitmap_end(fs->inode_map))) {
Theodore Ts'o1b6bf171997-10-03 17:48:10 +0000248 pctx.num = 4;
249 pctx.blk = 1;
250 pctx.blk2 = fs->super->s_inodes_count;
251 pctx.ino = ext2fs_get_inode_bitmap_start(fs->inode_map);
252 pctx.ino2 = ext2fs_get_inode_bitmap_end(fs->inode_map);
253 fix_problem(ctx, PR_5_BMAP_ENDPOINTS, &pctx);
Theodore Ts'o08b21301997-11-03 19:42:40 +0000254
255 ctx->flags |= E2F_FLAG_ABORT; /* fatal */
256 return;
Theodore Ts'o50e1e101997-04-26 13:58:21 +0000257 }
258
Theodore Ts'o1b6bf171997-10-03 17:48:10 +0000259redo_counts:
Theodore Ts'o3839e651997-04-26 13:21:57 +0000260 for (i = 1; i <= fs->super->s_inodes_count; i++) {
Theodore Ts'o1b6bf171997-10-03 17:48:10 +0000261 actual = ext2fs_fast_test_inode_bitmap(ctx->inode_used_map, i);
Theodore Ts'o50e1e101997-04-26 13:58:21 +0000262 bitmap = ext2fs_fast_test_inode_bitmap(fs->inode_map, i);
Theodore Ts'o3839e651997-04-26 13:21:57 +0000263
264 if (actual == bitmap)
265 goto do_counts;
266
Theodore Ts'o3839e651997-04-26 13:21:57 +0000267 if (!actual && bitmap) {
268 /*
269 * Inode wasn't used, but marked in bitmap
270 */
Theodore Ts'o1b6bf171997-10-03 17:48:10 +0000271 problem = PR_5_UNUSED_INODE;
272 } else /* if (actual && !bitmap) */ {
Theodore Ts'o3839e651997-04-26 13:21:57 +0000273 /*
274 * Inode used, but not in bitmap
275 */
Theodore Ts'o1b6bf171997-10-03 17:48:10 +0000276 problem = PR_5_INODE_USED;
Theodore Ts'o3839e651997-04-26 13:21:57 +0000277 }
Theodore Ts'o1b6bf171997-10-03 17:48:10 +0000278 pctx.ino = i;
279 fix_problem(ctx, problem, &pctx);
280
Theodore Ts'o3839e651997-04-26 13:21:57 +0000281do_counts:
282 if (!bitmap) {
283 group_free++;
284 free_inodes++;
285 } else {
Theodore Ts'o1b6bf171997-10-03 17:48:10 +0000286 if (ext2fs_test_inode_bitmap(ctx->inode_dir_map, i))
Theodore Ts'o3839e651997-04-26 13:21:57 +0000287 dirs_count++;
288 }
289 inodes++;
290 if ((inodes == fs->super->s_inodes_per_group) ||
291 (i == fs->super->s_inodes_count)) {
292 free_array[group] = group_free;
293 dir_array[group] = dirs_count;
294 group ++;
295 inodes = 0;
296 group_free = 0;
297 dirs_count = 0;
298 }
299 }
Theodore Ts'o1b6bf171997-10-03 17:48:10 +0000300 fixit = end_problem_latch(ctx, PR_LATCH_IBITMAP);
301 if (fixit == 1) {
302 ext2fs_free_inode_bitmap(fs->inode_map);
303 retval = ext2fs_copy_bitmap(ctx->inode_used_map,
304 &fs->inode_map);
305 /* XXX check retval --- should never fail! */
306 ext2fs_set_bitmap_padding(fs->inode_map);
307 ext2fs_mark_ib_dirty(fs);
308
309 /* redo counts */
310 inodes = 0; free_inodes = 0; group_free = 0;
311 dirs_count = 0; group = 0;
312 memset(free_array, 0, fs->group_desc_count * sizeof(int));
313 memset(dir_array, 0, fs->group_desc_count * sizeof(int));
314 goto redo_counts;
315 } else if (fixit == 0)
316 ext2fs_unmark_valid(fs);
Theodore Ts'o3839e651997-04-26 13:21:57 +0000317
318 for (i = 0; i < fs->group_desc_count; i++) {
319 if (free_array[i] != fs->group_desc[i].bg_free_inodes_count) {
Theodore Ts'o1b6bf171997-10-03 17:48:10 +0000320 pctx.group = i;
321 pctx.ino = fs->group_desc[i].bg_free_inodes_count;
322 pctx.ino2 = free_array[i];
323 if (fix_problem(ctx, PR_5_FREE_INODE_COUNT_GROUP,
324 &pctx)) {
Theodore Ts'o3839e651997-04-26 13:21:57 +0000325 fs->group_desc[i].bg_free_inodes_count =
326 free_array[i];
327 ext2fs_mark_super_dirty(fs);
328 } else
329 ext2fs_unmark_valid(fs);
330 }
331 if (dir_array[i] != fs->group_desc[i].bg_used_dirs_count) {
Theodore Ts'o1b6bf171997-10-03 17:48:10 +0000332 pctx.group = i;
333 pctx.ino = fs->group_desc[i].bg_used_dirs_count;
334 pctx.ino2 = dir_array[i];
335
336 if (fix_problem(ctx, PR_5_FREE_DIR_COUNT_GROUP,
337 &pctx)) {
Theodore Ts'o3839e651997-04-26 13:21:57 +0000338 fs->group_desc[i].bg_used_dirs_count =
339 dir_array[i];
340 ext2fs_mark_super_dirty(fs);
341 } else
342 ext2fs_unmark_valid(fs);
343 }
344 }
345 if (free_inodes != fs->super->s_free_inodes_count) {
Theodore Ts'o1b6bf171997-10-03 17:48:10 +0000346 pctx.group = -1;
347 pctx.ino = fs->super->s_free_inodes_count;
348 pctx.ino2 = free_inodes;
349
350 if (fix_problem(ctx, PR_5_FREE_INODE_COUNT, &pctx)) {
Theodore Ts'o3839e651997-04-26 13:21:57 +0000351 fs->super->s_free_inodes_count = free_inodes;
352 ext2fs_mark_super_dirty(fs);
353 } else
354 ext2fs_unmark_valid(fs);
355 }
Theodore Ts'o08b21301997-11-03 19:42:40 +0000356 ext2fs_free_mem((void **) &free_array);
357 ext2fs_free_mem((void **) &dir_array);
Theodore Ts'o3839e651997-04-26 13:21:57 +0000358}
359
Theodore Ts'o1b6bf171997-10-03 17:48:10 +0000360static void check_inode_end(e2fsck_t ctx)
Theodore Ts'o3839e651997-04-26 13:21:57 +0000361{
Theodore Ts'o1b6bf171997-10-03 17:48:10 +0000362 ext2_filsys fs = ctx->fs;
Theodore Ts'of3db3561997-04-26 13:34:30 +0000363 ino_t end, save_inodes_count, i;
Theodore Ts'o1b6bf171997-10-03 17:48:10 +0000364 struct problem_context pctx;
365
366 clear_problem_context(&pctx);
Theodore Ts'o3839e651997-04-26 13:21:57 +0000367
368 end = EXT2_INODES_PER_GROUP(fs->super) * fs->group_desc_count;
Theodore Ts'o1b6bf171997-10-03 17:48:10 +0000369 pctx.errcode = ext2fs_fudge_inode_bitmap_end(fs->inode_map, end,
370 &save_inodes_count);
371 if (pctx.errcode) {
372 pctx.num = 1;
373 fix_problem(ctx, PR_5_FUDGE_BITMAP_ERROR, &pctx);
Theodore Ts'o08b21301997-11-03 19:42:40 +0000374 ctx->flags |= E2F_FLAG_ABORT; /* fatal */
375 return;
Theodore Ts'of3db3561997-04-26 13:34:30 +0000376 }
Theodore Ts'o3839e651997-04-26 13:21:57 +0000377 if (save_inodes_count == end)
378 return;
379
Theodore Ts'o3839e651997-04-26 13:21:57 +0000380 for (i = save_inodes_count + 1; i <= end; i++) {
Theodore Ts'of3db3561997-04-26 13:34:30 +0000381 if (!ext2fs_test_inode_bitmap(fs->inode_map, i)) {
Theodore Ts'o1b6bf171997-10-03 17:48:10 +0000382 if (fix_problem(ctx, PR_5_INODE_BMAP_PADDING, &pctx)) {
Theodore Ts'o3839e651997-04-26 13:21:57 +0000383 for (i = save_inodes_count + 1; i <= end; i++)
Theodore Ts'of3db3561997-04-26 13:34:30 +0000384 ext2fs_mark_inode_bitmap(fs->inode_map,
Theodore Ts'o3839e651997-04-26 13:21:57 +0000385 i);
386 ext2fs_mark_ib_dirty(fs);
387 } else
388 ext2fs_unmark_valid(fs);
389 break;
390 }
391 }
392
Theodore Ts'o1b6bf171997-10-03 17:48:10 +0000393 pctx.errcode = ext2fs_fudge_inode_bitmap_end(fs->inode_map,
394 save_inodes_count, 0);
395 if (pctx.errcode) {
396 pctx.num = 2;
397 fix_problem(ctx, PR_5_FUDGE_BITMAP_ERROR, &pctx);
Theodore Ts'o08b21301997-11-03 19:42:40 +0000398 ctx->flags |= E2F_FLAG_ABORT; /* fatal */
399 return;
Theodore Ts'of3db3561997-04-26 13:34:30 +0000400 }
Theodore Ts'o3839e651997-04-26 13:21:57 +0000401}
402
Theodore Ts'o1b6bf171997-10-03 17:48:10 +0000403static void check_block_end(e2fsck_t ctx)
Theodore Ts'o3839e651997-04-26 13:21:57 +0000404{
Theodore Ts'o1b6bf171997-10-03 17:48:10 +0000405 ext2_filsys fs = ctx->fs;
Theodore Ts'of3db3561997-04-26 13:34:30 +0000406 blk_t end, save_blocks_count, i;
Theodore Ts'o1b6bf171997-10-03 17:48:10 +0000407 struct problem_context pctx;
408
409 clear_problem_context(&pctx);
Theodore Ts'o3839e651997-04-26 13:21:57 +0000410
Theodore Ts'of3db3561997-04-26 13:34:30 +0000411 end = fs->block_map->start +
412 (EXT2_BLOCKS_PER_GROUP(fs->super) * fs->group_desc_count) - 1;
Theodore Ts'o1b6bf171997-10-03 17:48:10 +0000413 pctx.errcode = ext2fs_fudge_block_bitmap_end(fs->block_map, end,
414 &save_blocks_count);
415 if (pctx.errcode) {
416 pctx.num = 3;
417 fix_problem(ctx, PR_5_FUDGE_BITMAP_ERROR, &pctx);
Theodore Ts'o08b21301997-11-03 19:42:40 +0000418 ctx->flags |= E2F_FLAG_ABORT; /* fatal */
419 return;
Theodore Ts'of3db3561997-04-26 13:34:30 +0000420 }
Theodore Ts'o3839e651997-04-26 13:21:57 +0000421 if (save_blocks_count == end)
422 return;
423
Theodore Ts'of3db3561997-04-26 13:34:30 +0000424 for (i = save_blocks_count + 1; i <= end; i++) {
425 if (!ext2fs_test_block_bitmap(fs->block_map, i)) {
Theodore Ts'o1b6bf171997-10-03 17:48:10 +0000426 if (fix_problem(ctx, PR_5_BLOCK_BMAP_PADDING, &pctx)) {
Theodore Ts'o3839e651997-04-26 13:21:57 +0000427 for (i = save_blocks_count + 1; i < end; i++)
Theodore Ts'of3db3561997-04-26 13:34:30 +0000428 ext2fs_mark_block_bitmap(fs->block_map,
Theodore Ts'o3839e651997-04-26 13:21:57 +0000429 i);
430 ext2fs_mark_bb_dirty(fs);
431 } else
432 ext2fs_unmark_valid(fs);
433 break;
434 }
435 }
436
Theodore Ts'o1b6bf171997-10-03 17:48:10 +0000437 pctx.errcode = ext2fs_fudge_block_bitmap_end(fs->block_map,
438 save_blocks_count, 0);
439 if (pctx.errcode) {
440 pctx.num = 4;
441 fix_problem(ctx, PR_5_FUDGE_BITMAP_ERROR, &pctx);
Theodore Ts'o08b21301997-11-03 19:42:40 +0000442 ctx->flags |= E2F_FLAG_ABORT; /* fatal */
443 return;
Theodore Ts'of3db3561997-04-26 13:34:30 +0000444 }
Theodore Ts'o3839e651997-04-26 13:21:57 +0000445}
446
Theodore Ts'o1b6bf171997-10-03 17:48:10 +0000447
448