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;
|
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 (inode->i_flags & EXT2_INDEX_FL) {
|
||||||
if (handle_htree(ctx, pctx, ino, inode, block_buf)) {
|
if (handle_htree(ctx, pctx, ino, inode, block_buf)) {
|
||||||
inode->i_flags &= ~EXT2_INDEX_FL;
|
inode->i_flags &= ~EXT2_INDEX_FL;
|
||||||
|
@ -1583,7 +1603,9 @@ static void check_blocks(e2fsck_t ctx, struct problem_context *pctx,
|
||||||
#endif
|
#endif
|
||||||
if (pb.is_dir) {
|
if (pb.is_dir) {
|
||||||
int nblock = inode->i_size >> EXT2_BLOCK_SIZE_BITS(fs->super);
|
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;
|
bad_size = 1;
|
||||||
else if (nblock < (pb.last_block + 1)) {
|
else if (nblock < (pb.last_block + 1)) {
|
||||||
if (((pb.last_block + 1) - nblock) >
|
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",
|
printf("Missing block (#%d) in directory inode %lu!\n",
|
||||||
blockcnt, p->ino);
|
blockcnt, p->ino);
|
||||||
#endif
|
#endif
|
||||||
|
p->last_block = blockcnt;
|
||||||
goto mark_dir;
|
goto mark_dir;
|
||||||
}
|
}
|
||||||
return 0;
|
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 #6. Allocate? yes
|
||||||
|
|
||||||
Directory inode 11 has an unallocated block #11. Allocate? yes
|
|
||||||
|
|
||||||
Pass 3: Checking directory connectivity
|
Pass 3: Checking directory connectivity
|
||||||
Pass 4: Checking reference counts
|
Pass 4: Checking reference counts
|
||||||
Pass 5: Checking group summary information
|
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: ***** 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
|
Exit status is 1
|
||||||
|
|
|
@ -3,5 +3,5 @@ Pass 2: Checking directory structure
|
||||||
Pass 3: Checking directory connectivity
|
Pass 3: Checking directory connectivity
|
||||||
Pass 4: Checking reference counts
|
Pass 4: Checking reference counts
|
||||||
Pass 5: Checking group summary information
|
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
|
Exit status is 0
|
||||||
|
|
Loading…
Reference in New Issue