Skip to content

Commit

Permalink
btrfs: scrub: implement data verification code for scrub_fs
Browse files Browse the repository at this point in the history
For data verification it's much simpler, only need to do csum
verification and we have very handy helper for it.

Signed-off-by: Qu Wenruo <wqu@suse.com>
  • Loading branch information
adam900710 authored and intel-lab-lkp committed Sep 3, 2022
1 parent caeb024 commit ac4b644
Showing 1 changed file with 57 additions and 1 deletion.
58 changes: 57 additions & 1 deletion fs/btrfs/scrub.c
Original file line number Diff line number Diff line change
Expand Up @@ -5228,6 +5228,60 @@ static void scrub_fs_verify_meta(struct scrub_fs_ctx *sfctx, int sector_nr)
scrub_fs_verify_one_meta(sfctx, sector_nr, i);
}

/* Convert a sector pointer to its index inside sfctx->sectors[] array. */
static int scrub_fs_sector_to_sector_index(struct scrub_fs_ctx *sfctx,
struct scrub_fs_sector *sector)
{
int i;

ASSERT(sector);
for (i = 0; i < sfctx->total_sectors; i++) {
if (&sfctx->sectors[i] == sector)
break;
}
/* As long as @sector is from sfctx->sectors[], we should have found it. */
ASSERT(i < sfctx->total_sectors);
return i;
}

static void scrub_fs_verify_one_data(struct scrub_fs_ctx *sfctx, int sector_nr,
int mirror_nr)
{
struct btrfs_fs_info *fs_info = sfctx->fs_info;
struct scrub_fs_sector *sector =
scrub_fs_get_sector(sfctx, sector_nr, mirror_nr);
int index = scrub_fs_sector_to_sector_index(sfctx, sector);
struct page *data_page = scrub_fs_get_page(sfctx, index);
unsigned int data_page_off = scrub_fs_get_page_offset(sfctx, index);
u8 csum_result[BTRFS_CSUM_SIZE];
u8 *csum_expected = sector->csum;
int ret;

sfctx->stat.data_scrubbed += fs_info->sectorsize;

/* No IO done, just increase the accounting. */
if (!(sector->flags & SCRUB_FS_SECTOR_FLAG_IO_DONE)) {
sfctx->stat.data_io_fail += fs_info->sectorsize;
return;
}

/*
* NODATASUM case, just skip, we will come back later to determine
* the status when checking the sectors inside the same vertical stripe.
*/
if (!csum_expected)
return;

ret = btrfs_check_sector_csum(fs_info, data_page, data_page_off,
csum_result, csum_expected);
if (ret < 0) {
sfctx->stat.data_csum_mismatch += fs_info->sectorsize;
return;
}
/* All good. */
sector->flags |= SCRUB_FS_SECTOR_FLAG_GOOD;
}

static void scrub_fs_verify_one_stripe(struct scrub_fs_ctx *sfctx)
{
struct btrfs_fs_info *fs_info = sfctx->fs_info;
Expand All @@ -5238,6 +5292,7 @@ static void scrub_fs_verify_one_stripe(struct scrub_fs_ctx *sfctx)
for (sector_nr = 0; sector_nr < sectors_per_stripe; sector_nr++) {
struct scrub_fs_sector *sector =
scrub_fs_get_sector(sfctx, sector_nr, 0);
int mirror_nr;

/*
* All sectors in the same veritical stripe should share
Expand All @@ -5260,7 +5315,8 @@ static void scrub_fs_verify_one_stripe(struct scrub_fs_ctx *sfctx)
continue;
}

/* Place holder for data verification. */
for (mirror_nr = 0; mirror_nr < sfctx->nr_copies; mirror_nr++)
scrub_fs_verify_one_data(sfctx, sector_nr, mirror_nr);
}
/* Place holder for recoverable checks. */
}
Expand Down

0 comments on commit ac4b644

Please sign in to comment.