aboutsummaryrefslogtreecommitdiff
path: root/e2fsck/pass5.c
diff options
context:
space:
mode:
authorTheodore Ts'o <tytso@mit.edu>1997-10-03 17:48:10 +0000
committerTheodore Ts'o <tytso@mit.edu>1997-10-03 17:48:10 +0000
commit1b6bf1759af884957234b7dce768b785f792abd0 (patch)
tree275137be213c5a3d049080df8febbeac4b857684 /e2fsck/pass5.c
parentd163b0948731e6d84bd3efe75075a2d0a8009272 (diff)
downloade2fsprogs-1b6bf1759af884957234b7dce768b785f792abd0.tar.gz
Many files:
pass*.c, super.c: Massive changes to avoid using printf and com_err routines. All diagnostic messages are now routed through the fix_problem interface. pass2.c (check_dir_block): Check for duplicate '.' and '..' entries. problem.c, problem.h: Add new problem codes PR_2_DUP_DOT and PR_2_DUP_DOT_DOT. problem.c: Added new problem codes for some of the superblock corruption checks, and for the pass header messages. ("Pass 1: xxxxx") util.c (print_resource_track): Now takes a description argument. super.c, unix.c, e2fsck.c: New files to separate out the operating-specific operations out from e2fsck.c. e2fsck.c now contains the global e2fsck context management routines, and super.c contains the "pass 0" initial validation of the superblock and global block group descriptors. pass1.c, pass2.c, pass3.c, pass4.c, pass5.c, util.c: Eliminate (nearly) all global variables and moved them to the e2fsck context structure. problem.c, problem.h: Added new problem codes PR_0_SB_CORRUPT, PR_0_FS_SIZE_WRONG, PR_0_NO_FRAGMENTS, PR_0_BLOCKS_PER_GROUP, PR_0_FIRST_DATA_BLOCK expect.1, expect.2: Updated tests to align with e2fsck problem.c changes.
Diffstat (limited to 'e2fsck/pass5.c')
-rw-r--r--e2fsck/pass5.c354
1 files changed, 179 insertions, 175 deletions
diff --git a/e2fsck/pass5.c b/e2fsck/pass5.c
index def492a9..499c92ce 100644
--- a/e2fsck/pass5.c
+++ b/e2fsck/pass5.c
@@ -10,21 +10,18 @@
*
*/
-#include "et/com_err.h"
-
#include "e2fsck.h"
+#include "problem.h"
-static void check_block_bitmaps(ext2_filsys fs);
-static void check_inode_bitmaps(ext2_filsys fs);
-static void check_inode_end(ext2_filsys fs);
-static void check_block_end(ext2_filsys fs);
-
-static int do_fix = -1;
-static const char *fix_question = "Fix summary information";
+static void check_block_bitmaps(e2fsck_t ctx);
+static void check_inode_bitmaps(e2fsck_t ctx);
+static void check_inode_end(e2fsck_t ctx);
+static void check_block_end(e2fsck_t ctx);
-void pass5(ext2_filsys fs)
+void pass5(e2fsck_t ctx)
{
struct resource_track rtrack;
+ struct problem_context pctx;
#ifdef MTRACE
mtrace_print("Pass 5");
@@ -32,28 +29,32 @@ void pass5(ext2_filsys fs)
init_resource_track(&rtrack);
- if (!preen)
- printf("Pass 5: Checking group summary information\n");
+ clear_problem_context(&pctx);
- read_bitmaps(fs);
+ if (!(ctx->options & E2F_OPT_PREEN))
+ fix_problem(ctx, PR_5_PASS_HEADER, &pctx);
- check_block_bitmaps(fs);
- check_inode_bitmaps(fs);
- check_inode_end(fs);
- check_block_end(fs);
+ read_bitmaps(ctx);
- ext2fs_free_inode_bitmap(inode_used_map);
- ext2fs_free_inode_bitmap(inode_dir_map);
- ext2fs_free_block_bitmap(block_found_map);
+ check_block_bitmaps(ctx);
+ check_inode_bitmaps(ctx);
+ check_inode_end(ctx);
+ check_block_end(ctx);
- if (tflag > 1) {
- printf("Pass 5: ");
- print_resource_track(&rtrack);
- }
+ ext2fs_free_inode_bitmap(ctx->inode_used_map);
+ ctx->inode_used_map = 0;
+ ext2fs_free_inode_bitmap(ctx->inode_dir_map);
+ ctx->inode_dir_map = 0;
+ ext2fs_free_block_bitmap(ctx->block_found_map);
+ ctx->block_found_map = 0;
+
+ if (ctx->options & E2F_OPT_TIME2)
+ print_resource_track("Pass 5", &rtrack);
}
-static void check_block_bitmaps(ext2_filsys fs)
+static void check_block_bitmaps(e2fsck_t ctx)
{
+ ext2_filsys fs = ctx->fs;
blk_t i;
int *free_array;
int group = 0;
@@ -61,21 +62,25 @@ static void check_block_bitmaps(ext2_filsys fs)
int free_blocks = 0;
int group_free = 0;
int actual, bitmap;
- const char *print_header = "Block bitmap differences:";
+ struct problem_context pctx;
+ int problem, fixit;
+ errcode_t retval;
+ clear_problem_context(&pctx);
free_array = allocate_memory(fs->group_desc_count * sizeof(int),
"free block count array");
if ((fs->super->s_first_data_block <
- ext2fs_get_block_bitmap_start(block_found_map)) ||
+ ext2fs_get_block_bitmap_start(ctx->block_found_map)) ||
(fs->super->s_blocks_count-1 >
- ext2fs_get_block_bitmap_end(block_found_map))) {
- printf("PROGRAMMING ERROR: filesystem endpoints (%d, %d)\n\t"
- "don't match block_found_map endpoints (%d, %d).\n",
- fs->super->s_first_data_block,
- fs->super->s_blocks_count -1,
- ext2fs_get_block_bitmap_start(block_found_map),
- ext2fs_get_block_bitmap_end(block_found_map));
+ ext2fs_get_block_bitmap_end(ctx->block_found_map))) {
+ pctx.num = 1;
+ pctx.blk = fs->super->s_first_data_block;
+ pctx.blk2 = fs->super->s_blocks_count -1;
+ pctx.ino = ext2fs_get_block_bitmap_start(ctx->block_found_map);
+ pctx.ino2 = ext2fs_get_block_bitmap_end(ctx->block_found_map);
+ fix_problem(ctx, PR_5_BMAP_ENDPOINTS, &pctx);
+ /* fatal */
fatal_error(0);
}
@@ -83,56 +88,40 @@ static void check_block_bitmaps(ext2_filsys fs)
ext2fs_get_block_bitmap_start(fs->block_map)) ||
(fs->super->s_blocks_count-1 >
ext2fs_get_block_bitmap_end(fs->block_map))) {
- printf("PROGRAMMING ERROR: filesystem endpoints (%d, %d)\n\t"
- "don't match fs->block_map endpoints (%d, %d).\n",
- fs->super->s_first_data_block,
- fs->super->s_blocks_count -1,
- ext2fs_get_block_bitmap_start(fs->block_map),
- ext2fs_get_block_bitmap_end(fs->block_map));
+ pctx.num = 2;
+ pctx.blk = fs->super->s_first_data_block;
+ pctx.blk2 = fs->super->s_blocks_count -1;
+ pctx.ino = ext2fs_get_block_bitmap_start(fs->block_map);
+ pctx.ino2 = ext2fs_get_block_bitmap_end(fs->block_map);
+ fix_problem(ctx, PR_5_BMAP_ENDPOINTS, &pctx);
+ /* fatal */
fatal_error(0);
}
-
+redo_counts:
for (i = fs->super->s_first_data_block;
i < fs->super->s_blocks_count;
i++) {
- actual = ext2fs_fast_test_block_bitmap(block_found_map, i);
+ actual = ext2fs_fast_test_block_bitmap(ctx->block_found_map, i);
bitmap = ext2fs_fast_test_block_bitmap(fs->block_map, i);
if (actual == bitmap)
goto do_counts;
-
- if (do_fix < 0)
- do_fix = ask(fix_question, 1);
- if (!preen && print_header) {
- printf(print_header);
- print_header = 0;
- }
+
if (!actual && bitmap) {
/*
* Block not used, but marked in use in the bitmap.
*/
- if (!preen)
- printf(" -%u", i);
- if (do_fix)
- ext2fs_unmark_block_bitmap(fs->block_map,
- i);
+ problem = PR_5_UNUSED_BLOCK;
} else {
/*
* Block used, but not marked in use in the bitmap.
*/
- if (!preen)
- printf(" +%u", i);
- if (do_fix)
- ext2fs_mark_block_bitmap(fs->block_map,
- i);
+ problem = PR_5_BLOCK_USED;
}
- if (do_fix) {
- ext2fs_mark_bb_dirty(fs);
- bitmap = actual;
- } else
- ext2fs_unmark_valid(fs);
-
+ pctx.blk = i;
+ fix_problem(ctx, problem, &pctx);
+
do_counts:
if (!bitmap) {
group_free++;
@@ -147,18 +136,30 @@ static void check_block_bitmaps(ext2_filsys fs)
group_free = 0;
}
}
- if (!print_header)
- printf(". %s\n", fix_msg[do_fix]);
+ fixit = end_problem_latch(ctx, PR_LATCH_BBITMAP);
+ if (fixit == 1) {
+ ext2fs_free_block_bitmap(fs->block_map);
+ retval = ext2fs_copy_bitmap(ctx->block_found_map,
+ &fs->block_map);
+ /* XXX check retval --- should never fail! */
+ ext2fs_set_bitmap_padding(fs->block_map);
+ ext2fs_mark_bb_dirty(fs);
+
+ /* Redo the counts */
+ blocks = 0; free_blocks = 0; group_free = 0; group = 0;
+ memset(free_array, 0, fs->group_desc_count * sizeof(int));
+ goto redo_counts;
+ } else if (fixit == 0)
+ ext2fs_unmark_valid(fs);
+
for (i = 0; i < fs->group_desc_count; i++) {
if (free_array[i] != fs->group_desc[i].bg_free_blocks_count) {
- if (do_fix < 0)
- do_fix = ask(fix_question, 1);
- if (!preen)
- printf("Free blocks count wrong for "
- "group %u (%u, counted=%d). %s\n", i,
- fs->group_desc[i].bg_free_blocks_count,
- free_array[i], fix_msg[do_fix]);
- if (do_fix) {
+ pctx.group = i;
+ pctx.blk = fs->group_desc[i].bg_free_blocks_count;
+ pctx.blk2 = free_array[i];
+
+ if (fix_problem(ctx, PR_5_FREE_BLOCK_COUNT_GROUP,
+ &pctx)) {
fs->group_desc[i].bg_free_blocks_count =
free_array[i];
ext2fs_mark_super_dirty(fs);
@@ -167,14 +168,11 @@ static void check_block_bitmaps(ext2_filsys fs)
}
}
if (free_blocks != fs->super->s_free_blocks_count) {
- if (do_fix < 0)
- do_fix = ask(fix_question, 1);
- if (!preen)
- printf("Free blocks count wrong "
- "(%u, counted=%d). %s\n",
- fs->super->s_free_blocks_count, free_blocks,
- fix_msg[do_fix]);
- if (do_fix) {
+ pctx.group = 0;
+ pctx.blk = fs->super->s_free_blocks_count;
+ pctx.blk2 = free_blocks;
+
+ if (fix_problem(ctx, PR_5_FREE_BLOCK_COUNT, &pctx)) {
fs->super->s_free_blocks_count = free_blocks;
ext2fs_mark_super_dirty(fs);
} else
@@ -183,8 +181,9 @@ static void check_block_bitmaps(ext2_filsys fs)
free(free_array);
}
-static void check_inode_bitmaps(ext2_filsys fs)
+static void check_inode_bitmaps(e2fsck_t ctx)
{
+ ext2_filsys fs = ctx->fs;
ino_t i;
int free_inodes = 0;
int group_free = 0;
@@ -194,77 +193,70 @@ static void check_inode_bitmaps(ext2_filsys fs)
int *free_array;
int *dir_array;
int actual, bitmap;
- const char *print_header = "Inode bitmap differences:";
+ errcode_t retval;
+ struct problem_context pctx;
+ int problem, fixit;
+ clear_problem_context(&pctx);
free_array = allocate_memory(fs->group_desc_count * sizeof(int),
"free inode count array");
dir_array = allocate_memory(fs->group_desc_count * sizeof(int),
"directory count array");
- if ((1 < ext2fs_get_inode_bitmap_start(inode_used_map)) ||
+ if ((1 < ext2fs_get_inode_bitmap_start(ctx->inode_used_map)) ||
(fs->super->s_inodes_count >
- ext2fs_get_inode_bitmap_end(inode_used_map))) {
- printf("PROGRAMMING ERROR: filesystem inode endpoints (%d, %d)\n\t"
- "don't match inode_used_map endpoints (%d, %d).\n",
- 1, fs->super->s_inodes_count,
- ext2fs_get_inode_bitmap_start(inode_used_map),
- ext2fs_get_inode_bitmap_end(inode_used_map));
+ ext2fs_get_inode_bitmap_end(ctx->inode_used_map))) {
+ pctx.num = 3;
+ pctx.blk = 1;
+ pctx.blk2 = fs->super->s_inodes_count;
+ pctx.ino = ext2fs_get_inode_bitmap_start(ctx->inode_used_map);
+ pctx.ino2 = ext2fs_get_inode_bitmap_end(ctx->inode_used_map);
+ fix_problem(ctx, PR_5_BMAP_ENDPOINTS, &pctx);
+ /* fatal */
fatal_error(0);
}
if ((1 < ext2fs_get_inode_bitmap_start(fs->inode_map)) ||
(fs->super->s_inodes_count >
ext2fs_get_inode_bitmap_end(fs->inode_map))) {
- printf("PROGRAMMING ERROR: filesystem inode endpoints (%d, %d)\n\t"
- "don't match fs->inode_map endpoints (%d, %d).\n",
- 1, fs->super->s_inodes_count,
- ext2fs_get_inode_bitmap_start(fs->inode_map),
- ext2fs_get_inode_bitmap_end(fs->inode_map));
+ pctx.num = 4;
+ pctx.blk = 1;
+ pctx.blk2 = fs->super->s_inodes_count;
+ pctx.ino = ext2fs_get_inode_bitmap_start(fs->inode_map);
+ pctx.ino2 = ext2fs_get_inode_bitmap_end(fs->inode_map);
+ fix_problem(ctx, PR_5_BMAP_ENDPOINTS, &pctx);
+ /* fatal */
fatal_error(0);
}
+redo_counts:
for (i = 1; i <= fs->super->s_inodes_count; i++) {
- actual = ext2fs_fast_test_inode_bitmap(inode_used_map, i);
+ actual = ext2fs_fast_test_inode_bitmap(ctx->inode_used_map, i);
bitmap = ext2fs_fast_test_inode_bitmap(fs->inode_map, i);
if (actual == bitmap)
goto do_counts;
- if (do_fix < 0)
- do_fix = ask(fix_question, 1);
- if (!preen && print_header) {
- printf(print_header);
- print_header = 0;
- }
if (!actual && bitmap) {
/*
* Inode wasn't used, but marked in bitmap
*/
- if (!preen)
- printf(" -%lu", i);
- if (do_fix)
- ext2fs_unmark_inode_bitmap(fs->inode_map, i);
- } else if (actual && !bitmap) {
+ problem = PR_5_UNUSED_INODE;
+ } else /* if (actual && !bitmap) */ {
/*
* Inode used, but not in bitmap
*/
- if (!preen)
- printf (" +%lu", i);
- if (do_fix)
- ext2fs_mark_inode_bitmap(fs->inode_map, i);
+ problem = PR_5_INODE_USED;
}
- if (do_fix) {
- ext2fs_mark_ib_dirty(fs);
- bitmap = actual;
- } else
- ext2fs_unmark_valid(fs);
-
+ pctx.ino = i;
+ fix_problem(ctx, problem, &pctx);
+
do_counts:
if (!bitmap) {
group_free++;
free_inodes++;
} else {
- if (ext2fs_test_inode_bitmap(inode_dir_map, i))
+ if (ext2fs_test_inode_bitmap(ctx->inode_dir_map, i))
dirs_count++;
}
inodes++;
@@ -278,19 +270,31 @@ do_counts:
dirs_count = 0;
}
}
- if (!print_header)
- printf(". %s\n", fix_msg[do_fix]);
+ fixit = end_problem_latch(ctx, PR_LATCH_IBITMAP);
+ if (fixit == 1) {
+ ext2fs_free_inode_bitmap(fs->inode_map);
+ retval = ext2fs_copy_bitmap(ctx->inode_used_map,
+ &fs->inode_map);
+ /* XXX check retval --- should never fail! */
+ ext2fs_set_bitmap_padding(fs->inode_map);
+ ext2fs_mark_ib_dirty(fs);
+
+ /* redo counts */
+ inodes = 0; free_inodes = 0; group_free = 0;
+ dirs_count = 0; group = 0;
+ memset(free_array, 0, fs->group_desc_count * sizeof(int));
+ memset(dir_array, 0, fs->group_desc_count * sizeof(int));
+ goto redo_counts;
+ } else if (fixit == 0)
+ ext2fs_unmark_valid(fs);
for (i = 0; i < fs->group_desc_count; i++) {
if (free_array[i] != fs->group_desc[i].bg_free_inodes_count) {
- if (do_fix < 0)
- do_fix = ask(fix_question, 1);
- if (!preen)
- printf ("Free inodes count wrong for "
- "group #%lu (%u, counted=%d). %s\n", i,
- fs->group_desc[i].bg_free_inodes_count,
- free_array[i], fix_msg[do_fix]);
- if (do_fix) {
+ pctx.group = i;
+ pctx.ino = fs->group_desc[i].bg_free_inodes_count;
+ pctx.ino2 = free_array[i];
+ if (fix_problem(ctx, PR_5_FREE_INODE_COUNT_GROUP,
+ &pctx)) {
fs->group_desc[i].bg_free_inodes_count =
free_array[i];
ext2fs_mark_super_dirty(fs);
@@ -298,14 +302,12 @@ do_counts:
ext2fs_unmark_valid(fs);
}
if (dir_array[i] != fs->group_desc[i].bg_used_dirs_count) {
- if (do_fix < 0)
- do_fix = ask(fix_question, 1);
- if (!preen)
- printf ("Directories count wrong for "
- "group #%lu (%u, counted=%d). %s\n", i,
- fs->group_desc[i].bg_used_dirs_count,
- dir_array[i], fix_msg[do_fix]);
- if (do_fix) {
+ pctx.group = i;
+ pctx.ino = fs->group_desc[i].bg_used_dirs_count;
+ pctx.ino2 = dir_array[i];
+
+ if (fix_problem(ctx, PR_5_FREE_DIR_COUNT_GROUP,
+ &pctx)) {
fs->group_desc[i].bg_used_dirs_count =
dir_array[i];
ext2fs_mark_super_dirty(fs);
@@ -314,14 +316,11 @@ do_counts:
}
}
if (free_inodes != fs->super->s_free_inodes_count) {
- if (do_fix < 0)
- do_fix = ask(fix_question, 1);
- if (!preen)
- printf("Free inodes count wrong "
- "(%u, counted=%d). %s\n",
- fs->super->s_free_inodes_count, free_inodes,
- fix_msg[do_fix]);
- if (do_fix) {
+ pctx.group = -1;
+ pctx.ino = fs->super->s_free_inodes_count;
+ pctx.ino2 = free_inodes;
+
+ if (fix_problem(ctx, PR_5_FREE_INODE_COUNT, &pctx)) {
fs->super->s_free_inodes_count = free_inodes;
ext2fs_mark_super_dirty(fs);
} else
@@ -331,17 +330,20 @@ do_counts:
free(dir_array);
}
-static void check_inode_end(ext2_filsys fs)
+static void check_inode_end(e2fsck_t ctx)
{
+ ext2_filsys fs = ctx->fs;
ino_t end, save_inodes_count, i;
- errcode_t retval;
+ struct problem_context pctx;
+
+ clear_problem_context(&pctx);
end = EXT2_INODES_PER_GROUP(fs->super) * fs->group_desc_count;
- retval = ext2fs_fudge_inode_bitmap_end(fs->inode_map, end,
- &save_inodes_count);
- if (retval) {
- com_err("check_inode_end", retval,
- "while trying to fudge end of inode bitmap");
+ pctx.errcode = ext2fs_fudge_inode_bitmap_end(fs->inode_map, end,
+ &save_inodes_count);
+ if (pctx.errcode) {
+ pctx.num = 1;
+ fix_problem(ctx, PR_5_FUDGE_BITMAP_ERROR, &pctx);
fatal_error(0);
}
if (save_inodes_count == end)
@@ -349,8 +351,7 @@ static void check_inode_end(ext2_filsys fs)
for (i = save_inodes_count + 1; i <= end; i++) {
if (!ext2fs_test_inode_bitmap(fs->inode_map, i)) {
- printf("Padding at end of inode bitmap is not set. ");
- if (ask("Fix", 1)) {
+ if (fix_problem(ctx, PR_5_INODE_BMAP_PADDING, &pctx)) {
for (i = save_inodes_count + 1; i <= end; i++)
ext2fs_mark_inode_bitmap(fs->inode_map,
i);
@@ -361,27 +362,30 @@ static void check_inode_end(ext2_filsys fs)
}
}
- retval = ext2fs_fudge_inode_bitmap_end(fs->inode_map,
- save_inodes_count, 0);
- if (retval) {
- com_err("check_inode_end", retval,
- "while trying to fudge end of inode bitmap back");
+ pctx.errcode = ext2fs_fudge_inode_bitmap_end(fs->inode_map,
+ save_inodes_count, 0);
+ if (pctx.errcode) {
+ pctx.num = 2;
+ fix_problem(ctx, PR_5_FUDGE_BITMAP_ERROR, &pctx);
fatal_error(0);
}
}
-static void check_block_end(ext2_filsys fs)
+static void check_block_end(e2fsck_t ctx)
{
+ ext2_filsys fs = ctx->fs;
blk_t end, save_blocks_count, i;
- errcode_t retval;
+ struct problem_context pctx;
+
+ clear_problem_context(&pctx);
end = fs->block_map->start +
(EXT2_BLOCKS_PER_GROUP(fs->super) * fs->group_desc_count) - 1;
- retval = ext2fs_fudge_block_bitmap_end(fs->block_map, end,
- &save_blocks_count);
- if (retval) {
- com_err("check_block_end", retval,
- "while trying to fudge end of block bitmap");
+ pctx.errcode = ext2fs_fudge_block_bitmap_end(fs->block_map, end,
+ &save_blocks_count);
+ if (pctx.errcode) {
+ pctx.num = 3;
+ fix_problem(ctx, PR_5_FUDGE_BITMAP_ERROR, &pctx);
fatal_error(0);
}
if (save_blocks_count == end)
@@ -389,9 +393,7 @@ static void check_block_end(ext2_filsys fs)
for (i = save_blocks_count + 1; i <= end; i++) {
if (!ext2fs_test_block_bitmap(fs->block_map, i)) {
- printf("Padding at end of block bitmap is not set. ");
-
- if (ask("Fix", 1)) {
+ if (fix_problem(ctx, PR_5_BLOCK_BMAP_PADDING, &pctx)) {
for (i = save_blocks_count + 1; i < end; i++)
ext2fs_mark_block_bitmap(fs->block_map,
i);
@@ -402,12 +404,14 @@ static void check_block_end(ext2_filsys fs)
}
}
- retval = ext2fs_fudge_block_bitmap_end(fs->block_map,
- save_blocks_count, 0);
- if (retval) {
- com_err("check_block_end", retval,
- "while trying to fudge end of block bitmap back");
+ pctx.errcode = ext2fs_fudge_block_bitmap_end(fs->block_map,
+ save_blocks_count, 0);
+ if (pctx.errcode) {
+ pctx.num = 4;
+ fix_problem(ctx, PR_5_FUDGE_BITMAP_ERROR, &pctx);
fatal_error(0);
}
}
+
+