diff options
-rw-r--r-- | e2fsck/ChangeLog | 9 | ||||
-rw-r--r-- | e2fsck/problem.c | 11 | ||||
-rw-r--r-- | e2fsck/problem.h | 6 | ||||
-rw-r--r-- | e2fsck/super.c | 36 |
4 files changed, 60 insertions, 2 deletions
diff --git a/e2fsck/ChangeLog b/e2fsck/ChangeLog index ba88f6a9..78be211f 100644 --- a/e2fsck/ChangeLog +++ b/e2fsck/ChangeLog @@ -1,3 +1,12 @@ +2004-12-16 Theodore Ts'o <tytso@mit.edu> + + * super.c (check_super_block): If the resize_inode feature is not + set, check to make sure that s_reserved_gdt_blocks is + zero, and that the resize inode is clear. + + * problem.h (PR_0_NONZERO_RESERVED_GDT_BLOCKS, + PR_0_CLEAR_RESIZE_INODE): Add new problem codes. + 2004-12-15 Theodore Ts'o <tytso@mit.edu> * pass1.c (process_block): Applied resize inode patch. Mark the diff --git a/e2fsck/problem.c b/e2fsck/problem.c index 75708b70..bb81d520 100644 --- a/e2fsck/problem.c +++ b/e2fsck/problem.c @@ -314,6 +314,17 @@ static const struct e2fsck_problem problem_table[] = { N_("Backing up @j @i @b information.\n\n"), PROMPT_NONE, 0 }, + /* Reserved blocks w/o resize_inode */ + { PR_0_NONZERO_RESERVED_GDT_BLOCKS, + N_("@f does not have resize_@i enabled, but s_reserved_gdt_@bs\n" + "is %N; @s zero. "), + PROMPT_FIX, 0 }, + + /* Resize_inode not enabled, but resize inode is non-zero */ + { PR_0_CLEAR_RESIZE_INODE, + N_("Resize_@i not enabled, but the resize inode is non-zero. "), + PROMPT_CLEAR, 0 }, + /* Pass 1 errors */ /* Pass 1: Checking inodes, blocks, and sizes */ diff --git a/e2fsck/problem.h b/e2fsck/problem.h index 8e2e1405..1eb4ab6b 100644 --- a/e2fsck/problem.h +++ b/e2fsck/problem.h @@ -175,6 +175,12 @@ struct problem_context { /* Backup journal inode blocks */ #define PR_0_BACKUP_JNL 0x00002D +/* Reserved blocks w/o resize_inode */ +#define PR_0_NONZERO_RESERVED_GDT_BLOCKS 0x00002E + +/* Resize_inode not enabled, but resize inode is non-zero */ +#define PR_0_CLEAR_RESIZE_INODE 0x00002F + /* * Pass 1 errors */ diff --git a/e2fsck/super.c b/e2fsck/super.c index 9a1ab4c0..11ab7c9a 100644 --- a/e2fsck/super.c +++ b/e2fsck/super.c @@ -325,6 +325,7 @@ void check_super_block(e2fsck_t ctx) dgrp_t i; blk_t should_be; struct problem_context pctx; + struct ext2_inode inode; __u32 free_blocks = 0, free_inodes = 0; inodes_per_block = EXT2_INODES_PER_BLOCK(fs->super); @@ -541,6 +542,39 @@ void check_super_block(e2fsck_t ctx) ext2fs_mark_super_dirty(fs); } + /* + * If the resize inode feature isn't set, then + * s_reserved_gdt_blocks must be zero, and the resize inode + * must be cleared. + */ + if (!(fs->super->s_feature_compat & + EXT2_FEATURE_COMPAT_RESIZE_INODE)) { + if (fs->super->s_reserved_gdt_blocks) { + pctx.num = fs->super->s_reserved_gdt_blocks; + if (fix_problem(ctx, PR_0_NONZERO_RESERVED_GDT_BLOCKS, + &pctx)) { + fs->super->s_reserved_gdt_blocks = 0; + ext2fs_mark_super_dirty(fs); + } + } + e2fsck_read_inode(ctx, EXT2_RESIZE_INO, &inode, + "check_resize"); + for (i=0; i < EXT2_N_BLOCKS; i++) { + if (inode.i_block[i]) + break; + } + pctx.ino = EXT2_RESIZE_INO; + if ((i < EXT2_N_BLOCKS) && + fix_problem(ctx, PR_0_CLEAR_RESIZE_INODE, &pctx)) { + for (i=0; i < EXT2_N_BLOCKS; i++) { + inode.i_block[i] = 0; + } + inode.i_blocks = 0; + e2fsck_write_inode(ctx, EXT2_RESIZE_INO, &inode, + "clear_resize"); + } + } + /* * Clean up any orphan inodes, if present. */ @@ -555,5 +589,3 @@ void check_super_block(e2fsck_t ctx) e2fsck_move_ext3_journal(ctx); return; } - - |