diff mbox

[37/37] e2fsck: Support CRC32c checksum in journal commit blocks

Message ID 20110901003908.1176.88497.stgit@elm3c44.beaverton.ibm.com
State Superseded, archived
Headers show

Commit Message

Darrick J. Wong Sept. 1, 2011, 12:39 a.m. UTC
The CRC32c polynomial provides better error detection and can be hardware
accelerated on newer machines.  To that end, support replaying transactions
with this checksum type.

Signed-off-by: Darrick J. Wong <djwong@us.ibm.com>
---
 e2fsck/jfs_user.h       |    1 +
 e2fsck/recovery.c       |   19 ++++++++++++++++---
 lib/ext2fs/kernel-jbd.h |    1 +
 3 files changed, 18 insertions(+), 3 deletions(-)



--
To unsubscribe from this list: send the line "unsubscribe linux-ext4" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
diff mbox

Patch

diff --git a/e2fsck/jfs_user.h b/e2fsck/jfs_user.h
index 802f6e8..2f15c19 100644
--- a/e2fsck/jfs_user.h
+++ b/e2fsck/jfs_user.h
@@ -13,6 +13,7 @@ 
  * Pull in the definition of the e2fsck context structure
  */
 #include "e2fsck.h"
+#include "ext2fs/ext2fs.h"
 
 struct buffer_head {
 	e2fsck_t	b_ctx;
diff --git a/e2fsck/recovery.c b/e2fsck/recovery.c
index cac9294..2d4dd06 100644
--- a/e2fsck/recovery.c
+++ b/e2fsck/recovery.c
@@ -323,7 +323,8 @@  static inline unsigned long long read_tag_block(int tag_bytes, journal_block_tag
  * descriptor block.
  */
 static int calc_chksums(journal_t *journal, struct buffer_head *bh,
-			unsigned long *next_log_block, __u32 *crc32_sum)
+			unsigned long *next_log_block, __u32 *crc32_sum,
+			__u32 *crc32c_sum)
 {
 	int i, num_blks, err;
 	unsigned long io_block;
@@ -332,6 +333,7 @@  static int calc_chksums(journal_t *journal, struct buffer_head *bh,
 	num_blks = count_tags(journal, bh);
 	/* Calculate checksum of the descriptor block. */
 	*crc32_sum = crc32_be(*crc32_sum, (void *)bh->b_data, bh->b_size);
+	*crc32c_sum = crc32c_le(*crc32c_sum, (void *)bh->b_data, bh->b_size);
 
 	for (i = 0; i < num_blks; i++) {
 		io_block = (*next_log_block)++;
@@ -344,6 +346,9 @@  static int calc_chksums(journal_t *journal, struct buffer_head *bh,
 		} else {
 			*crc32_sum = crc32_be(*crc32_sum, (void *)obh->b_data,
 				     obh->b_size);
+			*crc32c_sum = crc32c_le(*crc32c_sum,
+				     (void *)obh->b_data,
+				     obh->b_size);
 		}
 		brelse(obh);
 	}
@@ -363,6 +368,7 @@  static int do_one_pass(journal_t *journal,
 	int			blocktype;
 	int			tag_bytes = journal_tag_bytes(journal);
 	__u32			crc32_sum = ~0; /* Transactional Checksums */
+	__u32			crc32c_sum = ~0; /* Transactional Checksums */
 
 	/* Precompute the maximum metadata descriptors in a descriptor block */
 	int			MAX_BLOCKS_PER_DESC;
@@ -464,7 +470,8 @@  static int do_one_pass(journal_t *journal,
 				    !info->end_transaction) {
 					if (calc_chksums(journal, bh,
 							&next_log_block,
-							&crc32_sum)) {
+							&crc32_sum,
+							&crc32c_sum)) {
 						brelse(bh);
 						break;
 					}
@@ -627,7 +634,12 @@  static int do_one_pass(journal_t *journal,
 				    cbh->h_chksum_type == JBD2_CRC32_CHKSUM &&
 				    cbh->h_chksum_size ==
 						JBD2_CRC32_CHKSUM_SIZE)
-				       chksum_seen = 1;
+					chksum_seen = 1;
+				else if (crc32c_sum == found_chksum &&
+				    cbh->h_chksum_type == JBD2_CRC32C_CHKSUM &&
+				    cbh->h_chksum_size ==
+						JBD2_CRC32_CHKSUM_SIZE)
+					chksum_seen = 1;
 				else if (!(cbh->h_chksum_type == 0 &&
 					     cbh->h_chksum_size == 0 &&
 					     found_chksum == 0 &&
@@ -657,6 +669,7 @@  static int do_one_pass(journal_t *journal,
 					}
 				}
 				crc32_sum = ~0;
+				crc32c_sum = ~0;
 			}
 			brelse(bh);
 			next_commit_ID++;
diff --git a/lib/ext2fs/kernel-jbd.h b/lib/ext2fs/kernel-jbd.h
index 066c031..7d92b56 100644
--- a/lib/ext2fs/kernel-jbd.h
+++ b/lib/ext2fs/kernel-jbd.h
@@ -114,6 +114,7 @@  typedef struct journal_header_s
 #define JBD2_CRC32_CHKSUM   1
 #define JBD2_MD5_CHKSUM     2
 #define JBD2_SHA1_CHKSUM    3
+#define JBD2_CRC32C_CHKSUM  4
 
 #define JBD2_CRC32_CHKSUM_SIZE 4