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
Subject: [PATCH v2 1/3] btrfs: use dummy extent buffer for super block sys chunk array read
Date: Tue, 11 Jan 2022 10:34:32 +0800	[thread overview]
Message-ID: <20220111023434.22915-2-wqu@suse.com> (raw)
In-Reply-To: <20220111023434.22915-1-wqu@suse.com>

[BUG]
During test for 16K page size with 4K sectorsize and 64K nodesize, btrfs
will reject the mount with the following dmesg:

 BTRFS warning (device dm-1): read-write for sector size 4096 with page size 16384 is experimental
 BTRFS error (device dm-1): tree block crosses page boundary, start 65536 nodesize 65536
 BTRFS error (device dm-1): failed to read the system array: -22
 BTRFS error (device dm-1): open_ctree failed

The rejection only happens with sectorsize=4K, page_size=16K and
nodesize=64K combination.

For sectorsize=4K, page_size=16K and nodesize=16K (default) case, it
works fine.

[CAUSE]
The problem is in how we read sys chunk array.

In function btrfs_read_sys_array(), we allocate an extent buffer and
copy super block into the extent buffer, so that we can use various
extent buffer helpers to do the work.

But the problem is, we're calling btrfs_find_create_tree_block(), which
will do all the validation check, including the page boundary check for
subpage cases.

[FIX]
In fact, we only need a dummy extent buffer, without all the checks for
a real extent buffer.

This patch will replace the btrfs_find_create_tree_block() call with
__alloc_dummy_extent_buffer().

By this we can:

- Set the extent buffer size to BTRFS_SUPER_INFO_SIZE
- Avoid the unnecessary validation checks

Also since we're here, remove some stale comments on setting the eb page
uptodate, as now set_extent_buffer_uptodate() can handle dummy eb cases
without any problem.

Signed-off-by: Qu Wenruo <wqu@suse.com>
---
 fs/btrfs/volumes.c | 27 ++++-----------------------
 1 file changed, 4 insertions(+), 23 deletions(-)

diff --git a/fs/btrfs/volumes.c b/fs/btrfs/volumes.c
index b07d382d53a8..00c7f5cf4b52 100644
--- a/fs/btrfs/volumes.c
+++ b/fs/btrfs/volumes.c
@@ -7373,7 +7373,6 @@ static int read_one_dev(struct extent_buffer *leaf,
 
 int btrfs_read_sys_array(struct btrfs_fs_info *fs_info)
 {
-	struct btrfs_root *root = fs_info->tree_root;
 	struct btrfs_super_block *super_copy = fs_info->super_copy;
 	struct extent_buffer *sb;
 	struct btrfs_disk_key *disk_key;
@@ -7388,31 +7387,13 @@ int btrfs_read_sys_array(struct btrfs_fs_info *fs_info)
 	u64 type;
 	struct btrfs_key key;
 
-	ASSERT(BTRFS_SUPER_INFO_SIZE <= fs_info->nodesize);
-	/*
-	 * This will create extent buffer of nodesize, superblock size is
-	 * fixed to BTRFS_SUPER_INFO_SIZE. If nodesize > sb size, this will
-	 * overallocate but we can keep it as-is, only the first page is used.
-	 */
-	sb = btrfs_find_create_tree_block(fs_info, BTRFS_SUPER_INFO_OFFSET,
-					  root->root_key.objectid, 0);
+	ASSERT(BTRFS_SUPER_INFO_SIZE <= fs_info->nodesize &&
+	       BTRFS_SUPER_INFO_SIZE <= PAGE_SIZE);
+	sb = __alloc_dummy_extent_buffer(fs_info, BTRFS_SUPER_INFO_OFFSET,
+					 BTRFS_SUPER_INFO_SIZE);
 	if (IS_ERR(sb))
 		return PTR_ERR(sb);
 	set_extent_buffer_uptodate(sb);
-	/*
-	 * The sb extent buffer is artificial and just used to read the system array.
-	 * set_extent_buffer_uptodate() call does not properly mark all it's
-	 * pages up-to-date when the page is larger: extent does not cover the
-	 * whole page and consequently check_page_uptodate does not find all
-	 * the page's extents up-to-date (the hole beyond sb),
-	 * write_extent_buffer then triggers a WARN_ON.
-	 *
-	 * Regular short extents go through mark_extent_buffer_dirty/writeback cycle,
-	 * but sb spans only this function. Add an explicit SetPageUptodate call
-	 * to silence the warning eg. on PowerPC 64.
-	 */
-	if (PAGE_SIZE > BTRFS_SUPER_INFO_SIZE)
-		SetPageUptodate(sb->pages[0]);
 
 	write_extent_buffer(sb, super_copy, 0, BTRFS_SUPER_INFO_SIZE);
 	array_size = btrfs_super_sys_array_size(super_copy);
-- 
2.34.1


  reply	other threads:[~2022-01-11  2:34 UTC|newest]

Thread overview: 5+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-01-11  2:34 [PATCH v2 0/3] btrfs: support more pages sizes for the subpage support Qu Wenruo
2022-01-11  2:34 ` Qu Wenruo [this message]
2022-01-11  9:56   ` [PATCH v2 1/3] btrfs: use dummy extent buffer for super block sys chunk array read Qu Wenruo
2022-01-11  2:34 ` [PATCH v2 2/3] btrfs: make nodesize >= PAGE_SIZE case to reuse the non-subpage routine Qu Wenruo
2022-01-11  2:34 ` [PATCH v2 3/3] btrfs: expand subpage support to any PAGE_SIZE > 4K 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=20220111023434.22915-2-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