All of lore.kernel.org
 help / color / mirror / Atom feed
From: Qu Wenruo <wqu@suse.com>
To: linux-btrfs@vger.kernel.org
Subject: [PATCH PoC v2 10/10] btrfs: scrub: implement the repair (writeback) functionality
Date: Wed, 28 Sep 2022 16:35:47 +0800	[thread overview]
Message-ID: <85c4ff6d001e19fca2cc44dcbb98c75f4558d8ff.1664353497.git.wqu@suse.com> (raw)
In-Reply-To: <cover.1664353497.git.wqu@suse.com>

This adds the repair functionality for scrub_fs.

Since previous patch has implemented the final verification part, all
sectors that can be repaired will have SCRUB_FS_SECTOR_FLAG_RECOVERABLE,
we just need to submit write bios for them.

And just like the old scrub interface, we don't report writeback error.

Signed-off-by: Qu Wenruo <wqu@suse.com>
---
 fs/btrfs/scrub.c | 96 +++++++++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 95 insertions(+), 1 deletion(-)

diff --git a/fs/btrfs/scrub.c b/fs/btrfs/scrub.c
index 89735ff6143a..27d96778206c 100644
--- a/fs/btrfs/scrub.c
+++ b/fs/btrfs/scrub.c
@@ -5362,6 +5362,93 @@ static void scrub_fs_update_veritical(struct scrub_fs_ctx *sfctx,
 	}
 }
 
+static void scrub_fs_write_endio(struct bio *bio)
+{
+	struct scrub_fs_ctx *sfctx = bio->bi_private;
+	struct bio_vec *bvec;
+	struct bvec_iter_all iter_all;
+	unsigned int bio_size = 0;
+
+	bio_for_each_segment_all(bvec, bio, iter_all)
+		bio_size += bvec->bv_len;
+
+	/* Repair should be inside one stripe. */
+	ASSERT(bio_size <= BTRFS_STRIPE_LEN);
+
+	atomic_dec(&sfctx->bios_under_io);
+	wake_up(&sfctx->wait);
+	bio_put(bio);
+}
+
+static void scrub_fs_repair_mirror(struct scrub_fs_ctx *sfctx,
+				   struct btrfs_io_context *bioc, int mirror_nr)
+{
+	struct bio *bio = NULL;
+	int last_sector = -1;
+	int i;
+
+	ASSERT(mirror_nr < bioc->num_stripes);
+
+	for (i = 0; i < sfctx->sectors_per_stripe; i++) {
+		struct scrub_fs_sector *sector =
+			scrub_fs_get_sector(sfctx, i, mirror_nr);
+
+		if (sector->flags & SCRUB_FS_SECTOR_FLAG_DEV_MISSING ||
+		    sector->flags & SCRUB_FS_SECTOR_FLAG_GOOD ||
+		    !(sector->flags & SCRUB_FS_SECTOR_FLAG_RECOVERABLE))
+			continue;
+
+		/* No bio allocated, alloc a new one. */
+		if (!bio) {
+			blk_opf_t opf = REQ_OP_WRITE | REQ_BACKGROUND;
+
+			if (sector->flags & SCRUB_FS_SECTOR_FLAG_META)
+				opf |= REQ_META;
+
+			bio = bio_alloc(bioc->stripes[mirror_nr].dev->bdev,
+					sfctx->sectors_per_stripe, opf,
+					GFP_KERNEL);
+			/* It's backed up by mempool. */
+			ASSERT(bio);
+
+			bio->bi_iter.bi_sector =
+				(bioc->stripes[mirror_nr].physical +
+				 (i << sfctx->fs_info->sectorsize_bits)) >>
+				SECTOR_SHIFT;
+			bio->bi_private = sfctx;
+			bio->bi_end_io = scrub_fs_write_endio;
+
+			last_sector = i - 1;
+		}
+
+		/* Can merge into preivous bio.*/
+		if (last_sector == i - 1) {
+			struct page *page =
+				scrub_fs_get_page(sfctx, i, mirror_nr);
+			unsigned int page_off =
+				scrub_fs_get_page_offset(sfctx, i, mirror_nr);
+			int ret;
+
+			ret = bio_add_page(bio, page, sfctx->fs_info->sectorsize,
+					   page_off);
+			ASSERT(ret == sfctx->fs_info->sectorsize);
+			last_sector = i;
+			continue;
+		}
+
+		/* Can not merge, has to submit the current one and retry. */
+		ASSERT(bio);
+		atomic_inc(&sfctx->bios_under_io);
+		submit_bio(bio);
+		bio = NULL;
+		i--;
+	}
+	if (bio) {
+		atomic_inc(&sfctx->bios_under_io);
+		submit_bio(bio);
+	}
+}
+
 static int scrub_fs_one_stripe(struct scrub_fs_ctx *sfctx)
 {
 	struct btrfs_fs_info *fs_info = sfctx->fs_info;
@@ -5413,7 +5500,14 @@ static int scrub_fs_one_stripe(struct scrub_fs_ctx *sfctx)
 	for (i = 0; i < sfctx->sectors_per_stripe; i++)
 		scrub_fs_update_veritical(sfctx, i);
 
-	/* Place holder for repair write-back code */
+	/* Submit repair*/
+	if (!sfctx->readonly) {
+		for (i = 0; i < sfctx->nr_copies; i++)
+			scrub_fs_repair_mirror(sfctx, bioc, i);
+		wait_event(sfctx->wait, atomic_read(&sfctx->bios_under_io) == 0);
+	}
+	ASSERT(atomic_read(&sfctx->bios_under_io) == 0);
+
 out:
 	btrfs_put_bioc(bioc);
 	btrfs_bio_counter_dec(fs_info);
-- 
2.37.3


      parent reply	other threads:[~2022-09-28  8:36 UTC|newest]

Thread overview: 15+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-09-28  8:35 [PATCH PoC v2 00/10] btrfs: scrub: introduce a new family of ioctl, scrub_fs Qu Wenruo
2022-09-28  8:35 ` [PATCH PoC v2 01/10] btrfs: introduce BTRFS_IOC_SCRUB_FS family of ioctls Qu Wenruo
2022-12-03 15:10   ` li zhang
2022-12-03 23:09     ` Qu Wenruo
2022-09-28  8:35 ` [PATCH PoC v2 02/10] btrfs: scrub: introduce place holder for btrfs_scrub_fs() Qu Wenruo
2022-09-28  8:35 ` [PATCH PoC v2 03/10] btrfs: scrub: introduce a place holder helper scrub_fs_iterate_bgs() Qu Wenruo
2022-09-28  8:35 ` [PATCH PoC v2 04/10] btrfs: scrub: introduce place holder helper scrub_fs_block_group() Qu Wenruo
2022-09-28 14:30   ` Wang Yugui
2022-09-28 22:54     ` Qu Wenruo
2022-09-28  8:35 ` [PATCH PoC v2 05/10] btrfs: scrub: add helpers to fulfill csum/extent_generation Qu Wenruo
2022-09-28  8:35 ` [PATCH PoC v2 06/10] btrfs: scrub: submit and wait for the read of each copy Qu Wenruo
2022-09-28  8:35 ` [PATCH PoC v2 07/10] btrfs: scrub: implement metadata verification code for scrub_fs Qu Wenruo
2022-09-28  8:35 ` [PATCH PoC v2 08/10] btrfs: scrub: implement data " Qu Wenruo
2022-09-28  8:35 ` [PATCH PoC v2 09/10] btrfs: scrub: implement the later stage of verification Qu Wenruo
2022-09-28  8:35 ` Qu Wenruo [this message]

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=85c4ff6d001e19fca2cc44dcbb98c75f4558d8ff.1664353497.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.