diff mbox series

[v2,5/7] btrfs: make buffered read path to use the new read repair infrastructure

Message ID 9d5aa449b6e26247b3ad8437b3a948913f427cba.1653476251.git.wqu@suse.com (mailing list archive)
State New, archived
Headers show
Series btrfs: read-repair rework based on bitmap | expand

Commit Message

Qu Wenruo May 25, 2022, 10:59 a.m. UTC
We only need to prepare the logical bytenr and file offset of the
corrupted sector, and pass it to btrfs_read_repair_add_sector().

And call btrfs_read_repair_finish() before we free the csum.

Signed-off-by: Qu Wenruo <wqu@suse.com>
---
 fs/btrfs/extent_io.c | 44 ++++++++++++++++++++------------------------
 1 file changed, 20 insertions(+), 24 deletions(-)
diff mbox series

Patch

diff --git a/fs/btrfs/extent_io.c b/fs/btrfs/extent_io.c
index 160dedb078fd..c14699b5758b 100644
--- a/fs/btrfs/extent_io.c
+++ b/fs/btrfs/extent_io.c
@@ -30,6 +30,7 @@ 
 #include "zoned.h"
 #include "block-group.h"
 #include "compression.h"
+#include "read-repair.h"
 
 static struct kmem_cache *extent_state_cache;
 static struct kmem_cache *extent_buffer_cache;
@@ -2749,13 +2750,15 @@  void end_sector_io(struct page *page, u64 offset, bool uptodate)
 			offset + sectorsize - 1, &cached);
 }
 
-static void submit_data_read_repair(struct inode *inode, struct bio *failed_bio,
+static void submit_data_read_repair(struct inode *inode,
+		struct btrfs_read_repair_ctrl *ctrl, struct bio *failed_bio,
 		u32 bio_offset, const struct bio_vec *bvec, int failed_mirror,
 		unsigned int error_bitmap)
 {
 	const unsigned int pgoff = bvec->bv_offset;
 	struct btrfs_fs_info *fs_info = btrfs_sb(inode->i_sb);
 	struct page *page = bvec->bv_page;
+	struct btrfs_bio *failed_bbio = btrfs_bio(failed_bio);
 	const u64 start = page_offset(bvec->bv_page) + bvec->bv_offset;
 	const u64 end = start + bvec->bv_len - 1;
 	const u32 sectorsize = fs_info->sectorsize;
@@ -2780,7 +2783,9 @@  static void submit_data_read_repair(struct inode *inode, struct bio *failed_bio,
 	for (i = 0; i < nr_bits; i++) {
 		const unsigned int offset = i * sectorsize;
 		bool uptodate = false;
-		int ret;
+		u64 logical = (failed_bbio->iter.bi_sector << SECTOR_SHIFT) +
+			      bio_offset + offset;
+		u8 *csum = NULL;
 
 		if (!(error_bitmap & (1U << i))) {
 			/*
@@ -2788,28 +2793,17 @@  static void submit_data_read_repair(struct inode *inode, struct bio *failed_bio,
 			 * and unlock the range.
 			 */
 			uptodate = true;
-			goto next;
-		}
-
-		ret = btrfs_repair_one_sector(inode, failed_bio,
-				bio_offset + offset,
-				page, pgoff + offset, start + offset,
-				failed_mirror, btrfs_submit_data_bio);
-		if (!ret) {
-			/*
-			 * We have submitted the read repair, the page release
-			 * will be handled by the endio function of the
-			 * submitted repair bio.
-			 * Thus we don't need to do any thing here.
-			 */
+			end_sector_io(page, start + offset, uptodate);
 			continue;
 		}
-		/*
-		 * Continue on failed repair, otherwise the remaining sectors
-		 * will not be properly unlocked.
-		 */
-next:
-		end_sector_io(page, start + offset, uptodate);
+		if (failed_bbio->csum)
+			csum = btrfs_csum_ptr(fs_info, failed_bbio->csum,
+					      bio_offset + offset);
+
+		/* The function will release the page if hit failure. */
+		btrfs_read_repair_add_sector(inode, ctrl, page, pgoff + offset,
+					     logical, start + offset, csum,
+					     failed_mirror, false);
 	}
 }
 
@@ -3017,6 +3011,7 @@  static void end_bio_extent_readpage(struct bio *bio)
 	struct btrfs_bio *bbio = btrfs_bio(bio);
 	struct extent_io_tree *tree, *failure_tree;
 	struct processed_extent processed = { 0 };
+	struct btrfs_read_repair_ctrl ctrl = { 0 };
 	/*
 	 * The offset to the beginning of a bio, since one bio can never be
 	 * larger than UINT_MAX, u32 here is enough.
@@ -3126,8 +3121,8 @@  static void end_bio_extent_readpage(struct bio *bio)
 			 * submit_data_read_repair() will handle all the good
 			 * and bad sectors, we just continue to the next bvec.
 			 */
-			submit_data_read_repair(inode, bio, bio_offset, bvec,
-						mirror, error_bitmap);
+			submit_data_read_repair(inode, &ctrl, bio, bio_offset,
+						bvec, mirror, error_bitmap);
 		} else {
 			/* Update page status and unlock */
 			end_page_read(page, uptodate, start, len);
@@ -3142,6 +3137,7 @@  static void end_bio_extent_readpage(struct bio *bio)
 	}
 	/* Release the last extent */
 	endio_readpage_release_extent(&processed, NULL, 0, 0, false);
+	btrfs_read_repair_finish(&ctrl);
 	btrfs_bio_free_csum(bbio);
 	bio_put(bio);
 }