diff options
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 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, | |||
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 | ||