mirror of https://github.com/vitalif/e2fsprogs
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
parent
52b1dd5e49
commit
2cd1233839
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue