ref: f925f21abdc2a3b49967ae8f38bdb1ba1d40dde2
parent: c8ca698ba9f650dda21b022918033a0c625b27c4
author: ngkaho1234 <[email protected]>
date: Fri Oct 23 18:25:06 EDT 2015
METADATA_CSUM: block & inode bitmap checksum added.
--- a/lwext4/ext4_balloc.c
+++ b/lwext4/ext4_balloc.c
@@ -42,6 +42,7 @@
#include "ext4_config.h"
#include "ext4_balloc.h"
#include "ext4_super.h"
+#include "ext4_crc32c.h"
#include "ext4_block_group.h"
#include "ext4_fs.h"
#include "ext4_bitmap.h"
@@ -77,6 +78,37 @@
return baddr;
}
+static uint32_t ext4_balloc_bitmap_csum(struct ext4_sblock *sb,
+ void *bitmap)
+{
+ uint32_t checksum = 0;
+ if (ext4_sb_has_feature_read_only(sb,
+ EXT4_FEATURE_RO_COMPAT_METADATA_CSUM)) {
+ /* First calculate crc32 checksum against fs uuid */
+ checksum = ext4_crc32c(~0, sb->uuid, sizeof(sb->uuid));
+ /* Then calculate crc32 checksum against block_group_desc */
+ checksum = ext4_crc32c(checksum, bitmap,
+ ext4_sb_get_block_size(sb));
+ }
+ return checksum;
+}
+
+static void ext4_balloc_set_bitmap_csum(struct ext4_sblock *sb,
+ struct ext4_bgroup *bg,
+ void *bitmap)
+{
+ int desc_size = ext4_sb_get_desc_size(sb);
+ uint32_t checksum = ext4_balloc_bitmap_csum(sb, bitmap);
+ uint16_t lo_checksum = to_le16(checksum & 0xFFFF),
+ hi_checksum = to_le16(checksum >> 16);
+
+ /* See if we need to assign a 32bit checksum */
+ bg->block_bitmap_csum_lo = lo_checksum;
+ if (desc_size == EXT4_MAX_BLOCK_GROUP_DESCRIPTOR_SIZE)
+ bg->block_bitmap_csum_hi = hi_checksum;
+
+}
+
int ext4_balloc_free_block(struct ext4_inode_ref *inode_ref, ext4_fsblk_t baddr)
{
struct ext4_fs *fs = inode_ref->fs;
@@ -106,6 +138,8 @@
/* Modify bitmap */
ext4_bmap_bit_clr(bitmap_block.data, index_in_group);
bitmap_block.dirty = true;
+ ext4_balloc_set_bitmap_csum(sb, bg_ref.block_group,
+ bitmap_block.data);
/* Release block with bitmap */
rc = ext4_block_set(fs->bdev, &bitmap_block);
@@ -196,6 +230,8 @@
ext4_bmap_bits_free(bitmap_block.data, index_in_group_first,
free_cnt);
bitmap_block.dirty = true;
+ ext4_balloc_set_bitmap_csum(sb, bg_ref.block_group,
+ bitmap_block.data);
count -= free_cnt;
first += free_cnt;
@@ -294,6 +330,8 @@
if (ext4_bmap_is_bit_clr(bitmap_block.data, index_in_group)) {
ext4_bmap_bit_set(bitmap_block.data, index_in_group);
bitmap_block.dirty = true;
+ ext4_balloc_set_bitmap_csum(sb, bg_ref.block_group,
+ bitmap_block.data);
rc = ext4_block_set(inode_ref->fs->bdev, &bitmap_block);
if (rc != EOK) {
ext4_fs_put_block_group_ref(&bg_ref);
@@ -319,6 +357,8 @@
ext4_bmap_bit_set(bitmap_block.data, tmp_idx);
bitmap_block.dirty = true;
+ ext4_balloc_set_bitmap_csum(sb, bg_ref.block_group,
+ bitmap_block.data);
rc = ext4_block_set(inode_ref->fs->bdev, &bitmap_block);
if (rc != EOK)
return rc;
@@ -336,6 +376,8 @@
if (rc == EOK) {
ext4_bmap_bit_set(bitmap_block.data, rel_block_idx);
bitmap_block.dirty = true;
+ ext4_balloc_set_bitmap_csum(sb, bg_ref.block_group,
+ bitmap_block.data);
rc = ext4_block_set(inode_ref->fs->bdev, &bitmap_block);
if (rc != EOK)
return rc;
@@ -409,6 +451,8 @@
ext4_bmap_bit_set(bitmap_block.data, rel_block_idx);
bitmap_block.dirty = true;
+ ext4_balloc_set_bitmap_csum(sb, bg_ref.block_group,
+ bitmap_block.data);
rc = ext4_block_set(inode_ref->fs->bdev, &bitmap_block);
if (rc != EOK) {
ext4_fs_put_block_group_ref(&bg_ref);
@@ -508,6 +552,8 @@
if (*free) {
ext4_bmap_bit_set(bitmap_block.data, index_in_group);
bitmap_block.dirty = true;
+ ext4_balloc_set_bitmap_csum(sb, bg_ref.block_group,
+ bitmap_block.data);
}
/* Release block with bitmap */
--- a/lwext4/ext4_ialloc.c
+++ b/lwext4/ext4_ialloc.c
@@ -43,6 +43,7 @@
#include "ext4_types.h"
#include "ext4_ialloc.h"
#include "ext4_super.h"
+#include "ext4_crc32c.h"
#include "ext4_fs.h"
#include "ext4_blockdev.h"
#include "ext4_block_group.h"
@@ -85,6 +86,37 @@
return (inode - 1) / inodes_per_group;
}
+static uint32_t ext4_ialloc_bitmap_csum(struct ext4_sblock *sb,
+ void *bitmap)
+{
+ uint32_t checksum = 0;
+ if (ext4_sb_has_feature_read_only(sb,
+ EXT4_FEATURE_RO_COMPAT_METADATA_CSUM)) {
+ /* First calculate crc32 checksum against fs uuid */
+ checksum = ext4_crc32c(~0, sb->uuid, sizeof(sb->uuid));
+ /* Then calculate crc32 checksum against block_group_desc */
+ checksum = ext4_crc32c(checksum, bitmap,
+ ext4_sb_get_block_size(sb));
+ }
+ return checksum;
+}
+
+static void ext4_ialloc_set_bitmap_csum(struct ext4_sblock *sb,
+ struct ext4_bgroup *bg,
+ void *bitmap)
+{
+ int desc_size = ext4_sb_get_desc_size(sb);
+ uint32_t checksum = ext4_ialloc_bitmap_csum(sb, bitmap);
+ uint16_t lo_checksum = to_le16(checksum & 0xFFFF),
+ hi_checksum = to_le16(checksum >> 16);
+
+ /* See if we need to assign a 32bit checksum */
+ bg->block_bitmap_csum_lo = lo_checksum;
+ if (desc_size == EXT4_MAX_BLOCK_GROUP_DESCRIPTOR_SIZE)
+ bg->block_bitmap_csum_hi = hi_checksum;
+
+}
+
int ext4_ialloc_free_inode(struct ext4_fs *fs, uint32_t index, bool is_dir)
{
struct ext4_sblock *sb = &fs->sb;
@@ -110,6 +142,8 @@
uint32_t index_in_group = ext4_ialloc_inode2index_in_group(sb, index);
ext4_bmap_bit_clr(bitmap_block.data, index_in_group);
bitmap_block.dirty = true;
+ ext4_ialloc_set_bitmap_csum(sb, bg_ref.block_group,
+ bitmap_block.data);
/* Put back the block with bitmap */
rc = ext4_block_set(fs->bdev, &bitmap_block);
@@ -223,6 +257,8 @@
/* Free i-node found, save the bitmap */
bitmap_block.dirty = true;
+ ext4_ialloc_set_bitmap_csum(sb, bg_ref.block_group,
+ bitmap_block.data);
ext4_block_set(fs->bdev, &bitmap_block);
if (rc != EOK) {