shithub: lwext4

Download patch

ref: b4f7056e3443f86eaf265ad2290c9862f7001d32
parent: 193a315b1cb77111ce76592c3bf6fe9ef875df63
author: gkostka <[email protected]>
date: Sun Oct 11 10:11:48 EDT 2015

Port create_fs_aux_info form ext4-utils

--- a/lwext4/ext4_mkfs.c
+++ b/lwext4/ext4_mkfs.c
@@ -46,6 +46,22 @@
 #define DIV_ROUND_UP(x, y) (((x) + (y) - 1)/(y))
 #define EXT4_ALIGN(x, y) ((y) * DIV_ROUND_UP((x), (y)))
 
+struct fs_aux_info {
+	struct ext4_sblock *sb;
+	struct ext4_sblock *sb_block;
+	struct ext4_bgroup *bg_desc;
+	struct xattr_list_element *xattrs;
+	uint32_t first_data_block;
+	uint64_t len_blocks;
+	uint32_t inode_table_blocks;
+	uint32_t groups;
+	uint32_t bg_desc_blocks;
+	uint32_t default_i_flags;
+	uint32_t blocks_per_ind;
+	uint32_t blocks_per_dind;
+	uint32_t blocks_per_tind;
+};
+
 static int sb2info(struct ext4_sblock *sb, struct ext4_mkfs_info *info)
 {
         if (to_le16(sb->magic) != EXT4_SUPERBLOCK_MAGIC)
@@ -127,8 +143,58 @@
 	return journal_blocks;
 }
 
+static void create_fs_aux_info(struct fs_aux_info *aux_info, struct ext4_mkfs_info *info)
+{
+	aux_info->first_data_block = (info->block_size > 1024) ? 0 : 1;
+	aux_info->len_blocks = info->len / info->block_size;
+	aux_info->inode_table_blocks = DIV_ROUND_UP(info->inodes_per_group * info->inode_size,
+		info->block_size);
+	aux_info->groups = DIV_ROUND_UP(aux_info->len_blocks - aux_info->first_data_block,
+		info->blocks_per_group);
+	aux_info->blocks_per_ind = info->block_size / sizeof(uint32_t);
+	aux_info->blocks_per_dind = aux_info->blocks_per_ind * aux_info->blocks_per_ind;
+	aux_info->blocks_per_tind = 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),
+			info->block_size);
 
+	aux_info->default_i_flags = EXT4_INODE_FLAG_NOATIME;
+
+	uint32_t last_group_size = aux_info->len_blocks % info->blocks_per_group;
+	uint32_t last_header_size = 2 + aux_info->inode_table_blocks;
+	if (!(info->feat_ro_compat & EXT4_FEATURE_RO_COMPAT_SPARSE_SUPER) ||
+			ext4_sb_sparse(aux_info->groups - 1))
+		last_header_size += 1 + aux_info->bg_desc_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;
+	}
+
+	/* The write_data* functions expect only block aligned calls.
+	 * This is not an issue, except when we write out the super
+	 * block on a system with a block size > 1K.  So, we need to
+	 * deal with that here.
+	 */
+	aux_info->sb_block = calloc(1, info->block_size);
+	ext4_assert(aux_info->sb_block);
+
+
+	if (info->block_size > 1024)
+		aux_info->sb = (struct ext4_sblock *)((char *)aux_info->sb_block + 1024);
+	else
+		aux_info->sb = aux_info->sb_block;
+
+	aux_info->bg_desc = calloc(info->block_size, aux_info->bg_desc_blocks);
+	ext4_assert(aux_info->bg_desc);
+
+	aux_info->xattrs = NULL;
+}
+
+
+
 int ext4_mkfs_read_info(struct ext4_blockdev *bd, struct ext4_mkfs_info *info)
 {
 	int r;
@@ -228,6 +294,9 @@
 	ext4_dbg(DEBUG_MKFS, DBG_NONE "journal: %s\n",
 			!info->no_journal ? "yes" : "no");
 	ext4_dbg(DEBUG_MKFS, DBG_NONE "Label: %s\n", info->label);
+
+	struct fs_aux_info aux_info;
+	create_fs_aux_info(&aux_info, info);
 
 	/*TODO: write filesystem metadata*/