summaryrefslogtreecommitdiff
path: root/disk-io.c
diff options
context:
space:
mode:
authorJosef Bacik <jwhiter@redhat.com>2007-06-28 16:20:29 -0400
committerDavid Woodhouse <dwmw2@hera.kernel.org>2007-06-28 16:20:29 -0400
commit4623a01bdc07756ab9b3102786f56c104bff744b (patch)
tree16b3bf41dbd1d1503ae18d8b7a09027f40bc1dce /disk-io.c
parent2b3741c47c8757e01e472a85c43283ed75d65b32 (diff)
calculate checksums during IO
Diffstat (limited to 'disk-io.c')
-rw-r--r--disk-io.c31
1 files changed, 31 insertions, 0 deletions
diff --git a/disk-io.c b/disk-io.c
index cb5d1420..2c92d54e 100644
--- a/disk-io.c
+++ b/disk-io.c
@@ -29,6 +29,7 @@
#include "ctree.h"
#include "disk-io.h"
#include "transaction.h"
+#include "crc32c.h"
static int allocated_blocks = 0;
int cache_max = 10000;
@@ -159,6 +160,30 @@ int clean_tree_block(struct btrfs_trans_handle *trans, struct btrfs_root *root,
return 0;
}
+int btrfs_csum_node(struct btrfs_root *root, struct btrfs_node *node)
+{
+ u32 crc;
+ size_t len = root->blocksize - BTRFS_CSUM_SIZE;
+
+ crc = crc32c(0, (char *)(node) + BTRFS_CSUM_SIZE, len);
+ memcpy(node->header.csum, &crc, BTRFS_CRC32_SIZE);
+ return 0;
+}
+
+int btrfs_csum_super(struct btrfs_root *root, struct btrfs_super_block *super)
+{
+ u32 crc;
+ char block[root->blocksize];
+ size_t len = root->blocksize - BTRFS_CSUM_SIZE;
+
+ memset(block, 0, root->blocksize);
+ memcpy(block, super, sizeof(*super));
+
+ crc = crc32c(0, block + BTRFS_CSUM_SIZE, len);
+ memcpy(super->csum, &crc, BTRFS_CRC32_SIZE);
+ return 0;
+}
+
int write_tree_block(struct btrfs_trans_handle *trans, struct btrfs_root *root,
struct btrfs_buffer *buf)
{
@@ -169,6 +194,9 @@ int write_tree_block(struct btrfs_trans_handle *trans, struct btrfs_root *root,
btrfs_map_bh_to_logical(root, buf, buf->blocknr);
if (check_tree_block(root, buf))
BUG();
+
+ btrfs_csum_node(root, &buf->node);
+
ret = pwrite(buf->fd, &buf->node, root->blocksize,
buf->dev_blocknr * root->blocksize);
if (ret != root->blocksize)
@@ -361,7 +389,10 @@ int write_ctree_super(struct btrfs_trans_handle *trans, struct btrfs_root
*root, struct btrfs_super_block *s)
{
int ret;
+
btrfs_set_super_root(s, root->fs_info->tree_root->node->blocknr);
+ btrfs_csum_super(root, s);
+
ret = pwrite(root->fs_info->fp, s, sizeof(*s),
BTRFS_SUPER_INFO_OFFSET);
if (ret != sizeof(*s)) {