u32 block = bg->first_block + 2;
if (bg->has_superblock)
- block += aux_info.bg_desc_blocks + aux_info.bg_desc_reserve_blocks + 1;
+ block += aux_info.bg_desc_blocks + info.bg_desc_reserve_blocks + 1;
bg->inode_table = calloc(aux_info.inode_table_blocks, info.block_size);
if (bg->inode_table == NULL)
bg->has_superblock = ext4_bg_has_super_block(i);
if (bg->has_superblock)
- header_blocks += 1 + aux_info.bg_desc_blocks + aux_info.bg_desc_reserve_blocks;
+ header_blocks += 1 + aux_info.bg_desc_blocks + info.bg_desc_reserve_blocks;
bg->bitmaps = calloc(info.block_size, 2);
bg->block_bitmap = bg->bitmaps;
u32 block = bg->first_block;
if (bg->has_superblock)
- block += 1 + aux_info.bg_desc_blocks + aux_info.bg_desc_reserve_blocks;
+ block += 1 + aux_info.bg_desc_blocks + info.bg_desc_reserve_blocks;
queue_data_block(bg->bitmaps, 2 * info.block_size, block);
bg->data_blocks_used = 0;
DIV_ROUND_UP(aux_info.groups * sizeof(struct ext2_group_desc),
info.block_size);
- aux_info.bg_desc_reserve_blocks =
- DIV_ROUND_UP(aux_info.groups * 1024 * sizeof(struct ext2_group_desc),
- info.block_size) - aux_info.bg_desc_blocks;
-
- if (aux_info.bg_desc_reserve_blocks > aux_info.blocks_per_ind)
- aux_info.bg_desc_reserve_blocks = aux_info.blocks_per_ind;
-
aux_info.default_i_flags = EXT4_NOATIME_FL;
u32 last_group_size = aux_info.len_blocks % info.blocks_per_group;
u32 last_header_size = 2 + aux_info.inode_table_blocks;
if (ext4_bg_has_super_block(aux_info.groups - 1))
last_header_size += 1 + aux_info.bg_desc_blocks +
- aux_info.bg_desc_reserve_blocks;
+ info.bg_desc_reserve_blocks;
if (last_group_size > 0 && last_group_size < last_header_size) {
aux_info.groups--;
aux_info.len_blocks -= last_group_size;
memset(sb->s_last_mounted, 0, sizeof(sb->s_last_mounted));
sb->s_algorithm_usage_bitmap = 0;
- sb->s_reserved_gdt_blocks = aux_info.bg_desc_reserve_blocks;
+ sb->s_reserved_gdt_blocks = info.bg_desc_reserve_blocks;
sb->s_prealloc_blocks = 0;
sb->s_prealloc_dir_blocks = 0;
aux_info.bg_desc_blocks * info.block_size,
group_start_block + 1);
}
- header_size = 1 + aux_info.bg_desc_blocks + aux_info.bg_desc_reserve_blocks;
+ header_size = 1 + aux_info.bg_desc_blocks + info.bg_desc_reserve_blocks;
}
aux_info.bg_desc[i].bg_block_bitmap = group_start_block + header_size;
info.blocks_per_group;
u32 reserved_block_start = group_start_block + 1 +
aux_info.bg_desc_blocks;
- u32 reserved_block_len = aux_info.bg_desc_reserve_blocks;
+ u32 reserved_block_len = info.bg_desc_reserve_blocks;
append_region(reserve_inode_alloc, reserved_block_start,
reserved_block_len, i);
reserve_inode_len += reserved_block_len;
u16 feat_ro_compat;
u16 feat_compat;
u16 feat_incompat;
+ u32 bg_desc_reserve_blocks;
const char *label;
u8 no_journal;
};
u32 inode_table_blocks;
u32 groups;
u32 bg_desc_blocks;
- u32 bg_desc_reserve_blocks;
u32 default_i_flags;
u32 blocks_per_ind;
u32 blocks_per_dind;
struct block_allocation *alloc)
{
u32 block_len = block_allocation_len(alloc);
- u32 superblocks = block_len / aux_info.bg_desc_reserve_blocks;
+ u32 superblocks = block_len / info.bg_desc_reserve_blocks;
u32 i, j;
u64 blocks;
u64 size;
- if (block_len % aux_info.bg_desc_reserve_blocks)
+ if (block_len % info.bg_desc_reserve_blocks)
critical_error("reserved blocks not a multiple of %d",
- aux_info.bg_desc_reserve_blocks);
+ info.bg_desc_reserve_blocks);
append_oob_allocation(alloc, 1);
u32 dind_block = get_oob_block(alloc, 0);
critical_error_errno("calloc");
queue_data_block((u8 *)dind_block_data, info.block_size, dind_block);
- u32 *ind_block_data = calloc(info.block_size, aux_info.bg_desc_reserve_blocks);
+ u32 *ind_block_data = calloc(info.block_size, info.bg_desc_reserve_blocks);
if (!ind_block_data)
critical_error_errno("calloc");
queue_data_block((u8 *)ind_block_data,
- info.block_size * aux_info.bg_desc_reserve_blocks,
+ info.block_size * info.bg_desc_reserve_blocks,
get_block(alloc, 0));
- for (i = 0; i < aux_info.bg_desc_reserve_blocks; i++) {
- int r = (i - aux_info.bg_desc_blocks) % aux_info.bg_desc_reserve_blocks;
+ for (i = 0; i < info.bg_desc_reserve_blocks; i++) {
+ int r = (i - aux_info.bg_desc_blocks) % info.bg_desc_reserve_blocks;
if (r < 0)
- r += aux_info.bg_desc_reserve_blocks;
+ r += info.bg_desc_reserve_blocks;
dind_block_data[i] = get_block(alloc, r);
for (j = 1; j < superblocks; j++) {
- u32 b = j * aux_info.bg_desc_reserve_blocks + r;
+ u32 b = j * info.bg_desc_reserve_blocks + r;
ind_block_data[r * aux_info.blocks_per_ind + j - 1] = get_block(alloc, b);
}
}
u32 last_block = EXT4_NDIR_BLOCKS + aux_info.blocks_per_ind +
- aux_info.blocks_per_ind * (aux_info.bg_desc_reserve_blocks - 1) +
+ aux_info.blocks_per_ind * (info.bg_desc_reserve_blocks - 1) +
superblocks - 2;
blocks = ((u64)block_len + 1) * info.block_size / 512;
return DIV_ROUND_UP(info.inodes, block_groups);
}
+static u32 compute_bg_desc_reserve_blocks()
+{
+ u32 blocks = DIV_ROUND_UP(info.len, info.block_size);
+ u32 block_groups = DIV_ROUND_UP(blocks, info.blocks_per_group);
+ u32 bg_desc_blocks = DIV_ROUND_UP(block_groups * sizeof(struct ext2_group_desc),
+ info.block_size);
+
+ u32 bg_desc_reserve_blocks =
+ DIV_ROUND_UP(block_groups * 1024 * sizeof(struct ext2_group_desc),
+ info.block_size) - bg_desc_blocks;
+
+ if (bg_desc_reserve_blocks > info.block_size / sizeof(u32))
+ bg_desc_reserve_blocks = info.block_size / sizeof(u32);
+
+ return bg_desc_reserve_blocks;
+}
+
void reset_ext4fs_info() {
// Reset all the global data structures used by make_ext4fs so it
// can be called again.
EXT4_FEATURE_INCOMPAT_FILETYPE;
+ info.bg_desc_reserve_blocks = compute_bg_desc_reserve_blocks();
+
printf("Creating filesystem with parameters:\n");
printf(" Size: %llu\n", info.len);
printf(" Block size: %d\n", info.block_size);
printf(" Blocks: %llu\n", aux_info.len_blocks);
printf(" Block groups: %d\n", aux_info.groups);
- printf(" Reserved block group size: %d\n", aux_info.bg_desc_reserve_blocks);
+ printf(" Reserved block group size: %d\n", info.bg_desc_reserve_blocks);
block_allocator_init();