btrfs: use iosize while reading compressed pages
authorGoldwyn Rodrigues <rgoldwyn@suse.de>
Tue, 15 Sep 2020 15:41:40 +0000 (10:41 -0500)
committerDavid Sterba <dsterba@suse.com>
Tue, 8 Dec 2020 14:53:37 +0000 (15:53 +0100)
While using compression, a submitted bio is mapped with a compressed bio
which performs the read from disk, decompresses and returns uncompressed
data to original bio. The original bio must reflect the uncompressed
size (iosize) of the I/O to be performed, or else the page just gets the
decompressed I/O length of data (disk_io_size). The compressed bio
checks the extent map and gets the correct length while performing the
I/O from disk.

This came up in subpage work when only compressed length of the original
bio was filled in the page. This worked correctly for pagesize ==
sectorsize because both compressed and uncompressed data are at pagesize
boundaries, and would end up filling the requested page.

Reviewed-by: Josef Bacik <josef@toxicpanda.com>
Signed-off-by: Goldwyn Rodrigues <rgoldwyn@suse.com>
Reviewed-by: David Sterba <dsterba@suse.com>
Signed-off-by: David Sterba <dsterba@suse.com>
fs/btrfs/extent_io.c

index 60f5f68d892dffa16c353dc902fbeee31868dbfd..14d01b76f5c97affb66f3c49399f4386a1c9d757 100644 (file)
@@ -3158,7 +3158,6 @@ int btrfs_do_readpage(struct page *page, struct extent_map **em_cached,
        int nr = 0;
        size_t pg_offset = 0;
        size_t iosize;
-       size_t disk_io_size;
        size_t blocksize = inode->i_sb->s_blocksize;
        unsigned long this_bio_flag = 0;
        struct extent_io_tree *tree = &BTRFS_I(inode)->io_tree;
@@ -3224,13 +3223,10 @@ int btrfs_do_readpage(struct page *page, struct extent_map **em_cached,
                iosize = min(extent_map_end(em) - cur, end - cur + 1);
                cur_end = min(extent_map_end(em) - 1, end);
                iosize = ALIGN(iosize, blocksize);
-               if (this_bio_flag & EXTENT_BIO_COMPRESSED) {
-                       disk_io_size = em->block_len;
+               if (this_bio_flag & EXTENT_BIO_COMPRESSED)
                        offset = em->block_start;
-               } else {
+               else
                        offset = em->block_start + extent_offset;
-                       disk_io_size = iosize;
-               }
                block_start = em->block_start;
                if (test_bit(EXTENT_FLAG_PREALLOC, &em->flags))
                        block_start = EXTENT_MAP_HOLE;
@@ -3319,7 +3315,7 @@ int btrfs_do_readpage(struct page *page, struct extent_map **em_cached,
                }
 
                ret = submit_extent_page(REQ_OP_READ | read_flags, NULL,
-                                        page, offset, disk_io_size,
+                                        page, offset, iosize,
                                         pg_offset, bio,
                                         end_bio_extent_readpage, 0,
                                         *bio_flags,