From: Theodore Ts'o Date: Tue, 3 Jun 2008 00:12:34 +0000 (-0400) Subject: e2fsck: Detect unordered extents in an extent node X-Git-Tag: v1.41-WIP-0617~28 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=d5a8f9a9f25a85b69335915e5dac2a359334b5d7;p=thirdparty%2Fe2fsprogs.git 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" --- diff --git a/e2fsck/pass1.c b/e2fsck/pass1.c index 73403848c..ee5749761 100644 --- a/e2fsck/pass1.c +++ b/e2fsck/pass1.c @@ -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, - struct process_block_struct *pb, + struct process_block_struct *pb, + blk64_t start_block, ext2_extent_handle_t ehandle) { 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 || extent.e_pblk >= ctx->fs->super->s_blocks_count) 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 && (extent.e_pblk + extent.e_len) > 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); abort(); } - scan_extent_node(ctx, pctx, pb, ehandle); + scan_extent_node(ctx, pctx, pb, extent.e_lblk, ehandle); pctx->errcode = ext2fs_extent_get(ehandle, EXT2_EXTENT_UP, &extent); 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->last_block = extent.e_lblk + extent.e_len - 1; + start_block = pb->last_block = extent.e_lblk + extent.e_len - 1; next: pctx->errcode = ext2fs_extent_get(ehandle, EXT2_EXTENT_NEXT_SIB, @@ -1736,7 +1739,7 @@ static void check_blocks_extents(e2fsck_t ctx, struct problem_context *pctx, return; } - scan_extent_node(ctx, pctx, pb, ehandle); + scan_extent_node(ctx, pctx, pb, 0, ehandle); ext2fs_extent_free(ehandle); } diff --git a/e2fsck/problem.c b/e2fsck/problem.c index d9ae9115c..81ad9b0ee 100644 --- a/e2fsck/problem.c +++ b/e2fsck/problem.c @@ -849,6 +849,11 @@ static struct e2fsck_problem problem_table[] = { N_("Fast symlink %i has EXTENT_FL set. "), 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: Rescan for duplicate/bad blocks */ diff --git a/e2fsck/problem.h b/e2fsck/problem.h index ab5c4df7b..5f90a1801 100644 --- a/e2fsck/problem.h +++ b/e2fsck/problem.h @@ -494,6 +494,9 @@ struct problem_context { /* Fast symlink has EXTENTS_FL set */ #define PR_1_FAST_SYMLINK_EXTENT_FL 0x01005D +/* Extents are out of order */ +#define PR_1_OUT_OF_ORDER_EXTENTS 0x01005E + /* * Pass 1b errors */