Skip to content

Commit

Permalink
Btrfs: in scrub repair code, optimize the reading of mirrors
Browse files Browse the repository at this point in the history
In case that disk blocks need to be repaired (rewritten), the
current code at first (for simplicity reasons) reads all alternate
mirrors in the first step, afterwards selects the best one in a
second step. This is now changed to read one alternate mirror
after the other and to leave the loop early when a perfect mirror
is found.

Signed-off-by: Stefan Behrens <sbehrens@giantdisaster.de>
Signed-off-by: Chris Mason <chris.mason@fusionio.com>
  • Loading branch information
Stefan Behrens authored and Josef Bacik committed Dec 12, 2012
1 parent 7a9e998 commit cb2ced7
Showing 1 changed file with 12 additions and 23 deletions.
35 changes: 12 additions & 23 deletions fs/btrfs/scrub.c
Original file line number Diff line number Diff line change
Expand Up @@ -819,26 +819,8 @@ static int scrub_handle_errored_block(struct scrub_block *sblock_to_check)

/*
* now build and submit the bios for the other mirrors, check
* checksums
*/
for (mirror_index = 0;
mirror_index < BTRFS_MAX_MIRRORS &&
sblocks_for_recheck[mirror_index].page_count > 0;
mirror_index++) {
if (mirror_index == failed_mirror_index)
continue;

/* build and submit the bios, check checksums */
ret = scrub_recheck_block(fs_info,
sblocks_for_recheck + mirror_index,
is_metadata, have_csum, csum,
generation, sctx->csum_size);
if (ret)
goto did_not_correct_error;
}

/*
* first try to pick the mirror which is completely without I/O
* checksums.
* First try to pick the mirror which is completely without I/O
* errors and also does not have a checksum error.
* If one is found, and if a checksum is present, the full block
* that is known to contain an error is rewritten. Afterwards
Expand All @@ -854,10 +836,17 @@ static int scrub_handle_errored_block(struct scrub_block *sblock_to_check)
mirror_index < BTRFS_MAX_MIRRORS &&
sblocks_for_recheck[mirror_index].page_count > 0;
mirror_index++) {
struct scrub_block *sblock_other = sblocks_for_recheck +
mirror_index;
struct scrub_block *sblock_other;

if (!sblock_other->header_error &&
if (mirror_index == failed_mirror_index)
continue;
sblock_other = sblocks_for_recheck + mirror_index;

/* build and submit the bios, check checksums */
ret = scrub_recheck_block(fs_info, sblock_other, is_metadata,
have_csum, csum, generation,
sctx->csum_size);
if (!ret && !sblock_other->header_error &&
!sblock_other->checksum_error &&
sblock_other->no_io_error_seen) {
int force_write = is_metadata || have_csum;
Expand Down

0 comments on commit cb2ced7

Please sign in to comment.