All of lore.kernel.org
 help / color / mirror / Atom feed
From: Qu Wenruo <wqu@suse.com>
To: linux-btrfs@vger.kernel.org
Subject: [PATCH v3 03/12] btrfs: introduce a new helper to submit write bio for scrub
Date: Mon, 20 Mar 2023 10:12:49 +0800	[thread overview]
Message-ID: <c9482839875af328d7fe5ff6a9bebdc84c33c5ab.1679278088.git.wqu@suse.com> (raw)
In-Reply-To: <cover.1679278088.git.wqu@suse.com>

Just like the special scrub read, scrub write also has its extra niches:

- Only write back to single device
  Even for read-repair on RAID56, we only update the corrupted data
  stripe itself, not triggering the full RMW path.

  This makes scrub writeback a perfect match for the single stripe
  quick path.

- Requires a valid @mirror_num
  For RAID56 case, only @mirror_num == 1 is supported.
  For non-RAID56 cases, we need @mirror_num to locate our stripe.

- Need to manually specify if it's for dev-replace
  For scrub path we can write back to the original device (for
  read-repair) and to the target device (for replace) at the same
  time, but with different sectors (read-repair only writes repaired
  sectors, while dev-replace writes all good sectors).

  So here we need a bool to specify the case.

- No data csum generation

Signed-off-by: Qu Wenruo <wqu@suse.com>
---
 fs/btrfs/bio.c | 92 ++++++++++++++++++++++++++++++++++++++++++++++++++
 fs/btrfs/bio.h |  3 ++
 2 files changed, 95 insertions(+)

diff --git a/fs/btrfs/bio.c b/fs/btrfs/bio.c
index b96f40160b08..633447b6ba44 100644
--- a/fs/btrfs/bio.c
+++ b/fs/btrfs/bio.c
@@ -733,6 +733,98 @@ void btrfs_submit_scrub_read(struct btrfs_fs_info *fs_info,
 	btrfs_bio_end_io(orig_bbio, ret);
 }
 
+/*
+ * Scrub write special version. Some extra limits:
+ *
+ * - Only support write back for dev-replace and read-repair.
+ *   This means, the write bio, even for RAID56, would only
+ *   be mapped to single device.
+ *
+ * - @mirror_num must be >0.
+ *   To indicate which mirror to be written.
+ *   If it's RAID56, it must be 1 (data stripes).
+ *
+ * - The @bbio must not cross stripe boundary.
+ *
+ * - If @dev_replace is true, the resulted stripe must be mapped to
+ *   replace source device.
+ *
+ * - No csum geneartion.
+ */
+void btrfs_submit_scrub_write(struct btrfs_fs_info *fs_info,
+			      struct btrfs_bio *bbio, int mirror_num,
+			      bool dev_replace)
+{
+	struct btrfs_bio *orig_bbio = bbio;
+	u64 logical = bbio->bio.bi_iter.bi_sector << SECTOR_SHIFT;
+	u64 length = bbio->bio.bi_iter.bi_size;
+	u64 map_length = length;
+	struct btrfs_io_context *bioc = NULL;
+	struct btrfs_io_stripe smap;
+	int ret;
+
+	ASSERT(mirror_num > 0);
+	ASSERT(btrfs_op(&bbio->bio) == BTRFS_MAP_WRITE);
+	ASSERT(!bbio->inode);
+
+	bbio->fs_info = fs_info;
+	btrfs_bio_counter_inc_blocked(fs_info);
+	ret = __btrfs_map_block(fs_info, btrfs_op(&bbio->bio), logical,
+				&map_length, &bioc, &smap, &mirror_num, 1);
+	if (ret)
+		goto fail;
+
+	/* Caller should ensure the @bbio doesn't cross stripe boundary. */
+	ASSERT(map_length >= length);
+	if (btrfs_op(&bbio->bio) == BTRFS_MAP_WRITE && btrfs_is_zoned(fs_info)) {
+		bbio->bio.bi_opf &= ~REQ_OP_WRITE;
+		bbio->bio.bi_opf |= REQ_OP_ZONE_APPEND;
+	}
+
+	if (!bioc)
+		goto submit;
+	/* Map the RAID56 multi-stripe writes to a single one. */
+	if (bioc->map_type & BTRFS_BLOCK_GROUP_RAID56_MASK) {
+		int data_stripes = bioc->map_type & BTRFS_BLOCK_GROUP_RAID5 ?
+				   bioc->num_stripes - 1 : bioc->num_stripes - 2;
+		int i;
+
+		/* This special write only works for data stripes. */
+		ASSERT(mirror_num == 1);
+		for (i = 0; i < data_stripes; i++) {
+			u64 stripe_start = bioc->full_stripe_logical +
+					   (i << BTRFS_STRIPE_LEN_SHIFT);
+
+			if (logical >= stripe_start &&
+			    logical < stripe_start + BTRFS_STRIPE_LEN)
+				break;
+		}
+		ASSERT(i < data_stripes);
+		smap.dev = bioc->stripes[i].dev;
+		smap.physical = bioc->stripes[i].physical +
+				((logical - bioc->full_stripe_logical) &
+				 BTRFS_STRIPE_LEN_MASK);
+		goto submit;
+	}
+	ASSERT(mirror_num <= bioc->num_stripes);
+	smap.dev = bioc->stripes[mirror_num - 1].dev;
+	smap.physical = bioc->stripes[mirror_num - 1].physical;
+submit:
+	ASSERT(smap.dev);
+	btrfs_put_bioc(bioc);
+	bioc = NULL;
+	if (dev_replace) {
+		ASSERT(smap.dev == fs_info->dev_replace.srcdev);
+		smap.dev = fs_info->dev_replace.tgtdev;
+	}
+	__btrfs_submit_bio(&bbio->bio, bioc, &smap, mirror_num);
+	return;
+
+fail:
+	btrfs_bio_counter_dec(fs_info);
+	btrfs_bio_end_io(orig_bbio, ret);
+}
+
 void btrfs_submit_bio(struct btrfs_bio *bbio, int mirror_num)
 {
 	while (!btrfs_submit_chunk(bbio, mirror_num))
diff --git a/fs/btrfs/bio.h b/fs/btrfs/bio.h
index 073df13365e4..d5b4a15dde35 100644
--- a/fs/btrfs/bio.h
+++ b/fs/btrfs/bio.h
@@ -104,6 +104,9 @@ static inline void btrfs_bio_end_io(struct btrfs_bio *bbio, blk_status_t status)
 void btrfs_submit_bio(struct btrfs_bio *bbio, int mirror_num);
 void btrfs_submit_scrub_read(struct btrfs_fs_info *fs_info,
 			     struct btrfs_bio *bbio, int mirror_num);
+void btrfs_submit_scrub_write(struct btrfs_fs_info *fs_info,
+			      struct btrfs_bio *bbio, int mirror_num,
+			      bool dev_replace);
 int btrfs_repair_io_failure(struct btrfs_fs_info *fs_info, u64 ino, u64 start,
 			    u64 length, u64 logical, struct page *page,
 			    unsigned int pg_offset, int mirror_num);
-- 
2.39.2


  parent reply	other threads:[~2023-03-20  2:13 UTC|newest]

Thread overview: 36+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-03-20  2:12 [PATCH v3 00/12] btrfs: scrub: use a more reader friendly code to implement scrub_simple_mirror() Qu Wenruo
2023-03-20  2:12 ` [PATCH v3 01/12] btrfs: scrub: use dedicated super block verification function to scrub one super block Qu Wenruo
2023-03-21  5:22   ` Anand Jain
2023-03-21  7:25     ` Qu Wenruo
2023-03-21 22:12       ` David Sterba
2023-03-20  2:12 ` [PATCH v3 02/12] btrfs: introduce a new helper to submit bio for scrub Qu Wenruo
2023-03-21 12:02   ` Christoph Hellwig
2023-03-24  9:58     ` Qu Wenruo
2023-03-25  8:09       ` Christoph Hellwig
2023-03-25  8:21         ` Qu Wenruo
2023-03-25  8:31           ` Christoph Hellwig
2023-03-25  8:48             ` Qu Wenruo
2023-03-27  3:36               ` Christoph Hellwig
2023-03-20  2:12 ` Qu Wenruo [this message]
2023-03-21  0:14   ` [PATCH v3 03/12] btrfs: introduce a new helper to submit write " David Sterba
2023-03-21  0:54     ` Qu Wenruo
2023-03-21  1:27       ` David Sterba
2023-03-23  8:48     ` Qu Wenruo
2023-03-20  2:12 ` [PATCH v3 04/12] btrfs: scrub: introduce the structure for new BTRFS_STRIPE_LEN based interface Qu Wenruo
2023-03-21  0:22   ` David Sterba
2023-03-20  2:12 ` [PATCH v3 05/12] btrfs: scrub: introduce a helper to find and fill the sector info for a scrub_stripe Qu Wenruo
2023-03-20  2:12 ` [PATCH v3 06/12] btrfs: scrub: introduce a helper to verify one metadata Qu Wenruo
2023-03-21  0:31   ` David Sterba
2023-03-20  2:12 ` [PATCH v3 07/12] btrfs: scrub: introduce a helper to verify one scrub_stripe Qu Wenruo
2023-03-20  2:12 ` [PATCH v3 08/12] btrfs: scrub: introduce the main read repair worker for scrub_stripe Qu Wenruo
2023-03-20  2:12 ` [PATCH v3 09/12] btrfs: scrub: introduce a writeback helper " Qu Wenruo
2023-03-21  0:43   ` David Sterba
2023-03-20  2:12 ` [PATCH v3 10/12] btrfs: scrub: introduce error reporting functionality " Qu Wenruo
2023-03-20  2:12 ` [PATCH v3 11/12] btrfs: scrub: introduce the helper to queue a stripe for scrub Qu Wenruo
2023-03-20  2:12 ` [PATCH v3 12/12] btrfs: scrub: switch scrub_simple_mirror() to scrub_stripe infrastructure Qu Wenruo
2023-03-21  1:12   ` David Sterba
2023-03-21  0:09 ` [PATCH v3 00/12] btrfs: scrub: use a more reader friendly code to implement scrub_simple_mirror() David Sterba
2023-03-23  6:28   ` Qu Wenruo
2023-03-23 17:51     ` David Sterba
2023-03-24  0:42       ` Qu Wenruo
2023-03-27 23:28         ` David Sterba

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=c9482839875af328d7fe5ff6a9bebdc84c33c5ab.1679278088.git.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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.