Fix e2fsck so that it will clean up filesystesm that have the

resize_inode capability disabled, but which still have the
s_reserved_gdt_blocks field set in the superblock, or which 
still have blocks in the inode #7 (the resize inode).
This commit is contained in:
Theodore Ts'o 2004-12-16 20:13:45 -05:00
parent 1b4cd9c746
commit e75cfc5da8
4 changed files with 60 additions and 2 deletions

View File

@ -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

View File

@ -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 */

View File

@ -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
*/

View File

@ -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;
}