e2fsck: Detect unordered extents in an extent node

The logical block numbers must be monotonically increasing, and there
must not be any overlapping extents.  If any are found, report them as
filesystem corruption.

Signed-off-by: "Theodore Ts'o" <tytso@mit.edu>
This commit is contained in:
Theodore Ts'o 2008-06-02 20:12:34 -04:00
parent 16bd349e1f
commit d5a8f9a9f2
3 changed files with 15 additions and 4 deletions

View File

@ -1613,7 +1613,8 @@ void e2fsck_clear_inode(e2fsck_t ctx, ext2_ino_t ino,
} }
static void scan_extent_node(e2fsck_t ctx, struct problem_context *pctx, static void scan_extent_node(e2fsck_t ctx, struct problem_context *pctx,
struct process_block_struct *pb, struct process_block_struct *pb,
blk64_t start_block,
ext2_extent_handle_t ehandle) ext2_extent_handle_t ehandle)
{ {
struct ext2fs_extent extent; struct ext2fs_extent extent;
@ -1638,6 +1639,8 @@ static void scan_extent_node(e2fsck_t ctx, struct problem_context *pctx,
if (extent.e_pblk < ctx->fs->super->s_first_data_block || if (extent.e_pblk < ctx->fs->super->s_first_data_block ||
extent.e_pblk >= ctx->fs->super->s_blocks_count) extent.e_pblk >= ctx->fs->super->s_blocks_count)
problem = PR_1_EXTENT_BAD_START_BLK; problem = PR_1_EXTENT_BAD_START_BLK;
else if (extent.e_lblk < start_block)
problem = PR_1_OUT_OF_ORDER_EXTENTS;
else if (is_leaf && else if (is_leaf &&
(extent.e_pblk + extent.e_len) > (extent.e_pblk + extent.e_len) >
ctx->fs->super->s_blocks_count) ctx->fs->super->s_blocks_count)
@ -1680,7 +1683,7 @@ static void scan_extent_node(e2fsck_t ctx, struct problem_context *pctx,
error_message(pctx->errcode), pctx->ino); error_message(pctx->errcode), pctx->ino);
abort(); abort();
} }
scan_extent_node(ctx, pctx, pb, ehandle); scan_extent_node(ctx, pctx, pb, extent.e_lblk, ehandle);
pctx->errcode = ext2fs_extent_get(ehandle, pctx->errcode = ext2fs_extent_get(ehandle,
EXT2_EXTENT_UP, &extent); EXT2_EXTENT_UP, &extent);
if (pctx->errcode) { if (pctx->errcode) {
@ -1709,7 +1712,7 @@ static void scan_extent_node(e2fsck_t ctx, struct problem_context *pctx,
} }
} }
pb->num_blocks += extent.e_len; pb->num_blocks += extent.e_len;
pb->last_block = extent.e_lblk + extent.e_len - 1; start_block = pb->last_block = extent.e_lblk + extent.e_len - 1;
next: next:
pctx->errcode = ext2fs_extent_get(ehandle, pctx->errcode = ext2fs_extent_get(ehandle,
EXT2_EXTENT_NEXT_SIB, EXT2_EXTENT_NEXT_SIB,
@ -1736,7 +1739,7 @@ static void check_blocks_extents(e2fsck_t ctx, struct problem_context *pctx,
return; return;
} }
scan_extent_node(ctx, pctx, pb, ehandle); scan_extent_node(ctx, pctx, pb, 0, ehandle);
ext2fs_extent_free(ehandle); ext2fs_extent_free(ehandle);
} }

View File

@ -849,6 +849,11 @@ static struct e2fsck_problem problem_table[] = {
N_("Fast symlink %i has EXTENT_FL set. "), N_("Fast symlink %i has EXTENT_FL set. "),
PROMPT_CLEAR, 0 }, PROMPT_CLEAR, 0 },
/* Extents are out of order */
{ PR_1_OUT_OF_ORDER_EXTENTS,
N_("@i %i has out of order extents\n\t(@n logical @b %c, physical @b %b, len %N)\n"),
PROMPT_CLEAR, 0 },
/* Pass 1b errors */ /* Pass 1b errors */
/* Pass 1B: Rescan for duplicate/bad blocks */ /* Pass 1B: Rescan for duplicate/bad blocks */

View File

@ -494,6 +494,9 @@ struct problem_context {
/* Fast symlink has EXTENTS_FL set */ /* Fast symlink has EXTENTS_FL set */
#define PR_1_FAST_SYMLINK_EXTENT_FL 0x01005D #define PR_1_FAST_SYMLINK_EXTENT_FL 0x01005D
/* Extents are out of order */
#define PR_1_OUT_OF_ORDER_EXTENTS 0x01005E
/* /*
* Pass 1b errors * Pass 1b errors
*/ */