#include "ext4_config.h"
#include "ext4_super.h"
+#include "ext4_crc32c.h"
uint32_t ext4_block_group_cnt(struct ext4_sblock *s)
{
return (total_inodes - ((block_group_count - 1) * inodes_per_group));
}
+static uint32_t ext4_sb_csum(struct ext4_sblock *s)
+{
+ return ext4_crc32c(EXT4_CRC32_INIT, s,
+ offsetof(struct ext4_sblock, checksum));
+}
+
+static bool ext4_sb_verify_csum(struct ext4_sblock *s)
+{
+ if (!ext4_sb_feature_ro_com(s, EXT4_FRO_COM_METADATA_CSUM))
+ return true;
+
+ if (s->checksum_type != to_le32(EXT4_CHECKSUM_CRC32C))
+ return false;
+
+ return s->checksum == to_le32(ext4_sb_csum(s));
+}
+
+static void ext4_sb_set_csum(struct ext4_sblock *s)
+{
+ if (!ext4_sb_feature_ro_com(s, EXT4_FRO_COM_METADATA_CSUM))
+ return;
+
+ s->checksum = to_le32(ext4_sb_csum(s));
+}
+
int ext4_sb_write(struct ext4_blockdev *bdev, struct ext4_sblock *s)
{
+ ext4_sb_set_csum(s);
return ext4_block_writebytes(bdev, EXT4_SUPERBLOCK_OFFSET, s,
EXT4_SUPERBLOCK_SIZE);
}
if (ext4_sb_get_desc_size(s) > EXT4_MAX_BLOCK_GROUP_DESCRIPTOR_SIZE)
return false;
+ if (!ext4_sb_verify_csum(s))
+ return false;
+
return true;
}
bool ext4_sb_is_super_in_bg(struct ext4_sblock *s, uint32_t group)
{
- if (ext4_sb_has_feature_read_only(
- s, EXT4_FEATURE_RO_COMPAT_SPARSE_SUPER) &&
+ if (ext4_sb_feature_ro_com(s, EXT4_FRO_COM_SPARSE_SUPER) &&
!ext4_sb_sparse(group))
return false;
return true;
uint32_t db_count =
(ext4_block_group_cnt(s) + dsc_per_block - 1) / dsc_per_block;
- if (ext4_sb_has_feature_incompatible(s, EXT4_FEATURE_INCOMPAT_META_BG))
+ if (ext4_sb_feature_incom(s, EXT4_FINCOM_META_BG))
return ext4_sb_first_meta_bg(s);
return db_count;
uint32_t first_meta_bg = ext4_sb_first_meta_bg(s);
uint32_t metagroup = group / dsc_per_block;
- if (!ext4_sb_has_feature_incompatible(s,
- EXT4_FEATURE_INCOMPAT_META_BG) ||
+ if (!ext4_sb_feature_incom(s,EXT4_FINCOM_META_BG) ||
metagroup < first_meta_bg)
return ext4_bg_num_gdb_nometa(s, group);
num = ext4_sb_is_super_in_bg(s, block_group);
- if (!ext4_sb_has_feature_incompatible(s,
- EXT4_FEATURE_INCOMPAT_META_BG) ||
+ if (!ext4_sb_feature_incom(s, EXT4_FINCOM_META_BG) ||
block_group < ext4_sb_first_meta_bg(s) * dsc_per_block) {
if (num) {
num += ext4_bg_num_gdb(s, block_group);