summaryrefslogtreecommitdiff
path: root/fs/btrfs/disk-io.c
diff options
context:
space:
mode:
authorChris Mason <chris.mason@oracle.com>2007-03-29 15:15:27 -0400
committerDavid Woodhouse <dwmw2@hera.kernel.org>2007-03-29 15:15:27 -0400
commitf254e52c1ce550fdaa0d31f5e068f0d67c2485d4 (patch)
tree1232b7e16b6f0b1b1b150c5df396452cac5e3853 /fs/btrfs/disk-io.c
parent75dfe3960e602e63ea42ac7a2a0520832b189ffa (diff)
downloadlwn-f254e52c1ce550fdaa0d31f5e068f0d67c2485d4.tar.gz
lwn-f254e52c1ce550fdaa0d31f5e068f0d67c2485d4.zip
Btrfs: verify csums on read
Signed-off-by: Chris Mason <chris.mason@oracle.com>
Diffstat (limited to 'fs/btrfs/disk-io.c')
-rw-r--r--fs/btrfs/disk-io.c37
1 files changed, 26 insertions, 11 deletions
diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c
index f2c1dd40c087..f5db2b936502 100644
--- a/fs/btrfs/disk-io.c
+++ b/fs/btrfs/disk-io.c
@@ -127,31 +127,46 @@ static int btree_get_block(struct inode *inode, sector_t iblock,
return 0;
}
-static int csum_tree_block(struct btrfs_root * root, struct buffer_head *bh,
- int verify)
+int btrfs_csum_data(struct btrfs_root * root, char *data, size_t len,
+ char *result)
{
- struct btrfs_node *node = btrfs_buffer_node(bh);
struct scatterlist sg;
struct crypto_hash *tfm = root->fs_info->hash_tfm;
struct hash_desc desc;
int ret;
- char result[32];
desc.tfm = tfm;
desc.flags = 0;
- sg_init_one(&sg, bh->b_data + 32, bh->b_size - 32);
+ sg_init_one(&sg, data, len);
spin_lock(&root->fs_info->hash_lock);
- ret = crypto_hash_digest(&desc, &sg, bh->b_size - 32, result);
+ ret = crypto_hash_digest(&desc, &sg, len, result);
spin_unlock(&root->fs_info->hash_lock);
if (ret) {
printk("sha256 digest failed\n");
}
+ return ret;
+}
+static int csum_tree_block(struct btrfs_root *root, struct buffer_head *bh,
+ int verify)
+{
+ char result[BTRFS_CSUM_SIZE];
+ int ret;
+ struct btrfs_node *node;
+
+ ret = btrfs_csum_data(root, bh->b_data + BTRFS_CSUM_SIZE,
+ bh->b_size - BTRFS_CSUM_SIZE, result);
+ if (ret)
+ return ret;
if (verify) {
- if (memcmp(node->header.csum, result, sizeof(result)))
- printk("csum verify failed on %Lu\n", bh->b_blocknr);
- return -EINVAL;
- } else
- memcpy(node->header.csum, result, sizeof(node->header.csum));
+ if (memcmp(bh->b_data, result, BTRFS_CSUM_SIZE)) {
+ printk("checksum verify failed on %lu\n",
+ bh->b_blocknr);
+ return 1;
+ }
+ } else {
+ node = btrfs_buffer_node(bh);
+ memcpy(&node->header.csum, result, BTRFS_CSUM_SIZE);
+ }
return 0;
}