ctx->flags |= E2F_FLAG_ABORT;
return;
}
- pctx.errcode = ext2fs_allocate_block_bitmap(fs, _("in-use block map"),
- &ctx->block_found_map);
+ pctx.errcode = ext2fs_allocate_subcluster_bitmap(fs,
+ _("in-use block map"),
+ &ctx->block_found_map);
if (pctx.errcode) {
pctx.num = 1;
fix_problem(ctx, PR_1_ALLOCATE_BBITMAP_ERROR, &pctx);
}
mark_table_blocks(ctx);
+ pctx.errcode = ext2fs_convert_subcluster_bitmap(fs,
+ &ctx->block_found_map);
+ if (pctx.errcode) {
+ fix_problem(ctx, PR_1_CONVERT_SUBCLUSTER, &pctx);
+ ctx->flags |= E2F_FLAG_ABORT;
+ ext2fs_free_mem(&inode);
+ return;
+ }
block_buf = (char *) e2fsck_allocate_memory(ctx, fs->blocksize * 3,
"block interate buffer");
e2fsck_use_inode_shortcuts(ctx, 1);
for (blk = extent.e_pblk, blockcnt = extent.e_lblk, i = 0;
i < extent.e_len;
blk++, blockcnt++, i++) {
- mark_block_used(ctx, blk);
+ if (!(ctx->fs->cluster_ratio_bits &&
+ pb->previous_block &&
+ (EXT2FS_B2C(ctx->fs, blk) ==
+ EXT2FS_B2C(ctx->fs, pb->previous_block)) &&
+ (blk & EXT2FS_CLUSTER_MASK(ctx->fs)) ==
+ (blockcnt & EXT2FS_CLUSTER_MASK(ctx->fs))))
+ mark_block_used(ctx, blk);
+
+ pb->previous_block = blk;
if (is_dir) {
pctx->errcode = ext2fs_add_dir_block2(ctx->fs->dblist, pctx->ino, blk, blockcnt);
free_array = (int *) e2fsck_allocate_memory(ctx,
fs->group_desc_count * sizeof(int), "free block count array");
- if ((fs->super->s_first_data_block <
+ if ((EXT2FS_B2C(fs, fs->super->s_first_data_block) <
ext2fs_get_block_bitmap_start2(ctx->block_found_map)) ||
- (ext2fs_blocks_count(fs->super)-1 >
+ (EXT2FS_B2C(fs, ext2fs_blocks_count(fs->super)-1) >
ext2fs_get_block_bitmap_end2(ctx->block_found_map))) {
pctx.num = 1;
- pctx.blk = fs->super->s_first_data_block;
- pctx.blk2 = ext2fs_blocks_count(fs->super) -1;
+ pctx.blk = EXT2FS_B2C(fs, fs->super->s_first_data_block);
+ pctx.blk2 = EXT2FS_B2C(fs, ext2fs_blocks_count(fs->super) - 1);
pctx.ino = ext2fs_get_block_bitmap_start2(ctx->block_found_map);
pctx.ino2 = ext2fs_get_block_bitmap_end2(ctx->block_found_map);
fix_problem(ctx, PR_5_BMAP_ENDPOINTS, &pctx);
goto errout;
}
- if ((fs->super->s_first_data_block <
+ if ((EXT2FS_B2C(fs, fs->super->s_first_data_block) <
ext2fs_get_block_bitmap_start2(fs->block_map)) ||
- (ext2fs_blocks_count(fs->super)-1 >
+ (EXT2FS_B2C(fs, ext2fs_blocks_count(fs->super)-1) >
ext2fs_get_block_bitmap_end2(fs->block_map))) {
pctx.num = 2;
- pctx.blk = fs->super->s_first_data_block;
- pctx.blk2 = ext2fs_blocks_count(fs->super) -1;
+ pctx.blk = EXT2FS_B2C(fs, fs->super->s_first_data_block);
+ pctx.blk2 = EXT2FS_B2C(fs, ext2fs_blocks_count(fs->super) - 1);
pctx.ino = ext2fs_get_block_bitmap_start2(fs->block_map);
pctx.ino2 = ext2fs_get_block_bitmap_end2(fs->block_map);
fix_problem(ctx, PR_5_BMAP_ENDPOINTS, &pctx);
if (csum_flag &&
(ext2fs_bg_flags_test(fs, group, EXT2_BG_BLOCK_UNINIT)))
skip_group++;
- for (i = fs->super->s_first_data_block;
+ for (i = EXT2FS_B2C(fs, fs->super->s_first_data_block);
i < ext2fs_blocks_count(fs->super);
- i++) {
+ i += EXT2FS_CLUSTER_RATIO(fs)) {
actual = ext2fs_fast_test_block_bitmap2(ctx->block_found_map, i);
if (skip_group) {
first_free = ext2fs_blocks_count(fs->super);
}
blocks ++;
- if ((blocks == fs->super->s_blocks_per_group) ||
- (i == ext2fs_blocks_count(fs->super)-1)) {
+ if ((blocks == fs->super->s_clusters_per_group) ||
+ (EXT2FS_B2C(fs, i) ==
+ EXT2FS_B2C(fs, ext2fs_blocks_count(fs->super)-1))) {
free_array[group] = group_free;
group ++;
blocks = 0;
clear_problem_context(&pctx);
end = ext2fs_get_block_bitmap_start2(fs->block_map) +
- ((blk64_t)EXT2_BLOCKS_PER_GROUP(fs->super) * fs->group_desc_count) - 1;
+ ((blk64_t)EXT2_CLUSTERS_PER_GROUP(fs->super) * fs->group_desc_count) - 1;
pctx.errcode = ext2fs_fudge_block_bitmap_end2(fs->block_map, end,
&save_blocks_count);
if (pctx.errcode) {
/* Protect loop from wrap-around if end is maxed */
for (i = save_blocks_count + 1; i <= end && i > save_blocks_count; i++) {
- if (!ext2fs_test_block_bitmap2(fs->block_map, i)) {
+ if (!ext2fs_test_block_bitmap2(fs->block_map,
+ EXT2FS_C2B(fs, i))) {
if (fix_problem(ctx, PR_5_BLOCK_BMAP_PADDING, &pctx)) {
for (; i <= end; i++)
ext2fs_mark_block_bitmap2(fs->block_map,
- i);
+ EXT2FS_C2B(fs, i));
ext2fs_mark_bb_dirty(fs);
} else
ext2fs_unmark_valid(fs);
"(size %Is, lblk %r)\n"),
PROMPT_CLEAR, PR_PREEN_OK },
+ /* Failed to convert subcluster bitmap */
+ { PR_1_CONVERT_SUBCLUSTER,
+ N_("Error converting subcluster @b @B: %m\n"),
+ PROMPT_NONE, PR_FATAL },
+
/* Pass 1b errors */
/* Pass 1B: Rescan for duplicate/bad blocks */
/* EOFBLOCKS flag set when not necessary */
#define PR_1_EOFBLOCKS_FL_SET 0x010060
+/* Failed to convert subcluster bitmap */
+#define PR_1_CONVERT_SUBCLUSTER 0x010061
+
/*
* Pass 1b errors
*/
struct ext2_super_block *sb = fs->super;
problem_t problem;
blk64_t blocks_per_group = fs->super->s_blocks_per_group;
- __u32 bpg_max;
+ __u32 bpg_max, cpg_max;
int inodes_per_block;
int ipg_max;
int inode_size;
ipg_max = inodes_per_block * (blocks_per_group - 4);
if (ipg_max > EXT2_MAX_INODES_PER_GROUP(sb))
ipg_max = EXT2_MAX_INODES_PER_GROUP(sb);
- bpg_max = 8 * EXT2_BLOCK_SIZE(sb);
+ cpg_max = 8 * EXT2_BLOCK_SIZE(sb);
+ if (cpg_max > EXT2_MAX_CLUSTERS_PER_GROUP(sb))
+ cpg_max = EXT2_MAX_CLUSTERS_PER_GROUP(sb);
+ bpg_max = 8 * EXT2_BLOCK_SIZE(sb) * EXT2FS_CLUSTER_RATIO(fs);
if (bpg_max > EXT2_MAX_BLOCKS_PER_GROUP(sb))
bpg_max = EXT2_MAX_BLOCKS_PER_GROUP(sb);
(EXT2_MAX_CLUSTER_LOG_SIZE -
EXT2_MIN_CLUSTER_LOG_SIZE));
check_super_value(ctx, "clusters_per_group", sb->s_clusters_per_group,
- MIN_CHECK | MAX_CHECK, sb->s_blocks_per_group,
- bpg_max);
+ MIN_CHECK | MAX_CHECK, 8, cpg_max);
check_super_value(ctx, "blocks_per_group", sb->s_blocks_per_group,
MIN_CHECK | MAX_CHECK, 8, bpg_max);
check_super_value(ctx, "inodes_per_group", sb->s_inodes_per_group,
check_super_value(ctx, "inode_size",
inode_size, MIN_CHECK | MAX_CHECK,
EXT2_GOOD_OLD_INODE_SIZE, fs->blocksize);
+ if (sb->s_blocks_per_group != (sb->s_clusters_per_group *
+ EXT2FS_CLUSTER_RATIO(fs))) {
+ pctx.num = sb->s_clusters_per_group * EXT2FS_CLUSTER_RATIO(fs);
+ pctx.str = "block_size";
+ fix_problem(ctx, PR_0_MISC_CORRUPT_SUPER, &pctx);
+ ctx->flags |= E2F_FLAG_ABORT; /* never get here! */
+ return;
+ }
if (inode_size & (inode_size - 1)) {
pctx.num = inode_size;
pctx.str = "inode_size";
}
}
- if (sb->s_log_block_size != (__u32) sb->s_log_cluster_size) {
- pctx.blk = EXT2_BLOCK_SIZE(sb);
- pctx.blk2 = EXT2_CLUSTER_SIZE(sb);
- fix_problem(ctx, PR_0_NO_FRAGMENTS, &pctx);
- ctx->flags |= E2F_FLAG_ABORT;
- return;
- }
-
should_be = (sb->s_log_block_size == 0) ? 1 : 0;
if (sb->s_first_data_block != should_be) {
pctx.blk = sb->s_first_data_block;
EXT2_CHECK_MAGIC(fs, EXT2_ET_MAGIC_EXT2FS_FILSYS);
- retval = ext2fs_allocate_block_bitmap(fs, "check_desc map", &bmap);
+ retval = ext2fs_allocate_subcluster_bitmap(fs, "check_desc map", &bmap);
if (retval)
return retval;
EXT2_FEATURE_RO_COMPAT_LARGE_FILE|\
EXT4_FEATURE_RO_COMPAT_DIR_NLINK|\
EXT4_FEATURE_RO_COMPAT_EXTRA_ISIZE|\
- EXT4_FEATURE_RO_COMPAT_GDT_CSUM)
+ EXT4_FEATURE_RO_COMPAT_GDT_CSUM|\
+ EXT4_FEATURE_RO_COMPAT_BIGALLOC)
/*
* These features are only allowed if EXT2_FLAG_SOFTSUPP_FEATURES is passed