shithub: lwext4

Download patch

ref: 2cef2313027e81f74d164151f9f03925bb09f44c
parent: 3cb26f0dbccb51de9a23976d24b0db045c995866
author: ngkaho1234 <ngkaho1234@gmail.com>
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);