ref: a09a05013d92a98e5e8cf104bed7c8cc4288beb7
parent: 9befc593b01aee9c468ec7a4cb0de2e3b0c7594a
author: gkostka <[email protected]>
date: Sun Oct 11 12:06:49 EDT 2015
Introduce bdev_write_sb to mkfs module
--- a/lwext4/ext4_mkfs.c
+++ b/lwext4/ext4_mkfs.c
@@ -48,7 +48,6 @@
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;
@@ -92,15 +91,6 @@
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;
@@ -161,7 +151,7 @@
return ext4_sb_sparse(bgid);
}
-static void create_fs_aux_info(struct fs_aux_info *aux_info, struct ext4_mkfs_info *info)
+static int 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;
@@ -190,27 +180,28 @@
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);
+ aux_info->sb = calloc(1, sizeof(struct ext4_sblock));
+ if (!aux_info->sb)
+ return ENOMEM;
+ aux_info->bg_desc = calloc(sizeof(struct ext4_bgroup),
+ aux_info->bg_desc_blocks);
+ if (!aux_info->bg_desc)
+ return ENOMEM;
- 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;
+ return EOK;
}
+static void release_fs_aux_info(struct fs_aux_info *aux_info)
+{
+ if (aux_info->sb)
+ free(aux_info->sb);
+ if (aux_info->sb)
+ free(aux_info->bg_desc);
+}
+
/* Fill in the superblock memory buffer based on the filesystem parameters */
static void fill_in_sb(struct fs_aux_info *aux_info, struct ext4_mkfs_info *info)
{
@@ -298,18 +289,10 @@
info->blocks_per_group;
uint32_t header_size = 0;
- if (has_superblock(info, i)) {
- if (i != 0) {
-
- /* Update the block group nr of this backup superblock */
- sb->block_group_index = i;
- /*TODO: write superblock i*/
-
- }
-
+ if (has_superblock(info, i))
header_size = 1 + aux_info->bg_desc_blocks + info->bg_desc_reserve_blocks;
- }
+
aux_info->bg_desc[i].block_bitmap_lo = group_start_block + header_size;
aux_info->bg_desc[i].inode_bitmap_lo = group_start_block + header_size + 1;
aux_info->bg_desc[i].inode_table_first_block_lo = group_start_block + header_size + 2;
@@ -318,17 +301,31 @@
aux_info->bg_desc[i].free_inodes_count_lo = sb->inodes_per_group;
aux_info->bg_desc[i].used_dirs_count_lo = 0;
}
+}
- /* Queue the primary superblock to be written out - if it's a block device,
- * queue a zero-filled block first, the correct version of superblock will
- * be written to the block device after all other blocks are written.
- *
- * The file-system on the block device will not be valid until the correct
- * version of superblocks are written, this is to avoid the likelihood of a
- * partially created file-system.
- */
- sb->block_group_index = 0;
- /*TODO: write superblock 0*/
+static int bdev_write_sb(struct ext4_blockdev *bd, struct fs_aux_info *aux_info,
+ struct ext4_mkfs_info *info)
+{
+ uint64_t offset;
+ uint32_t i;
+ int r;
+
+ /* write out the backup superblocks */
+ for (i = 1; i < aux_info->groups; i++) {
+ if (has_superblock(info, i)) {
+ offset = info->block_size * (aux_info->first_data_block
+ + i * info->blocks_per_group);
+
+ aux_info->sb->block_group_index = i;
+ r = ext4_block_writebytes(bd, offset, aux_info->sb, 1024);
+ if (r != EOK)
+ return r;
+ }
+ }
+
+ /* write out the primary superblock */
+ aux_info->sb->block_group_index = 0;
+ return ext4_block_writebytes(bd, 1024, aux_info->sb, 1024);
}
@@ -361,15 +358,10 @@
int ext4_mkfs(struct ext4_blockdev *bd, struct ext4_mkfs_info *info)
{
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->len == 0)
info->len = bd->ph_bcnt * bd->ph_bsize;
@@ -405,10 +397,6 @@
info->bg_desc_reserve_blocks = compute_bg_desc_reserve_blocks(info);
- r = info2sb(info, sb);
- if (r != EOK)
- return r;
-
ext4_dbg(DEBUG_MKFS, DBG_INFO "Creating filesystem with parameters:\n");
ext4_dbg(DEBUG_MKFS, DBG_NONE "Size: %"PRIu64"\n", info->len);
ext4_dbg(DEBUG_MKFS, DBG_NONE "Block size: %d\n", info->block_size);
@@ -433,13 +421,21 @@
ext4_dbg(DEBUG_MKFS, DBG_NONE "Label: %s\n", info->label);
struct fs_aux_info aux_info;
- create_fs_aux_info(&aux_info, info);
+ memset(&aux_info, 0, sizeof(struct fs_aux_info));
- /*TODO: write filesystem metadata*/
+ r = create_fs_aux_info(&aux_info, info);
+ if (r != EOK)
+ goto Finish;
+ fill_in_sb(&aux_info, info);
+
+
+ r = bdev_write_sb(bd, &aux_info, info);
+ if (r != EOK)
+ goto Finish;
+
Finish:
- if (sb)
- free(sb);
+ release_fs_aux_info(&aux_info);
ext4_block_fini(bd);
return r;
}