Skip to content

Commit 10fe6ca

Browse files
Johannes Thumshirnkdave
authored andcommitted
btrfs: don't assume compressed_bio sums to be 4 bytes
BTRFS has the implicit assumption that a checksum in compressed_bio is 4 bytes. While this is true for CRC32C, it is not for any other checksum. Change the data type to be a byte array and adjust loop index calculation accordingly. Signed-off-by: Johannes Thumshirn <[email protected]> Reviewed-by: David Sterba <[email protected]> Signed-off-by: David Sterba <[email protected]>
1 parent 1e25a2e commit 10fe6ca

File tree

3 files changed

+19
-12
lines changed

3 files changed

+19
-12
lines changed

fs/btrfs/compression.c

Lines changed: 17 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -57,12 +57,14 @@ static int check_compressed_csum(struct btrfs_inode *inode,
5757
struct compressed_bio *cb,
5858
u64 disk_start)
5959
{
60+
struct btrfs_fs_info *fs_info = inode->root->fs_info;
61+
const u16 csum_size = btrfs_super_csum_size(fs_info->super_copy);
6062
int ret;
6163
struct page *page;
6264
unsigned long i;
6365
char *kaddr;
6466
u32 csum;
65-
u32 *cb_sum = &cb->sums;
67+
u8 *cb_sum = cb->sums;
6668

6769
if (inode->flags & BTRFS_INODE_NODATASUM)
6870
return 0;
@@ -76,13 +78,13 @@ static int check_compressed_csum(struct btrfs_inode *inode,
7678
btrfs_csum_final(csum, (u8 *)&csum);
7779
kunmap_atomic(kaddr);
7880

79-
if (csum != *cb_sum) {
81+
if (memcmp(&csum, cb_sum, csum_size)) {
8082
btrfs_print_data_csum_error(inode, disk_start, csum,
81-
*cb_sum, cb->mirror_num);
83+
*(u32 *)cb_sum, cb->mirror_num);
8284
ret = -EIO;
8385
goto fail;
8486
}
85-
cb_sum++;
87+
cb_sum += csum_size;
8688

8789
}
8890
ret = 0;
@@ -536,7 +538,8 @@ blk_status_t btrfs_submit_compressed_read(struct inode *inode, struct bio *bio,
536538
struct extent_map *em;
537539
blk_status_t ret = BLK_STS_RESOURCE;
538540
int faili = 0;
539-
u32 *sums;
541+
const u16 csum_size = btrfs_super_csum_size(fs_info->super_copy);
542+
u8 *sums;
540543

541544
em_tree = &BTRFS_I(inode)->extent_tree;
542545

@@ -558,7 +561,7 @@ blk_status_t btrfs_submit_compressed_read(struct inode *inode, struct bio *bio,
558561
cb->errors = 0;
559562
cb->inode = inode;
560563
cb->mirror_num = mirror_num;
561-
sums = &cb->sums;
564+
sums = cb->sums;
562565

563566
cb->start = em->orig_start;
564567
em_len = em->len;
@@ -617,6 +620,8 @@ blk_status_t btrfs_submit_compressed_read(struct inode *inode, struct bio *bio,
617620
page->mapping = NULL;
618621
if (submit || bio_add_page(comp_bio, page, PAGE_SIZE, 0) <
619622
PAGE_SIZE) {
623+
unsigned int nr_sectors;
624+
620625
ret = btrfs_bio_wq_end_io(fs_info, comp_bio,
621626
BTRFS_WQ_ENDIO_DATA);
622627
BUG_ON(ret); /* -ENOMEM */
@@ -631,11 +636,13 @@ blk_status_t btrfs_submit_compressed_read(struct inode *inode, struct bio *bio,
631636

632637
if (!(BTRFS_I(inode)->flags & BTRFS_INODE_NODATASUM)) {
633638
ret = btrfs_lookup_bio_sums(inode, comp_bio,
634-
(u8 *)sums);
639+
sums);
635640
BUG_ON(ret); /* -ENOMEM */
636641
}
637-
sums += DIV_ROUND_UP(comp_bio->bi_iter.bi_size,
638-
fs_info->sectorsize);
642+
643+
nr_sectors = DIV_ROUND_UP(comp_bio->bi_iter.bi_size,
644+
fs_info->sectorsize);
645+
sums += csum_size * nr_sectors;
639646

640647
ret = btrfs_map_bio(fs_info, comp_bio, mirror_num, 0);
641648
if (ret) {
@@ -657,7 +664,7 @@ blk_status_t btrfs_submit_compressed_read(struct inode *inode, struct bio *bio,
657664
BUG_ON(ret); /* -ENOMEM */
658665

659666
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);
661668
BUG_ON(ret); /* -ENOMEM */
662669
}
663670

fs/btrfs/compression.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ struct compressed_bio {
6161
* the start of a variable length array of checksums only
6262
* used by reads
6363
*/
64-
u32 sums;
64+
u8 sums[];
6565
};
6666

6767
static inline unsigned int btrfs_compress_type(unsigned int type_level)

fs/btrfs/file-item.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -186,7 +186,7 @@ static blk_status_t __btrfs_lookup_bio_sums(struct inode *inode, struct bio *bio
186186
}
187187
csum = btrfs_bio->csum;
188188
} else {
189-
csum = (u8 *)dst;
189+
csum = dst;
190190
}
191191

192192
if (bio->bi_iter.bi_size > PAGE_SIZE * 8)

0 commit comments

Comments
 (0)