e2fsck: Fix directory i_size handling

If a directory's i_size is bigger than the number of blocks, don't try
to allocate extra empty blocks to the end of the directory; there's no
real point to do that.  Also, if a directory's i_size is not a
multiple of the blocksize, flag that as a mistake so it can be fixed.

This more elegantly addresses the problem which was found on Bas van
Schaik's filesystem.

Signed-off-by: "Theodore Ts'o" <tytso@mit.edu>
bitmap-optimize
Theodore Ts'o 2008-03-13 00:58:54 -04:00
parent 52b1dd5e49
commit 2cd1233839
3 changed files with 35 additions and 5 deletions

View File

@ -1546,6 +1546,26 @@ static void check_blocks(e2fsck_t ctx, struct problem_context *pctx,
goto out;
}
if (pb.is_dir) {
while (1) {
struct ext2_db_entry *entry;
if (ext2fs_dblist_get_last(fs->dblist, &entry) ||
(entry->ino != ino) ||
(entry->blk != 0) ||
(entry->blockcnt == 0))
break;
/* printf("Dropping ino %lu blk %lu blockcnt %d\n",
entry->ino, entry->blk, entry->blockcnt); */
ext2fs_dblist_drop_last(fs->dblist);
if (ext2fs_dblist_get_last(fs->dblist, &entry) ||
(entry->ino != ino))
pb.last_block--;
else
pb.last_block = entry->blockcnt;
}
}
if (inode->i_flags & EXT2_INDEX_FL) {
if (handle_htree(ctx, pctx, ino, inode, block_buf)) {
inode->i_flags &= ~EXT2_INDEX_FL;
@ -1583,7 +1603,9 @@ static void check_blocks(e2fsck_t ctx, struct problem_context *pctx,
#endif
if (pb.is_dir) {
int nblock = inode->i_size >> EXT2_BLOCK_SIZE_BITS(fs->super);
if (nblock > (pb.last_block + 1))
if (inode->i_size & (fs->blocksize - 1))
bad_size = 5;
else if (nblock > (pb.last_block + 1))
bad_size = 1;
else if (nblock < (pb.last_block + 1)) {
if (((pb.last_block + 1) - nblock) >
@ -1745,6 +1767,7 @@ static int process_block(ext2_filsys fs,
printf("Missing block (#%d) in directory inode %lu!\n",
blockcnt, p->ino);
#endif
p->last_block = blockcnt;
goto mark_dir;
}
return 0;

View File

@ -15,12 +15,19 @@ Directory inode 11 has an unallocated block #3. Allocate? yes
Directory inode 11 has an unallocated block #6. Allocate? yes
Directory inode 11 has an unallocated block #11. Allocate? yes
Pass 3: Checking directory connectivity
Pass 4: Checking reference counts
Pass 5: Checking group summary information
Block bitmap differences: -21
Fix? yes
Free blocks count wrong for group #0 (78, counted=79).
Fix? yes
Free blocks count wrong (78, counted=79).
Fix? yes
test_filesys: ***** FILE SYSTEM WAS MODIFIED *****
test_filesys: 11/32 files (9.1% non-contiguous), 22/100 blocks
test_filesys: 11/32 files (9.1% non-contiguous), 21/100 blocks
Exit status is 1

View File

@ -3,5 +3,5 @@ Pass 2: Checking directory structure
Pass 3: Checking directory connectivity
Pass 4: Checking reference counts
Pass 5: Checking group summary information
test_filesys: 11/32 files (0.0% non-contiguous), 22/100 blocks
test_filesys: 11/32 files (0.0% non-contiguous), 21/100 blocks
Exit status is 0