From a9ca2016e14b5b56e5f0b61a73d52c4caee718bc Mon Sep 17 00:00:00 2001 From: Theodore Ts'o Date: Fri, 12 Jan 2001 21:53:25 +0000 Subject: [PATCH] ChangeLog, pass1.c, problem.c, problem.h: pass1.c (e2fsck_pass1): Cap the maximum legal size of a file by the limit caused by the fact that i_blocks is in 512 byte units, and that the Linux buffer cache also fundamentally assumes 512 byte sectors. Make sure that the journal inode is a regular file, and when clearing an unused journal inode, make sure the icount db is updated. problem.c, problem.h (PR_1_JOURNAL_BAD_MODE): Add new problem code. ChangeLog, journal.c: journal.c (e2fsck_journal_fix_unsupported_super): Remove unused function. Add FIXME notes to e2fsck_get_journal(), from Andreas Dilger. --- e2fsck/ChangeLog | 14 ++++++++++++++ e2fsck/journal.c | 23 ++--------------------- e2fsck/pass1.c | 34 ++++++++++++++++++++++++---------- e2fsck/problem.c | 7 ++++++- e2fsck/problem.h | 5 ++++- 5 files changed, 50 insertions(+), 33 deletions(-) diff --git a/e2fsck/ChangeLog b/e2fsck/ChangeLog index 594ca91..eb48f31 100644 --- a/e2fsck/ChangeLog +++ b/e2fsck/ChangeLog @@ -1,5 +1,19 @@ 2001-01-12 Theodore Ts'o + * journal.c (e2fsck_journal_fix_unsupported_super): Remove unused + function. Add FIXME notes to e2fsck_get_journal(), from + Andreas Dilger. + + * pass1.c (e2fsck_pass1): Cap the maximum legal size of a file by + the limit caused by the fact that i_blocks is in 512 byte + units, and that the Linux buffer cache also fundamentally + assumes 512 byte sectors. + Make sure that the journal inode is a regular file, and + when clearing an unused journal inode, make sure the + icount db is updated. + + * problem.c, problem.h (PR_1_JOURNAL_BAD_MODE): Add new problem code. + * problem.c: For PR_1_RESERVED_BAD_MODE, print a description of the reserved inode. In PR_0_JOURNAL_HAS_JOURNAL, prompt to clear the journal, rather than deleting it (which is diff --git a/e2fsck/journal.c b/e2fsck/journal.c index 5a83c06..9ddcf89 100644 --- a/e2fsck/journal.c +++ b/e2fsck/journal.c @@ -220,6 +220,7 @@ static errcode_t e2fsck_get_journal(e2fsck_t ctx, journal_t **journal) clear_problem_context(&pctx); if (sb->s_feature_compat & EXT3_FEATURE_COMPAT_HAS_JOURNAL) { + /* FIXME: check if UUID is valid block dev, has a journal */ if (sb->s_journal_dev) { pctx.num = sb->s_journal_dev; /* this problem aborts on -y, -p, unsupported on -n */ @@ -229,6 +230,7 @@ static errcode_t e2fsck_get_journal(e2fsck_t ctx, journal_t **journal) sb->s_state &= ~EXT2_VALID_FS; ext2fs_mark_super_dirty(ctx->fs); } + /* FIXME: check if UUID is valid block dev, has a journal */ if (!uuid_is_null(sb->s_journal_uuid)) { uuid_unparse(sb->s_journal_uuid, uuid_str); pctx.str = uuid_str; @@ -296,27 +298,6 @@ static errcode_t e2fsck_journal_fix_bad_inode(e2fsck_t ctx, return 0; } -static errcode_t e2fsck_journal_fix_unsupported_super(e2fsck_t ctx, - struct problem_context *pctx) -{ - struct ext2_super_block *sb = ctx->fs->super; - - /* Unsupported journal superblock - first choice is abort. - * Declining that gives the option to reset the superblock. - * - * Otherwise we get the chance to delete the journal, and - * failing that we abort because we can't handle this. - */ - if (sb->s_feature_compat & EXT3_FEATURE_COMPAT_HAS_JOURNAL && - fix_problem(ctx, PR_0_JOURNAL_UNSUPP_SUPER, pctx)) - return EXT2_ET_CORRUPT_SUPERBLOCK; - - if (e2fsck_journal_fix_bad_inode(ctx, pctx)) - return EXT2_ET_UNSUPP_FEATURE; - - return 0; -} - static errcode_t e2fsck_journal_load(journal_t *journal) { e2fsck_t ctx = journal->j_dev; diff --git a/e2fsck/pass1.c b/e2fsck/pass1.c index 90530c7..1999532 100644 --- a/e2fsck/pass1.c +++ b/e2fsck/pass1.c @@ -184,7 +184,7 @@ static void check_size(e2fsck_t ctx, struct problem_context *pctx) void e2fsck_pass1(e2fsck_t ctx) { int i; - __u64 max_sizes; + __u64 max_sizes, max_sect_limit; ext2_filsys fs = ctx->fs; ext2_ino_t ino; struct ext2_inode inode; @@ -220,6 +220,9 @@ void e2fsck_pass1(e2fsck_t ctx) (__u64) EXT2_BPP(10+i) * EXT2_BPP(10+i) * EXT2_BPP(10+i)); max_sizes = (max_sizes * (1UL << (10+i))) - 1; + max_sect_limit = 512ULL * ((1LL << 32) - (1 << (i+1))); + if (max_sizes > max_sect_limit) + max_sizes = max_sect_limit; ext2_max_sizes[i] = max_sizes; } #undef EXT2_BPP @@ -357,8 +360,7 @@ void e2fsck_pass1(e2fsck_t ctx) ext2fs_mark_inode_bitmap(ctx->inode_used_map, ino); clear_problem_context(&pctx); goto next; - } - if (ino == EXT2_ROOT_INO) { + } else if (ino == EXT2_ROOT_INO) { /* * Make sure the root inode is a directory; if * not, offer to clear it. It will be @@ -391,22 +393,34 @@ void e2fsck_pass1(e2fsck_t ctx) "pass1"); } } - } - if (ino == EXT2_JOURNAL_INO) { + } else if (ino == EXT2_JOURNAL_INO) { ext2fs_mark_inode_bitmap(ctx->inode_used_map, ino); if (fs->super->s_journal_inum == EXT2_JOURNAL_INO) { + /* + * XXX arguably this check should be + * in journal.c, before we decide it's + * safe to run the journal... + */ + if (!LINUX_S_ISREG(inode.i_mode) && + fix_problem(ctx, PR_1_JOURNAL_BAD_MODE, + &pctx)) { + inode.i_mode = LINUX_S_IFREG; + e2fsck_write_inode(ctx, ino, &inode, + "pass1"); + } check_blocks(ctx, &pctx, block_buf); goto next; } - if ((inode.i_blocks || inode.i_block[0]) && - fix_problem(ctx, PR1_JOURNAL_INODE_NOT_CLEAR, + if ((inode.i_links_count || inode.i_blocks || + inode.i_blocks || inode.i_block[0]) && + fix_problem(ctx, PR_1_JOURNAL_INODE_NOT_CLEAR, &pctx)) { memset(&inode, 0, sizeof(inode)); + ext2fs_icount_store(ctx->inode_link_info, + ino, 0); e2fsck_write_inode(ctx, ino, &inode, "pass1"); } - } - if ((ino != EXT2_ROOT_INO) && - (ino < EXT2_FIRST_INODE(fs->super))) { + } else if (ino < EXT2_FIRST_INODE(fs->super)) { int problem = 0; ext2fs_mark_inode_bitmap(ctx->inode_used_map, ino); diff --git a/e2fsck/problem.c b/e2fsck/problem.c index 46b041e..abec3cb 100644 --- a/e2fsck/problem.c +++ b/e2fsck/problem.c @@ -529,10 +529,15 @@ static const struct e2fsck_problem problem_table[] = { PROMPT_FIX, PR_PREEN_OK | PR_NO_OK }, /* Journal inode is not in use, but contains data */ - { PR1_JOURNAL_INODE_NOT_CLEAR, + { PR_1_JOURNAL_INODE_NOT_CLEAR, "@j @i is not in use, but contains data. ", PROMPT_CLEAR, PR_PREEN_OK }, + /* Journal has bad mode */ + { PR_1_JOURNAL_BAD_MODE, + N_("Journal is not regular file. "), + PROMPT_FIX, PR_PREEN_OK }, + /* Pass 1b errors */ /* Pass 1B: Rescan for duplicate/bad blocks */ diff --git a/e2fsck/problem.h b/e2fsck/problem.h index 280b22a..b6c0d00 100644 --- a/e2fsck/problem.h +++ b/e2fsck/problem.h @@ -306,8 +306,11 @@ struct problem_context { #define PR_1_FS_REV_LEVEL 0x010033 /* Journal inode not in use, needs clearing */ -#define PR1_JOURNAL_INODE_NOT_CLEAR 0x010034 +#define PR_1_JOURNAL_INODE_NOT_CLEAR 0x010034 +/* Journal inode has wrong mode */ +#define PR_1_JOURNAL_BAD_MODE 0x010035 + /* * Pass 1b errors */ -- 1.8.3.1