diff mbox series

[5/7] btrfs: use the new read repair code for buffered reads

Message ID fd4b85fcfaee593638818f9dd5f216d4e8b3d73e.1653270322.git.wqu@suse.com (mailing list archive)
State New, archived
Headers show
Series btrfs: synchronous (but super simple) read-repair rework | expand

Commit Message

Qu Wenruo May 23, 2022, 1:48 a.m. UTC
Just call the new btrfs_read_repair_sector() to replace the old
btrfs_repair_one_sector().

And since the new helper only handles the page content, the caller still
needs to handle the page status update and unlock.

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

Patch

diff --git a/fs/btrfs/extent_io.c b/fs/btrfs/extent_io.c
index 1083d6cfa858..cf32b2ff0568 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;
@@ -2756,10 +2757,13 @@  static void submit_data_read_repair(struct inode *inode, struct bio *failed_bio,
 	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 bio_logical = failed_bbio->iter.bi_sector << SECTOR_SHIFT;
 	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;
 	const int nr_bits = (end + 1 - start) >> fs_info->sectorsize_bits;
+	int num_copies;
 	int i;
 
 	BUG_ON(bio_op(failed_bio) == REQ_OP_WRITE);
@@ -2776,10 +2780,13 @@  static void submit_data_read_repair(struct inode *inode, struct bio *failed_bio,
 	 */
 	ASSERT(page->mapping && !bio_flagged(failed_bio, BIO_CLONED));
 
+	num_copies = btrfs_num_copies(fs_info, bio_logical, fs_info->sectorsize);
+
 	/* Iterate through all the sectors in the range */
 	for (i = 0; i < nr_bits; i++) {
 		const unsigned int offset = i * sectorsize;
 		bool uptodate = false;
+		u8 *expected_csum = NULL;
 		int ret;
 
 		if (!(error_bitmap & (1U << i))) {
@@ -2791,22 +2798,19 @@  static void submit_data_read_repair(struct inode *inode, struct bio *failed_bio,
 			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.
-			 */
-			continue;
-		}
+		if (failed_bbio->csum)
+			expected_csum = btrfs_csum_ptr(fs_info,
+					failed_bbio->csum, bio_offset + offset);
+
+		ret = btrfs_read_repair_sector(inode, page, pgoff + offset,
+				bio_logical + bio_offset + offset,
+				start + offset, failed_bbio->mirror_num,
+				num_copies, expected_csum);
+		if (!ret)
+			uptodate = true;
 		/*
-		 * Continue on failed repair, otherwise the remaining sectors
-		 * will not be properly unlocked.
+		 * If above repair failed, we have tried all mirrors, time to
+		 * release the corrupted sector.
 		 */
 next:
 		end_sector_io(page, start + offset, uptodate);