ref: b4abf659b90682936b698f73f80ffab56e187a40
parent: 67935cc9bd8f2702b081b0a046f57d7b67e73bd2
author: ngkaho1234 <ngkaho1234@gmail.com>
date: Fri Oct 23 00:21:04 EDT 2015
METADATA_CSUM: superblock checksum added.
--- a/lwext4/ext4_config.h
+++ b/lwext4/ext4_config.h
@@ -153,6 +153,11 @@
#endif
#endif
+#ifndef ext4_offsetof
+#define ext4_offsetof(type, field) \
+ ((long)(&(((type *)0)->field)))
+#endif
+
#endif /* EXT4_CONFIG_H_ */
/**
--- a/lwext4/ext4_mkfs.c
+++ b/lwext4/ext4_mkfs.c
@@ -259,7 +259,7 @@
sb->last_orphan = 0;
sb->hash_seed[0] = 0; /* FIXME */
sb->default_hash_version = EXT2_HTREE_HALF_MD4;
- sb->reserved_char_pad = 1;
+ sb->checksum_type = 1;
sb->desc_size = EXT4_MIN_BLOCK_GROUP_DESCRIPTOR_SIZE;
sb->default_mount_opts = 0; /* FIXME */
sb->first_meta_bg = 0;
--- a/lwext4/ext4_super.c
+++ b/lwext4/ext4_super.c
@@ -41,6 +41,7 @@
#include "ext4_config.h"
#include "ext4_super.h"
+#include "ext4_crc32c.h"
uint32_t ext4_block_group_cnt(struct ext4_sblock *s)
{
@@ -79,8 +80,36 @@
return (total_inodes - ((block_group_count - 1) * inodes_per_group));
}
+static uint32_t ext4_sb_csum(struct ext4_sblock *s)
+{
+ return ext4_crc32c(~0, s,
+ ext4_offsetof(struct ext4_sblock, checksum));
+}
+
+static bool ext4_sb_verify_csum(struct ext4_sblock *s)
+{
+ if (!ext4_sb_has_feature_read_only(s,
+ EXT4_FEATURE_INCOMPAT_BG_USE_META_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_has_feature_read_only(s,
+ EXT4_FEATURE_INCOMPAT_BG_USE_META_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);
}
@@ -118,6 +147,9 @@
return false;
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;
--- a/lwext4/ext4_types.h
+++ b/lwext4/ext4_types.h
@@ -48,6 +48,8 @@
#include <stdint.h>
+#define EXT4_CHECKSUM_CRC32C 1
+
/*
* Structure of the super block
*/
@@ -126,7 +128,7 @@
uint64_t mmp_block; /* Block for multi-mount protection */
uint32_t raid_stripe_width; /* Blocks on all data disks (N * stride) */
uint8_t log_groups_per_flex; /* FLEX_BG group size */
- uint8_t reserved_char_pad;
+ uint8_t checksum_type;
uint16_t reserved_pad;
uint64_t kbytes_written; /* Number of lifetime kilobytes written */
uint32_t snapshot_inum; /* I-node number of active snapshot */
@@ -149,7 +151,15 @@
uint64_t last_error_block; /* Block involved of last error */
uint8_t last_error_func[32]; /* Function where the error happened */
uint8_t mount_opts[64];
- uint32_t padding[112]; /* Padding to the end of the block */
+ uint32_t usr_quota_inum; /* inode for tracking user quota */
+ uint32_t grp_quota_inum; /* inode for tracking group quota */
+ uint32_t overhead_clusters; /* overhead blocks/clusters in fs */
+ uint32_t backup_bgs[2]; /* groups with sparse_super2 SBs */
+ uint8_t encrypt_algos[4]; /* Encryption algorithms in use */
+ uint8_t encrypt_pw_salt[16]; /* Salt used for string2key algorithm */
+ uint32_t lpf_ino; /* Location of the lost+found inode */
+ uint32_t padding[100]; /* Padding to the end of the block */
+ uint32_t checksum; /* crc32c(superblock) */
} __attribute__((packed));
#define EXT4_SUPERBLOCK_MAGIC 0xEF53