Whamcloud - gitweb
Merge branch 'maint' into next
[tools/e2fsprogs.git] / e2fsck / pass1.c
index ba6025b..24b2e16 100644 (file)
@@ -1849,6 +1849,7 @@ 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,
                             blk64_t start_block, blk64_t end_block,
+                            blk64_t eof_block,
                             ext2_extent_handle_t ehandle)
 {
        struct ext2fs_extent    extent;
@@ -1892,7 +1893,9 @@ static void scan_extent_node(e2fsck_t ctx, struct problem_context *pctx,
                        problem = PR_1_EXTENT_BAD_START_BLK;
                else if (extent.e_lblk < start_block)
                        problem = PR_1_OUT_OF_ORDER_EXTENTS;
-               else if (end_block && last_lblk > end_block)
+               else if ((end_block && last_lblk > end_block) &&
+                        (!(extent.e_flags & EXT2_EXTENT_FLAGS_UNINIT &&
+                               last_lblk > eof_block)))
                        problem = PR_1_EXTENT_END_OUT_OF_BOUNDS;
                else if (is_leaf && extent.e_len == 0)
                        problem = PR_1_EXTENT_LENGTH_ZERO;
@@ -1900,6 +1903,10 @@ static void scan_extent_node(e2fsck_t ctx, struct problem_context *pctx,
                         (extent.e_pblk + extent.e_len) >
                         ext2fs_blocks_count(ctx->fs->super))
                        problem = PR_1_EXTENT_ENDS_BEYOND;
+               else if (is_leaf && is_dir &&
+                        ((extent.e_lblk + extent.e_len) >
+                         (1 << (21 - ctx->fs->super->s_log_block_size))))
+                       problem = PR_1_TOOBIG_DIR;
 
                /* Corrupt but passes checks?  Ask to fix checksum. */
                if (failed_csum) {
@@ -1917,6 +1924,7 @@ report_problem:
                        pctx->blk = extent.e_pblk;
                        pctx->blk2 = extent.e_lblk;
                        pctx->num = extent.e_len;
+                       pctx->blkcount = extent.e_lblk + extent.e_len;
                        if (fix_problem(ctx, problem, pctx)) {
 fix_problem_now:
                                e2fsck_read_bitmaps(ctx);
@@ -1968,7 +1976,7 @@ fix_problem_now:
                                        ext2fs_extent_fix_parents(ehandle);
                        }
                        scan_extent_node(ctx, pctx, pb, extent.e_lblk,
-                                        last_lblk, ehandle);
+                                        last_lblk, eof_block, ehandle);
                        if (pctx->errcode)
                                return;
                        pctx->errcode = ext2fs_extent_get(ehandle,
@@ -2071,6 +2079,7 @@ static void check_blocks_extents(e2fsck_t ctx, struct problem_context *pctx,
        ext2_filsys             fs = ctx->fs;
        ext2_ino_t              ino = pctx->ino;
        errcode_t               retval;
+       blk64_t                 eof_lblk;
 
        pctx->errcode = ext2fs_extent_open2(fs, ino, inode, &ehandle);
        if (pctx->errcode) {
@@ -2088,7 +2097,9 @@ static void check_blocks_extents(e2fsck_t ctx, struct problem_context *pctx,
                ctx->extent_depth_count[info.max_depth]++;
        }
 
-       scan_extent_node(ctx, pctx, pb, 0, 0, ehandle);
+       eof_lblk = ((EXT2_I_SIZE(inode) + fs->blocksize - 1) >>
+               EXT2_BLOCK_SIZE_BITS(fs->super)) - 1;
+       scan_extent_node(ctx, pctx, pb, 0, 0, eof_lblk, ehandle);
        if (pctx->errcode &&
            fix_problem(ctx, PR_1_EXTENT_ITERATE_FAILURE, pctx)) {
                pb->num_blocks = 0;