info->bg_desc_reserve_blocks = to_le16(sb->s_reserved_gdt_blocks);
info->label = sb->volume_name;
info->len = (uint64_t)info->block_size * ext4_sb_get_blocks_cnt(sb);
+ info->dsc_size = to_le16(sb->desc_size);
return EOK;
}
aux_info->blocks_per_dind * aux_info->blocks_per_dind;
aux_info->bg_desc_blocks =
- DIV_ROUND_UP(aux_info->groups * sizeof(struct ext4_bgroup),
+ DIV_ROUND_UP(aux_info->groups * info->dsc_size,
info->block_size);
aux_info->default_i_flags = EXT4_INODE_FLAG_NOATIME;
uint32_t blk_off = 0;
bg_free_blk = info->blocks_per_group -
- (aux_info->inode_table_blocks + aux_info->bg_desc_blocks);
+ aux_info->inode_table_blocks;
bg_free_blk -= 2;
blk_off += aux_info->bg_desc_blocks;
+ if (i == (aux_info->groups - 1))
+ bg_free_blk -= aux_info->first_data_block;
+
if (has_superblock(info, i)) {
bg_start_block++;
blk_off += info->bg_desc_reserve_blocks;
bg_free_blk -= info->bg_desc_reserve_blocks + 1;
- } else {
- bg_free_blk++;
+ bg_free_blk -= aux_info->bg_desc_blocks;
}
ext4_bg_set_block_bitmap(&aux_info->bg_desc[i], aux_info->sb,
struct ext4_block b;
for (i = 0; i < aux_info->groups; i++) {
uint64_t bg_start_block = aux_info->first_data_block +
- aux_info->first_data_block + i * info->blocks_per_group;
+ + i * info->blocks_per_group;
uint32_t blk_off = 0;
blk_off += aux_info->bg_desc_blocks;
if (r != EOK)
return r;
- while (dsc_pos + dsc_size < block_size) {
+ dsc_pos = 0;
+ while (dsc_pos + dsc_size <= block_size) {
memcpy(b.data + dsc_pos,
&aux_info->bg_desc[dsc_id],
dsc_size);
dsc_pos += dsc_size;
dsc_id++;
+
+ if (dsc_id == aux_info->groups)
+ break;
}
b.dirty = true;
r = ext4_block_set(bd, &b);
if (r != EOK)
return r;
+
+ if (dsc_id == aux_info->groups)
+ break;
}
r = ext4_block_get_noread(bd, &b, bg_start_block + blk_off + 1);
offset = info->block_size * (aux_info->first_data_block
+ i * info->blocks_per_group);
- aux_info->sb->block_group_index = i;
+ aux_info->sb->block_group_index = to_le16(i);
r = ext4_block_writebytes(bd, offset, aux_info->sb,
EXT4_SUPERBLOCK_SIZE);
if (r != EOK)
}
/* write out the primary superblock */
- aux_info->sb->block_group_index = 0;
+ aux_info->sb->block_group_index = to_le16(0);
return ext4_block_writebytes(bd, 1024, aux_info->sb,
EXT4_SUPERBLOCK_SIZE);
}
}
int ext4_mkfs(struct ext4_fs *fs, struct ext4_blockdev *bd,
- struct ext4_mkfs_info *info)
+ struct ext4_mkfs_info *info, int fs_type)
{
int r;
info->inodes_per_group = compute_inodes_per_group(info);
- info->feat_compat = EXT4_SUPPORTED_FCOM;
- info->feat_ro_compat = EXT4_SUPPORTED_FRO_COM;
- info->feat_incompat = EXT4_SUPPORTED_FINCOM;
+ switch (fs_type) {
+ case F_SET_EXT2:
+ info->feat_compat = EXT2_SUPPORTED_FCOM;
+ info->feat_ro_compat = EXT2_SUPPORTED_FRO_COM;
+ info->feat_incompat = EXT2_SUPPORTED_FINCOM;
+ break;
+ case F_SET_EXT3:
+ info->feat_compat = EXT3_SUPPORTED_FCOM;
+ info->feat_ro_compat = EXT3_SUPPORTED_FRO_COM;
+ info->feat_incompat = EXT3_SUPPORTED_FINCOM;
+ break;
+ case F_SET_EXT4:
+ info->feat_compat = EXT4_SUPPORTED_FCOM;
+ info->feat_ro_compat = EXT4_SUPPORTED_FRO_COM;
+ info->feat_incompat = EXT4_SUPPORTED_FINCOM;
+ break;
+ }
/*TODO: handle this features*/
info->feat_incompat &= ~EXT4_FINCOM_META_BG;
info->feat_incompat &= ~EXT4_FINCOM_FLEX_BG;
info->feat_ro_compat &= ~EXT4_FRO_COM_METADATA_CSUM;
- if (info->no_journal == 0)
+ /*TODO: handle journal feature & inode*/
+ if (info->journal == 0)
info->feat_compat |= 0;
if (info->dsc_size == 0) {
ext4_dbg(DEBUG_MKFS, DBG_NONE "BG desc reserve: %"PRIu32"\n",
info->bg_desc_reserve_blocks);
ext4_dbg(DEBUG_MKFS, DBG_NONE "Descriptor size: %"PRIu32"\n",
- info->dsc_size);
+ info->dsc_size);
ext4_dbg(DEBUG_MKFS, DBG_NONE "journal: %s\n",
- !info->no_journal ? "yes" : "no");
+ info->journal ? "yes" : "no");
ext4_dbg(DEBUG_MKFS, DBG_NONE "Label: %s\n", info->label);
struct ext4_bcache bc;
if (r != EOK)
goto cache_fini;
- r = ext4_block_cache_write_back(bd, 0);
+ r = ext4_block_cache_write_back(bd, 1);
if (r != EOK)
goto cache_fini;
ext4_fs_fini(fs);
cache_fini:
+ ext4_block_cache_write_back(bd, 0);
ext4_bcache_fini_dynamic(&bc);
block_fini: