Introduce bdev_write_sb to mkfs module
authorgkostka <kostka.grzegorz@gmail.com>
Sun, 11 Oct 2015 14:06:49 +0000 (16:06 +0200)
committergkostka <kostka.grzegorz@gmail.com>
Sun, 11 Oct 2015 14:06:49 +0000 (16:06 +0200)
lwext4/ext4_mkfs.c

index 1b744e271c4c0569aa417f149b9d2cb460821a8b..8324911fc44d04cb1c09e0933235b8b11718e61c 100644 (file)
@@ -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 @@ static int sb2info(struct ext4_sblock *sb, struct ext4_mkfs_info *info)
        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 @@ static bool has_superblock(struct ext4_mkfs_info *info, uint32_t bgid)
        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,24 +180,25 @@ static void create_fs_aux_info(struct fs_aux_info *aux_info, struct ext4_mkfs_in
                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->sb = calloc(1, sizeof(struct ext4_sblock));
+       if (!aux_info->sb)
+               return ENOMEM;
 
-       aux_info->bg_desc = calloc(info->block_size, aux_info->bg_desc_blocks);
-       ext4_assert(aux_info->bg_desc);
+       aux_info->bg_desc = calloc(sizeof(struct ext4_bgroup),
+                       aux_info->bg_desc_blocks);
+       if (!aux_info->bg_desc)
+               return ENOMEM;
 
        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);
 }
 
 
@@ -298,17 +289,9 @@ static void fill_in_sb(struct fs_aux_info *aux_info, struct ext4_mkfs_info *info
                        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;
@@ -318,17 +301,31 @@ static void fill_in_sb(struct fs_aux_info *aux_info, struct ext4_mkfs_info *info
                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 @@ Finish:
 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 @@ int ext4_mkfs(struct ext4_blockdev *bd, struct ext4_mkfs_info *info)
 
        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 @@ int ext4_mkfs(struct ext4_blockdev *bd, struct ext4_mkfs_info *info)
        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));
+
+       r = create_fs_aux_info(&aux_info, info);
+       if (r != EOK)
+               goto Finish;
+
+       fill_in_sb(&aux_info, info);
 
-       /*TODO: write filesystem metadata*/
+
+       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;
 }