aboutsummaryrefslogtreecommitdiffstats
path: root/fs/btrfs/disk-io.c
diff options
context:
space:
mode:
authorJosef Bacik <jbacik@redhat.com>2008-12-02 07:17:45 -0500
committerChris Mason <chris.mason@oracle.com>2008-12-02 07:17:45 -0500
commit607d432da0542e84ddcd358adfddac6f68500e3d (patch)
tree44425bf1fe8378022bc1b84425ca4ba9d0176566 /fs/btrfs/disk-io.c
parentc6e2bac1a52ffc36dd10769b594dfa3994e95f77 (diff)
Btrfs: add support for multiple csum algorithms
This patch gives us the space we will need in order to have different csum algorithims at some point in the future. We save the csum algorithim type in the superblock, and use those instead of define's. Signed-off-by: Josef Bacik <jbacik@redhat.com>
Diffstat (limited to 'fs/btrfs/disk-io.c')
-rw-r--r--fs/btrfs/disk-io.c25
1 files changed, 20 insertions, 5 deletions
diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c
index dfd5ba05ce45..3eb7c2576fe5 100644
--- a/fs/btrfs/disk-io.c
+++ b/fs/btrfs/disk-io.c
@@ -176,7 +176,9 @@ void btrfs_csum_final(u32 crc, char *result)
176static int csum_tree_block(struct btrfs_root *root, struct extent_buffer *buf, 176static int csum_tree_block(struct btrfs_root *root, struct extent_buffer *buf,
177 int verify) 177 int verify)
178{ 178{
179 char result[BTRFS_CRC32_SIZE]; 179 u16 csum_size =
180 btrfs_super_csum_size(&root->fs_info->super_copy);
181 char *result = NULL;
180 unsigned long len; 182 unsigned long len;
181 unsigned long cur_len; 183 unsigned long cur_len;
182 unsigned long offset = BTRFS_CSUM_SIZE; 184 unsigned long offset = BTRFS_CSUM_SIZE;
@@ -186,6 +188,7 @@ static int csum_tree_block(struct btrfs_root *root, struct extent_buffer *buf,
186 unsigned long map_len; 188 unsigned long map_len;
187 int err; 189 int err;
188 u32 crc = ~(u32)0; 190 u32 crc = ~(u32)0;
191 unsigned long inline_result;
189 192
190 len = buf->len - offset; 193 len = buf->len - offset;
191 while(len > 0) { 194 while(len > 0) {
@@ -204,25 +207,37 @@ static int csum_tree_block(struct btrfs_root *root, struct extent_buffer *buf,
204 offset += cur_len; 207 offset += cur_len;
205 unmap_extent_buffer(buf, map_token, KM_USER0); 208 unmap_extent_buffer(buf, map_token, KM_USER0);
206 } 209 }
210 if (csum_size > sizeof(inline_result)) {
211 result = kzalloc(csum_size * sizeof(char), GFP_NOFS);
212 if (!result)
213 return 1;
214 } else {
215 result = (char *)&inline_result;
216 }
217
207 btrfs_csum_final(crc, result); 218 btrfs_csum_final(crc, result);
208 219
209 if (verify) { 220 if (verify) {
210 /* FIXME, this is not good */ 221 /* FIXME, this is not good */
211 if (memcmp_extent_buffer(buf, result, 0, BTRFS_CRC32_SIZE)) { 222 if (memcmp_extent_buffer(buf, result, 0, csum_size)) {
212 u32 val; 223 u32 val;
213 u32 found = 0; 224 u32 found = 0;
214 memcpy(&found, result, BTRFS_CRC32_SIZE); 225 memcpy(&found, result, csum_size);
215 226
216 read_extent_buffer(buf, &val, 0, BTRFS_CRC32_SIZE); 227 read_extent_buffer(buf, &val, 0, csum_size);
217 printk("btrfs: %s checksum verify failed on %llu " 228 printk("btrfs: %s checksum verify failed on %llu "
218 "wanted %X found %X level %d\n", 229 "wanted %X found %X level %d\n",
219 root->fs_info->sb->s_id, 230 root->fs_info->sb->s_id,
220 buf->start, val, found, btrfs_header_level(buf)); 231 buf->start, val, found, btrfs_header_level(buf));
232 if (result != (char *)&inline_result)
233 kfree(result);
221 return 1; 234 return 1;
222 } 235 }
223 } else { 236 } else {
224 write_extent_buffer(buf, result, 0, BTRFS_CRC32_SIZE); 237 write_extent_buffer(buf, result, 0, csum_size);
225 } 238 }
239 if (result != (char *)&inline_result)
240 kfree(result);
226 return 0; 241 return 0;
227} 242}
228 243