diff mbox series

[PoC,v2,08/10] btrfs: scrub: implement data verification code for scrub_fs

Message ID e699b31bdc9a4e56c6afbd308e77240944111ca4.1664353497.git.wqu@suse.com (mailing list archive)
State New, archived
Headers show
Series btrfs: scrub: introduce a new family of ioctl, scrub_fs | expand

Commit Message

Qu Wenruo Sept. 28, 2022, 8:35 a.m. UTC
For data verification it's much simpler, only need to do csum
verification and we already have very handy helper for it.

Signed-off-by: Qu Wenruo <wqu@suse.com>
---
 fs/btrfs/scrub.c | 40 ++++++++++++++++++++++++++++++++++++++--
 1 file changed, 38 insertions(+), 2 deletions(-)
diff mbox series

Patch

diff --git a/fs/btrfs/scrub.c b/fs/btrfs/scrub.c
index a693e35d172d..efe49a04dceb 100644
--- a/fs/btrfs/scrub.c
+++ b/fs/btrfs/scrub.c
@@ -5117,6 +5117,41 @@  static void scrub_fs_verify_meta(struct scrub_fs_endio_ctrl *endio_ctrl,
 	}
 }
 
+static void scrub_fs_verify_data(struct scrub_fs_endio_ctrl *endio_ctrl,
+				 int sector_nr, int mirror_nr)
+{
+	struct scrub_fs_ctx *sfctx = endio_ctrl->sfctx;
+	struct btrfs_fs_info *fs_info = sfctx->fs_info;
+	struct scrub_fs_sector *sector =
+		scrub_fs_get_sector(sfctx, sector_nr, mirror_nr);
+	u8 csum_result[BTRFS_CSUM_SIZE] = {0};
+	u8 *csum_expected = sector->csum;
+	unsigned int set_flag;
+	int ret;
+
+	scrub_fs_check_sector_mirror_nr(sfctx, sector_nr, mirror_nr);
+
+	/*
+	 * No checksum case, we can not determine if it's preallocate or real
+	 * NODATASUM. Just mark it good unconditionally.
+	 */
+	if (!csum_expected) {
+		set_flag = SCRUB_FS_SECTOR_FLAG_GOOD;
+		goto out;
+	}
+
+	ret = btrfs_check_sector_csum(fs_info,
+			scrub_fs_get_page(sfctx, sector_nr, mirror_nr),
+			scrub_fs_get_page_offset(sfctx, sector_nr, mirror_nr),
+			csum_result, csum_expected);
+	if (ret < 0)
+		set_flag = SCRUB_FS_SECTOR_FLAG_BAD_CSUM;
+	else
+		set_flag = SCRUB_FS_SECTOR_FLAG_GOOD;
+out:
+	sector->flags |= set_flag;
+}
+
 static void scrub_fs_read_endio(struct bio *bio)
 {
 	struct scrub_fs_endio_ctrl *endio_ctrl = bio->bi_private;
@@ -5163,9 +5198,10 @@  static void scrub_fs_read_endio(struct bio *bio)
 		    !(sector->flags & SCRUB_FS_SECTOR_FLAG_IO_DONE))
 			continue;
 
-		/* Place holder for data verification. */
-		if (sector->flags & SCRUB_FS_SECTOR_FLAG_DATA)
+		if (sector->flags & SCRUB_FS_SECTOR_FLAG_DATA) {
+			scrub_fs_verify_data(endio_ctrl, i, mirror_nr);
 			continue;
+		}
 
 		/* We must be at a metadata sector. */
 		ASSERT(sector->flags & SCRUB_FS_SECTOR_FLAG_META);