public inbox for linux-btrfs@vger.kernel.org
 help / color / mirror / Atom feed
From: Qu Wenruo <wqu@suse.com>
To: linux-btrfs@vger.kernel.org
Cc: Qu Wenruo <wqu@suse.com>
Subject: [PATCH v7 15/17] btrfs: fix a subpage false alert for relocating partial preallocated data extents
Date: Mon, 12 Jul 2021 16:30:25 +0800	[thread overview]
Message-ID: <20210712083027.212734-16-wqu@suse.com> (raw)
In-Reply-To: <20210712083027.212734-1-wqu@suse.com>

[BUG]
When relocating partial preallocated data extents (part of the
preallocated extent is written) for subpage, it can cause the following
false alert and make the relocation to fail:

  BTRFS info (device dm-3): balance: start -d
  BTRFS info (device dm-3): relocating block group 13631488 flags data
  BTRFS warning (device dm-3): csum failed root -9 ino 257 off 4096 csum 0x98757625 expected csum 0x00000000 mirror 1
  BTRFS error (device dm-3): bdev /dev/mapper/arm_nvme-test errs: wr 0, rd 0, flush 0, corrupt 1, gen 0
  BTRFS warning (device dm-3): csum failed root -9 ino 257 off 4096 csum 0x98757625 expected csum 0x00000000 mirror 1
  BTRFS error (device dm-3): bdev /dev/mapper/arm_nvme-test errs: wr 0, rd 0, flush 0, corrupt 2, gen 0
  BTRFS info (device dm-3): balance: ended with status: -5

The minimal script to reproduce looks like this:

  mkfs.btrfs -f -s 4k $dev
  mount $dev -o nospace_cache $mnt
  xfs_io -f -c "falloc 0 8k" $mnt/file
  xfs_io -f -c "pwrite 0 4k" $mnt/file
  btrfs balance start -d $mnt

[CAUSE]
Function btrfs_verify_data_csum() checks if the full range has
EXTENT_NODATASUM bit for data reloc inode, if *all* bytes of the range
has EXTENT_NODATASUM bit, then it skip the range.

This works pretty well for regular sectorsize, as in that case
btrfs_verify_data_csum() is called for each sector, thus no problem at
all.

But for subpage case, btrfs_verify_data_csum() is called on each bvec,
which can contain several sectors, and since it checks *all* bytes for
EXTENT_NODATASUM bit, if we have some range with csum, then we will
continue checking all the sectors.

For the preallocated sectors, it doesn't have any csum, thus obviously
the csum won't match and cause the false alert.

[FIX]
Move the EXTENT_NODATASUM check into the main loop, so that we can check
each sector for EXTENT_NODATASUM bit for subpage case.

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

diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c
index 938b314cdd78..41d5f7f420d0 100644
--- a/fs/btrfs/inode.c
+++ b/fs/btrfs/inode.c
@@ -3290,19 +3290,24 @@ unsigned int btrfs_verify_data_csum(struct btrfs_io_bio *io_bio, u32 bio_offset,
 	if (!root->fs_info->csum_root)
 		return 0;
 
-	if (root->root_key.objectid == BTRFS_DATA_RELOC_TREE_OBJECTID &&
-	    test_range_bit(io_tree, start, end, EXTENT_NODATASUM, 1, NULL)) {
-		clear_extent_bits(io_tree, start, end, EXTENT_NODATASUM);
-		return 0;
-	}
-
 	ASSERT(page_offset(page) <= start &&
 	       end <= page_offset(page) + PAGE_SIZE - 1);
 	for (pg_off = offset_in_page(start);
 	     pg_off < offset_in_page(end);
 	     pg_off += sectorsize, bio_offset += sectorsize) {
+		u64 file_offset = pg_off + page_offset(page);
 		int ret;
 
+		if (root->root_key.objectid == BTRFS_DATA_RELOC_TREE_OBJECTID &&
+		    test_range_bit(io_tree, file_offset,
+				   file_offset + sectorsize - 1,
+				   EXTENT_NODATASUM, 1, NULL)) {
+			/* Skip the range without csum for data reloc inode */
+			clear_extent_bits(io_tree, file_offset,
+					  file_offset + sectorsize - 1,
+					  EXTENT_NODATASUM);
+			continue;
+		}
 		ret = check_data_csum(inode, io_bio, bio_offset, page, pg_off,
 				      page_offset(page) + pg_off);
 		if (ret < 0) {
-- 
2.32.0


  parent reply	other threads:[~2021-07-12  8:34 UTC|newest]

Thread overview: 20+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-07-12  8:30 [PATCH v7 00/17] btrfs: add data write support for subpage Qu Wenruo
2021-07-12  8:30 ` [PATCH v7 01/17] btrfs: properly reset @this_bio_flag in btrfs_do_readpage() to avoid inheriting old bio flags to next extent Qu Wenruo
2021-07-16 13:59   ` Anand Jain
2021-07-12  8:30 ` [PATCH v7 02/17] btrfs: fix NULL pointer dereference when reading two compressed extent inside the same page Qu Wenruo
2021-07-12  8:30 ` [PATCH v7 03/17] btrfs: disable compressed readahead for subpage Qu Wenruo
2021-07-12  8:30 ` [PATCH v7 04/17] btrfs: grab correct extent map for subpage compressed extent read Qu Wenruo
2021-07-12  8:30 ` [PATCH v7 05/17] btrfs: rework btrfs_decompress_buf2page() Qu Wenruo
2021-07-12  8:30 ` [PATCH v7 06/17] btrfs: rework lzo_decompress_bio() to make it subpage compatible Qu Wenruo
2021-07-12  8:30 ` [PATCH v7 07/17] btrfs: extract relocation page read and dirty part into its own function Qu Wenruo
2021-07-12  8:30 ` [PATCH v7 08/17] btrfs: make relocate_one_page() to handle subpage case Qu Wenruo
2021-07-12  8:30 ` [PATCH v7 09/17] btrfs: fix wild subpage writeback which does not have ordered extent Qu Wenruo
2021-07-12  8:30 ` [PATCH v7 10/17] btrfs: disable inline extent creation for subpage Qu Wenruo
2021-07-12  8:30 ` [PATCH v7 11/17] btrfs: allow submit_extent_page() to do bio split " Qu Wenruo
2021-07-12  8:30 ` [PATCH v7 12/17] btrfs: reject raid5/6 fs " Qu Wenruo
2021-07-13  0:39   ` Anand Jain
2021-07-12  8:30 ` [PATCH v7 13/17] btrfs: fix a crash caused by race between prepare_pages() and btrfs_releasepage() Qu Wenruo
2021-07-12  8:30 ` [PATCH v7 14/17] btrfs: fix a use-after-free bug in writeback subpage helper Qu Wenruo
2021-07-12  8:30 ` Qu Wenruo [this message]
2021-07-12  8:30 ` [PATCH v7 16/17] btrfs: fix a subpage relocation data corruption Qu Wenruo
2021-07-12  8:30 ` [PATCH v7 17/17] btrfs: allow read-write for 4K sectorsize on 64K page size systems Qu Wenruo

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20210712083027.212734-16-wqu@suse.com \
    --to=wqu@suse.com \
    --cc=linux-btrfs@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox