btrfs-progs: scrub: Introduce function to recover data parity

Introduce function, recover_from_parities(), to recover data stripes.

It just wraps raid56_recov() with extra check functions to
scrub_full_stripe structure.

Signed-off-by: Qu Wenruo <quwenruo@cn.fujitsu.com>
This commit is contained in:
Qu Wenruo 2016-12-26 14:29:36 +08:00 committed by David Sterba
parent e2c28e53dd
commit fa8040d571
1 changed files with 51 additions and 0 deletions

51
scrub.c
View File

@ -818,3 +818,54 @@ out:
free(ptrs);
return ret;
}
/*
* Try to recover data stripe from P or Q stripe
*
* Return >0 if it can't be require any more.
* Return 0 for successful repair or no need to repair at all
* Return <0 for fatal error
*/
static int recover_from_parities(struct btrfs_fs_info *fs_info,
struct btrfs_scrub_progress *scrub_ctx,
struct scrub_full_stripe *fstripe)
{
void **ptrs;
int nr_stripes = fstripe->nr_stripes;
int stripe_len = BTRFS_STRIPE_LEN;
int max_tolerance;
int i;
int ret;
/* No need to recover */
if (!fstripe->nr_corrupted_stripes)
return 0;
/* Already recovered once, no more chance */
if (fstripe->recovered)
return 1;
if (fstripe->bg_type & BTRFS_BLOCK_GROUP_RAID5)
max_tolerance = 1;
else
max_tolerance = 2;
/* Out of repair */
if (fstripe->nr_corrupted_stripes > max_tolerance)
return 1;
ptrs = malloc(sizeof(void *) * fstripe->nr_stripes);
if (!ptrs)
return -ENOMEM;
/* Construct ptrs */
for (i = 0; i < nr_stripes; i++)
ptrs[i] = fstripe->stripes[i].data;
ret = raid56_recov(nr_stripes, stripe_len, fstripe->bg_type,
fstripe->corrupted_index[0],
fstripe->corrupted_index[1], ptrs);
fstripe->recovered = 1;
free(ptrs);
return ret;
}