e2fsck: fix mysterious "FILE SYSTEM WAS MODIFIED" with no changes

Commit 2a77a784a3 (firest released in e2fsprogs 1.33) compared
superblock summary free blocks and inode counts with the allocation
bitmap counts before starting the file system check proper, and if
they differed, set the superblock and marked it as dirty.  If no other
file systme changes were required, this would cause a "*** FILE SYSTEM
WAS MODIFIED ***" message without any explanation of what e2fsck had
changed.

We fix this by only setting the superblock summary free block/inodes
counts if we are skipping a full check, and in non-preen mode, e2fsck
will now print an explicit message stating how the superblock had been
updated.

In a full check, any updates to the superblock free blocks/inodes
fields will be noted in pass5.

This change requires changing a few test results (essentially
reversing the changes made in commit 2a77a784a3).

Signed-off-by: "Theodore Ts'o" <tytso@mit.edu>
bitmap-optimize
Theodore Ts'o 2011-06-16 01:13:42 -04:00
parent 96367ad3bc
commit a3efe48420
12 changed files with 58 additions and 33 deletions

View File

@ -212,10 +212,12 @@ struct e2fsck_struct {
char *io_options;
int flags; /* E2fsck internal flags */
int options;
int blocksize; /* blocksize */
blk64_t use_superblock; /* sb requested by user */
blk64_t superblock; /* sb used to open fs */
int blocksize; /* blocksize */
blk64_t num_blocks; /* Total number of blocks */
blk64_t free_blocks;
ino_t free_inodes;
int mount_flags;
blkid_cache blkid; /* blkid cache */

View File

@ -402,6 +402,16 @@ static struct e2fsck_problem problem_table[] = {
N_("One or more @b @g descriptor checksums are invalid. "),
PROMPT_FIX, PR_PREEN_OK },
/* Free inodes count wrong */
{ PR_0_FREE_INODE_COUNT,
N_("Setting free @is count to %j (was %i)\n"),
PROMPT_NONE, PR_PREEN_NOMSG },
/* Free blocks count wrong */
{ PR_0_FREE_BLOCK_COUNT,
N_("Setting free @bs count to %c (was %b)\n"),
PROMPT_NONE, PR_PREEN_NOMSG },
/* Pass 1 errors */
/* Pass 1: Checking inodes, blocks, and sizes */

View File

@ -227,6 +227,12 @@ struct problem_context {
/* Block group checksum (latch question) */
#define PR_0_GDT_CSUM_LATCH 0x00003E
/* Free inodes count wrong */
#define PR_0_FREE_INODE_COUNT 0x00003F
/* Free blocks count wrong */
#define PR_0_FREE_BLOCK_COUNT 0x000040
/*
* Pass 1 errors

View File

@ -690,23 +690,8 @@ void check_super_block(e2fsck_t ctx)
return;
}
/*
* Update the global counts from the block group counts. This
* is needed for an experimental patch which eliminates
* locking the entire filesystem when allocating blocks or
* inodes; if the filesystem is not unmounted cleanly, the
* global counts may not be accurate.
*/
if ((free_blocks != ext2fs_free_blocks_count(sb)) ||
(free_inodes != sb->s_free_inodes_count)) {
if (ctx->options & E2F_OPT_READONLY)
ext2fs_unmark_valid(fs);
else {
ext2fs_free_blocks_count_set(sb, free_blocks);
sb->s_free_inodes_count = free_inodes;
ext2fs_mark_super_dirty(fs);
}
}
ctx->free_blocks = free_blocks;
ctx->free_inodes = free_inodes;
if ((ext2fs_free_blocks_count(sb) > ext2fs_blocks_count(sb)) ||
(sb->s_free_inodes_count > sb->s_inodes_count))

View File

@ -287,6 +287,7 @@ static int is_on_batt(void)
static void check_if_skip(e2fsck_t ctx)
{
ext2_filsys fs = ctx->fs;
struct problem_context pctx;
const char *reason = NULL;
unsigned int reason_arg = 0;
long next_check;
@ -349,6 +350,36 @@ static void check_if_skip(e2fsck_t ctx)
fputs(_(", check forced.\n"), stdout);
return;
}
/*
* Update the global counts from the block group counts. This
* is needed since modern kernels don't update the global
* counts so as to avoid locking the entire file system. So
* if the filesystem is not unmounted cleanly, the global
* counts may not be accurate. Update them here if we can,
* for the benefit of users who might examine the file system
* using dumpe2fs. (This is for cosmetic reasons only.)
*/
clear_problem_context(&pctx);
pctx.ino = fs->super->s_free_inodes_count;
pctx.ino2 = ctx->free_inodes;
if ((pctx.ino != pctx.ino2) &&
!(ctx->options & E2F_OPT_READONLY) &&
fix_problem(ctx, PR_0_FREE_INODE_COUNT, &pctx)) {
fs->super->s_free_inodes_count = ctx->free_inodes;
ext2fs_mark_super_dirty(fs);
}
clear_problem_context(&pctx);
pctx.blk = ext2fs_free_blocks_count(fs->super);
pctx.blk2 = ctx->free_blocks;
if ((pctx.blk != pctx.blk2) &&
!(ctx->options & E2F_OPT_READONLY) &&
fix_problem(ctx, PR_0_FREE_BLOCK_COUNT, &pctx)) {
ext2fs_free_blocks_count_set(fs->super, ctx->free_blocks);
ext2fs_mark_super_dirty(fs);
}
/* Print the summary message when we're skipping a full check */
printf(_("%s: clean, %u/%u files, %llu/%llu blocks"), ctx->device_name,
fs->super->s_inodes_count - fs->super->s_free_inodes_count,
fs->super->s_inodes_count,

View File

@ -39,6 +39,9 @@ Pass 5: Checking group summary information
Block bitmap differences: -22
Fix? yes
Free blocks count wrong (74, counted=75).
Fix? yes
Inode bitmap differences: -13
Fix? yes

View File

@ -27,7 +27,7 @@ Pass 5: Checking group summary information
Free blocks count wrong for group #0 (44, counted=60).
Fix? yes
Free blocks count wrong (44, counted=60).
Free blocks count wrong (62, counted=60).
Fix? yes
Padding at end of block bitmap is not set. Fix? yes

View File

@ -34,7 +34,7 @@ Pass 5: Checking group summary information
Free blocks count wrong for group #0 (8, counted=22).
Fix? yes
Free blocks count wrong (8, counted=22).
Free blocks count wrong (26, counted=22).
Fix? yes
Padding at end of block bitmap is not set. Fix? yes

View File

@ -8,9 +8,6 @@ Pass 5: Checking group summary information
Free blocks count wrong for group #0 (44, counted=63).
Fix? yes
Free blocks count wrong (44, counted=63).
Fix? yes
Padding at end of block bitmap is not set. Fix? yes

View File

@ -30,7 +30,7 @@ Fix? yes
Free blocks count wrong for group #0 (24, counted=33).
Fix? yes
Free blocks count wrong (24, counted=33).
Free blocks count wrong (38, counted=33).
Fix? yes
Inode bitmap differences: +13

View File

@ -7,18 +7,12 @@ Pass 5: Checking group summary information
Free blocks count wrong for group #0 (200, counted=80).
Fix? yes
Free blocks count wrong (200, counted=80).
Fix? yes
Free inodes count wrong for group #0 (250, counted=5).
Fix? yes
Directories count wrong for group #0 (150, counted=2).
Fix? yes
Free inodes count wrong (250, counted=5).
Fix? yes
test_filesys: ***** FILE SYSTEM WAS MODIFIED *****
test_filesys: 11/16 files (0.0% non-contiguous), 20/100 blocks

View File

@ -22,9 +22,6 @@ Fix? yes
Free inodes count wrong for group #1 (64, counted=58).
Fix? yes
Free inodes count wrong (117, counted=109).
Fix? yes
test_filesys: ***** FILE SYSTEM WAS MODIFIED *****
test_filesys: 19/128 files (0.0% non-contiguous), 165/1000 blocks