On 16.05.19 г. 11:47 ч., Johannes Thumshirn wrote:
> 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 <jthumsh...@suse.de>
> ---
>  fs/btrfs/compression.c  | 27 +++++++++++++++++----------
>  fs/btrfs/compression.h  |  2 +-
>  fs/btrfs/file-item.c    |  2 +-
>  fs/btrfs/ordered-data.c |  3 ++-
>  4 files changed, 21 insertions(+), 13 deletions(-)
> 
> diff --git a/fs/btrfs/compression.c b/fs/btrfs/compression.c
> index 98d8c2ed367f..d5642f3b5c44 100644
> --- a/fs/btrfs/compression.c
> +++ b/fs/btrfs/compression.c
> @@ -57,12 +57,14 @@ static int check_compressed_csum(struct btrfs_inode 
> *inode,
>                                struct compressed_bio *cb,
>                                u64 disk_start)
>  {
> +     struct btrfs_fs_info *fs_info = inode->root->fs_info;
> +     u16 csum_size = btrfs_super_csum_size(fs_info->super_copy);
>       int ret;
>       struct page *page;
>       unsigned long i;
>       char *kaddr;
>       u32 csum;
> -     u32 *cb_sum = &cb->sums;
> +     u8 *cb_sum = cb->sums;
>  
>       if (inode->flags & BTRFS_INODE_NODATASUM)
>               return 0;
> @@ -76,13 +78,13 @@ static int check_compressed_csum(struct btrfs_inode 
> *inode,
>               btrfs_csum_final(csum, (u8 *)&csum);
>               kunmap_atomic(kaddr);
>  
> -             if (csum != *cb_sum) {
> +             if (memcmp(&csum, cb_sum, csum_size)) {
>                       btrfs_print_data_csum_error(inode, disk_start, csum,
> -                                     *cb_sum, cb->mirror_num);
> +                                     *(u32 *)cb_sum, cb->mirror_num);
>                       ret = -EIO;
>                       goto fail;
>               }
> -             cb_sum++;
> +             cb_sum += csum_size;
>  
>       }
>       ret = 0;
> @@ -537,7 +539,8 @@ blk_status_t btrfs_submit_compressed_read(struct inode 
> *inode, struct bio *bio,
>       struct extent_map *em;
>       blk_status_t ret = BLK_STS_RESOURCE;
>       int faili = 0;
> -     u32 *sums;
> +     u16 csum_size = btrfs_super_csum_size(fs_info->super_copy);
> +     u8 *sums;
>  
>       em_tree = &BTRFS_I(inode)->extent_tree;
>  
> @@ -559,7 +562,7 @@ blk_status_t btrfs_submit_compressed_read(struct inode 
> *inode, struct bio *bio,
>       cb->errors = 0;
>       cb->inode = inode;
>       cb->mirror_num = mirror_num;
> -     sums = &cb->sums;
> +     sums = cb->sums;
>  
>       cb->start = em->orig_start;
>       em_len = em->len;
> @@ -618,6 +621,8 @@ blk_status_t btrfs_submit_compressed_read(struct inode 
> *inode, struct bio *bio,
>               page->mapping = NULL;
>               if (submit || bio_add_page(comp_bio, page, PAGE_SIZE, 0) <
>                   PAGE_SIZE) {
> +                     unsigned int nr_sectors;
> +
>                       ret = btrfs_bio_wq_end_io(fs_info, comp_bio,
>                                                 BTRFS_WQ_ENDIO_DATA);
>                       BUG_ON(ret); /* -ENOMEM */
> @@ -632,11 +637,13 @@ blk_status_t btrfs_submit_compressed_read(struct inode 
> *inode, struct bio *bio,
>  
>                       if (!(BTRFS_I(inode)->flags & BTRFS_INODE_NODATASUM)) {
>                               ret = btrfs_lookup_bio_sums(inode, comp_bio,
> -                                                         (u8 *)sums);
> +                                                         sums);
>                               BUG_ON(ret); /* -ENOMEM */
>                       }
> -                     sums += DIV_ROUND_UP(comp_bio->bi_iter.bi_size,
> -                                          fs_info->sectorsize);
> +
> +                     nr_sectors = DIV_ROUND_UP(comp_bio->bi_iter.bi_size,
> +                                               fs_info->sectorsize);
> +                     sums += csum_size * nr_sectors;

nit: I think nr_sectors is not a good name in this particular case
because you really care about nr_csums this bio spans. To me at least,
it feels more intuitive to see :

nr_csums = DIV_ROUND_UP
sums += csum_size * nr_csums.


>  
>                       ret = btrfs_map_bio(fs_info, comp_bio, mirror_num, 0);
>                       if (ret) {
> @@ -658,7 +665,7 @@ blk_status_t btrfs_submit_compressed_read(struct inode 
> *inode, struct bio *bio,
>       BUG_ON(ret); /* -ENOMEM */
>  
>       if (!(BTRFS_I(inode)->flags & BTRFS_INODE_NODATASUM)) {
> -             ret = btrfs_lookup_bio_sums(inode, comp_bio, (u8 *) sums);
> +             ret = btrfs_lookup_bio_sums(inode, comp_bio, sums);
>               BUG_ON(ret); /* -ENOMEM */
>       }
>  
> 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 {
>        * the start of a variable length array of checksums only
>        * used by reads
>        */
> -     u32 sums;
> +     u8 sums[];
>  };
>  
>  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 210ff69917a0..c551479afa63 100644
> --- a/fs/btrfs/file-item.c
> +++ b/fs/btrfs/file-item.c
> @@ -182,7 +182,7 @@ static blk_status_t __btrfs_lookup_bio_sums(struct inode 
> *inode, struct bio *bio
>               }
>               csum = btrfs_bio->csum;
>       } else {
> -             csum = (u8 *)dst;
> +             csum = dst;
>       }
>  
>       if (bio->bi_iter.bi_size > PAGE_SIZE * 8)
> diff --git a/fs/btrfs/ordered-data.c b/fs/btrfs/ordered-data.c
> index 6f7a18148dcb..a65e5f32160b 100644
> --- a/fs/btrfs/ordered-data.c
> +++ b/fs/btrfs/ordered-data.c
> @@ -927,9 +927,10 @@ int btrfs_find_ordered_sum(struct inode *inode, u64 
> offset, u64 disk_bytenr,
>                          u8 *sum, int len)
>  {
>       struct btrfs_fs_info *fs_info = btrfs_sb(inode->i_sb);
> +     struct btrfs_inode *btrfs_inode = BTRFS_I(inode);
>       struct btrfs_ordered_sum *ordered_sum;
>       struct btrfs_ordered_extent *ordered;
> -     struct btrfs_ordered_inode_tree *tree = &BTRFS_I(inode)->ordered_tree;
> +     struct btrfs_ordered_inode_tree *tree = &btrfs_inode->ordered_tree;
>       unsigned long num_sectors;
>       unsigned long i;
>       u32 sectorsize = btrfs_inode_sectorsize(inode);
> 

Irrelevant change, this hunk could be dropped. Furthermore, I don't see
how having an explicit variable brings any value apart from increased
stack usage.

Reply via email to