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 | |
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')
-rw-r--r-- | fs/btrfs/ctree.h | 19 | ||||
-rw-r--r-- | fs/btrfs/disk-io.c | 25 | ||||
-rw-r--r-- | fs/btrfs/file-item.c | 56 | ||||
-rw-r--r-- | fs/btrfs/ioctl.c | 9 | ||||
-rw-r--r-- | fs/btrfs/tree-log.c | 10 |
5 files changed, 81 insertions, 38 deletions
diff --git a/fs/btrfs/ctree.h b/fs/btrfs/ctree.h index b5af1fc77c5d..6d8350332b1d 100644 --- a/fs/btrfs/ctree.h +++ b/fs/btrfs/ctree.h | |||
@@ -109,8 +109,14 @@ struct btrfs_ordered_sum; | |||
109 | 109 | ||
110 | /* 32 bytes in various csum fields */ | 110 | /* 32 bytes in various csum fields */ |
111 | #define BTRFS_CSUM_SIZE 32 | 111 | #define BTRFS_CSUM_SIZE 32 |
112 | |||
113 | /* csum types */ | ||
114 | #define BTRFS_CSUM_TYPE_CRC32 0 | ||
115 | |||
116 | static int btrfs_csum_sizes[] = { 4, 0 }; | ||
117 | |||
112 | /* four bytes for CRC32 */ | 118 | /* four bytes for CRC32 */ |
113 | #define BTRFS_CRC32_SIZE 4 | 119 | //#define BTRFS_CRC32_SIZE 4 |
114 | #define BTRFS_EMPTY_DIR_SIZE 0 | 120 | #define BTRFS_EMPTY_DIR_SIZE 0 |
115 | 121 | ||
116 | #define BTRFS_FT_UNKNOWN 0 | 122 | #define BTRFS_FT_UNKNOWN 0 |
@@ -308,6 +314,7 @@ struct btrfs_super_block { | |||
308 | __le64 compat_flags; | 314 | __le64 compat_flags; |
309 | __le64 compat_ro_flags; | 315 | __le64 compat_ro_flags; |
310 | __le64 incompat_flags; | 316 | __le64 incompat_flags; |
317 | __le16 csum_type; | ||
311 | u8 root_level; | 318 | u8 root_level; |
312 | u8 chunk_root_level; | 319 | u8 chunk_root_level; |
313 | u8 log_root_level; | 320 | u8 log_root_level; |
@@ -1483,6 +1490,7 @@ BTRFS_SETGET_STACK_FUNCS(root_last_snapshot, struct btrfs_root_item, | |||
1483 | last_snapshot, 64); | 1490 | last_snapshot, 64); |
1484 | 1491 | ||
1485 | /* struct btrfs_super_block */ | 1492 | /* struct btrfs_super_block */ |
1493 | |||
1486 | BTRFS_SETGET_STACK_FUNCS(super_bytenr, struct btrfs_super_block, bytenr, 64); | 1494 | BTRFS_SETGET_STACK_FUNCS(super_bytenr, struct btrfs_super_block, bytenr, 64); |
1487 | BTRFS_SETGET_STACK_FUNCS(super_flags, struct btrfs_super_block, flags, 64); | 1495 | BTRFS_SETGET_STACK_FUNCS(super_flags, struct btrfs_super_block, flags, 64); |
1488 | BTRFS_SETGET_STACK_FUNCS(super_generation, struct btrfs_super_block, | 1496 | BTRFS_SETGET_STACK_FUNCS(super_generation, struct btrfs_super_block, |
@@ -1524,6 +1532,15 @@ BTRFS_SETGET_STACK_FUNCS(super_compat_ro_flags, struct btrfs_super_block, | |||
1524 | compat_flags, 64); | 1532 | compat_flags, 64); |
1525 | BTRFS_SETGET_STACK_FUNCS(super_incompat_flags, struct btrfs_super_block, | 1533 | BTRFS_SETGET_STACK_FUNCS(super_incompat_flags, struct btrfs_super_block, |
1526 | incompat_flags, 64); | 1534 | incompat_flags, 64); |
1535 | BTRFS_SETGET_STACK_FUNCS(super_csum_type, struct btrfs_super_block, | ||
1536 | csum_type, 16); | ||
1537 | |||
1538 | static inline int btrfs_super_csum_size(struct btrfs_super_block *s) | ||
1539 | { | ||
1540 | int t = btrfs_super_csum_type(s); | ||
1541 | BUG_ON(t >= ARRAY_SIZE(btrfs_csum_sizes)); | ||
1542 | return btrfs_csum_sizes[t]; | ||
1543 | } | ||
1527 | 1544 | ||
1528 | static inline unsigned long btrfs_leaf_data(struct extent_buffer *l) | 1545 | static inline unsigned long btrfs_leaf_data(struct extent_buffer *l) |
1529 | { | 1546 | { |
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 | ||
diff --git a/fs/btrfs/file-item.c b/fs/btrfs/file-item.c index f76378831407..234ed441736c 100644 --- a/fs/btrfs/file-item.c +++ b/fs/btrfs/file-item.c | |||
@@ -24,9 +24,9 @@ | |||
24 | #include "transaction.h" | 24 | #include "transaction.h" |
25 | #include "print-tree.h" | 25 | #include "print-tree.h" |
26 | 26 | ||
27 | #define MAX_CSUM_ITEMS(r) ((((BTRFS_LEAF_DATA_SIZE(r) - \ | 27 | #define MAX_CSUM_ITEMS(r,size) ((((BTRFS_LEAF_DATA_SIZE(r) - \ |
28 | sizeof(struct btrfs_item) * 2) / \ | 28 | sizeof(struct btrfs_item) * 2) / \ |
29 | BTRFS_CRC32_SIZE) - 1)) | 29 | size) - 1)) |
30 | int btrfs_insert_file_extent(struct btrfs_trans_handle *trans, | 30 | int btrfs_insert_file_extent(struct btrfs_trans_handle *trans, |
31 | struct btrfs_root *root, | 31 | struct btrfs_root *root, |
32 | u64 objectid, u64 pos, | 32 | u64 objectid, u64 pos, |
@@ -83,6 +83,8 @@ struct btrfs_csum_item *btrfs_lookup_csum(struct btrfs_trans_handle *trans, | |||
83 | struct btrfs_csum_item *item; | 83 | struct btrfs_csum_item *item; |
84 | struct extent_buffer *leaf; | 84 | struct extent_buffer *leaf; |
85 | u64 csum_offset = 0; | 85 | u64 csum_offset = 0; |
86 | u16 csum_size = | ||
87 | btrfs_super_csum_size(&root->fs_info->super_copy); | ||
86 | int csums_in_item; | 88 | int csums_in_item; |
87 | 89 | ||
88 | file_key.objectid = objectid; | 90 | file_key.objectid = objectid; |
@@ -105,7 +107,7 @@ struct btrfs_csum_item *btrfs_lookup_csum(struct btrfs_trans_handle *trans, | |||
105 | csum_offset = (offset - found_key.offset) >> | 107 | csum_offset = (offset - found_key.offset) >> |
106 | root->fs_info->sb->s_blocksize_bits; | 108 | root->fs_info->sb->s_blocksize_bits; |
107 | csums_in_item = btrfs_item_size_nr(leaf, path->slots[0]); | 109 | csums_in_item = btrfs_item_size_nr(leaf, path->slots[0]); |
108 | csums_in_item /= BTRFS_CRC32_SIZE; | 110 | csums_in_item /= csum_size; |
109 | 111 | ||
110 | if (csum_offset >= csums_in_item) { | 112 | if (csum_offset >= csums_in_item) { |
111 | ret = -EFBIG; | 113 | ret = -EFBIG; |
@@ -114,7 +116,7 @@ struct btrfs_csum_item *btrfs_lookup_csum(struct btrfs_trans_handle *trans, | |||
114 | } | 116 | } |
115 | item = btrfs_item_ptr(leaf, path->slots[0], struct btrfs_csum_item); | 117 | item = btrfs_item_ptr(leaf, path->slots[0], struct btrfs_csum_item); |
116 | item = (struct btrfs_csum_item *)((unsigned char *)item + | 118 | item = (struct btrfs_csum_item *)((unsigned char *)item + |
117 | csum_offset * BTRFS_CRC32_SIZE); | 119 | csum_offset * csum_size); |
118 | return item; | 120 | return item; |
119 | fail: | 121 | fail: |
120 | if (ret > 0) | 122 | if (ret > 0) |
@@ -150,6 +152,8 @@ int btrfs_lookup_bio_sums(struct btrfs_root *root, struct inode *inode, | |||
150 | u64 item_start_offset = 0; | 152 | u64 item_start_offset = 0; |
151 | u64 item_last_offset = 0; | 153 | u64 item_last_offset = 0; |
152 | u32 diff; | 154 | u32 diff; |
155 | u16 csum_size = | ||
156 | btrfs_super_csum_size(&root->fs_info->super_copy); | ||
153 | int ret; | 157 | int ret; |
154 | struct btrfs_path *path; | 158 | struct btrfs_path *path; |
155 | struct btrfs_csum_item *item = NULL; | 159 | struct btrfs_csum_item *item = NULL; |
@@ -195,7 +199,7 @@ int btrfs_lookup_bio_sums(struct btrfs_root *root, struct inode *inode, | |||
195 | item_size = btrfs_item_size_nr(path->nodes[0], | 199 | item_size = btrfs_item_size_nr(path->nodes[0], |
196 | path->slots[0]); | 200 | path->slots[0]); |
197 | item_last_offset = item_start_offset + | 201 | item_last_offset = item_start_offset + |
198 | (item_size / BTRFS_CRC32_SIZE) * | 202 | (item_size / csum_size) * |
199 | root->sectorsize; | 203 | root->sectorsize; |
200 | item = btrfs_item_ptr(path->nodes[0], path->slots[0], | 204 | item = btrfs_item_ptr(path->nodes[0], path->slots[0], |
201 | struct btrfs_csum_item); | 205 | struct btrfs_csum_item); |
@@ -206,11 +210,11 @@ int btrfs_lookup_bio_sums(struct btrfs_root *root, struct inode *inode, | |||
206 | */ | 210 | */ |
207 | diff = offset - item_start_offset; | 211 | diff = offset - item_start_offset; |
208 | diff = diff / root->sectorsize; | 212 | diff = diff / root->sectorsize; |
209 | diff = diff * BTRFS_CRC32_SIZE; | 213 | diff = diff * csum_size; |
210 | 214 | ||
211 | read_extent_buffer(path->nodes[0], &sum, | 215 | read_extent_buffer(path->nodes[0], &sum, |
212 | ((unsigned long)item) + diff, | 216 | ((unsigned long)item) + diff, |
213 | BTRFS_CRC32_SIZE); | 217 | csum_size); |
214 | found: | 218 | found: |
215 | set_state_private(io_tree, offset, sum); | 219 | set_state_private(io_tree, offset, sum); |
216 | bio_index++; | 220 | bio_index++; |
@@ -383,6 +387,8 @@ int btrfs_csum_file_blocks(struct btrfs_trans_handle *trans, | |||
383 | char *eb_token; | 387 | char *eb_token; |
384 | unsigned long map_len; | 388 | unsigned long map_len; |
385 | unsigned long map_start; | 389 | unsigned long map_start; |
390 | u16 csum_size = | ||
391 | btrfs_super_csum_size(&root->fs_info->super_copy); | ||
386 | 392 | ||
387 | path = btrfs_alloc_path(); | 393 | path = btrfs_alloc_path(); |
388 | BUG_ON(!path); | 394 | BUG_ON(!path); |
@@ -408,7 +414,8 @@ again: | |||
408 | /* we found one, but it isn't big enough yet */ | 414 | /* we found one, but it isn't big enough yet */ |
409 | leaf = path->nodes[0]; | 415 | leaf = path->nodes[0]; |
410 | item_size = btrfs_item_size_nr(leaf, path->slots[0]); | 416 | item_size = btrfs_item_size_nr(leaf, path->slots[0]); |
411 | if ((item_size / BTRFS_CRC32_SIZE) >= MAX_CSUM_ITEMS(root)) { | 417 | if ((item_size / csum_size) >= |
418 | MAX_CSUM_ITEMS(root, csum_size)) { | ||
412 | /* already at max size, make a new one */ | 419 | /* already at max size, make a new one */ |
413 | goto insert; | 420 | goto insert; |
414 | } | 421 | } |
@@ -441,7 +448,7 @@ again: | |||
441 | */ | 448 | */ |
442 | btrfs_release_path(root, path); | 449 | btrfs_release_path(root, path); |
443 | ret = btrfs_search_slot(trans, root, &file_key, path, | 450 | ret = btrfs_search_slot(trans, root, &file_key, path, |
444 | BTRFS_CRC32_SIZE, 1); | 451 | csum_size, 1); |
445 | if (ret < 0) | 452 | if (ret < 0) |
446 | goto fail_unlock; | 453 | goto fail_unlock; |
447 | if (ret == 0) { | 454 | if (ret == 0) { |
@@ -457,14 +464,14 @@ again: | |||
457 | root->fs_info->sb->s_blocksize_bits; | 464 | root->fs_info->sb->s_blocksize_bits; |
458 | if (btrfs_key_type(&found_key) != BTRFS_CSUM_ITEM_KEY || | 465 | if (btrfs_key_type(&found_key) != BTRFS_CSUM_ITEM_KEY || |
459 | found_key.objectid != objectid || | 466 | found_key.objectid != objectid || |
460 | csum_offset >= MAX_CSUM_ITEMS(root)) { | 467 | csum_offset >= MAX_CSUM_ITEMS(root, csum_size)) { |
461 | goto insert; | 468 | goto insert; |
462 | } | 469 | } |
463 | if (csum_offset >= btrfs_item_size_nr(leaf, path->slots[0]) / | 470 | if (csum_offset >= btrfs_item_size_nr(leaf, path->slots[0]) / |
464 | BTRFS_CRC32_SIZE) { | 471 | csum_size) { |
465 | u32 diff = (csum_offset + 1) * BTRFS_CRC32_SIZE; | 472 | u32 diff = (csum_offset + 1) * csum_size; |
466 | diff = diff - btrfs_item_size_nr(leaf, path->slots[0]); | 473 | diff = diff - btrfs_item_size_nr(leaf, path->slots[0]); |
467 | if (diff != BTRFS_CRC32_SIZE) | 474 | if (diff != csum_size) |
468 | goto insert; | 475 | goto insert; |
469 | ret = btrfs_extend_item(trans, root, path, diff); | 476 | ret = btrfs_extend_item(trans, root, path, diff); |
470 | BUG_ON(ret); | 477 | BUG_ON(ret); |
@@ -479,10 +486,10 @@ insert: | |||
479 | tmp -= offset & ~((u64)root->sectorsize -1); | 486 | tmp -= offset & ~((u64)root->sectorsize -1); |
480 | tmp >>= root->fs_info->sb->s_blocksize_bits; | 487 | tmp >>= root->fs_info->sb->s_blocksize_bits; |
481 | tmp = max((u64)1, tmp); | 488 | tmp = max((u64)1, tmp); |
482 | tmp = min(tmp, (u64)MAX_CSUM_ITEMS(root)); | 489 | tmp = min(tmp, (u64)MAX_CSUM_ITEMS(root, csum_size)); |
483 | ins_size = BTRFS_CRC32_SIZE * tmp; | 490 | ins_size = csum_size * tmp; |
484 | } else { | 491 | } else { |
485 | ins_size = BTRFS_CRC32_SIZE; | 492 | ins_size = csum_size; |
486 | } | 493 | } |
487 | ret = btrfs_insert_empty_item(trans, root, path, &file_key, | 494 | ret = btrfs_insert_empty_item(trans, root, path, &file_key, |
488 | ins_size); | 495 | ins_size); |
@@ -497,7 +504,7 @@ csum: | |||
497 | item = btrfs_item_ptr(leaf, path->slots[0], struct btrfs_csum_item); | 504 | item = btrfs_item_ptr(leaf, path->slots[0], struct btrfs_csum_item); |
498 | ret = 0; | 505 | ret = 0; |
499 | item = (struct btrfs_csum_item *)((unsigned char *)item + | 506 | item = (struct btrfs_csum_item *)((unsigned char *)item + |
500 | csum_offset * BTRFS_CRC32_SIZE); | 507 | csum_offset * csum_size); |
501 | found: | 508 | found: |
502 | item_end = btrfs_item_ptr(leaf, path->slots[0], struct btrfs_csum_item); | 509 | item_end = btrfs_item_ptr(leaf, path->slots[0], struct btrfs_csum_item); |
503 | item_end = (struct btrfs_csum_item *)((unsigned char *)item_end + | 510 | item_end = (struct btrfs_csum_item *)((unsigned char *)item_end + |
@@ -508,14 +515,14 @@ found: | |||
508 | next_sector: | 515 | next_sector: |
509 | 516 | ||
510 | if (!eb_token || | 517 | if (!eb_token || |
511 | (unsigned long)item + BTRFS_CRC32_SIZE >= map_start + map_len) { | 518 | (unsigned long)item + csum_size >= map_start + map_len) { |
512 | int err; | 519 | int err; |
513 | 520 | ||
514 | if (eb_token) | 521 | if (eb_token) |
515 | unmap_extent_buffer(leaf, eb_token, KM_USER1); | 522 | unmap_extent_buffer(leaf, eb_token, KM_USER1); |
516 | eb_token = NULL; | 523 | eb_token = NULL; |
517 | err = map_private_extent_buffer(leaf, (unsigned long)item, | 524 | err = map_private_extent_buffer(leaf, (unsigned long)item, |
518 | BTRFS_CRC32_SIZE, | 525 | csum_size, |
519 | &eb_token, &eb_map, | 526 | &eb_token, &eb_map, |
520 | &map_start, &map_len, KM_USER1); | 527 | &map_start, &map_len, KM_USER1); |
521 | if (err) | 528 | if (err) |
@@ -523,17 +530,17 @@ next_sector: | |||
523 | } | 530 | } |
524 | if (eb_token) { | 531 | if (eb_token) { |
525 | memcpy(eb_token + ((unsigned long)item & (PAGE_CACHE_SIZE - 1)), | 532 | memcpy(eb_token + ((unsigned long)item & (PAGE_CACHE_SIZE - 1)), |
526 | §or_sum->sum, BTRFS_CRC32_SIZE); | 533 | §or_sum->sum, csum_size); |
527 | } else { | 534 | } else { |
528 | write_extent_buffer(leaf, §or_sum->sum, | 535 | write_extent_buffer(leaf, §or_sum->sum, |
529 | (unsigned long)item, BTRFS_CRC32_SIZE); | 536 | (unsigned long)item, csum_size); |
530 | } | 537 | } |
531 | 538 | ||
532 | total_bytes += root->sectorsize; | 539 | total_bytes += root->sectorsize; |
533 | sector_sum++; | 540 | sector_sum++; |
534 | if (total_bytes < sums->len) { | 541 | if (total_bytes < sums->len) { |
535 | item = (struct btrfs_csum_item *)((char *)item + | 542 | item = (struct btrfs_csum_item *)((char *)item + |
536 | BTRFS_CRC32_SIZE); | 543 | csum_size); |
537 | if (item < item_end && offset + PAGE_CACHE_SIZE == | 544 | if (item < item_end && offset + PAGE_CACHE_SIZE == |
538 | sector_sum->offset) { | 545 | sector_sum->offset) { |
539 | offset = sector_sum->offset; | 546 | offset = sector_sum->offset; |
@@ -577,7 +584,8 @@ int btrfs_csum_truncate(struct btrfs_trans_handle *trans, | |||
577 | new_item_span = isize - key.offset; | 584 | new_item_span = isize - key.offset; |
578 | blocks = (new_item_span + root->sectorsize - 1) >> | 585 | blocks = (new_item_span + root->sectorsize - 1) >> |
579 | root->fs_info->sb->s_blocksize_bits; | 586 | root->fs_info->sb->s_blocksize_bits; |
580 | new_item_size = blocks * BTRFS_CRC32_SIZE; | 587 | new_item_size = blocks * |
588 | btrfs_super_csum_size(&root->fs_info->super_copy); | ||
581 | if (new_item_size >= btrfs_item_size_nr(leaf, slot)) | 589 | if (new_item_size >= btrfs_item_size_nr(leaf, slot)) |
582 | return 0; | 590 | return 0; |
583 | ret = btrfs_truncate_item(trans, root, path, new_item_size, 1); | 591 | ret = btrfs_truncate_item(trans, root, path, new_item_size, 1); |
diff --git a/fs/btrfs/ioctl.c b/fs/btrfs/ioctl.c index caea9eed9d62..b4da53d55c82 100644 --- a/fs/btrfs/ioctl.c +++ b/fs/btrfs/ioctl.c | |||
@@ -714,7 +714,8 @@ static long btrfs_ioctl_clone(struct file *file, unsigned long srcfd, | |||
714 | u64 len = olen; | 714 | u64 len = olen; |
715 | u64 bs = root->fs_info->sb->s_blocksize; | 715 | u64 bs = root->fs_info->sb->s_blocksize; |
716 | u64 hint_byte; | 716 | u64 hint_byte; |
717 | 717 | u16 csum_size = | |
718 | btrfs_super_csum_size(&root->fs_info->super_copy); | ||
718 | /* | 719 | /* |
719 | * TODO: | 720 | * TODO: |
720 | * - split compressed inline extents. annoying: we need to | 721 | * - split compressed inline extents. annoying: we need to |
@@ -964,7 +965,7 @@ static long btrfs_ioctl_clone(struct file *file, unsigned long srcfd, | |||
964 | int coff, clen; | 965 | int coff, clen; |
965 | 966 | ||
966 | size = btrfs_item_size_nr(leaf, slot); | 967 | size = btrfs_item_size_nr(leaf, slot); |
967 | coverslen = (size / BTRFS_CRC32_SIZE) << | 968 | coverslen = (size / csum_size) << |
968 | root->fs_info->sb->s_blocksize_bits; | 969 | root->fs_info->sb->s_blocksize_bits; |
969 | printk("csums for %llu~%llu\n", | 970 | printk("csums for %llu~%llu\n", |
970 | key.offset, coverslen); | 971 | key.offset, coverslen); |
@@ -981,12 +982,12 @@ static long btrfs_ioctl_clone(struct file *file, unsigned long srcfd, | |||
981 | if (off > key.offset) | 982 | if (off > key.offset) |
982 | coff = ((off - key.offset) >> | 983 | coff = ((off - key.offset) >> |
983 | root->fs_info->sb->s_blocksize_bits) * | 984 | root->fs_info->sb->s_blocksize_bits) * |
984 | BTRFS_CRC32_SIZE; | 985 | csum_size; |
985 | clen = size - coff; | 986 | clen = size - coff; |
986 | if (key.offset + coverslen > off+len) | 987 | if (key.offset + coverslen > off+len) |
987 | clen -= ((key.offset+coverslen-off-len) >> | 988 | clen -= ((key.offset+coverslen-off-len) >> |
988 | root->fs_info->sb->s_blocksize_bits) * | 989 | root->fs_info->sb->s_blocksize_bits) * |
989 | BTRFS_CRC32_SIZE; | 990 | csum_size; |
990 | printk(" will dup %d~%d of %d\n", | 991 | printk(" will dup %d~%d of %d\n", |
991 | coff, clen, size); | 992 | coff, clen, size); |
992 | 993 | ||
diff --git a/fs/btrfs/tree-log.c b/fs/btrfs/tree-log.c index 4fcfc8b1189b..c766649ad453 100644 --- a/fs/btrfs/tree-log.c +++ b/fs/btrfs/tree-log.c | |||
@@ -929,13 +929,15 @@ static noinline int replay_one_csum(struct btrfs_trans_handle *trans, | |||
929 | int ret; | 929 | int ret; |
930 | u32 item_size = btrfs_item_size_nr(eb, slot); | 930 | u32 item_size = btrfs_item_size_nr(eb, slot); |
931 | u64 cur_offset; | 931 | u64 cur_offset; |
932 | u16 csum_size = | ||
933 | btrfs_super_csum_size(&root->fs_info->super_copy); | ||
932 | unsigned long file_bytes; | 934 | unsigned long file_bytes; |
933 | struct btrfs_ordered_sum *sums; | 935 | struct btrfs_ordered_sum *sums; |
934 | struct btrfs_sector_sum *sector_sum; | 936 | struct btrfs_sector_sum *sector_sum; |
935 | struct inode *inode; | 937 | struct inode *inode; |
936 | unsigned long ptr; | 938 | unsigned long ptr; |
937 | 939 | ||
938 | file_bytes = (item_size / BTRFS_CRC32_SIZE) * root->sectorsize; | 940 | file_bytes = (item_size / csum_size) * root->sectorsize; |
939 | inode = read_one_inode(root, key->objectid); | 941 | inode = read_one_inode(root, key->objectid); |
940 | if (!inode) { | 942 | if (!inode) { |
941 | return -EIO; | 943 | return -EIO; |
@@ -959,10 +961,10 @@ static noinline int replay_one_csum(struct btrfs_trans_handle *trans, | |||
959 | ptr = btrfs_item_ptr_offset(eb, slot); | 961 | ptr = btrfs_item_ptr_offset(eb, slot); |
960 | while(item_size > 0) { | 962 | while(item_size > 0) { |
961 | sector_sum->offset = cur_offset; | 963 | sector_sum->offset = cur_offset; |
962 | read_extent_buffer(eb, §or_sum->sum, ptr, BTRFS_CRC32_SIZE); | 964 | read_extent_buffer(eb, §or_sum->sum, ptr, csum_size); |
963 | sector_sum++; | 965 | sector_sum++; |
964 | item_size -= BTRFS_CRC32_SIZE; | 966 | item_size -= csum_size; |
965 | ptr += BTRFS_CRC32_SIZE; | 967 | ptr += csum_size; |
966 | cur_offset += root->sectorsize; | 968 | cur_offset += root->sectorsize; |
967 | } | 969 | } |
968 | 970 | ||