diff options
-rw-r--r-- | fs/btrfs/compression.c | 27 | ||||
-rw-r--r-- | fs/btrfs/compression.h | 2 | ||||
-rw-r--r-- | fs/btrfs/file-item.c | 2 |
3 files changed, 19 insertions, 12 deletions
diff --git a/fs/btrfs/compression.c b/fs/btrfs/compression.c index a8e551ca8798..92291f266324 100644 --- a/fs/btrfs/compression.c +++ b/fs/btrfs/compression.c | |||
@@ -57,12 +57,14 @@ static int check_compressed_csum(struct btrfs_inode *inode, | |||
57 | struct compressed_bio *cb, | 57 | struct compressed_bio *cb, |
58 | u64 disk_start) | 58 | u64 disk_start) |
59 | { | 59 | { |
60 | struct btrfs_fs_info *fs_info = inode->root->fs_info; | ||
61 | const u16 csum_size = btrfs_super_csum_size(fs_info->super_copy); | ||
60 | int ret; | 62 | int ret; |
61 | struct page *page; | 63 | struct page *page; |
62 | unsigned long i; | 64 | unsigned long i; |
63 | char *kaddr; | 65 | char *kaddr; |
64 | u32 csum; | 66 | u32 csum; |
65 | u32 *cb_sum = &cb->sums; | 67 | u8 *cb_sum = cb->sums; |
66 | 68 | ||
67 | if (inode->flags & BTRFS_INODE_NODATASUM) | 69 | if (inode->flags & BTRFS_INODE_NODATASUM) |
68 | return 0; | 70 | return 0; |
@@ -76,13 +78,13 @@ static int check_compressed_csum(struct btrfs_inode *inode, | |||
76 | btrfs_csum_final(csum, (u8 *)&csum); | 78 | btrfs_csum_final(csum, (u8 *)&csum); |
77 | kunmap_atomic(kaddr); | 79 | kunmap_atomic(kaddr); |
78 | 80 | ||
79 | if (csum != *cb_sum) { | 81 | if (memcmp(&csum, cb_sum, csum_size)) { |
80 | btrfs_print_data_csum_error(inode, disk_start, csum, | 82 | btrfs_print_data_csum_error(inode, disk_start, csum, |
81 | *cb_sum, cb->mirror_num); | 83 | *(u32 *)cb_sum, cb->mirror_num); |
82 | ret = -EIO; | 84 | ret = -EIO; |
83 | goto fail; | 85 | goto fail; |
84 | } | 86 | } |
85 | cb_sum++; | 87 | cb_sum += csum_size; |
86 | 88 | ||
87 | } | 89 | } |
88 | ret = 0; | 90 | ret = 0; |
@@ -536,7 +538,8 @@ blk_status_t btrfs_submit_compressed_read(struct inode *inode, struct bio *bio, | |||
536 | struct extent_map *em; | 538 | struct extent_map *em; |
537 | blk_status_t ret = BLK_STS_RESOURCE; | 539 | blk_status_t ret = BLK_STS_RESOURCE; |
538 | int faili = 0; | 540 | int faili = 0; |
539 | u32 *sums; | 541 | const u16 csum_size = btrfs_super_csum_size(fs_info->super_copy); |
542 | u8 *sums; | ||
540 | 543 | ||
541 | em_tree = &BTRFS_I(inode)->extent_tree; | 544 | em_tree = &BTRFS_I(inode)->extent_tree; |
542 | 545 | ||
@@ -558,7 +561,7 @@ blk_status_t btrfs_submit_compressed_read(struct inode *inode, struct bio *bio, | |||
558 | cb->errors = 0; | 561 | cb->errors = 0; |
559 | cb->inode = inode; | 562 | cb->inode = inode; |
560 | cb->mirror_num = mirror_num; | 563 | cb->mirror_num = mirror_num; |
561 | sums = &cb->sums; | 564 | sums = cb->sums; |
562 | 565 | ||
563 | cb->start = em->orig_start; | 566 | cb->start = em->orig_start; |
564 | em_len = em->len; | 567 | em_len = em->len; |
@@ -617,6 +620,8 @@ blk_status_t btrfs_submit_compressed_read(struct inode *inode, struct bio *bio, | |||
617 | page->mapping = NULL; | 620 | page->mapping = NULL; |
618 | if (submit || bio_add_page(comp_bio, page, PAGE_SIZE, 0) < | 621 | if (submit || bio_add_page(comp_bio, page, PAGE_SIZE, 0) < |
619 | PAGE_SIZE) { | 622 | PAGE_SIZE) { |
623 | unsigned int nr_sectors; | ||
624 | |||
620 | ret = btrfs_bio_wq_end_io(fs_info, comp_bio, | 625 | ret = btrfs_bio_wq_end_io(fs_info, comp_bio, |
621 | BTRFS_WQ_ENDIO_DATA); | 626 | BTRFS_WQ_ENDIO_DATA); |
622 | BUG_ON(ret); /* -ENOMEM */ | 627 | BUG_ON(ret); /* -ENOMEM */ |
@@ -631,11 +636,13 @@ blk_status_t btrfs_submit_compressed_read(struct inode *inode, struct bio *bio, | |||
631 | 636 | ||
632 | if (!(BTRFS_I(inode)->flags & BTRFS_INODE_NODATASUM)) { | 637 | if (!(BTRFS_I(inode)->flags & BTRFS_INODE_NODATASUM)) { |
633 | ret = btrfs_lookup_bio_sums(inode, comp_bio, | 638 | ret = btrfs_lookup_bio_sums(inode, comp_bio, |
634 | (u8 *)sums); | 639 | sums); |
635 | BUG_ON(ret); /* -ENOMEM */ | 640 | BUG_ON(ret); /* -ENOMEM */ |
636 | } | 641 | } |
637 | sums += DIV_ROUND_UP(comp_bio->bi_iter.bi_size, | 642 | |
638 | fs_info->sectorsize); | 643 | nr_sectors = DIV_ROUND_UP(comp_bio->bi_iter.bi_size, |
644 | fs_info->sectorsize); | ||
645 | sums += csum_size * nr_sectors; | ||
639 | 646 | ||
640 | ret = btrfs_map_bio(fs_info, comp_bio, mirror_num, 0); | 647 | ret = btrfs_map_bio(fs_info, comp_bio, mirror_num, 0); |
641 | if (ret) { | 648 | if (ret) { |
@@ -657,7 +664,7 @@ blk_status_t btrfs_submit_compressed_read(struct inode *inode, struct bio *bio, | |||
657 | BUG_ON(ret); /* -ENOMEM */ | 664 | BUG_ON(ret); /* -ENOMEM */ |
658 | 665 | ||
659 | if (!(BTRFS_I(inode)->flags & BTRFS_INODE_NODATASUM)) { | 666 | if (!(BTRFS_I(inode)->flags & BTRFS_INODE_NODATASUM)) { |
660 | ret = btrfs_lookup_bio_sums(inode, comp_bio, (u8 *) sums); | 667 | ret = btrfs_lookup_bio_sums(inode, comp_bio, sums); |
661 | BUG_ON(ret); /* -ENOMEM */ | 668 | BUG_ON(ret); /* -ENOMEM */ |
662 | } | 669 | } |
663 | 670 | ||
diff --git a/fs/btrfs/compression.h b/fs/btrfs/compression.h index 9976fe0f7526..191e5f4e3523 100644 --- a/fs/btrfs/compression.h +++ b/fs/btrfs/compression.h | |||
@@ -61,7 +61,7 @@ struct compressed_bio { | |||
61 | * the start of a variable length array of checksums only | 61 | * the start of a variable length array of checksums only |
62 | * used by reads | 62 | * used by reads |
63 | */ | 63 | */ |
64 | u32 sums; | 64 | u8 sums[]; |
65 | }; | 65 | }; |
66 | 66 | ||
67 | static inline unsigned int btrfs_compress_type(unsigned int type_level) | 67 | static inline unsigned int btrfs_compress_type(unsigned int type_level) |
diff --git a/fs/btrfs/file-item.c b/fs/btrfs/file-item.c index 0464dd4c0579..de89fd1310a6 100644 --- a/fs/btrfs/file-item.c +++ b/fs/btrfs/file-item.c | |||
@@ -186,7 +186,7 @@ static blk_status_t __btrfs_lookup_bio_sums(struct inode *inode, struct bio *bio | |||
186 | } | 186 | } |
187 | csum = btrfs_bio->csum; | 187 | csum = btrfs_bio->csum; |
188 | } else { | 188 | } else { |
189 | csum = (u8 *)dst; | 189 | csum = dst; |
190 | } | 190 | } |
191 | 191 | ||
192 | if (bio->bi_iter.bi_size > PAGE_SIZE * 8) | 192 | if (bio->bi_iter.bi_size > PAGE_SIZE * 8) |