+2003-09-13 Theodore Ts'o <tytso@mit.edu>
+
+ * pass1.c (e2fsck_pass1), problem.h (PR_1_BB_FS_BLOCK),
+ problem.c (PR_1_BB_FS_BLOCK, PR_1_BBINODE_BAD_METABLOCK_PROMPT):
+ Fix up the handling of corrupted indirect blocks in the
+ bad block. We now correctly handle the case where there
+ is an overlap between a block group descriptor or
+ a superblock and a bad block indirect block. In the case
+ where the indirect block is corrupted, we now suggest
+ "e2fsck -c".
+
2003-09-12 Theodore Ts'o <tytso@mit.edu>
* unix.c (PRS): Check the returned name from blkid_get_devname and
struct process_block_struct {
ext2_ino_t ino;
int is_dir:1, is_reg:1, clear:1, suppress:1,
- fragmented:1, compressed:1;
+ fragmented:1, compressed:1, bbcheck:1;
blk_t num_blocks;
blk_t max_blocks;
e2_blkcnt_t last_block;
blk_t previous_block;
struct ext2_inode *inode;
struct problem_context *pctx;
+ ext2fs_block_bitmap fs_meta_blocks;
e2fsck_t ctx;
};
if (ino == EXT2_BAD_INO) {
struct process_block_struct pb;
+ pctx.errcode = ext2fs_copy_bitmap(ctx->block_found_map,
+ &pb.fs_meta_blocks);
+ if (pctx.errcode) {
+ pctx.num = 4;
+ fix_problem(ctx, PR_1_ALLOCATE_BBITMAP_ERROR, &pctx);
+ ctx->flags |= E2F_FLAG_ABORT;
+ return;
+ }
pb.ino = EXT2_BAD_INO;
pb.num_blocks = pb.last_block = 0;
pb.num_illegal_blocks = 0;
pb.suppress = 0; pb.clear = 0; pb.is_dir = 0;
- pb.is_reg = 0; pb.fragmented = 0;
+ pb.is_reg = 0; pb.fragmented = 0; pb.bbcheck = 0;
pb.inode = &inode;
pb.pctx = &pctx;
pb.ctx = ctx;
pctx.errcode = ext2fs_block_iterate2(fs, ino, 0,
block_buf, process_bad_block, &pb);
+ ext2fs_free_block_bitmap(pb.fs_meta_blocks);
if (pctx.errcode) {
fix_problem(ctx, PR_1_BLOCK_ITERATE, &pctx);
ctx->flags |= E2F_FLAG_ABORT;
return;
}
+ if (pb.bbcheck)
+ if (!fix_problem(ctx, PR_1_BBINODE_BAD_METABLOCK_PROMPT, &pctx)) {
+ ctx->flags |= E2F_FLAG_ABORT;
+ return;
+ }
ext2fs_mark_inode_bitmap(ctx->inode_used_map, ino);
clear_problem_context(&pctx);
continue;
return ret_code;
}
-static void bad_block_indirect(e2fsck_t ctx, blk_t blk)
-{
- struct problem_context pctx;
-
- clear_problem_context(&pctx);
- /*
- * Prompt to see if we should continue or not.
- */
- if (!fix_problem(ctx, PR_1_BBINODE_BAD_METABLOCK, &pctx))
- ctx->flags |= E2F_FLAG_ABORT;
-}
-
static int process_bad_block(ext2_filsys fs,
blk_t *block_nr,
e2_blkcnt_t blockcnt,
}
if (blockcnt < 0) {
- if (ext2fs_test_block_bitmap(ctx->block_found_map, blk)) {
- bad_block_indirect(ctx, blk);
+ if (ext2fs_test_block_bitmap(p->fs_meta_blocks, blk)) {
+ p->bbcheck = 1;
+ if (fix_problem(ctx, PR_1_BB_FS_BLOCK, pctx)) {
+ *block_nr = 0;
+ return BLOCK_CHANGED;
+ }
+ } else if (ext2fs_test_block_bitmap(ctx->block_found_map,
+ blk)) {
+ p->bbcheck = 1;
+ if (fix_problem(ctx, PR_1_BBINODE_BAD_METABLOCK,
+ pctx)) {
+ *block_nr = 0;
+ return BLOCK_CHANGED;
+ }
if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
return BLOCK_ABORT;
} else
* is using a bad block.
*/
if ((blk == p->inode->i_block[EXT2_IND_BLOCK]) ||
- p->inode->i_block[EXT2_DIND_BLOCK]) {
- bad_block_indirect(ctx, blk);
+ (blk == p->inode->i_block[EXT2_DIND_BLOCK]) ||
+ (blk == p->inode->i_block[EXT2_TIND_BLOCK])) {
+ p->bbcheck = 1;
+ if (fix_problem(ctx, PR_1_BBINODE_BAD_METABLOCK, pctx)) {
+ *block_nr = 0;
+ return BLOCK_CHANGED;
+ }
if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
return BLOCK_ABORT;
return 0;
/* Bad block used as bad block indirect block */
{ PR_1_BBINODE_BAD_METABLOCK,
- N_("Bad @b %b used as bad @b indirect @b?!?\n"),
- PROMPT_NONE, PR_AFTER_CODE, PR_1_BBINODE_BAD_METABLOCK_PROMPT },
+ N_("Bad @b %b used as bad @b @i indirect @b. "),
+ PROMPT_CLEAR, PR_LATCH_BBLOCK },
/* Inconsistency can't be fixed prompt */
{ PR_1_BBINODE_BAD_METABLOCK_PROMPT,
- N_("\nThis inconsistency can not be fixed with e2fsck; to fix it, use\n"
- """dumpe2fs -b"" to dump out the bad @b "
- "list and ""e2fsck -L filename""\n"
- "to read it back in again.\n"),
+ N_("\nThe bad @b @i has probably been corrupted. You probably\n"
+ "should stop now and run ""e2fsck -c"" to scan for bad blocks\n"
+ "in the @f.\n"),
PROMPT_CONTINUE, PR_PREEN_NOMSG },
/* Bad primary block */
N_("@h %i has a tree depth (%N) which is too big\n"),
PROMPT_CLEAR_HTREE, PR_PREEN_OK },
+ /* Bad block has indirect block that conflicts with filesystem block */
+ { PR_1_BB_FS_BLOCK,
+ N_("Bad @b @i has an indirect @b (%b) that conflicts with\n"
+ "@f metadata. "),
+ PROMPT_CLEAR, PR_LATCH_BBLOCK },
+
/* Pass 1b errors */
/* Pass 1B: Rescan for duplicate/bad blocks */