linux-btrfs.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 0/2] btrfs: add proper subpage compress read support
@ 2021-02-04  7:03 Qu Wenruo
  2021-02-04  7:03 ` [PATCH 1/2] btrfs: make btrfs_submit_compressed_read() to be subpage compatible Qu Wenruo
                   ` (3 more replies)
  0 siblings, 4 replies; 5+ messages in thread
From: Qu Wenruo @ 2021-02-04  7:03 UTC (permalink / raw)
  To: linux-btrfs

During the long time subpage development, I forgot to properly check
compression code after just one compression read success during early
development.

It turns out that, with current RO support, the compression read needs
more modification to make it work.

Thankfully, the patchset is small, and should not cause problems for
regular sectorsize == PAGE_SIZE case.

Thanks Anand for exposing the problems.

Qu Wenruo (2):
  btrfs: make btrfs_submit_compressed_read() to be subpage compatible
  btrfs: make check_compressed_csum() to be subpage compatible

 fs/btrfs/compression.c | 67 ++++++++++++++++++++++++++++++------------
 1 file changed, 48 insertions(+), 19 deletions(-)

-- 
2.30.0


^ permalink raw reply	[flat|nested] 5+ messages in thread

* [PATCH 1/2] btrfs: make btrfs_submit_compressed_read() to be subpage compatible
  2021-02-04  7:03 [PATCH 0/2] btrfs: add proper subpage compress read support Qu Wenruo
@ 2021-02-04  7:03 ` Qu Wenruo
  2021-02-04  7:03 ` [PATCH 2/2] btrfs: make check_compressed_csum() " Qu Wenruo
                   ` (2 subsequent siblings)
  3 siblings, 0 replies; 5+ messages in thread
From: Qu Wenruo @ 2021-02-04  7:03 UTC (permalink / raw)
  To: linux-btrfs

For compressed read, we always submit page read using page size.

This doesn't work well with subpage, as for subpage one page can contain
several sectors.
Such submission will read range out of what we want, and cause problems.

Thankfully to make it subpage compatible, we only need to change how the
last page of the compressed extent is read.

Instead of always adding a full page to the compressed read bio, if we're
at the last page, calculate the size using compressed length, so that we
only add part of the range into the compressed read bio.

Since we are here, also change the PAGE_SIZE used in
lookup_extent_mapping() to sectorsize.
This modification won't cause any functional change, as
lookup_extent_mapping() can handle the case where the search range is
larger than found extent range.

Signed-off-by: Qu Wenruo <wqu@suse.com>
---
 fs/btrfs/compression.c | 26 ++++++++++++++++++++------
 1 file changed, 20 insertions(+), 6 deletions(-)

diff --git a/fs/btrfs/compression.c b/fs/btrfs/compression.c
index 6d203acfdeb3..3d16ca5d420d 100644
--- a/fs/btrfs/compression.c
+++ b/fs/btrfs/compression.c
@@ -640,7 +640,7 @@ blk_status_t btrfs_submit_compressed_read(struct inode *inode, struct bio *bio,
 	read_lock(&em_tree->lock);
 	em = lookup_extent_mapping(em_tree,
 				   page_offset(bio_first_page_all(bio)),
-				   PAGE_SIZE);
+				   fs_info->sectorsize);
 	read_unlock(&em_tree->lock);
 	if (!em)
 		return BLK_STS_IOERR;
@@ -698,19 +698,33 @@ blk_status_t btrfs_submit_compressed_read(struct inode *inode, struct bio *bio,
 	refcount_set(&cb->pending_bios, 1);
 
 	for (pg_index = 0; pg_index < nr_pages; pg_index++) {
+		u32 pg_len;
 		int submit = 0;
 
+		/*
+		 * To handle subpage case, we need to make sure the bio only
+		 * covers the range we need.
+		 *
+		 * If we're at the last page, truncate the length to only cover
+		 * the remaining part.
+		 */
+		if (pg_index == nr_pages - 1)
+			pg_len = min_t(u32, PAGE_SIZE,
+					compressed_len - pg_index * PAGE_SIZE);
+		else
+			pg_len = PAGE_SIZE;
+
 		page = cb->compressed_pages[pg_index];
 		page->mapping = inode->i_mapping;
 		page->index = em_start >> PAGE_SHIFT;
 
 		if (comp_bio->bi_iter.bi_size)
-			submit = btrfs_bio_fits_in_stripe(page, PAGE_SIZE,
+			submit = btrfs_bio_fits_in_stripe(page, pg_len,
 							  comp_bio, 0);
 
 		page->mapping = NULL;
-		if (submit || bio_add_page(comp_bio, page, PAGE_SIZE, 0) <
-		    PAGE_SIZE) {
+		if (submit || bio_add_page(comp_bio, page, pg_len, 0) <
+		    pg_len) {
 			unsigned int nr_sectors;
 
 			ret = btrfs_bio_wq_end_io(fs_info, comp_bio,
@@ -743,9 +757,9 @@ blk_status_t btrfs_submit_compressed_read(struct inode *inode, struct bio *bio,
 			comp_bio->bi_private = cb;
 			comp_bio->bi_end_io = end_compressed_bio_read;
 
-			bio_add_page(comp_bio, page, PAGE_SIZE, 0);
+			bio_add_page(comp_bio, page, pg_len, 0);
 		}
-		cur_disk_byte += PAGE_SIZE;
+		cur_disk_byte += pg_len;
 	}
 
 	ret = btrfs_bio_wq_end_io(fs_info, comp_bio, BTRFS_WQ_ENDIO_DATA);
-- 
2.30.0


^ permalink raw reply related	[flat|nested] 5+ messages in thread

* [PATCH 2/2] btrfs: make check_compressed_csum() to be subpage compatible
  2021-02-04  7:03 [PATCH 0/2] btrfs: add proper subpage compress read support Qu Wenruo
  2021-02-04  7:03 ` [PATCH 1/2] btrfs: make btrfs_submit_compressed_read() to be subpage compatible Qu Wenruo
@ 2021-02-04  7:03 ` Qu Wenruo
  2021-02-04 12:17 ` [PATCH 0/2] btrfs: add proper subpage compress read support Anand Jain
  2021-02-10 22:21 ` David Sterba
  3 siblings, 0 replies; 5+ messages in thread
From: Qu Wenruo @ 2021-02-04  7:03 UTC (permalink / raw)
  To: linux-btrfs

Currently check_compressed_csum() completely relies on sectorsize ==
PAGE_SIZE to do checksum verification for compressed extents.

To make it subpage compatible, this patch will:
- Do extra calculation for the csum range
  Since we have multiple sectors inside a page, we need to only hash
  the range we want, not the full page anymore.

- Do sector-by-sector hash inside the page

With this patch and previous conversion on
btrfs_submit_compressed_read(), now we can read subpage compressed
extents properly, and do proper csum verification.

Signed-off-by: Qu Wenruo <wqu@suse.com>
---
 fs/btrfs/compression.c | 41 ++++++++++++++++++++++++++++-------------
 1 file changed, 28 insertions(+), 13 deletions(-)

diff --git a/fs/btrfs/compression.c b/fs/btrfs/compression.c
index 3d16ca5d420d..696459d9d244 100644
--- a/fs/btrfs/compression.c
+++ b/fs/btrfs/compression.c
@@ -141,6 +141,7 @@ static int check_compressed_csum(struct btrfs_inode *inode, struct bio *bio,
 	struct btrfs_fs_info *fs_info = inode->root->fs_info;
 	SHASH_DESC_ON_STACK(shash, fs_info->csum_shash);
 	const u32 csum_size = fs_info->csum_size;
+	const u32 sectorsize = fs_info->sectorsize;
 	struct page *page;
 	unsigned long i;
 	char *kaddr;
@@ -154,22 +155,36 @@ static int check_compressed_csum(struct btrfs_inode *inode, struct bio *bio,
 	shash->tfm = fs_info->csum_shash;
 
 	for (i = 0; i < cb->nr_pages; i++) {
+		u32 pg_offset;
+		u32 bytes_left;
 		page = cb->compressed_pages[i];
 
-		kaddr = kmap_atomic(page);
-		crypto_shash_digest(shash, kaddr, PAGE_SIZE, csum);
-		kunmap_atomic(kaddr);
-
-		if (memcmp(&csum, cb_sum, csum_size)) {
-			btrfs_print_data_csum_error(inode, disk_start,
-					csum, cb_sum, cb->mirror_num);
-			if (btrfs_io_bio(bio)->device)
-				btrfs_dev_stat_inc_and_print(
-					btrfs_io_bio(bio)->device,
-					BTRFS_DEV_STAT_CORRUPTION_ERRS);
-			return -EIO;
+		/* Determine the remaining bytes inside the page first */
+		if (i == cb->nr_pages - 1)
+			bytes_left = cb->compressed_len - i * PAGE_SIZE;
+		else
+			bytes_left = PAGE_SIZE;
+
+		/* Hash through the page sector by sector */
+		for (pg_offset = 0; pg_offset < bytes_left;
+		     pg_offset += sectorsize) {
+			kaddr = kmap_atomic(page);
+			crypto_shash_digest(shash, kaddr + pg_offset,
+					    sectorsize, csum);
+			kunmap_atomic(kaddr);
+
+			if (memcmp(&csum, cb_sum, csum_size)) {
+				btrfs_print_data_csum_error(inode, disk_start,
+						csum, cb_sum, cb->mirror_num);
+				if (btrfs_io_bio(bio)->device)
+					btrfs_dev_stat_inc_and_print(
+						btrfs_io_bio(bio)->device,
+						BTRFS_DEV_STAT_CORRUPTION_ERRS);
+				return -EIO;
+			}
+			cb_sum += csum_size;
+			disk_start += sectorsize;
 		}
-		cb_sum += csum_size;
 	}
 	return 0;
 }
-- 
2.30.0


^ permalink raw reply related	[flat|nested] 5+ messages in thread

* Re: [PATCH 0/2] btrfs: add proper subpage compress read support
  2021-02-04  7:03 [PATCH 0/2] btrfs: add proper subpage compress read support Qu Wenruo
  2021-02-04  7:03 ` [PATCH 1/2] btrfs: make btrfs_submit_compressed_read() to be subpage compatible Qu Wenruo
  2021-02-04  7:03 ` [PATCH 2/2] btrfs: make check_compressed_csum() " Qu Wenruo
@ 2021-02-04 12:17 ` Anand Jain
  2021-02-10 22:21 ` David Sterba
  3 siblings, 0 replies; 5+ messages in thread
From: Anand Jain @ 2021-02-04 12:17 UTC (permalink / raw)
  To: Qu Wenruo, linux-btrfs


  Nice. Works well.

Thanks, Anand


On 2/4/2021 3:03 PM, Qu Wenruo wrote:
> During the long time subpage development, I forgot to properly check
> compression code after just one compression read success during early
> development.
> 
> It turns out that, with current RO support, the compression read needs
> more modification to make it work.
> 
> Thankfully, the patchset is small, and should not cause problems for
> regular sectorsize == PAGE_SIZE case.
> 
> Thanks Anand for exposing the problems.
> 
> Qu Wenruo (2):
>    btrfs: make btrfs_submit_compressed_read() to be subpage compatible
>    btrfs: make check_compressed_csum() to be subpage compatible
> 
>   fs/btrfs/compression.c | 67 ++++++++++++++++++++++++++++++------------
>   1 file changed, 48 insertions(+), 19 deletions(-)
> 


^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [PATCH 0/2] btrfs: add proper subpage compress read support
  2021-02-04  7:03 [PATCH 0/2] btrfs: add proper subpage compress read support Qu Wenruo
                   ` (2 preceding siblings ...)
  2021-02-04 12:17 ` [PATCH 0/2] btrfs: add proper subpage compress read support Anand Jain
@ 2021-02-10 22:21 ` David Sterba
  3 siblings, 0 replies; 5+ messages in thread
From: David Sterba @ 2021-02-10 22:21 UTC (permalink / raw)
  To: Qu Wenruo; +Cc: linux-btrfs

On Thu, Feb 04, 2021 at 03:03:22PM +0800, Qu Wenruo wrote:
> During the long time subpage development, I forgot to properly check
> compression code after just one compression read success during early
> development.
> 
> It turns out that, with current RO support, the compression read needs
> more modification to make it work.
> 
> Thankfully, the patchset is small, and should not cause problems for
> regular sectorsize == PAGE_SIZE case.
> 
> Thanks Anand for exposing the problems.
> 
> Qu Wenruo (2):
>   btrfs: make btrfs_submit_compressed_read() to be subpage compatible
>   btrfs: make check_compressed_csum() to be subpage compatible

Thanks, now in for-next, will go to 5.12-rc as regression fixes.

^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2021-02-10 22:24 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-02-04  7:03 [PATCH 0/2] btrfs: add proper subpage compress read support Qu Wenruo
2021-02-04  7:03 ` [PATCH 1/2] btrfs: make btrfs_submit_compressed_read() to be subpage compatible Qu Wenruo
2021-02-04  7:03 ` [PATCH 2/2] btrfs: make check_compressed_csum() " Qu Wenruo
2021-02-04 12:17 ` [PATCH 0/2] btrfs: add proper subpage compress read support Anand Jain
2021-02-10 22:21 ` David Sterba

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).