shithub: lwext4

Download patch

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