blob: 274052ece2138bb1970a0647a3a0f80bc72b90cb [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)
Theodore Ts'oefac9a11998-05-07 05:02:00 +000042 if ((ctx->progress)(ctx, 5, 0, ctx->fs->group_desc_count*2))
Theodore Ts'oa02ce9d1998-02-24 20:22:23 +000043 return;
Theodore Ts'of8188ff1997-11-14 05:23:04 +000044
45 e2fsck_read_bitmaps(ctx);
46
Theodore Ts'o1b6bf171997-10-03 17:48:10 +000047 check_block_bitmaps(ctx);
Theodore Ts'oa02ce9d1998-02-24 20:22:23 +000048 if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
Theodore Ts'o08b21301997-11-03 19:42:40 +000049 return;
Theodore Ts'o1b6bf171997-10-03 17:48:10 +000050 check_inode_bitmaps(ctx);
Theodore Ts'oa02ce9d1998-02-24 20:22:23 +000051 if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
Theodore Ts'o08b21301997-11-03 19:42:40 +000052 return;
Theodore Ts'o1b6bf171997-10-03 17:48:10 +000053 check_inode_end(ctx);
Theodore Ts'oa02ce9d1998-02-24 20:22:23 +000054 if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
Theodore Ts'o08b21301997-11-03 19:42:40 +000055 return;
Theodore Ts'o1b6bf171997-10-03 17:48:10 +000056 check_block_end(ctx);
Theodore Ts'oa02ce9d1998-02-24 20:22:23 +000057 if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
Theodore Ts'o08b21301997-11-03 19:42:40 +000058 return;
Theodore Ts'o3839e651997-04-26 13:21:57 +000059
Theodore Ts'o1b6bf171997-10-03 17:48:10 +000060 ext2fs_free_inode_bitmap(ctx->inode_used_map);
61 ctx->inode_used_map = 0;
62 ext2fs_free_inode_bitmap(ctx->inode_dir_map);
63 ctx->inode_dir_map = 0;
64 ext2fs_free_block_bitmap(ctx->block_found_map);
65 ctx->block_found_map = 0;
66
Theodore Ts'o8bf191e1997-10-20 01:38:32 +000067#ifdef RESOURCE_TRACK
Theodore Ts'o1b6bf171997-10-03 17:48:10 +000068 if (ctx->options & E2F_OPT_TIME2)
69 print_resource_track("Pass 5", &rtrack);
Theodore Ts'o8bf191e1997-10-20 01:38:32 +000070#endif
Theodore Ts'o3839e651997-04-26 13:21:57 +000071}
72
Theodore Ts'o1b6bf171997-10-03 17:48:10 +000073static void check_block_bitmaps(e2fsck_t ctx)
Theodore Ts'o3839e651997-04-26 13:21:57 +000074{
Theodore Ts'o1b6bf171997-10-03 17:48:10 +000075 ext2_filsys fs = ctx->fs;
Theodore Ts'of3db3561997-04-26 13:34:30 +000076 blk_t i;
Theodore Ts'o3839e651997-04-26 13:21:57 +000077 int *free_array;
78 int group = 0;
79 int blocks = 0;
80 int free_blocks = 0;
81 int group_free = 0;
82 int actual, bitmap;
Theodore Ts'o1b6bf171997-10-03 17:48:10 +000083 struct problem_context pctx;
Theodore Ts'o63c49691998-02-20 05:24:59 +000084 int problem, fixit, had_problem;
Theodore Ts'o1b6bf171997-10-03 17:48:10 +000085 errcode_t retval;
Theodore Ts'o3839e651997-04-26 13:21:57 +000086
Theodore Ts'o1b6bf171997-10-03 17:48:10 +000087 clear_problem_context(&pctx);
Theodore Ts'o54dc7ca1998-01-19 14:50:49 +000088 free_array = (int *) e2fsck_allocate_memory(ctx,
Theodore Ts'of8188ff1997-11-14 05:23:04 +000089 fs->group_desc_count * sizeof(int), "free block count array");
Theodore Ts'o50e1e101997-04-26 13:58:21 +000090
91 if ((fs->super->s_first_data_block <
Theodore Ts'o1b6bf171997-10-03 17:48:10 +000092 ext2fs_get_block_bitmap_start(ctx->block_found_map)) ||
Theodore Ts'o50e1e101997-04-26 13:58:21 +000093 (fs->super->s_blocks_count-1 >
Theodore Ts'o1b6bf171997-10-03 17:48:10 +000094 ext2fs_get_block_bitmap_end(ctx->block_found_map))) {
95 pctx.num = 1;
96 pctx.blk = fs->super->s_first_data_block;
97 pctx.blk2 = fs->super->s_blocks_count -1;
98 pctx.ino = ext2fs_get_block_bitmap_start(ctx->block_found_map);
99 pctx.ino2 = ext2fs_get_block_bitmap_end(ctx->block_found_map);
100 fix_problem(ctx, PR_5_BMAP_ENDPOINTS, &pctx);
Theodore Ts'o08b21301997-11-03 19:42:40 +0000101
102 ctx->flags |= E2F_FLAG_ABORT; /* fatal */
103 return;
Theodore Ts'o50e1e101997-04-26 13:58:21 +0000104 }
105
106 if ((fs->super->s_first_data_block <
107 ext2fs_get_block_bitmap_start(fs->block_map)) ||
108 (fs->super->s_blocks_count-1 >
109 ext2fs_get_block_bitmap_end(fs->block_map))) {
Theodore Ts'o1b6bf171997-10-03 17:48:10 +0000110 pctx.num = 2;
111 pctx.blk = fs->super->s_first_data_block;
112 pctx.blk2 = fs->super->s_blocks_count -1;
113 pctx.ino = ext2fs_get_block_bitmap_start(fs->block_map);
114 pctx.ino2 = ext2fs_get_block_bitmap_end(fs->block_map);
115 fix_problem(ctx, PR_5_BMAP_ENDPOINTS, &pctx);
Theodore Ts'o08b21301997-11-03 19:42:40 +0000116
117 ctx->flags |= E2F_FLAG_ABORT; /* fatal */
118 return;
Theodore Ts'o50e1e101997-04-26 13:58:21 +0000119 }
120
Theodore Ts'o63c49691998-02-20 05:24:59 +0000121redo_counts:
122 had_problem = 0;
Theodore Ts'o3839e651997-04-26 13:21:57 +0000123 for (i = fs->super->s_first_data_block;
124 i < fs->super->s_blocks_count;
125 i++) {
Theodore Ts'o1b6bf171997-10-03 17:48:10 +0000126 actual = ext2fs_fast_test_block_bitmap(ctx->block_found_map, i);
Theodore Ts'o50e1e101997-04-26 13:58:21 +0000127 bitmap = ext2fs_fast_test_block_bitmap(fs->block_map, i);
Theodore Ts'o3839e651997-04-26 13:21:57 +0000128
129 if (actual == bitmap)
130 goto do_counts;
Theodore Ts'o1b6bf171997-10-03 17:48:10 +0000131
Theodore Ts'o3839e651997-04-26 13:21:57 +0000132 if (!actual && bitmap) {
133 /*
134 * Block not used, but marked in use in the bitmap.
135 */
Theodore Ts'o1b6bf171997-10-03 17:48:10 +0000136 problem = PR_5_UNUSED_BLOCK;
Theodore Ts'o3839e651997-04-26 13:21:57 +0000137 } else {
138 /*
139 * Block used, but not marked in use in the bitmap.
140 */
Theodore Ts'o1b6bf171997-10-03 17:48:10 +0000141 problem = PR_5_BLOCK_USED;
Theodore Ts'o3839e651997-04-26 13:21:57 +0000142 }
Theodore Ts'o1b6bf171997-10-03 17:48:10 +0000143 pctx.blk = i;
144 fix_problem(ctx, problem, &pctx);
Theodore Ts'o63c49691998-02-20 05:24:59 +0000145 had_problem++;
Theodore Ts'o1b6bf171997-10-03 17:48:10 +0000146
Theodore Ts'o3839e651997-04-26 13:21:57 +0000147 do_counts:
148 if (!bitmap) {
149 group_free++;
150 free_blocks++;
151 }
152 blocks ++;
153 if ((blocks == fs->super->s_blocks_per_group) ||
154 (i == fs->super->s_blocks_count-1)) {
155 free_array[group] = group_free;
156 group ++;
157 blocks = 0;
158 group_free = 0;
Theodore Ts'oefac9a11998-05-07 05:02:00 +0000159 if (ctx->progress)
160 if ((ctx->progress)(ctx, 5, group,
161 fs->group_desc_count*2))
162 return;
Theodore Ts'o3839e651997-04-26 13:21:57 +0000163 }
164 }
Theodore Ts'o63c49691998-02-20 05:24:59 +0000165 if (had_problem)
166 fixit = end_problem_latch(ctx, PR_LATCH_BBITMAP);
167 else
168 fixit = -1;
Theodore Ts'o1b6bf171997-10-03 17:48:10 +0000169 if (fixit == 1) {
170 ext2fs_free_block_bitmap(fs->block_map);
171 retval = ext2fs_copy_bitmap(ctx->block_found_map,
172 &fs->block_map);
173 /* XXX check retval --- should never fail! */
174 ext2fs_set_bitmap_padding(fs->block_map);
175 ext2fs_mark_bb_dirty(fs);
176
177 /* Redo the counts */
178 blocks = 0; free_blocks = 0; group_free = 0; group = 0;
179 memset(free_array, 0, fs->group_desc_count * sizeof(int));
180 goto redo_counts;
181 } else if (fixit == 0)
182 ext2fs_unmark_valid(fs);
183
Theodore Ts'o3839e651997-04-26 13:21:57 +0000184 for (i = 0; i < fs->group_desc_count; i++) {
185 if (free_array[i] != fs->group_desc[i].bg_free_blocks_count) {
Theodore Ts'o1b6bf171997-10-03 17:48:10 +0000186 pctx.group = i;
187 pctx.blk = fs->group_desc[i].bg_free_blocks_count;
188 pctx.blk2 = free_array[i];
189
190 if (fix_problem(ctx, PR_5_FREE_BLOCK_COUNT_GROUP,
191 &pctx)) {
Theodore Ts'o3839e651997-04-26 13:21:57 +0000192 fs->group_desc[i].bg_free_blocks_count =
193 free_array[i];
194 ext2fs_mark_super_dirty(fs);
195 } else
196 ext2fs_unmark_valid(fs);
197 }
198 }
199 if (free_blocks != fs->super->s_free_blocks_count) {
Theodore Ts'o1b6bf171997-10-03 17:48:10 +0000200 pctx.group = 0;
201 pctx.blk = fs->super->s_free_blocks_count;
202 pctx.blk2 = free_blocks;
203
204 if (fix_problem(ctx, PR_5_FREE_BLOCK_COUNT, &pctx)) {
Theodore Ts'o3839e651997-04-26 13:21:57 +0000205 fs->super->s_free_blocks_count = free_blocks;
206 ext2fs_mark_super_dirty(fs);
207 } else
208 ext2fs_unmark_valid(fs);
209 }
Theodore Ts'o08b21301997-11-03 19:42:40 +0000210 ext2fs_free_mem((void **) &free_array);
Theodore Ts'o3839e651997-04-26 13:21:57 +0000211}
212
Theodore Ts'o1b6bf171997-10-03 17:48:10 +0000213static void check_inode_bitmaps(e2fsck_t ctx)
Theodore Ts'o3839e651997-04-26 13:21:57 +0000214{
Theodore Ts'o1b6bf171997-10-03 17:48:10 +0000215 ext2_filsys fs = ctx->fs;
Theodore Ts'of3db3561997-04-26 13:34:30 +0000216 ino_t i;
Theodore Ts'o3839e651997-04-26 13:21:57 +0000217 int free_inodes = 0;
218 int group_free = 0;
219 int dirs_count = 0;
220 int group = 0;
221 int inodes = 0;
222 int *free_array;
223 int *dir_array;
224 int actual, bitmap;
Theodore Ts'o1b6bf171997-10-03 17:48:10 +0000225 errcode_t retval;
226 struct problem_context pctx;
Theodore Ts'o63c49691998-02-20 05:24:59 +0000227 int problem, fixit, had_problem;
Theodore Ts'o3839e651997-04-26 13:21:57 +0000228
Theodore Ts'o1b6bf171997-10-03 17:48:10 +0000229 clear_problem_context(&pctx);
Theodore Ts'o54dc7ca1998-01-19 14:50:49 +0000230 free_array = (int *) e2fsck_allocate_memory(ctx,
Theodore Ts'of8188ff1997-11-14 05:23:04 +0000231 fs->group_desc_count * sizeof(int), "free inode count array");
Theodore Ts'o3839e651997-04-26 13:21:57 +0000232
Theodore Ts'o54dc7ca1998-01-19 14:50:49 +0000233 dir_array = (int *) e2fsck_allocate_memory(ctx,
Theodore Ts'of8188ff1997-11-14 05:23:04 +0000234 fs->group_desc_count * sizeof(int), "directory count array");
Theodore Ts'o3839e651997-04-26 13:21:57 +0000235
Theodore Ts'o1b6bf171997-10-03 17:48:10 +0000236 if ((1 < ext2fs_get_inode_bitmap_start(ctx->inode_used_map)) ||
Theodore Ts'o50e1e101997-04-26 13:58:21 +0000237 (fs->super->s_inodes_count >
Theodore Ts'o1b6bf171997-10-03 17:48:10 +0000238 ext2fs_get_inode_bitmap_end(ctx->inode_used_map))) {
239 pctx.num = 3;
240 pctx.blk = 1;
241 pctx.blk2 = fs->super->s_inodes_count;
242 pctx.ino = ext2fs_get_inode_bitmap_start(ctx->inode_used_map);
243 pctx.ino2 = ext2fs_get_inode_bitmap_end(ctx->inode_used_map);
244 fix_problem(ctx, PR_5_BMAP_ENDPOINTS, &pctx);
Theodore Ts'o08b21301997-11-03 19:42:40 +0000245
246 ctx->flags |= E2F_FLAG_ABORT; /* fatal */
247 return;
Theodore Ts'o50e1e101997-04-26 13:58:21 +0000248 }
249 if ((1 < ext2fs_get_inode_bitmap_start(fs->inode_map)) ||
250 (fs->super->s_inodes_count >
251 ext2fs_get_inode_bitmap_end(fs->inode_map))) {
Theodore Ts'o1b6bf171997-10-03 17:48:10 +0000252 pctx.num = 4;
253 pctx.blk = 1;
254 pctx.blk2 = fs->super->s_inodes_count;
255 pctx.ino = ext2fs_get_inode_bitmap_start(fs->inode_map);
256 pctx.ino2 = ext2fs_get_inode_bitmap_end(fs->inode_map);
257 fix_problem(ctx, PR_5_BMAP_ENDPOINTS, &pctx);
Theodore Ts'o08b21301997-11-03 19:42:40 +0000258
259 ctx->flags |= E2F_FLAG_ABORT; /* fatal */
260 return;
Theodore Ts'o50e1e101997-04-26 13:58:21 +0000261 }
262
Theodore Ts'o1b6bf171997-10-03 17:48:10 +0000263redo_counts:
Theodore Ts'o63c49691998-02-20 05:24:59 +0000264 had_problem = 0;
Theodore Ts'o3839e651997-04-26 13:21:57 +0000265 for (i = 1; i <= fs->super->s_inodes_count; i++) {
Theodore Ts'o1b6bf171997-10-03 17:48:10 +0000266 actual = ext2fs_fast_test_inode_bitmap(ctx->inode_used_map, i);
Theodore Ts'o50e1e101997-04-26 13:58:21 +0000267 bitmap = ext2fs_fast_test_inode_bitmap(fs->inode_map, i);
Theodore Ts'o3839e651997-04-26 13:21:57 +0000268
269 if (actual == bitmap)
270 goto do_counts;
271
Theodore Ts'o3839e651997-04-26 13:21:57 +0000272 if (!actual && bitmap) {
273 /*
274 * Inode wasn't used, but marked in bitmap
275 */
Theodore Ts'o1b6bf171997-10-03 17:48:10 +0000276 problem = PR_5_UNUSED_INODE;
277 } else /* if (actual && !bitmap) */ {
Theodore Ts'o3839e651997-04-26 13:21:57 +0000278 /*
279 * Inode used, but not in bitmap
280 */
Theodore Ts'o1b6bf171997-10-03 17:48:10 +0000281 problem = PR_5_INODE_USED;
Theodore Ts'o3839e651997-04-26 13:21:57 +0000282 }
Theodore Ts'o1b6bf171997-10-03 17:48:10 +0000283 pctx.ino = i;
284 fix_problem(ctx, problem, &pctx);
Theodore Ts'o63c49691998-02-20 05:24:59 +0000285 had_problem++;
Theodore Ts'o1b6bf171997-10-03 17:48:10 +0000286
Theodore Ts'o3839e651997-04-26 13:21:57 +0000287do_counts:
288 if (!bitmap) {
289 group_free++;
290 free_inodes++;
291 } else {
Theodore Ts'o1b6bf171997-10-03 17:48:10 +0000292 if (ext2fs_test_inode_bitmap(ctx->inode_dir_map, i))
Theodore Ts'o3839e651997-04-26 13:21:57 +0000293 dirs_count++;
294 }
295 inodes++;
296 if ((inodes == fs->super->s_inodes_per_group) ||
297 (i == fs->super->s_inodes_count)) {
298 free_array[group] = group_free;
299 dir_array[group] = dirs_count;
300 group ++;
301 inodes = 0;
302 group_free = 0;
303 dirs_count = 0;
Theodore Ts'oefac9a11998-05-07 05:02:00 +0000304 if (ctx->progress)
305 if ((ctx->progress)(ctx, 5,
306 group + fs->group_desc_count,
307 fs->group_desc_count*2))
308 return;
Theodore Ts'o3839e651997-04-26 13:21:57 +0000309 }
310 }
Theodore Ts'o63c49691998-02-20 05:24:59 +0000311 if (had_problem)
312 fixit = end_problem_latch(ctx, PR_LATCH_IBITMAP);
313 else
314 fixit = -1;
Theodore Ts'o1b6bf171997-10-03 17:48:10 +0000315 if (fixit == 1) {
316 ext2fs_free_inode_bitmap(fs->inode_map);
317 retval = ext2fs_copy_bitmap(ctx->inode_used_map,
318 &fs->inode_map);
319 /* XXX check retval --- should never fail! */
320 ext2fs_set_bitmap_padding(fs->inode_map);
321 ext2fs_mark_ib_dirty(fs);
322
323 /* redo counts */
324 inodes = 0; free_inodes = 0; group_free = 0;
325 dirs_count = 0; group = 0;
326 memset(free_array, 0, fs->group_desc_count * sizeof(int));
327 memset(dir_array, 0, fs->group_desc_count * sizeof(int));
328 goto redo_counts;
329 } else if (fixit == 0)
330 ext2fs_unmark_valid(fs);
Theodore Ts'o3839e651997-04-26 13:21:57 +0000331
332 for (i = 0; i < fs->group_desc_count; i++) {
333 if (free_array[i] != fs->group_desc[i].bg_free_inodes_count) {
Theodore Ts'o1b6bf171997-10-03 17:48:10 +0000334 pctx.group = i;
335 pctx.ino = fs->group_desc[i].bg_free_inodes_count;
336 pctx.ino2 = free_array[i];
337 if (fix_problem(ctx, PR_5_FREE_INODE_COUNT_GROUP,
338 &pctx)) {
Theodore Ts'o3839e651997-04-26 13:21:57 +0000339 fs->group_desc[i].bg_free_inodes_count =
340 free_array[i];
341 ext2fs_mark_super_dirty(fs);
342 } else
343 ext2fs_unmark_valid(fs);
344 }
345 if (dir_array[i] != fs->group_desc[i].bg_used_dirs_count) {
Theodore Ts'o1b6bf171997-10-03 17:48:10 +0000346 pctx.group = i;
347 pctx.ino = fs->group_desc[i].bg_used_dirs_count;
348 pctx.ino2 = dir_array[i];
349
350 if (fix_problem(ctx, PR_5_FREE_DIR_COUNT_GROUP,
351 &pctx)) {
Theodore Ts'o3839e651997-04-26 13:21:57 +0000352 fs->group_desc[i].bg_used_dirs_count =
353 dir_array[i];
354 ext2fs_mark_super_dirty(fs);
355 } else
356 ext2fs_unmark_valid(fs);
357 }
358 }
359 if (free_inodes != fs->super->s_free_inodes_count) {
Theodore Ts'o1b6bf171997-10-03 17:48:10 +0000360 pctx.group = -1;
361 pctx.ino = fs->super->s_free_inodes_count;
362 pctx.ino2 = free_inodes;
363
364 if (fix_problem(ctx, PR_5_FREE_INODE_COUNT, &pctx)) {
Theodore Ts'o3839e651997-04-26 13:21:57 +0000365 fs->super->s_free_inodes_count = free_inodes;
366 ext2fs_mark_super_dirty(fs);
367 } else
368 ext2fs_unmark_valid(fs);
369 }
Theodore Ts'o08b21301997-11-03 19:42:40 +0000370 ext2fs_free_mem((void **) &free_array);
371 ext2fs_free_mem((void **) &dir_array);
Theodore Ts'o3839e651997-04-26 13:21:57 +0000372}
373
Theodore Ts'o1b6bf171997-10-03 17:48:10 +0000374static void check_inode_end(e2fsck_t ctx)
Theodore Ts'o3839e651997-04-26 13:21:57 +0000375{
Theodore Ts'o1b6bf171997-10-03 17:48:10 +0000376 ext2_filsys fs = ctx->fs;
Theodore Ts'of3db3561997-04-26 13:34:30 +0000377 ino_t end, save_inodes_count, i;
Theodore Ts'o1b6bf171997-10-03 17:48:10 +0000378 struct problem_context pctx;
379
380 clear_problem_context(&pctx);
Theodore Ts'o3839e651997-04-26 13:21:57 +0000381
382 end = EXT2_INODES_PER_GROUP(fs->super) * fs->group_desc_count;
Theodore Ts'o1b6bf171997-10-03 17:48:10 +0000383 pctx.errcode = ext2fs_fudge_inode_bitmap_end(fs->inode_map, end,
384 &save_inodes_count);
385 if (pctx.errcode) {
386 pctx.num = 1;
387 fix_problem(ctx, PR_5_FUDGE_BITMAP_ERROR, &pctx);
Theodore Ts'o08b21301997-11-03 19:42:40 +0000388 ctx->flags |= E2F_FLAG_ABORT; /* fatal */
389 return;
Theodore Ts'of3db3561997-04-26 13:34:30 +0000390 }
Theodore Ts'o3839e651997-04-26 13:21:57 +0000391 if (save_inodes_count == end)
392 return;
393
Theodore Ts'o3839e651997-04-26 13:21:57 +0000394 for (i = save_inodes_count + 1; i <= end; i++) {
Theodore Ts'of3db3561997-04-26 13:34:30 +0000395 if (!ext2fs_test_inode_bitmap(fs->inode_map, i)) {
Theodore Ts'o1b6bf171997-10-03 17:48:10 +0000396 if (fix_problem(ctx, PR_5_INODE_BMAP_PADDING, &pctx)) {
Theodore Ts'o3839e651997-04-26 13:21:57 +0000397 for (i = save_inodes_count + 1; i <= end; i++)
Theodore Ts'of3db3561997-04-26 13:34:30 +0000398 ext2fs_mark_inode_bitmap(fs->inode_map,
Theodore Ts'o3839e651997-04-26 13:21:57 +0000399 i);
400 ext2fs_mark_ib_dirty(fs);
401 } else
402 ext2fs_unmark_valid(fs);
403 break;
404 }
405 }
406
Theodore Ts'o1b6bf171997-10-03 17:48:10 +0000407 pctx.errcode = ext2fs_fudge_inode_bitmap_end(fs->inode_map,
408 save_inodes_count, 0);
409 if (pctx.errcode) {
410 pctx.num = 2;
411 fix_problem(ctx, PR_5_FUDGE_BITMAP_ERROR, &pctx);
Theodore Ts'o08b21301997-11-03 19:42:40 +0000412 ctx->flags |= E2F_FLAG_ABORT; /* fatal */
413 return;
Theodore Ts'of3db3561997-04-26 13:34:30 +0000414 }
Theodore Ts'o3839e651997-04-26 13:21:57 +0000415}
416
Theodore Ts'o1b6bf171997-10-03 17:48:10 +0000417static void check_block_end(e2fsck_t ctx)
Theodore Ts'o3839e651997-04-26 13:21:57 +0000418{
Theodore Ts'o1b6bf171997-10-03 17:48:10 +0000419 ext2_filsys fs = ctx->fs;
Theodore Ts'of3db3561997-04-26 13:34:30 +0000420 blk_t end, save_blocks_count, i;
Theodore Ts'o1b6bf171997-10-03 17:48:10 +0000421 struct problem_context pctx;
422
423 clear_problem_context(&pctx);
Theodore Ts'o3839e651997-04-26 13:21:57 +0000424
Theodore Ts'of3db3561997-04-26 13:34:30 +0000425 end = fs->block_map->start +
426 (EXT2_BLOCKS_PER_GROUP(fs->super) * fs->group_desc_count) - 1;
Theodore Ts'o1b6bf171997-10-03 17:48:10 +0000427 pctx.errcode = ext2fs_fudge_block_bitmap_end(fs->block_map, end,
428 &save_blocks_count);
429 if (pctx.errcode) {
430 pctx.num = 3;
431 fix_problem(ctx, PR_5_FUDGE_BITMAP_ERROR, &pctx);
Theodore Ts'o08b21301997-11-03 19:42:40 +0000432 ctx->flags |= E2F_FLAG_ABORT; /* fatal */
433 return;
Theodore Ts'of3db3561997-04-26 13:34:30 +0000434 }
Theodore Ts'o3839e651997-04-26 13:21:57 +0000435 if (save_blocks_count == end)
436 return;
437
Theodore Ts'of3db3561997-04-26 13:34:30 +0000438 for (i = save_blocks_count + 1; i <= end; i++) {
439 if (!ext2fs_test_block_bitmap(fs->block_map, i)) {
Theodore Ts'o1b6bf171997-10-03 17:48:10 +0000440 if (fix_problem(ctx, PR_5_BLOCK_BMAP_PADDING, &pctx)) {
Theodore Ts'oe79d1b21999-06-18 01:06:59 +0000441 for (i = save_blocks_count + 1; i <= end; i++)
Theodore Ts'of3db3561997-04-26 13:34:30 +0000442 ext2fs_mark_block_bitmap(fs->block_map,
Theodore Ts'o3839e651997-04-26 13:21:57 +0000443 i);
444 ext2fs_mark_bb_dirty(fs);
445 } else
446 ext2fs_unmark_valid(fs);
447 break;
448 }
449 }
450
Theodore Ts'o1b6bf171997-10-03 17:48:10 +0000451 pctx.errcode = ext2fs_fudge_block_bitmap_end(fs->block_map,
452 save_blocks_count, 0);
453 if (pctx.errcode) {
454 pctx.num = 4;
455 fix_problem(ctx, PR_5_FUDGE_BITMAP_ERROR, &pctx);
Theodore Ts'o08b21301997-11-03 19:42:40 +0000456 ctx->flags |= E2F_FLAG_ABORT; /* fatal */
457 return;
Theodore Ts'of3db3561997-04-26 13:34:30 +0000458 }
Theodore Ts'o3839e651997-04-26 13:21:57 +0000459}
460
Theodore Ts'o1b6bf171997-10-03 17:48:10 +0000461
462