diff options
author | Chris Mason <chris.mason@oracle.com> | 2007-03-29 15:15:27 -0400 |
---|---|---|
committer | David Woodhouse <dwmw2@hera.kernel.org> | 2007-03-29 15:15:27 -0400 |
commit | f254e52c1ce550fdaa0d31f5e068f0d67c2485d4 (patch) | |
tree | 1232b7e16b6f0b1b1b150c5df396452cac5e3853 /fs/btrfs/disk-io.c | |
parent | 75dfe3960e602e63ea42ac7a2a0520832b189ffa (diff) |
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.c | 37 |
1 files changed, 26 insertions, 11 deletions
diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c index f2c1dd40c08..f5db2b93650 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, | |||
127 | return 0; | 127 | return 0; |
128 | } | 128 | } |
129 | 129 | ||
130 | static int csum_tree_block(struct btrfs_root * root, struct buffer_head *bh, | 130 | int btrfs_csum_data(struct btrfs_root * root, char *data, size_t len, |
131 | int verify) | 131 | char *result) |
132 | { | 132 | { |
133 | struct btrfs_node *node = btrfs_buffer_node(bh); | ||
134 | struct scatterlist sg; | 133 | struct scatterlist sg; |
135 | struct crypto_hash *tfm = root->fs_info->hash_tfm; | 134 | struct crypto_hash *tfm = root->fs_info->hash_tfm; |
136 | struct hash_desc desc; | 135 | struct hash_desc desc; |
137 | int ret; | 136 | int ret; |
138 | char result[32]; | ||
139 | 137 | ||
140 | desc.tfm = tfm; | 138 | desc.tfm = tfm; |
141 | desc.flags = 0; | 139 | desc.flags = 0; |
142 | sg_init_one(&sg, bh->b_data + 32, bh->b_size - 32); | 140 | sg_init_one(&sg, data, len); |
143 | spin_lock(&root->fs_info->hash_lock); | 141 | spin_lock(&root->fs_info->hash_lock); |
144 | ret = crypto_hash_digest(&desc, &sg, bh->b_size - 32, result); | 142 | ret = crypto_hash_digest(&desc, &sg, len, result); |
145 | spin_unlock(&root->fs_info->hash_lock); | 143 | spin_unlock(&root->fs_info->hash_lock); |
146 | if (ret) { | 144 | if (ret) { |
147 | printk("sha256 digest failed\n"); | 145 | printk("sha256 digest failed\n"); |
148 | } | 146 | } |
147 | return ret; | ||
148 | } | ||
149 | static int csum_tree_block(struct btrfs_root *root, struct buffer_head *bh, | ||
150 | int verify) | ||
151 | { | ||
152 | char result[BTRFS_CSUM_SIZE]; | ||
153 | int ret; | ||
154 | struct btrfs_node *node; | ||
155 | |||
156 | ret = btrfs_csum_data(root, bh->b_data + BTRFS_CSUM_SIZE, | ||
157 | bh->b_size - BTRFS_CSUM_SIZE, result); | ||
158 | if (ret) | ||
159 | return ret; | ||
149 | if (verify) { | 160 | if (verify) { |
150 | if (memcmp(node->header.csum, result, sizeof(result))) | 161 | if (memcmp(bh->b_data, result, BTRFS_CSUM_SIZE)) { |
151 | printk("csum verify failed on %Lu\n", bh->b_blocknr); | 162 | printk("checksum verify failed on %lu\n", |
152 | return -EINVAL; | 163 | bh->b_blocknr); |
153 | } else | 164 | return 1; |
154 | memcpy(node->header.csum, result, sizeof(node->header.csum)); | 165 | } |
166 | } else { | ||
167 | node = btrfs_buffer_node(bh); | ||
168 | memcpy(&node->header.csum, result, BTRFS_CSUM_SIZE); | ||
169 | } | ||
155 | return 0; | 170 | return 0; |
156 | } | 171 | } |
157 | 172 | ||