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:
parent
e2c28e53dd
commit
fa8040d571
51
scrub.c
51
scrub.c
|
@ -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;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue