ref: 5cfb1be8476ca3ae318c03e39d96b1a18a8c1516
parent: 00c04858f25eb0d90eb98ec117b9ccca19dbb70a
author: gkostka <[email protected]>
date: Sun Oct 11 07:50:35 EDT 2015
Add ext4_mkfs function (incomplete yet)
--- a/lwext4/ext4_mkfs.c
+++ b/lwext4/ext4_mkfs.c
@@ -38,8 +38,13 @@
#include "ext4_super.h"
#include "ext4_mkfs.h"
+#include <string.h>
+#include <stdlib.h>
-static int ext4_mkfs_sb2info(struct ext4_sblock *sb, struct ext4_mkfs_info *info)
+#define DIV_ROUND_UP(x, y) (((x) + (y) - 1)/(y))
+#define EXT4_ALIGN(x, y) ((y) * DIV_ROUND_UP((x), (y)))
+
+static int sb2info(struct ext4_sblock *sb, struct ext4_mkfs_info *info)
{
if (to_le16(sb->magic) != EXT4_SUPERBLOCK_MAGIC)
@@ -64,7 +69,41 @@
return EOK;
}
+static int info2sb(struct ext4_mkfs_info *info, struct ext4_sblock *sb)
+{
+ (void)info;
+ memset(sb, 0, sizeof(struct ext4_sblock));
+ /*TODO: Fill superblock with proper values*/
+ return EOK;
+}
+
+static uint32_t compute_blocks_per_group(struct ext4_mkfs_info *info)
+{
+ return info->block_size * 8;
+}
+
+static uint32_t compute_inodes(struct ext4_mkfs_info *info)
+{
+ return DIV_ROUND_UP(info->len, info->block_size) / 4;
+}
+
+static uint32_t compute_inodes_per_group(struct ext4_mkfs_info *info)
+{
+ uint32_t blocks = DIV_ROUND_UP(info->len, info->block_size);
+ uint32_t block_groups = DIV_ROUND_UP(blocks, info->blocks_per_group);
+ uint32_t inodes = DIV_ROUND_UP(info->inodes, block_groups);
+ inodes = EXT4_ALIGN(inodes, (info->block_size / info->inode_size));
+
+ /* After properly rounding up the number of inodes/group,
+ * make sure to update the total inodes field in the info struct.
+ */
+ info->inodes = inodes * block_groups;
+
+ return inodes;
+}
+
+
int ext4_mkfs_read_info(struct ext4_blockdev *bd, struct ext4_mkfs_info *info)
{
int r;
@@ -82,7 +121,7 @@
if (r != EOK)
goto Finish;
- r = ext4_mkfs_sb2info(sb, info);
+ r = sb2info(sb, info);
Finish:
if (sb)
@@ -93,9 +132,53 @@
int ext4_mkfs(struct ext4_blockdev *bd, struct ext4_mkfs_info *info)
{
- (void)bd;
- (void)info;
- return EOK;
+ int r;
+ struct ext4_sblock *sb = NULL;
+ r = ext4_block_init(bd);
+ if (r != EOK)
+ return r;
+
+ sb = malloc(sizeof(struct ext4_sblock));
+ if (!sb)
+ goto Finish;
+
+ if (info->block_size == 0)
+ info->block_size = 4096; /*Set block size to default value*/
+
+ /* Round down the filesystem length to be a multiple of the block size */
+ info->len &= ~((uint64_t)info->block_size - 1);
+
+
+ if (info->blocks_per_group == 0)
+ info->blocks_per_group = compute_blocks_per_group(info);
+
+ if (info->inodes == 0)
+ info->inodes = compute_inodes(info);
+
+ if (info->inode_size == 0)
+ info->inode_size = 256;
+
+ if (info->label == NULL)
+ info->label = "";
+
+ info->inodes_per_group = compute_inodes_per_group(info);
+
+ info->feat_compat = CONFIG_FEATURE_COMPAT_SUPP;
+ info->feat_ro_compat = CONFIG_FEATURE_RO_COMPAT_SUPP;
+ info->feat_incompat = CONFIG_FEATURE_INCOMPAT_SUPP;
+
+
+ r = info2sb(info, sb);
+ if (r != EOK)
+ return r;
+
+ /*TODO: write fisesystem metadata*/
+
+ Finish:
+ if (sb)
+ free(sb);
+ ext4_block_fini(bd);
+ return r;
}
/**