*
* Pass 1 is designed to stash away enough information so that the
* other passes should not need to read in the inode information
- * during the normal course of a filesystem check. (Althogh if an
+ * during the normal course of a filesystem check. (Although if an
* inconsistency is detected, other passes may need to read in an
* inode to fix it.)
*
struct problem_context *pctx;
ext2fs_block_bitmap fs_meta_blocks;
e2fsck_t ctx;
- region_t region;
+ blk64_t next_lblock;
struct extent_tree_info eti;
};
errcode_t retval;
char *tdb_dir;
int enable;
+ int full_map;
*ret = 0;
}
e2fsck_set_bitmap_type(ctx->fs, EXT2FS_BMAP64_RBTREE, icount_name,
&save_type);
+ if (ctx->options & E2F_OPT_ICOUNT_FULLMAP)
+ flags |= EXT2_ICOUNT_OPT_FULLMAP;
retval = ext2fs_create_icount2(ctx->fs, flags, 0, hint, ret);
ctx->fs->default_bitmap_type = save_type;
return retval;
/*
* Make sure the root inode is a directory; if
* not, offer to clear it. It will be
- * regnerated in pass #3.
+ * regenerated in pass #3.
*/
if (!LINUX_S_ISDIR(inode->i_mode)) {
if (fix_problem(ctx, PR_1_ROOT_NO_DIR, &pctx))
(1U << (21 - ctx->fs->super->s_log_block_size))))
problem = PR_1_TOOBIG_DIR;
- if (is_leaf && problem == 0 && extent.e_len > 0 &&
- region_allocate(pb->region, extent.e_lblk, extent.e_len))
- problem = PR_1_EXTENT_COLLISION;
+ if (is_leaf && problem == 0 && extent.e_len > 0) {
+#if 0
+ printf("extent_region(ino=%u, expect=%llu, "
+ "lblk=%llu, len=%u)\n",
+ pb->ino, pb->next_lblock,
+ extent.e_lblk, extent.e_len);
+#endif
+ if (extent.e_lblk < pb->next_lblock)
+ problem = PR_1_EXTENT_COLLISION;
+ else if (extent.e_lblk + extent.e_len > pb->next_lblock)
+ pb->next_lblock = extent.e_lblk + extent.e_len;
+ }
/*
* Uninitialized blocks in a directory? Clear the flag and
* will reallocate the block; then we can try again.
*/
if (pb->ino != EXT2_RESIZE_INO &&
+ extent.e_pblk < ctx->fs->super->s_blocks_count &&
ext2fs_test_block_bitmap2(ctx->block_metadata_map,
extent.e_pblk)) {
next_try_repairs = 0;
fix_problem(ctx,
PR_1_CRITICAL_METADATA_COLLISION,
pctx);
- ctx->flags |= E2F_FLAG_RESTART_LATER;
+ if ((ctx->options & E2F_OPT_NO) == 0)
+ ctx->flags |= E2F_FLAG_RESTART_LATER;
}
pctx->errcode = ext2fs_extent_get(ehandle,
EXT2_EXTENT_DOWN, &extent);
memset(pb->eti.ext_info, 0, sizeof(pb->eti.ext_info));
pb->eti.ino = pb->ino;
- pb->region = region_create(0, info.max_lblk);
- if (!pb->region) {
- ext2fs_extent_free(ehandle);
- fix_problem(ctx, PR_1_EXTENT_ALLOC_REGION_ABORT, pctx);
- ctx->flags |= E2F_FLAG_ABORT;
- return;
- }
+ pb->next_lblock = 0;
eof_lblk = ((EXT2_I_SIZE(inode) + fs->blocksize - 1) >>
EXT2_BLOCK_SIZE_BITS(fs->super)) - 1;
"check_blocks_extents");
pctx->errcode = 0;
}
- region_free(pb->region);
- pb->region = NULL;
ext2fs_extent_free(ehandle);
/* Rebuild unless it's a dir and we're rehashing it */
*/
if (blockcnt < 0 &&
p->ino != EXT2_RESIZE_INO &&
+ blk < ctx->fs->super->s_blocks_count &&
ext2fs_test_block_bitmap2(ctx->block_metadata_map, blk)) {
pctx->blk = blk;
fix_problem(ctx, PR_1_CRITICAL_METADATA_COLLISION, pctx);
- ctx->flags |= E2F_FLAG_RESTART_LATER;
+ if ((ctx->options & E2F_OPT_NO) == 0)
+ ctx->flags |= E2F_FLAG_RESTART_LATER;
}
if (problem) {
}
/*
- * Thes subroutines short circuits ext2fs_get_blocks and
+ * These subroutines short circuits ext2fs_get_blocks and
* ext2fs_check_directory; we use them since we already have the inode
* structure, so there's no point in letting the ext2fs library read
* the inode again.