blob: b39b3134355430201f1e3555de9d943f782c8373 [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'o5596def1999-07-19 15:27:37 +000068 if (ctx->options & E2F_OPT_TIME2) {
69 e2fsck_clear_progbar(ctx);
Theodore Ts'o1b6bf171997-10-03 17:48:10 +000070 print_resource_track("Pass 5", &rtrack);
Theodore Ts'o5596def1999-07-19 15:27:37 +000071 }
Theodore Ts'o8bf191e1997-10-20 01:38:32 +000072#endif
Theodore Ts'o3839e651997-04-26 13:21:57 +000073}
74
Theodore Ts'o1b6bf171997-10-03 17:48:10 +000075static void check_block_bitmaps(e2fsck_t ctx)
Theodore Ts'o3839e651997-04-26 13:21:57 +000076{
Theodore Ts'o1b6bf171997-10-03 17:48:10 +000077 ext2_filsys fs = ctx->fs;
Theodore Ts'of3db3561997-04-26 13:34:30 +000078 blk_t i;
Theodore Ts'o3839e651997-04-26 13:21:57 +000079 int *free_array;
80 int group = 0;
81 int blocks = 0;
82 int free_blocks = 0;
83 int group_free = 0;
84 int actual, bitmap;
Theodore Ts'o1b6bf171997-10-03 17:48:10 +000085 struct problem_context pctx;
Theodore Ts'o63c49691998-02-20 05:24:59 +000086 int problem, fixit, had_problem;
Theodore Ts'o1b6bf171997-10-03 17:48:10 +000087 errcode_t retval;
Theodore Ts'o3839e651997-04-26 13:21:57 +000088
Theodore Ts'o1b6bf171997-10-03 17:48:10 +000089 clear_problem_context(&pctx);
Theodore Ts'o54dc7ca1998-01-19 14:50:49 +000090 free_array = (int *) e2fsck_allocate_memory(ctx,
Theodore Ts'of8188ff1997-11-14 05:23:04 +000091 fs->group_desc_count * sizeof(int), "free block count array");
Theodore Ts'o50e1e101997-04-26 13:58:21 +000092
93 if ((fs->super->s_first_data_block <
Theodore Ts'o1b6bf171997-10-03 17:48:10 +000094 ext2fs_get_block_bitmap_start(ctx->block_found_map)) ||
Theodore Ts'o50e1e101997-04-26 13:58:21 +000095 (fs->super->s_blocks_count-1 >
Theodore Ts'o1b6bf171997-10-03 17:48:10 +000096 ext2fs_get_block_bitmap_end(ctx->block_found_map))) {
97 pctx.num = 1;
98 pctx.blk = fs->super->s_first_data_block;
99 pctx.blk2 = fs->super->s_blocks_count -1;
100 pctx.ino = ext2fs_get_block_bitmap_start(ctx->block_found_map);
101 pctx.ino2 = ext2fs_get_block_bitmap_end(ctx->block_found_map);
102 fix_problem(ctx, PR_5_BMAP_ENDPOINTS, &pctx);
Theodore Ts'o08b21301997-11-03 19:42:40 +0000103
104 ctx->flags |= E2F_FLAG_ABORT; /* fatal */
105 return;
Theodore Ts'o50e1e101997-04-26 13:58:21 +0000106 }
107
108 if ((fs->super->s_first_data_block <
109 ext2fs_get_block_bitmap_start(fs->block_map)) ||
110 (fs->super->s_blocks_count-1 >
111 ext2fs_get_block_bitmap_end(fs->block_map))) {
Theodore Ts'o1b6bf171997-10-03 17:48:10 +0000112 pctx.num = 2;
113 pctx.blk = fs->super->s_first_data_block;
114 pctx.blk2 = fs->super->s_blocks_count -1;
115 pctx.ino = ext2fs_get_block_bitmap_start(fs->block_map);
116 pctx.ino2 = ext2fs_get_block_bitmap_end(fs->block_map);
117 fix_problem(ctx, PR_5_BMAP_ENDPOINTS, &pctx);
Theodore Ts'o08b21301997-11-03 19:42:40 +0000118
119 ctx->flags |= E2F_FLAG_ABORT; /* fatal */
120 return;
Theodore Ts'o50e1e101997-04-26 13:58:21 +0000121 }
122
Theodore Ts'o63c49691998-02-20 05:24:59 +0000123redo_counts:
124 had_problem = 0;
Theodore Ts'o3839e651997-04-26 13:21:57 +0000125 for (i = fs->super->s_first_data_block;
126 i < fs->super->s_blocks_count;
127 i++) {
Theodore Ts'o1b6bf171997-10-03 17:48:10 +0000128 actual = ext2fs_fast_test_block_bitmap(ctx->block_found_map, i);
Theodore Ts'o50e1e101997-04-26 13:58:21 +0000129 bitmap = ext2fs_fast_test_block_bitmap(fs->block_map, i);
Theodore Ts'o3839e651997-04-26 13:21:57 +0000130
131 if (actual == bitmap)
132 goto do_counts;
Theodore Ts'o1b6bf171997-10-03 17:48:10 +0000133
Theodore Ts'o3839e651997-04-26 13:21:57 +0000134 if (!actual && bitmap) {
135 /*
136 * Block not used, but marked in use in the bitmap.
137 */
Theodore Ts'o1b6bf171997-10-03 17:48:10 +0000138 problem = PR_5_UNUSED_BLOCK;
Theodore Ts'o3839e651997-04-26 13:21:57 +0000139 } else {
140 /*
141 * Block used, but not marked in use in the bitmap.
142 */
Theodore Ts'o1b6bf171997-10-03 17:48:10 +0000143 problem = PR_5_BLOCK_USED;
Theodore Ts'o3839e651997-04-26 13:21:57 +0000144 }
Theodore Ts'o1b6bf171997-10-03 17:48:10 +0000145 pctx.blk = i;
146 fix_problem(ctx, problem, &pctx);
Theodore Ts'o5596def1999-07-19 15:27:37 +0000147 ctx->flags |= E2F_FLAG_PROG_SUPPRESS;
Theodore Ts'o63c49691998-02-20 05:24:59 +0000148 had_problem++;
Theodore Ts'o1b6bf171997-10-03 17:48:10 +0000149
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;
Theodore Ts'oefac9a11998-05-07 05:02:00 +0000162 if (ctx->progress)
163 if ((ctx->progress)(ctx, 5, group,
164 fs->group_desc_count*2))
165 return;
Theodore Ts'o3839e651997-04-26 13:21:57 +0000166 }
167 }
Theodore Ts'o63c49691998-02-20 05:24:59 +0000168 if (had_problem)
169 fixit = end_problem_latch(ctx, PR_LATCH_BBITMAP);
170 else
171 fixit = -1;
Theodore Ts'o5596def1999-07-19 15:27:37 +0000172 ctx->flags &= ~E2F_FLAG_PROG_SUPPRESS;
173
Theodore Ts'o1b6bf171997-10-03 17:48:10 +0000174 if (fixit == 1) {
175 ext2fs_free_block_bitmap(fs->block_map);
176 retval = ext2fs_copy_bitmap(ctx->block_found_map,
177 &fs->block_map);
178 /* XXX check retval --- should never fail! */
179 ext2fs_set_bitmap_padding(fs->block_map);
180 ext2fs_mark_bb_dirty(fs);
181
182 /* Redo the counts */
183 blocks = 0; free_blocks = 0; group_free = 0; group = 0;
184 memset(free_array, 0, fs->group_desc_count * sizeof(int));
185 goto redo_counts;
186 } else if (fixit == 0)
187 ext2fs_unmark_valid(fs);
188
Theodore Ts'o3839e651997-04-26 13:21:57 +0000189 for (i = 0; i < fs->group_desc_count; i++) {
190 if (free_array[i] != fs->group_desc[i].bg_free_blocks_count) {
Theodore Ts'o1b6bf171997-10-03 17:48:10 +0000191 pctx.group = i;
192 pctx.blk = fs->group_desc[i].bg_free_blocks_count;
193 pctx.blk2 = free_array[i];
194
195 if (fix_problem(ctx, PR_5_FREE_BLOCK_COUNT_GROUP,
196 &pctx)) {
Theodore Ts'o3839e651997-04-26 13:21:57 +0000197 fs->group_desc[i].bg_free_blocks_count =
198 free_array[i];
199 ext2fs_mark_super_dirty(fs);
200 } else
201 ext2fs_unmark_valid(fs);
202 }
203 }
204 if (free_blocks != fs->super->s_free_blocks_count) {
Theodore Ts'o1b6bf171997-10-03 17:48:10 +0000205 pctx.group = 0;
206 pctx.blk = fs->super->s_free_blocks_count;
207 pctx.blk2 = free_blocks;
208
209 if (fix_problem(ctx, PR_5_FREE_BLOCK_COUNT, &pctx)) {
Theodore Ts'o3839e651997-04-26 13:21:57 +0000210 fs->super->s_free_blocks_count = free_blocks;
211 ext2fs_mark_super_dirty(fs);
212 } else
213 ext2fs_unmark_valid(fs);
214 }
Theodore Ts'o08b21301997-11-03 19:42:40 +0000215 ext2fs_free_mem((void **) &free_array);
Theodore Ts'o3839e651997-04-26 13:21:57 +0000216}
217
Theodore Ts'o1b6bf171997-10-03 17:48:10 +0000218static void check_inode_bitmaps(e2fsck_t ctx)
Theodore Ts'o3839e651997-04-26 13:21:57 +0000219{
Theodore Ts'o1b6bf171997-10-03 17:48:10 +0000220 ext2_filsys fs = ctx->fs;
Theodore Ts'of3db3561997-04-26 13:34:30 +0000221 ino_t i;
Theodore Ts'o3839e651997-04-26 13:21:57 +0000222 int free_inodes = 0;
223 int group_free = 0;
224 int dirs_count = 0;
225 int group = 0;
226 int inodes = 0;
227 int *free_array;
228 int *dir_array;
229 int actual, bitmap;
Theodore Ts'o1b6bf171997-10-03 17:48:10 +0000230 errcode_t retval;
231 struct problem_context pctx;
Theodore Ts'o63c49691998-02-20 05:24:59 +0000232 int problem, fixit, had_problem;
Theodore Ts'o3839e651997-04-26 13:21:57 +0000233
Theodore Ts'o1b6bf171997-10-03 17:48:10 +0000234 clear_problem_context(&pctx);
Theodore Ts'o54dc7ca1998-01-19 14:50:49 +0000235 free_array = (int *) e2fsck_allocate_memory(ctx,
Theodore Ts'of8188ff1997-11-14 05:23:04 +0000236 fs->group_desc_count * sizeof(int), "free inode count array");
Theodore Ts'o3839e651997-04-26 13:21:57 +0000237
Theodore Ts'o54dc7ca1998-01-19 14:50:49 +0000238 dir_array = (int *) e2fsck_allocate_memory(ctx,
Theodore Ts'of8188ff1997-11-14 05:23:04 +0000239 fs->group_desc_count * sizeof(int), "directory count array");
Theodore Ts'o3839e651997-04-26 13:21:57 +0000240
Theodore Ts'o1b6bf171997-10-03 17:48:10 +0000241 if ((1 < ext2fs_get_inode_bitmap_start(ctx->inode_used_map)) ||
Theodore Ts'o50e1e101997-04-26 13:58:21 +0000242 (fs->super->s_inodes_count >
Theodore Ts'o1b6bf171997-10-03 17:48:10 +0000243 ext2fs_get_inode_bitmap_end(ctx->inode_used_map))) {
244 pctx.num = 3;
245 pctx.blk = 1;
246 pctx.blk2 = fs->super->s_inodes_count;
247 pctx.ino = ext2fs_get_inode_bitmap_start(ctx->inode_used_map);
248 pctx.ino2 = ext2fs_get_inode_bitmap_end(ctx->inode_used_map);
249 fix_problem(ctx, PR_5_BMAP_ENDPOINTS, &pctx);
Theodore Ts'o08b21301997-11-03 19:42:40 +0000250
251 ctx->flags |= E2F_FLAG_ABORT; /* fatal */
252 return;
Theodore Ts'o50e1e101997-04-26 13:58:21 +0000253 }
254 if ((1 < ext2fs_get_inode_bitmap_start(fs->inode_map)) ||
255 (fs->super->s_inodes_count >
256 ext2fs_get_inode_bitmap_end(fs->inode_map))) {
Theodore Ts'o1b6bf171997-10-03 17:48:10 +0000257 pctx.num = 4;
258 pctx.blk = 1;
259 pctx.blk2 = fs->super->s_inodes_count;
260 pctx.ino = ext2fs_get_inode_bitmap_start(fs->inode_map);
261 pctx.ino2 = ext2fs_get_inode_bitmap_end(fs->inode_map);
262 fix_problem(ctx, PR_5_BMAP_ENDPOINTS, &pctx);
Theodore Ts'o08b21301997-11-03 19:42:40 +0000263
264 ctx->flags |= E2F_FLAG_ABORT; /* fatal */
265 return;
Theodore Ts'o50e1e101997-04-26 13:58:21 +0000266 }
267
Theodore Ts'o1b6bf171997-10-03 17:48:10 +0000268redo_counts:
Theodore Ts'o63c49691998-02-20 05:24:59 +0000269 had_problem = 0;
Theodore Ts'o3839e651997-04-26 13:21:57 +0000270 for (i = 1; i <= fs->super->s_inodes_count; i++) {
Theodore Ts'o1b6bf171997-10-03 17:48:10 +0000271 actual = ext2fs_fast_test_inode_bitmap(ctx->inode_used_map, i);
Theodore Ts'o50e1e101997-04-26 13:58:21 +0000272 bitmap = ext2fs_fast_test_inode_bitmap(fs->inode_map, i);
Theodore Ts'o3839e651997-04-26 13:21:57 +0000273
274 if (actual == bitmap)
275 goto do_counts;
276
Theodore Ts'o3839e651997-04-26 13:21:57 +0000277 if (!actual && bitmap) {
278 /*
279 * Inode wasn't used, but marked in bitmap
280 */
Theodore Ts'o1b6bf171997-10-03 17:48:10 +0000281 problem = PR_5_UNUSED_INODE;
282 } else /* if (actual && !bitmap) */ {
Theodore Ts'o3839e651997-04-26 13:21:57 +0000283 /*
284 * Inode used, but not in bitmap
285 */
Theodore Ts'o1b6bf171997-10-03 17:48:10 +0000286 problem = PR_5_INODE_USED;
Theodore Ts'o3839e651997-04-26 13:21:57 +0000287 }
Theodore Ts'o1b6bf171997-10-03 17:48:10 +0000288 pctx.ino = i;
289 fix_problem(ctx, problem, &pctx);
Theodore Ts'o5596def1999-07-19 15:27:37 +0000290 ctx->flags |= E2F_FLAG_PROG_SUPPRESS;
Theodore Ts'o63c49691998-02-20 05:24:59 +0000291 had_problem++;
Theodore Ts'o1b6bf171997-10-03 17:48:10 +0000292
Theodore Ts'o3839e651997-04-26 13:21:57 +0000293do_counts:
294 if (!bitmap) {
295 group_free++;
296 free_inodes++;
297 } else {
Theodore Ts'o1b6bf171997-10-03 17:48:10 +0000298 if (ext2fs_test_inode_bitmap(ctx->inode_dir_map, i))
Theodore Ts'o3839e651997-04-26 13:21:57 +0000299 dirs_count++;
300 }
301 inodes++;
302 if ((inodes == fs->super->s_inodes_per_group) ||
303 (i == fs->super->s_inodes_count)) {
304 free_array[group] = group_free;
305 dir_array[group] = dirs_count;
306 group ++;
307 inodes = 0;
308 group_free = 0;
309 dirs_count = 0;
Theodore Ts'oefac9a11998-05-07 05:02:00 +0000310 if (ctx->progress)
311 if ((ctx->progress)(ctx, 5,
312 group + fs->group_desc_count,
313 fs->group_desc_count*2))
314 return;
Theodore Ts'o3839e651997-04-26 13:21:57 +0000315 }
316 }
Theodore Ts'o63c49691998-02-20 05:24:59 +0000317 if (had_problem)
318 fixit = end_problem_latch(ctx, PR_LATCH_IBITMAP);
319 else
320 fixit = -1;
Theodore Ts'o5596def1999-07-19 15:27:37 +0000321 ctx->flags &= ~E2F_FLAG_PROG_SUPPRESS;
322
Theodore Ts'o1b6bf171997-10-03 17:48:10 +0000323 if (fixit == 1) {
324 ext2fs_free_inode_bitmap(fs->inode_map);
325 retval = ext2fs_copy_bitmap(ctx->inode_used_map,
326 &fs->inode_map);
327 /* XXX check retval --- should never fail! */
328 ext2fs_set_bitmap_padding(fs->inode_map);
329 ext2fs_mark_ib_dirty(fs);
330
331 /* redo counts */
332 inodes = 0; free_inodes = 0; group_free = 0;
333 dirs_count = 0; group = 0;
334 memset(free_array, 0, fs->group_desc_count * sizeof(int));
335 memset(dir_array, 0, fs->group_desc_count * sizeof(int));
336 goto redo_counts;
337 } else if (fixit == 0)
338 ext2fs_unmark_valid(fs);
Theodore Ts'o3839e651997-04-26 13:21:57 +0000339
340 for (i = 0; i < fs->group_desc_count; i++) {
341 if (free_array[i] != fs->group_desc[i].bg_free_inodes_count) {
Theodore Ts'o1b6bf171997-10-03 17:48:10 +0000342 pctx.group = i;
343 pctx.ino = fs->group_desc[i].bg_free_inodes_count;
344 pctx.ino2 = free_array[i];
345 if (fix_problem(ctx, PR_5_FREE_INODE_COUNT_GROUP,
346 &pctx)) {
Theodore Ts'o3839e651997-04-26 13:21:57 +0000347 fs->group_desc[i].bg_free_inodes_count =
348 free_array[i];
349 ext2fs_mark_super_dirty(fs);
350 } else
351 ext2fs_unmark_valid(fs);
352 }
353 if (dir_array[i] != fs->group_desc[i].bg_used_dirs_count) {
Theodore Ts'o1b6bf171997-10-03 17:48:10 +0000354 pctx.group = i;
355 pctx.ino = fs->group_desc[i].bg_used_dirs_count;
356 pctx.ino2 = dir_array[i];
357
358 if (fix_problem(ctx, PR_5_FREE_DIR_COUNT_GROUP,
359 &pctx)) {
Theodore Ts'o3839e651997-04-26 13:21:57 +0000360 fs->group_desc[i].bg_used_dirs_count =
361 dir_array[i];
362 ext2fs_mark_super_dirty(fs);
363 } else
364 ext2fs_unmark_valid(fs);
365 }
366 }
367 if (free_inodes != fs->super->s_free_inodes_count) {
Theodore Ts'o1b6bf171997-10-03 17:48:10 +0000368 pctx.group = -1;
369 pctx.ino = fs->super->s_free_inodes_count;
370 pctx.ino2 = free_inodes;
371
372 if (fix_problem(ctx, PR_5_FREE_INODE_COUNT, &pctx)) {
Theodore Ts'o3839e651997-04-26 13:21:57 +0000373 fs->super->s_free_inodes_count = free_inodes;
374 ext2fs_mark_super_dirty(fs);
375 } else
376 ext2fs_unmark_valid(fs);
377 }
Theodore Ts'o08b21301997-11-03 19:42:40 +0000378 ext2fs_free_mem((void **) &free_array);
379 ext2fs_free_mem((void **) &dir_array);
Theodore Ts'o3839e651997-04-26 13:21:57 +0000380}
381
Theodore Ts'o1b6bf171997-10-03 17:48:10 +0000382static void check_inode_end(e2fsck_t ctx)
Theodore Ts'o3839e651997-04-26 13:21:57 +0000383{
Theodore Ts'o1b6bf171997-10-03 17:48:10 +0000384 ext2_filsys fs = ctx->fs;
Theodore Ts'of3db3561997-04-26 13:34:30 +0000385 ino_t end, save_inodes_count, i;
Theodore Ts'o1b6bf171997-10-03 17:48:10 +0000386 struct problem_context pctx;
387
388 clear_problem_context(&pctx);
Theodore Ts'o3839e651997-04-26 13:21:57 +0000389
390 end = EXT2_INODES_PER_GROUP(fs->super) * fs->group_desc_count;
Theodore Ts'o1b6bf171997-10-03 17:48:10 +0000391 pctx.errcode = ext2fs_fudge_inode_bitmap_end(fs->inode_map, end,
392 &save_inodes_count);
393 if (pctx.errcode) {
394 pctx.num = 1;
395 fix_problem(ctx, PR_5_FUDGE_BITMAP_ERROR, &pctx);
Theodore Ts'o08b21301997-11-03 19:42:40 +0000396 ctx->flags |= E2F_FLAG_ABORT; /* fatal */
397 return;
Theodore Ts'of3db3561997-04-26 13:34:30 +0000398 }
Theodore Ts'o3839e651997-04-26 13:21:57 +0000399 if (save_inodes_count == end)
400 return;
401
Theodore Ts'o3839e651997-04-26 13:21:57 +0000402 for (i = save_inodes_count + 1; i <= end; i++) {
Theodore Ts'of3db3561997-04-26 13:34:30 +0000403 if (!ext2fs_test_inode_bitmap(fs->inode_map, i)) {
Theodore Ts'o1b6bf171997-10-03 17:48:10 +0000404 if (fix_problem(ctx, PR_5_INODE_BMAP_PADDING, &pctx)) {
Theodore Ts'o3839e651997-04-26 13:21:57 +0000405 for (i = save_inodes_count + 1; i <= end; i++)
Theodore Ts'of3db3561997-04-26 13:34:30 +0000406 ext2fs_mark_inode_bitmap(fs->inode_map,
Theodore Ts'o3839e651997-04-26 13:21:57 +0000407 i);
408 ext2fs_mark_ib_dirty(fs);
409 } else
410 ext2fs_unmark_valid(fs);
411 break;
412 }
413 }
414
Theodore Ts'o1b6bf171997-10-03 17:48:10 +0000415 pctx.errcode = ext2fs_fudge_inode_bitmap_end(fs->inode_map,
416 save_inodes_count, 0);
417 if (pctx.errcode) {
418 pctx.num = 2;
419 fix_problem(ctx, PR_5_FUDGE_BITMAP_ERROR, &pctx);
Theodore Ts'o08b21301997-11-03 19:42:40 +0000420 ctx->flags |= E2F_FLAG_ABORT; /* fatal */
421 return;
Theodore Ts'of3db3561997-04-26 13:34:30 +0000422 }
Theodore Ts'o3839e651997-04-26 13:21:57 +0000423}
424
Theodore Ts'o1b6bf171997-10-03 17:48:10 +0000425static void check_block_end(e2fsck_t ctx)
Theodore Ts'o3839e651997-04-26 13:21:57 +0000426{
Theodore Ts'o1b6bf171997-10-03 17:48:10 +0000427 ext2_filsys fs = ctx->fs;
Theodore Ts'of3db3561997-04-26 13:34:30 +0000428 blk_t end, save_blocks_count, i;
Theodore Ts'o1b6bf171997-10-03 17:48:10 +0000429 struct problem_context pctx;
430
431 clear_problem_context(&pctx);
Theodore Ts'o3839e651997-04-26 13:21:57 +0000432
Theodore Ts'of3db3561997-04-26 13:34:30 +0000433 end = fs->block_map->start +
434 (EXT2_BLOCKS_PER_GROUP(fs->super) * fs->group_desc_count) - 1;
Theodore Ts'o1b6bf171997-10-03 17:48:10 +0000435 pctx.errcode = ext2fs_fudge_block_bitmap_end(fs->block_map, end,
436 &save_blocks_count);
437 if (pctx.errcode) {
438 pctx.num = 3;
439 fix_problem(ctx, PR_5_FUDGE_BITMAP_ERROR, &pctx);
Theodore Ts'o08b21301997-11-03 19:42:40 +0000440 ctx->flags |= E2F_FLAG_ABORT; /* fatal */
441 return;
Theodore Ts'of3db3561997-04-26 13:34:30 +0000442 }
Theodore Ts'o3839e651997-04-26 13:21:57 +0000443 if (save_blocks_count == end)
444 return;
445
Theodore Ts'of3db3561997-04-26 13:34:30 +0000446 for (i = save_blocks_count + 1; i <= end; i++) {
447 if (!ext2fs_test_block_bitmap(fs->block_map, i)) {
Theodore Ts'o1b6bf171997-10-03 17:48:10 +0000448 if (fix_problem(ctx, PR_5_BLOCK_BMAP_PADDING, &pctx)) {
Theodore Ts'oe79d1b21999-06-18 01:06:59 +0000449 for (i = save_blocks_count + 1; i <= end; i++)
Theodore Ts'of3db3561997-04-26 13:34:30 +0000450 ext2fs_mark_block_bitmap(fs->block_map,
Theodore Ts'o3839e651997-04-26 13:21:57 +0000451 i);
452 ext2fs_mark_bb_dirty(fs);
453 } else
454 ext2fs_unmark_valid(fs);
455 break;
456 }
457 }
458
Theodore Ts'o1b6bf171997-10-03 17:48:10 +0000459 pctx.errcode = ext2fs_fudge_block_bitmap_end(fs->block_map,
460 save_blocks_count, 0);
461 if (pctx.errcode) {
462 pctx.num = 4;
463 fix_problem(ctx, PR_5_FUDGE_BITMAP_ERROR, &pctx);
Theodore Ts'o08b21301997-11-03 19:42:40 +0000464 ctx->flags |= E2F_FLAG_ABORT; /* fatal */
465 return;
Theodore Ts'of3db3561997-04-26 13:34:30 +0000466 }
Theodore Ts'o3839e651997-04-26 13:21:57 +0000467}
468
Theodore Ts'o1b6bf171997-10-03 17:48:10 +0000469
470