e2fsck: clear uninit flag on directory extents

Directories can't have uninitialized extents, so offer to clear the
uninit flag when we find this situation.  The actual directory blocks
will be checked in pass 2 and 3 regardless of the uninit flag.

Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
Signed-off-by: Theodore Ts'o <tytso@mit.edu>
test-maint
Darrick J. Wong 2014-07-18 15:55:21 -07:00 committed by Theodore Ts'o
parent c28c2741ba
commit 57b7fabc2e
7 changed files with 71 additions and 3 deletions

View File

@ -1806,6 +1806,21 @@ static void scan_extent_node(e2fsck_t ctx, struct problem_context *pctx,
(1 << (21 - ctx->fs->super->s_log_block_size))))
problem = PR_1_TOOBIG_DIR;
/*
* Uninitialized blocks in a directory? Clear the flag and
* we'll interpret the blocks later.
*/
if (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;
}
if (problem) {
report_problem:
pctx->blk = extent.e_pblk;

View File

@ -972,6 +972,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

@ -565,6 +565,22 @@ struct problem_context {
#define PR_1_EXTENT_INDEX_START_INVALID 0x01006D
#define PR_1_EXTENT_END_OUT_OF_BOUNDS 0x01006E
/* Inode has inline data, but superblock is missing INLINE_DATA feature. */
#define PR_1_INLINE_DATA_FEATURE 0x01006F
/* INLINE_DATA feature is set in a non-inline-data filesystem */
#define PR_1_INLINE_DATA_SET 0x010070
/* 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
*/
@ -624,9 +640,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
*/

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