aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorStefan Behrens <sbehrens@giantdisaster.de>2012-11-02 11:14:21 -0400
committerJosef Bacik <jbacik@fusionio.com>2012-12-12 17:15:31 -0500
commitcb2ced73d8c7a38b5f699e267deadf2a2cfe911c (patch)
tree52d23d374ae31faac4d63b031387e532f577b895
parent7a9e9987681198c56ac7f165725ca322d7a196e1 (diff)
Btrfs: in scrub repair code, optimize the reading of mirrors
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>
-rw-r--r--fs/btrfs/scrub.c35
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;