diff options
| author | gkostka <kostka.grzegorz@gmail.com> | 2017-02-21 21:30:54 +0100 |
|---|---|---|
| committer | gkostka <kostka.grzegorz@gmail.com> | 2017-02-21 22:05:26 +0100 |
| commit | 12af982ed6f006c0ff4b73a2dc266d139d490904 (patch) | |
| tree | 4093a7f22678c4425c30cdce1ccd2b3814aef60f /src | |
| parent | 958b570b8fe80913ed607a15a3548cadac8a1195 (diff) | |
ext4_mkfs: add journal node creation support
Diffstat (limited to 'src')
| -rw-r--r-- | src/ext4.c | 2 | ||||
| -rw-r--r-- | src/ext4_fs.c | 31 | ||||
| -rw-r--r-- | src/ext4_mkfs.c | 95 |
3 files changed, 105 insertions, 23 deletions
@@ -998,6 +998,8 @@ static int ext4_generic_open2(ext4_file *f, const char *path, int flags, struct ext4_inode_ref child_ref; r = ext4_fs_alloc_inode(fs, &child_ref, is_goal ? ftype : EXT4_DE_DIR); + + ext4_fs_inode_blocks_init(fs, &child_ref); if (r != EOK) break; diff --git a/src/ext4_fs.c b/src/ext4_fs.c index e8b296d..3427df3 100644 --- a/src/ext4_fs.c +++ b/src/ext4_fs.c @@ -805,13 +805,18 @@ int ext4_fs_put_inode_ref(struct ext4_inode_ref *ref) void ext4_fs_inode_blocks_init(struct ext4_fs *fs, struct ext4_inode_ref *inode_ref) { - int i; struct ext4_inode *inode = inode_ref->inode; - for (i = 0; i < EXT4_INODE_BLOCKS; i++) - inode->blocks[i] = 0; + /* Reset blocks array. For inode which is not directory or file, just + * fill in blocks with 0 */ + switch (ext4_inode_type(&fs->sb, inode_ref->inode)) { + case EXT4_INODE_MODE_FILE: + case EXT4_INODE_MODE_DIRECTORY: + break; + default: + return; + } - (void)fs; #if CONFIG_EXTENT_ENABLE /* Initialize extents if needed */ if (ext4_sb_feature_incom(&fs->sb, EXT4_FINCOM_EXTENTS)) { @@ -820,6 +825,8 @@ void ext4_fs_inode_blocks_init(struct ext4_fs *fs, /* Initialize extent root header */ ext4_extent_tree_init(inode_ref); } + + inode_ref->dirty = true; #endif } @@ -850,7 +857,6 @@ int ext4_fs_alloc_inode(struct ext4_fs *fs, struct ext4_inode_ref *inode_ref, { /* Check if newly allocated i-node will be a directory */ bool is_dir; - uint32_t type; uint16_t inode_size = ext4_get16(&fs->sb, inode_size); is_dir = (filetype == EXT4_DE_DIR); @@ -919,20 +925,7 @@ int ext4_fs_alloc_inode(struct ext4_fs *fs, struct ext4_inode_ref *inode_ref, ext4_inode_set_extra_isize(&fs->sb, inode, size); } - /* Reset blocks array. For inode which is not directory or file, just - * fill in blocks with 0 */ - type = ext4_inode_type(&fs->sb, inode_ref->inode); - if (type == EXT4_INODE_MODE_CHARDEV || - type == EXT4_INODE_MODE_BLOCKDEV || - type == EXT4_INODE_MODE_SOCKET || - type == EXT4_INODE_MODE_SOFTLINK) { - for (int i = 0; i < EXT4_INODE_BLOCKS; i++) - inode->blocks[i] = 0; - - } else { - ext4_fs_inode_blocks_init(fs, inode_ref); - } - + memset(inode->blocks, 0, sizeof(inode->blocks)); inode_ref->dirty = true; return EOK; diff --git a/src/ext4_mkfs.c b/src/ext4_mkfs.c index 7af3301..81867d6 100644 --- a/src/ext4_mkfs.c +++ b/src/ext4_mkfs.c @@ -273,6 +273,8 @@ static void fill_sb(struct fs_aux_info *aux_info, struct ext4_mkfs_info *info) if (info->feat_compat & EXT4_FCOM_HAS_JOURNAL) sb->journal_inode_number = to_le32(EXT4_JOURNAL_INO); + + sb->journal_backup_type = 1; sb->journal_dev = to_le32(0); sb->last_orphan = to_le32(0); sb->hash_seed[0] = to_le32(0x11111111); @@ -541,6 +543,8 @@ static int alloc_inodes(struct ext4_fs *fs) case EXT4_GOOD_OLD_FIRST_INO: filetype = EXT4_DE_DIR; break; + default: + break; } r = ext4_fs_alloc_inode(fs, &inode_ref, filetype); @@ -548,6 +552,14 @@ static int alloc_inodes(struct ext4_fs *fs) return r; ext4_inode_set_mode(&fs->sb, inode_ref.inode, 0); + + switch (i) { + case EXT4_ROOT_INO: + case EXT4_JOURNAL_INO: + ext4_fs_inode_blocks_init(fs, &inode_ref); + break; + } + ext4_fs_put_inode_ref(&inode_ref); } @@ -621,6 +633,70 @@ static int create_dirs(struct ext4_fs *fs) return r; } +static int create_journal_inode(struct ext4_fs *fs, + struct ext4_mkfs_info *info) +{ + int ret; + struct ext4_inode_ref inode_ref; + uint64_t blocks_count; + + if (!info->journal) + return EOK; + + ret = ext4_fs_get_inode_ref(fs, EXT4_JOURNAL_INO, &inode_ref); + if (ret != EOK) + return ret; + + struct ext4_inode *inode = inode_ref.inode; + + ext4_inode_set_mode(&fs->sb, inode, EXT4_INODE_MODE_FILE | 0600); + ext4_inode_set_links_cnt(inode, 1); + + blocks_count = ext4_inode_get_blocks_count(&fs->sb, inode); + + while (blocks_count++ < info->journal_blocks) + { + ext4_fsblk_t fblock; + ext4_lblk_t iblock; + struct ext4_block blk; + + ret = ext4_fs_append_inode_dblk(&inode_ref, &fblock, &iblock); + if (ret != EOK) + goto Finish; + + if (iblock != 0) + continue; + + ret = ext4_block_get(fs->bdev, &blk, fblock); + if (ret != EOK) + goto Finish; + + + struct jbd_sb * jbd_sb = (struct jbd_sb * )blk.data; + memset(jbd_sb, 0, sizeof(struct jbd_sb)); + + jbd_sb->header.magic = to_be32(JBD_MAGIC_NUMBER); + jbd_sb->header.blocktype = to_be32(JBD_SUPERBLOCK_V2); + jbd_sb->blocksize = to_be32(info->block_size); + jbd_sb->maxlen = to_be32(info->journal_blocks); + jbd_sb->nr_users = to_be32(1); + jbd_sb->first = to_be32(1); + jbd_sb->sequence = to_be32(1); + + ext4_bcache_set_dirty(blk.buf); + ret = ext4_block_set(fs->bdev, &blk); + if (ret != EOK) + goto Finish; + } + + memcpy(fs->sb.journal_blocks, inode->blocks, sizeof(inode->blocks)); + + Finish: + ext4_fs_put_inode_ref(&inode_ref); + + return ret; +} + int ext4_mkfs(struct ext4_fs *fs, struct ext4_blockdev *bd, struct ext4_mkfs_info *info, int fs_type) { @@ -676,14 +752,19 @@ int ext4_mkfs(struct ext4_fs *fs, struct ext4_blockdev *bd, break; } - /*TODO: handle this features*/ + /*TODO: handle this features some day...*/ info->feat_incompat &= ~EXT4_FINCOM_META_BG; info->feat_incompat &= ~EXT4_FINCOM_FLEX_BG; + info->feat_incompat &= ~EXT4_FINCOM_64BIT; + info->feat_ro_compat &= ~EXT4_FRO_COM_METADATA_CSUM; + info->feat_ro_compat &= ~EXT4_FRO_COM_GDT_CSUM; + info->feat_ro_compat &= ~EXT4_FRO_COM_DIR_NLINK; + info->feat_ro_compat &= ~EXT4_FRO_COM_EXTRA_ISIZE; + info->feat_ro_compat &= ~EXT4_FRO_COM_HUGE_FILE; - /*TODO: handle journal feature & inode*/ - if (info->journal == 0) - info->feat_compat |= 0; + if (info->journal) + info->feat_compat |= EXT4_FCOM_HAS_JOURNAL; if (info->dsc_size == 0) { @@ -723,8 +804,10 @@ int ext4_mkfs(struct ext4_fs *fs, struct ext4_blockdev *bd, ext4_dbg(DEBUG_MKFS, DBG_NONE "Label: %s\n", info->label); struct ext4_bcache bc; + memset(&bc, 0, sizeof(struct ext4_bcache)); ext4_block_set_lb_size(bd, info->block_size); + r = ext4_bcache_init_dynamic(&bc, CONFIG_BLOCK_DEV_CACHE_SIZE, info->block_size); if (r != EOK) @@ -759,6 +842,10 @@ int ext4_mkfs(struct ext4_fs *fs, struct ext4_blockdev *bd, if (r != EOK) goto fs_fini; + r = create_journal_inode(fs, info); + if (r != EOK) + goto fs_fini; + fs_fini: ext4_fs_fini(fs); |
