diff options
Diffstat (limited to 'fs/btrfs/scrub.c')
-rw-r--r-- | fs/btrfs/scrub.c | 35 |
1 files changed, 12 insertions, 23 deletions
diff --git a/fs/btrfs/scrub.c b/fs/btrfs/scrub.c index 15ac82ae5770..7d38f4073243 100644 --- a/fs/btrfs/scrub.c +++ b/fs/btrfs/scrub.c | |||
@@ -819,26 +819,8 @@ static int scrub_handle_errored_block(struct scrub_block *sblock_to_check) | |||
819 | 819 | ||
820 | /* | 820 | /* |
821 | * now build and submit the bios for the other mirrors, check | 821 | * now build and submit the bios for the other mirrors, check |
822 | * checksums | 822 | * checksums. |
823 | */ | 823 | * First try to pick the mirror which is completely without I/O |
824 | for (mirror_index = 0; | ||
825 | mirror_index < BTRFS_MAX_MIRRORS && | ||
826 | sblocks_for_recheck[mirror_index].page_count > 0; | ||
827 | mirror_index++) { | ||
828 | if (mirror_index == failed_mirror_index) | ||
829 | continue; | ||
830 | |||
831 | /* build and submit the bios, check checksums */ | ||
832 | ret = scrub_recheck_block(fs_info, | ||
833 | sblocks_for_recheck + mirror_index, | ||
834 | is_metadata, have_csum, csum, | ||
835 | generation, sctx->csum_size); | ||
836 | if (ret) | ||
837 | goto did_not_correct_error; | ||
838 | } | ||
839 | |||
840 | /* | ||
841 | * first try to pick the mirror which is completely without I/O | ||
842 | * errors and also does not have a checksum error. | 824 | * errors and also does not have a checksum error. |
843 | * If one is found, and if a checksum is present, the full block | 825 | * If one is found, and if a checksum is present, the full block |
844 | * that is known to contain an error is rewritten. Afterwards | 826 | * that is known to contain an error is rewritten. Afterwards |
@@ -854,10 +836,17 @@ static int scrub_handle_errored_block(struct scrub_block *sblock_to_check) | |||
854 | mirror_index < BTRFS_MAX_MIRRORS && | 836 | mirror_index < BTRFS_MAX_MIRRORS && |
855 | sblocks_for_recheck[mirror_index].page_count > 0; | 837 | sblocks_for_recheck[mirror_index].page_count > 0; |
856 | mirror_index++) { | 838 | mirror_index++) { |
857 | struct scrub_block *sblock_other = sblocks_for_recheck + | 839 | struct scrub_block *sblock_other; |
858 | mirror_index; | ||
859 | 840 | ||
860 | if (!sblock_other->header_error && | 841 | if (mirror_index == failed_mirror_index) |
842 | continue; | ||
843 | sblock_other = sblocks_for_recheck + mirror_index; | ||
844 | |||
845 | /* build and submit the bios, check checksums */ | ||
846 | ret = scrub_recheck_block(fs_info, sblock_other, is_metadata, | ||
847 | have_csum, csum, generation, | ||
848 | sctx->csum_size); | ||
849 | if (!ret && !sblock_other->header_error && | ||
861 | !sblock_other->checksum_error && | 850 | !sblock_other->checksum_error && |
862 | sblock_other->no_io_error_seen) { | 851 | sblock_other->no_io_error_seen) { |
863 | int force_write = is_metadata || have_csum; | 852 | int force_write = is_metadata || have_csum; |