From: Qu Wenruo <wqu@suse.com>
To: linux-btrfs@vger.kernel.org
Subject: [PATCH 5/8] btrfs: scrub: introduce scrub_page::page_len for subpage support
Date: Mon, 26 Oct 2020 15:11:12 +0800 [thread overview]
Message-ID: <20201026071115.57225-6-wqu@suse.com> (raw)
In-Reply-To: <20201026071115.57225-1-wqu@suse.com>
Currently scrub_page only has one csum for each page, this is fine if
page size == sector size, then each page has one csum for it.
But for subpage support, we could have cases where only part of the page
is utilized. E.g one 4K sector is read into a 64K page.
In that case, we need a way to determine which range is really utilized.
This patch will introduce scrub_page::page_len so that we can know
where the utilized range ends.
This is especially important for subpage. As write bio can overwrite
existing data if we just submit full page bio.
Signed-off-by: Qu Wenruo <wqu@suse.com>
---
fs/btrfs/scrub.c | 36 +++++++++++++++++++++++++-----------
1 file changed, 25 insertions(+), 11 deletions(-)
diff --git a/fs/btrfs/scrub.c b/fs/btrfs/scrub.c
index 0d078393f986..bad88c651dd4 100644
--- a/fs/btrfs/scrub.c
+++ b/fs/btrfs/scrub.c
@@ -72,9 +72,15 @@ struct scrub_page {
u64 physical_for_dev_replace;
atomic_t refs;
struct {
- unsigned int mirror_num:8;
- unsigned int have_csum:1;
- unsigned int io_error:1;
+ /*
+ * For subpage case, where only part of the page is utilized
+ * Note that 16 bits can only go 65535, not 65536, thus we have
+ * to use 17 bits here.
+ */
+ u32 page_len:17;
+ u32 mirror_num:8;
+ u32 have_csum:1;
+ u32 io_error:1;
};
struct scrub_recover *recover;
@@ -217,6 +223,11 @@ static struct scrub_page *alloc_scrub_page(struct scrub_ctx *sctx, gfp_t mask)
u32 sectorsize = sctx->fs_info->sectorsize;
size_t size;
+ /*
+ * The bits in scrub_page::page_len only supports up to 64K page size.
+ */
+ BUILD_BUG_ON(PAGE_SIZE > SZ_64K);
+
/* No support for multi-page sector size yet */
ASSERT(PAGE_SIZE >= sectorsize && IS_ALIGNED(PAGE_SIZE, sectorsize));
@@ -1359,6 +1370,7 @@ static int scrub_setup_recheck_block(struct scrub_block *original_sblock,
}
scrub_page_get(spage);
sblock->pagev[page_index] = spage;
+ spage->page_len = sublen;
spage->sblock = sblock;
spage->flags = flags;
spage->generation = generation;
@@ -1452,7 +1464,7 @@ static void scrub_recheck_block_on_raid56(struct btrfs_fs_info *fs_info,
struct scrub_page *spage = sblock->pagev[page_num];
WARN_ON(!spage->page);
- bio_add_page(bio, spage->page, PAGE_SIZE, 0);
+ bio_add_page(bio, spage->page, spage->page_len, 0);
}
if (scrub_submit_raid56_bio_wait(fs_info, bio, first_page)) {
@@ -1505,7 +1517,7 @@ static void scrub_recheck_block(struct btrfs_fs_info *fs_info,
bio = btrfs_io_bio_alloc(1);
bio_set_dev(bio, spage->dev->bdev);
- bio_add_page(bio, spage->page, PAGE_SIZE, 0);
+ bio_add_page(bio, spage->page, spage->page_len, 0);
bio->bi_iter.bi_sector = spage->physical >> 9;
bio->bi_opf = REQ_OP_READ;
@@ -1588,8 +1600,8 @@ static int scrub_repair_page_from_good_copy(struct scrub_block *sblock_bad,
bio->bi_iter.bi_sector = spage_bad->physical >> 9;
bio->bi_opf = REQ_OP_WRITE;
- ret = bio_add_page(bio, spage_good->page, PAGE_SIZE, 0);
- if (PAGE_SIZE != ret) {
+ ret = bio_add_page(bio, spage_good->page, spage_good->page_len, 0);
+ if (ret != spage_good->page_len) {
bio_put(bio);
return -EIO;
}
@@ -1685,8 +1697,8 @@ static int scrub_add_page_to_wr_bio(struct scrub_ctx *sctx,
goto again;
}
- ret = bio_add_page(sbio->bio, spage->page, PAGE_SIZE, 0);
- if (ret != PAGE_SIZE) {
+ ret = bio_add_page(sbio->bio, spage->page, spage->page_len, 0);
+ if (ret != spage->page_len) {
if (sbio->page_count < 1) {
bio_put(sbio->bio);
sbio->bio = NULL;
@@ -2033,8 +2045,8 @@ static int scrub_add_page_to_rd_bio(struct scrub_ctx *sctx,
}
sbio->pagev[sbio->page_count] = spage;
- ret = bio_add_page(sbio->bio, spage->page, PAGE_SIZE, 0);
- if (ret != PAGE_SIZE) {
+ ret = bio_add_page(sbio->bio, spage->page, spage->page_len, 0);
+ if (ret != spage->page_len) {
if (sbio->page_count < 1) {
bio_put(sbio->bio);
sbio->bio = NULL;
@@ -2210,6 +2222,7 @@ static int scrub_pages(struct scrub_ctx *sctx, u64 logical, u64 len,
BUG_ON(index >= SCRUB_MAX_PAGES_PER_BLOCK);
scrub_page_get(spage);
sblock->pagev[index] = spage;
+ spage->page_len = l;
spage->sblock = sblock;
spage->dev = dev;
spage->flags = flags;
@@ -2554,6 +2567,7 @@ static int scrub_pages_for_parity(struct scrub_parity *sparity,
/* For scrub parity */
scrub_page_get(spage);
list_add_tail(&spage->list, &sparity->spages);
+ spage->page_len = l;
spage->sblock = sblock;
spage->dev = dev;
spage->flags = flags;
--
2.29.0
next prev parent reply other threads:[~2020-10-26 7:11 UTC|newest]
Thread overview: 13+ messages / expand[flat|nested] mbox.gz Atom feed top
2020-10-26 7:11 [PATCH 0/8] btrfs: scrub: support subpage scrub (completely independent version) Qu Wenruo
2020-10-26 7:11 ` [PATCH 1/8] btrfs: scrub: distinguish scrub_page from regular page Qu Wenruo
2020-10-26 14:13 ` Josef Bacik
2020-10-26 7:11 ` [PATCH 2/8] btrfs: scrub: remove the @force parameter of scrub_pages() Qu Wenruo
2020-10-26 14:20 ` Josef Bacik
2020-10-26 7:11 ` [PATCH 3/8] btrfs: scrub: use flexible array for scrub_page::csums Qu Wenruo
2020-10-26 14:23 ` Josef Bacik
2020-10-26 7:11 ` [PATCH 4/8] btrfs: scrub: refactor scrub_find_csum() Qu Wenruo
2020-10-26 14:39 ` Josef Bacik
2020-10-26 7:11 ` Qu Wenruo [this message]
2020-10-26 7:11 ` [PATCH 6/8] btrfs: scrub: always allocate one full page for one sector for RAID56 Qu Wenruo
2020-10-26 7:11 ` [PATCH 7/8] btrfs: scrub: support subpage tree block scrub Qu Wenruo
2020-10-26 7:11 ` [PATCH 8/8] btrfs: scrub: support subpage data scrub 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=20201026071115.57225-6-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