aboutsummaryrefslogtreecommitdiffstats
path: root/e2fsck/pass1.c
diff options
context:
space:
mode:
authorDarrick J. Wong <darrick.wong@oracle.com>2014-09-11 12:44:49 -0700
committerTheodore Ts'o <tytso@mit.edu>2014-09-11 18:08:26 -0400
commitc6c681632e45df376360303a00539b2a86ed7400 (patch)
treee3cd0842f152ee415e140984a29e69114f05328e /e2fsck/pass1.c
parent3f4c4079976f1ccf0a6d675b0115b519f596da89 (diff)
downloadandroid_external_e2fsprogs-c6c681632e45df376360303a00539b2a86ed7400.tar.gz
android_external_e2fsprogs-c6c681632e45df376360303a00539b2a86ed7400.tar.bz2
android_external_e2fsprogs-c6c681632e45df376360303a00539b2a86ed7400.zip
e2fsck: ignore badblocks if it says badblocks inode is bad
If the badblocks list says that the badblocks inode is bad, it's quite likely that badblocks is broken. Worse yet, if the root inode is in the same block as the badblocks inode (likely since they're adjacent), the filesystem becomes unfixable because pass3 notices the bad root inode and exits. So... if we encounter this case, just kill the badblocks inode. Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com> Signed-off-by: Theodore Ts'o <tytso@mit.edu>
Diffstat (limited to 'e2fsck/pass1.c')
-rw-r--r--e2fsck/pass1.c31
1 files changed, 31 insertions, 0 deletions
diff --git a/e2fsck/pass1.c b/e2fsck/pass1.c
index 4fc53112..7175c771 100644
--- a/e2fsck/pass1.c
+++ b/e2fsck/pass1.c
@@ -1076,6 +1076,37 @@ void e2fsck_pass1(e2fsck_t ctx)
if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
return;
if (pctx.errcode == EXT2_ET_BAD_BLOCK_IN_INODE_TABLE) {
+ /*
+ * If badblocks says badblocks is bad, offer to clear
+ * the list, update the in-core bb list, and restart
+ * the inode scan.
+ */
+ if (ino == EXT2_BAD_INO &&
+ fix_problem(ctx, PR_1_BADBLOCKS_IN_BADBLOCKS,
+ &pctx)) {
+ errcode_t err;
+
+ e2fsck_clear_inode(ctx, ino, inode, 0, "pass1");
+ ext2fs_badblocks_list_free(ctx->fs->badblocks);
+ ctx->fs->badblocks = NULL;
+ err = ext2fs_read_bb_inode(ctx->fs,
+ &ctx->fs->badblocks);
+ if (err) {
+ fix_problem(ctx, PR_1_ISCAN_ERROR,
+ &pctx);
+ ctx->flags |= E2F_FLAG_ABORT;
+ goto endit;
+ }
+ err = ext2fs_inode_scan_goto_blockgroup(scan,
+ 0);
+ if (err) {
+ fix_problem(ctx, PR_1_ISCAN_ERROR,
+ &pctx);
+ ctx->flags |= E2F_FLAG_ABORT;
+ goto endit;
+ }
+ continue;
+ }
if (!ctx->inode_bb_map)
alloc_bb_map(ctx);
ext2fs_mark_inode_bitmap2(ctx->inode_bb_map, ino);