aboutsummaryrefslogtreecommitdiffstats
path: root/fs
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
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')
-rw-r--r--fs/btrfs/ctree.h19
-rw-r--r--fs/btrfs/disk-io.c25
-rw-r--r--fs/btrfs/file-item.c56
-rw-r--r--fs/btrfs/ioctl.c9
-rw-r--r--fs/btrfs/tree-log.c10
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
116static 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
1486BTRFS_SETGET_STACK_FUNCS(super_bytenr, struct btrfs_super_block, bytenr, 64); 1494BTRFS_SETGET_STACK_FUNCS(super_bytenr, struct btrfs_super_block, bytenr, 64);
1487BTRFS_SETGET_STACK_FUNCS(super_flags, struct btrfs_super_block, flags, 64); 1495BTRFS_SETGET_STACK_FUNCS(super_flags, struct btrfs_super_block, flags, 64);
1488BTRFS_SETGET_STACK_FUNCS(super_generation, struct btrfs_super_block, 1496BTRFS_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);
1525BTRFS_SETGET_STACK_FUNCS(super_incompat_flags, struct btrfs_super_block, 1533BTRFS_SETGET_STACK_FUNCS(super_incompat_flags, struct btrfs_super_block,
1526 incompat_flags, 64); 1534 incompat_flags, 64);
1535BTRFS_SETGET_STACK_FUNCS(super_csum_type, struct btrfs_super_block,
1536 csum_type, 16);
1537
1538static 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
1528static inline unsigned long btrfs_leaf_data(struct extent_buffer *l) 1545static 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)
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
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))
30int btrfs_insert_file_extent(struct btrfs_trans_handle *trans, 30int 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;
119fail: 121fail:
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);
214found: 218found:
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);
501found: 508found:
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:
508next_sector: 515next_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 &sector_sum->sum, BTRFS_CRC32_SIZE); 533 &sector_sum->sum, csum_size);
527 } else { 534 } else {
528 write_extent_buffer(leaf, &sector_sum->sum, 535 write_extent_buffer(leaf, &sector_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, &sector_sum->sum, ptr, BTRFS_CRC32_SIZE); 964 read_extent_buffer(eb, &sector_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