diff options
author | Josef Bacik <jbacik@redhat.com> | 2008-12-02 07:17:45 -0500 |
---|---|---|
committer | Chris Mason <chris.mason@oracle.com> | 2008-12-02 07:17:45 -0500 |
commit | 607d432da0542e84ddcd358adfddac6f68500e3d (patch) | |
tree | 44425bf1fe8378022bc1b84425ca4ba9d0176566 /fs/btrfs/disk-io.c | |
parent | c6e2bac1a52ffc36dd10769b594dfa3994e95f77 (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.c | 25 |
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) | |||
176 | static int csum_tree_block(struct btrfs_root *root, struct extent_buffer *buf, | 176 | static 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 | ||