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".
bitmap-optimize
Theodore Ts'o 2003-11-21 10:41:58 -05:00
parent 817e49e3ce
commit 000ba4046f
4 changed files with 63 additions and 24 deletions

View File

@ -1,3 +1,14 @@
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

View File

@ -78,7 +78,7 @@ static void adjust_extattr_refcount(e2fsck_t ctx, ext2_refcount_t refcount,
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;
@ -86,6 +86,7 @@ struct process_block_struct {
blk_t previous_block;
struct ext2_inode *inode;
struct problem_context *pctx;
ext2fs_block_bitmap fs_meta_blocks;
e2fsck_t ctx;
};
@ -417,21 +418,35 @@ void e2fsck_pass1(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;
@ -1527,18 +1542,6 @@ mark_dir:
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,
@ -1579,8 +1582,20 @@ static int process_bad_block(ext2_filsys fs,
}
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
@ -1671,8 +1686,13 @@ static int process_bad_block(ext2_filsys fs,
* 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;

View File

@ -422,15 +422,14 @@ static const struct e2fsck_problem problem_table[] = {
/* 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 */
@ -703,6 +702,12 @@ static const struct e2fsck_problem problem_table[] = {
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 */

View File

@ -407,6 +407,9 @@ struct problem_context {
/* HTREE too deep */
#define PR_1_HTREE_DEPTH 0x01004C
/* Bad block has indirect block that conflicts with filesystem block */
#define PR_1_BB_FS_BLOCK 0x01004D
/*
* Pass 1b errors
*/