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