Merge branch 'maint' into next

Conflicts:
	e2fsck/pass1.c
	e2fsck/problem.h
crypto
Theodore Ts'o 2014-07-25 08:58:10 -04:00
commit e05a05630a
15 changed files with 134 additions and 3 deletions

View File

@ -1983,6 +1983,22 @@ static void scan_extent_node(e2fsck_t ctx, struct problem_context *pctx,
}
}
/*
* Uninitialized blocks in a directory? Clear the flag and
* we'll interpret the blocks later.
*/
if (try_repairs && is_dir && problem == 0 &&
(extent.e_flags & EXT2_EXTENT_FLAGS_UNINIT) &&
fix_problem(ctx, PR_1_UNINIT_DBLOCK, pctx)) {
extent.e_flags &= ~EXT2_EXTENT_FLAGS_UNINIT;
pb->inode_modified = 1;
pctx->errcode = ext2fs_extent_replace(ehandle, 0,
&extent);
if (pctx->errcode)
return;
failed_csum = 0;
}
if (try_repairs && problem) {
report_problem:
pctx->blk = extent.e_pblk;
@ -2619,6 +2635,21 @@ static int process_block(ext2_filsys fs,
return 0;
}
/*
* For a directory, add logical block zero for processing even if it's
* not mapped or we'll be perennially stuck with broken "." and ".."
* entries.
*/
if (p->is_dir && blockcnt == 0 && blk == 0) {
pctx->errcode = ext2fs_add_dir_block2(fs->dblist, p->ino, 0, 0);
if (pctx->errcode) {
pctx->blk = blk;
pctx->num = blockcnt;
goto failed_add_dir_block;
}
p->last_db_block++;
}
if (blk == 0)
return 0;
@ -2710,6 +2741,17 @@ static int process_block(ext2_filsys fs,
blk = *block_nr = 0;
ret_code = BLOCK_CHANGED;
p->inode_modified = 1;
/*
* If the directory block is too big and is beyond the
* end of the FS, don't bother trying to add it for
* processing -- the kernel would never have created a
* directory this large, and we risk an ENOMEM abort.
* In any case, the toobig handler for extent-based
* directories also doesn't feed toobig blocks to
* pass 2.
*/
if (problem == PR_1_TOOBIG_DIR)
return ret_code;
goto mark_dir;
} else
return 0;

View File

@ -1043,6 +1043,11 @@ static struct e2fsck_problem problem_table[] = {
N_("@d @i %i @b %b should be at @b %c. "),
PROMPT_FIX, 0 },
/* Extents/inlinedata flag set on a device or socket inode */
{ PR_1_UNINIT_DBLOCK,
N_("@d @i %i has @x marked uninitialized at @b %c. "),
PROMPT_FIX, PR_PREEN_OK },
/* Pass 1b errors */
/* Pass 1B: Rescan for duplicate/bad blocks */

View File

@ -603,6 +603,12 @@ struct problem_context {
/* file metadata collides with critical metadata */
#define PR_1_CRITICAL_METADATA_COLLISION 0x010071
/* Directory inode has a missing block (hole) */
#define PR_1_COLLAPSE_DBLOCK 0x010072
/* uninit directory block */
#define PR_1_UNINIT_DBLOCK 0x010073
/*
* Pass 1b errors
*/
@ -665,9 +671,6 @@ struct problem_context {
/* Couldn't clone file (error) */
#define PR_1D_CLONE_ERROR 0x013008
/* Directory inode has a missing block (hole) */
#define PR_1_COLLAPSE_DBLOCK 0x010072
/*
* Pass 2 errors
*/

19
tests/f_emptydir/expect.1 Normal file
View File

@ -0,0 +1,19 @@
Pass 1: Checking inodes, blocks, and sizes
Inode 12, i_size is 1024, should be 0. Fix? yes
Pass 2: Checking directory structure
Directory inode 12 has an unallocated block #0. Allocate? yes
Pass 3: Checking directory connectivity
Pass 4: Checking reference counts
Pass 5: Checking group summary information
Free blocks count wrong for group #0 (957, counted=956).
Fix? yes
Free blocks count wrong (957, counted=956).
Fix? yes
test_filesys: ***** FILE SYSTEM WAS MODIFIED *****
test_filesys: 12/256 files (8.3% non-contiguous), 1092/2048 blocks
Exit status is 1

View File

@ -0,0 +1,7 @@
Pass 1: Checking inodes, blocks, and sizes
Pass 2: Checking directory structure
Pass 3: Checking directory connectivity
Pass 4: Checking reference counts
Pass 5: Checking group summary information
test_filesys: 12/256 files (16.7% non-contiguous), 1092/2048 blocks
Exit status is 0

BIN
tests/f_emptydir/image.gz Normal file

Binary file not shown.

2
tests/f_emptydir/name Normal file
View File

@ -0,0 +1,2 @@
always iterate dir block 0 or e2fsck goes into infinite loop

View File

@ -0,0 +1,10 @@
Pass 1: Checking inodes, blocks, and sizes
Inode 12 is too big. Truncate? yes
Block #1074791435 (13) causes directory to be too big. CLEARED.
Pass 2: Checking directory structure
Pass 3: Checking directory connectivity
Pass 4: Checking reference counts
Pass 5: Checking group summary information
test_filesys: 12/128 files (8.3% non-contiguous), 22/512 blocks
Exit status is 0

View File

@ -0,0 +1,7 @@
Pass 1: Checking inodes, blocks, and sizes
Pass 2: Checking directory structure
Pass 3: Checking directory connectivity
Pass 4: Checking reference counts
Pass 5: Checking group summary information
test_filesys: 12/128 files (8.3% non-contiguous), 22/512 blocks
Exit status is 0

Binary file not shown.

View File

@ -0,0 +1 @@
crash e2fsck with a dir with an impossibly high logical blk offset

View File

@ -0,0 +1,27 @@
Pass 1: Checking inodes, blocks, and sizes
Directory inode 12 has extent marked uninitialized at block 0. Fix? yes
Directory inode 14 has extent marked uninitialized at block 0. Fix? yes
Pass 2: Checking directory structure
Directory inode 14, block #0, offset 0: directory corrupted
Salvage? yes
Missing '.' in directory inode 14.
Fix? yes
Setting filetype for entry '.' in ??? (14) to 2.
Missing '..' in directory inode 14.
Fix? yes
Setting filetype for entry '..' in ??? (14) to 2.
Pass 3: Checking directory connectivity
'..' in /abc (14) is <The NULL inode> (0), should be / (2).
Fix? yes
Pass 4: Checking reference counts
Pass 5: Checking group summary information
test_filesys: ***** FILE SYSTEM WAS MODIFIED *****
test_filesys: 14/128 files (0.0% non-contiguous), 20/512 blocks
Exit status is 1

View File

@ -0,0 +1,7 @@
Pass 1: Checking inodes, blocks, and sizes
Pass 2: Checking directory structure
Pass 3: Checking directory connectivity
Pass 4: Checking reference counts
Pass 5: Checking group summary information
test_filesys: 14/128 files (0.0% non-contiguous), 20/512 blocks
Exit status is 0

BIN
tests/f_uninit_dir/image.gz Normal file

Binary file not shown.

1
tests/f_uninit_dir/name Normal file
View File

@ -0,0 +1 @@
fix uninit flag on directory extents and check the dir blocks