ref: 2cef2313027e81f74d164151f9f03925bb09f44c
parent: 3cb26f0dbccb51de9a23976d24b0db045c995866
author: ngkaho1234 <[email protected]>
date: Wed Oct 28 10:20:52 EDT 2015
METADATA_CSUM: simple extent implementation checksum verification added
--- a/lwext4/ext4_extent.c
+++ b/lwext4/ext4_extent.c
@@ -101,16 +101,13 @@
#define ext4_ext_block_csum(...) 0
#endif
-/*
- * BIG FAT NOTES:
- * Currently we do not verify the checksum of extent
- * (only the case in ext4_extent.c)
- */
-
static void ext4_extent_block_csum_set(struct ext4_inode_ref *inode_ref,
struct ext4_extent_header *eh)
{
struct ext4_extent_tail *tail;
+ if (!ext4_sb_feature_ro_com(&inode_ref->fs->sb,
+ EXT4_FRO_COM_METADATA_CSUM))
+ return;
if (to_le16(eh->depth) < ext_depth(inode_ref->inode)) {
tail = find_ext4_extent_tail(eh);
@@ -118,6 +115,30 @@
}
}
+#if CONFIG_META_CSUM_ENABLE
+static bool
+ext4_extent_verify_block_csum(struct ext4_inode_ref *inode_ref,
+ struct ext4_block *block)
+{
+ struct ext4_extent_header *eh;
+ struct ext4_extent_tail *tail;
+ eh = (struct ext4_extent_header *)block->data;
+ if (!ext4_sb_feature_ro_com(&inode_ref->fs->sb,
+ EXT4_FRO_COM_METADATA_CSUM))
+ return true;
+
+ if (to_le16(eh->depth) < ext_depth(inode_ref->inode)) {
+ tail = find_ext4_extent_tail(eh);
+ return tail->et_checksum ==
+ to_le32(ext4_ext_block_csum(inode_ref, eh));
+ }
+
+ return true;
+}
+#else
+#define ext4_extent_verify_block_csum(...) true
+#endif
+
/**@brief Binary search in extent index node.
* @param header Extent header of index node
* @param index Output value - found index will be set here
@@ -239,6 +260,13 @@
int rc = ext4_block_get(inode_ref->fs->bdev, &block, child);
if (rc != EOK)
return rc;
+ if (!ext4_extent_verify_block_csum(inode_ref,
+ &block)) {
+ ext4_dbg(DEBUG_EXTENT,
+ DBG_WARN "Extent block checksum failed."
+ "Blocknr: %" PRIu64"\n",
+ child);
+ }
header = (struct ext4_extent_header *)block.data;
}
@@ -318,6 +346,14 @@
if (rc != EOK)
goto cleanup;
+ if (!ext4_extent_verify_block_csum(inode_ref,
+ &block)) {
+ ext4_dbg(DEBUG_EXTENT,
+ DBG_WARN "Extent block checksum failed."
+ "Blocknr: %" PRIu64"\n",
+ fblock);
+ }
+
pos++;
eh = (struct ext4_extent_header *)block.data;
@@ -387,6 +423,14 @@
if (rc != EOK)
return rc;
+ if (!ext4_extent_verify_block_csum(inode_ref,
+ &block)) {
+ ext4_dbg(DEBUG_EXTENT,
+ DBG_WARN "Extent block checksum failed."
+ "Blocknr: %" PRIu64"\n",
+ fblock);
+ }
+
struct ext4_extent_header *header = (void *)block.data;
if (ext4_extent_header_get_depth(header)) {
@@ -613,6 +657,14 @@
return rc;
}
+ if (!ext4_extent_verify_block_csum(inode_ref,
+ &block)) {
+ ext4_dbg(DEBUG_EXTENT,
+ DBG_WARN "Extent block checksum failed."
+ "Blocknr: %" PRIu64"\n",
+ fblock);
+ }
+
/* Put back not modified old block */
rc = ext4_block_set(inode_ref->fs->bdev,
&path_ptr->block);
@@ -714,6 +766,14 @@
rc = ext4_block_get(inode_ref->fs->bdev, &block, new_fblock);
if (rc != EOK)
return rc;
+
+ if (!ext4_extent_verify_block_csum(inode_ref,
+ &block)) {
+ ext4_dbg(DEBUG_EXTENT,
+ DBG_WARN "Extent block checksum failed."
+ "Blocknr: %" PRIu64"\n",
+ new_fblock);
+ }
/* Initialize newly allocated block */
memset(block.data, 0, block_size);