summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorngkaho1234 <ngkaho1234@gmail.com>2016-01-02 10:39:32 +0000
committergkostka <kostka.grzegorz@gmail.com>2016-01-02 12:19:03 +0100
commitc261c575aa8026aa4942cfabd5b61788b80b8ebb (patch)
treeb686b6d16e735814614e3ba8c347b0d552a5e13c
parentce2df9b216b46fe427f04ee993933c87c180edea (diff)
ext4_journal: add JBD_FEATURE_COMPAT_CHECKSUM support.
-rw-r--r--lwext4/ext4_journal.c27
-rw-r--r--lwext4/ext4_types.h1
2 files changed, 25 insertions, 3 deletions
diff --git a/lwext4/ext4_journal.c b/lwext4/ext4_journal.c
index a97bbe4..47bdf48 100644
--- a/lwext4/ext4_journal.c
+++ b/lwext4/ext4_journal.c
@@ -286,7 +286,12 @@ static bool jbd_verify_commit_csum(struct jbd_fs *jbd_fs,
#endif
#if CONFIG_META_CSUM_ENABLE
-static uint32_t jbd_block_csum(struct jbd_fs *jbd_fs, const void *buf)
+/*
+ * NOTE: We only make use of @csum parameter when
+ * JBD_FEATURE_COMPAT_CHECKSUM is enabled.
+ */
+static uint32_t jbd_block_csum(struct jbd_fs *jbd_fs, const void *buf,
+ uint32_t csum)
{
uint32_t checksum = 0;
@@ -298,6 +303,12 @@ static uint32_t jbd_block_csum(struct jbd_fs *jbd_fs, const void *buf)
/* Calculate crc32c checksum against tho whole block */
checksum = ext4_crc32c(checksum, buf,
block_size);
+ } else if (JBD_HAS_INCOMPAT_FEATURE(&jbd_fs->sb,
+ JBD_FEATURE_COMPAT_CHECKSUM)) {
+ uint32_t block_size = jbd_get32(&jbd_fs->sb, blocksize);
+ /* Calculate crc32c checksum against tho whole block */
+ checksum = ext4_crc32(csum, buf,
+ block_size);
}
return checksum;
}
@@ -1370,6 +1381,7 @@ jbd_journal_new_trans(struct jbd_journal *journal)
/* We will assign a trans_id to this transaction,
* once it has been committed.*/
trans->journal = journal;
+ trans->data_csum = EXT4_CRC32_INIT;
trans->error = EOK;
TAILQ_INIT(&trans->buf_queue);
return trans;
@@ -1611,6 +1623,12 @@ static int jbd_trans_write_commit_block(struct jbd_trans *trans)
jbd_set32(&header->header, blocktype, JBD_COMMIT_BLOCK);
jbd_set32(&header->header, sequence, trans->trans_id);
+ if (JBD_HAS_INCOMPAT_FEATURE(&journal->jbd_fs->sb,
+ JBD_FEATURE_COMPAT_CHECKSUM)) {
+ jbd_set32(header, chksum_type, JBD_CRC32_CHKSUM);
+ jbd_set32(header, chksum_size, JBD_CRC32_CHKSUM_SIZE);
+ jbd_set32(header, chksum[0], trans->data_csum);
+ }
jbd_commit_csum_set(journal->jbd_fs, header);
ext4_bcache_set_dirty(commit_block.buf);
rc = jbd_block_set(journal->jbd_fs, &commit_block);
@@ -1635,6 +1653,7 @@ static int jbd_journal_prepare(struct jbd_journal *journal,
struct jbd_buf *jbd_buf, *tmp;
struct ext4_block desc_block, data_block;
struct ext4_fs *fs = journal->jbd_fs->inode_ref.fs;
+ uint32_t checksum = EXT4_CRC32_INIT;
/* Try to remove any non-dirty buffers from the tail of
* buf_queue. */
@@ -1661,7 +1680,6 @@ static int jbd_journal_prepare(struct jbd_journal *journal,
TAILQ_FOREACH_SAFE(jbd_buf, &trans->buf_queue, buf_node, tmp) {
struct tag_info tag_info;
bool uuid_exist = false;
- uint32_t checksum;
if (!ext4_bcache_test_flag(jbd_buf->block.buf,
BC_DIRTY)) {
/* The buffer has not been modified, just release
@@ -1678,7 +1696,8 @@ static int jbd_journal_prepare(struct jbd_journal *journal,
continue;
}
checksum = jbd_block_csum(journal->jbd_fs,
- jbd_buf->block.data);
+ jbd_buf->block.data,
+ checksum);
again:
if (!desc_iblock) {
struct jbd_bhdr *bhdr;
@@ -1714,6 +1733,7 @@ again:
tag_info.last_tag = true;
else
tag_info.last_tag = false;
+
tag_info.checksum = checksum;
if (uuid_exist)
@@ -1755,6 +1775,7 @@ again:
if (rc == EOK && desc_iblock) {
jbd_meta_csum_set(journal->jbd_fs,
(struct jbd_bhdr *)desc_block.data);
+ trans->data_csum = checksum;
jbd_block_set(journal->jbd_fs, &desc_block);
}
diff --git a/lwext4/ext4_types.h b/lwext4/ext4_types.h
index 28c2d14..51036f9 100644
--- a/lwext4/ext4_types.h
+++ b/lwext4/ext4_types.h
@@ -1123,6 +1123,7 @@ struct jbd_trans {
uint32_t start_iblock;
int alloc_blocks;
int data_cnt;
+ uint32_t data_csum;
int written_cnt;
int error;