diff options
author | Stefan Behrens <sbehrens@giantdisaster.de> | 2012-11-02 11:16:26 -0400 |
---|---|---|
committer | Josef Bacik <jbacik@fusionio.com> | 2012-12-12 17:15:31 -0500 |
commit | 34f5c8e90b3f002672cd6b4e6e7c5b959fd981ae (patch) | |
tree | 64fc8e75af8e7d91b7392c2b99445c48ca23bdba | |
parent | cb2ced73d8c7a38b5f699e267deadf2a2cfe911c (diff) |
Btrfs: in scrub repair code, simplify alloc error handling
In the scrub repair code, the code is changed to handle memory
allocation errors a little bit smarter. The change is to handle
it just like a read error. This simplifies the code and removes
a couple of lines of code, since the code to handle read errors
is there anyway.
Signed-off-by: Stefan Behrens <sbehrens@giantdisaster.de>
Signed-off-by: Chris Mason <chris.mason@fusionio.com>
-rw-r--r-- | fs/btrfs/scrub.c | 61 |
1 files changed, 26 insertions, 35 deletions
diff --git a/fs/btrfs/scrub.c b/fs/btrfs/scrub.c index 7d38f4073243..fcd5bccaa4ed 100644 --- a/fs/btrfs/scrub.c +++ b/fs/btrfs/scrub.c | |||
@@ -151,10 +151,10 @@ static int scrub_setup_recheck_block(struct scrub_ctx *sctx, | |||
151 | struct btrfs_mapping_tree *map_tree, | 151 | struct btrfs_mapping_tree *map_tree, |
152 | u64 length, u64 logical, | 152 | u64 length, u64 logical, |
153 | struct scrub_block *sblock); | 153 | struct scrub_block *sblock); |
154 | static int scrub_recheck_block(struct btrfs_fs_info *fs_info, | 154 | static void scrub_recheck_block(struct btrfs_fs_info *fs_info, |
155 | struct scrub_block *sblock, int is_metadata, | 155 | struct scrub_block *sblock, int is_metadata, |
156 | int have_csum, u8 *csum, u64 generation, | 156 | int have_csum, u8 *csum, u64 generation, |
157 | u16 csum_size); | 157 | u16 csum_size); |
158 | static void scrub_recheck_block_checksum(struct btrfs_fs_info *fs_info, | 158 | static void scrub_recheck_block_checksum(struct btrfs_fs_info *fs_info, |
159 | struct scrub_block *sblock, | 159 | struct scrub_block *sblock, |
160 | int is_metadata, int have_csum, | 160 | int is_metadata, int have_csum, |
@@ -718,16 +718,8 @@ static int scrub_handle_errored_block(struct scrub_block *sblock_to_check) | |||
718 | sblock_bad = sblocks_for_recheck + failed_mirror_index; | 718 | sblock_bad = sblocks_for_recheck + failed_mirror_index; |
719 | 719 | ||
720 | /* build and submit the bios for the failed mirror, check checksums */ | 720 | /* build and submit the bios for the failed mirror, check checksums */ |
721 | ret = scrub_recheck_block(fs_info, sblock_bad, is_metadata, have_csum, | 721 | scrub_recheck_block(fs_info, sblock_bad, is_metadata, have_csum, |
722 | csum, generation, sctx->csum_size); | 722 | csum, generation, sctx->csum_size); |
723 | if (ret) { | ||
724 | spin_lock(&sctx->stat_lock); | ||
725 | sctx->stat.read_errors++; | ||
726 | sctx->stat.uncorrectable_errors++; | ||
727 | spin_unlock(&sctx->stat_lock); | ||
728 | btrfs_dev_stat_inc_and_print(dev, BTRFS_DEV_STAT_READ_ERRS); | ||
729 | goto out; | ||
730 | } | ||
731 | 723 | ||
732 | if (!sblock_bad->header_error && !sblock_bad->checksum_error && | 724 | if (!sblock_bad->header_error && !sblock_bad->checksum_error && |
733 | sblock_bad->no_io_error_seen) { | 725 | sblock_bad->no_io_error_seen) { |
@@ -843,10 +835,11 @@ static int scrub_handle_errored_block(struct scrub_block *sblock_to_check) | |||
843 | sblock_other = sblocks_for_recheck + mirror_index; | 835 | sblock_other = sblocks_for_recheck + mirror_index; |
844 | 836 | ||
845 | /* build and submit the bios, check checksums */ | 837 | /* build and submit the bios, check checksums */ |
846 | ret = scrub_recheck_block(fs_info, sblock_other, is_metadata, | 838 | scrub_recheck_block(fs_info, sblock_other, is_metadata, |
847 | have_csum, csum, generation, | 839 | have_csum, csum, generation, |
848 | sctx->csum_size); | 840 | sctx->csum_size); |
849 | if (!ret && !sblock_other->header_error && | 841 | |
842 | if (!sblock_other->header_error && | ||
850 | !sblock_other->checksum_error && | 843 | !sblock_other->checksum_error && |
851 | sblock_other->no_io_error_seen) { | 844 | sblock_other->no_io_error_seen) { |
852 | int force_write = is_metadata || have_csum; | 845 | int force_write = is_metadata || have_csum; |
@@ -931,10 +924,10 @@ static int scrub_handle_errored_block(struct scrub_block *sblock_to_check) | |||
931 | * is verified, but most likely the data comes out | 924 | * is verified, but most likely the data comes out |
932 | * of the page cache. | 925 | * of the page cache. |
933 | */ | 926 | */ |
934 | ret = scrub_recheck_block(fs_info, sblock_bad, | 927 | scrub_recheck_block(fs_info, sblock_bad, |
935 | is_metadata, have_csum, csum, | 928 | is_metadata, have_csum, csum, |
936 | generation, sctx->csum_size); | 929 | generation, sctx->csum_size); |
937 | if (!ret && !sblock_bad->header_error && | 930 | if (!sblock_bad->header_error && |
938 | !sblock_bad->checksum_error && | 931 | !sblock_bad->checksum_error && |
939 | sblock_bad->no_io_error_seen) | 932 | sblock_bad->no_io_error_seen) |
940 | goto corrected_error; | 933 | goto corrected_error; |
@@ -1061,10 +1054,10 @@ leave_nomem: | |||
1061 | * to take those pages that are not errored from all the mirrors so that | 1054 | * to take those pages that are not errored from all the mirrors so that |
1062 | * the pages that are errored in the just handled mirror can be repaired. | 1055 | * the pages that are errored in the just handled mirror can be repaired. |
1063 | */ | 1056 | */ |
1064 | static int scrub_recheck_block(struct btrfs_fs_info *fs_info, | 1057 | static void scrub_recheck_block(struct btrfs_fs_info *fs_info, |
1065 | struct scrub_block *sblock, int is_metadata, | 1058 | struct scrub_block *sblock, int is_metadata, |
1066 | int have_csum, u8 *csum, u64 generation, | 1059 | int have_csum, u8 *csum, u64 generation, |
1067 | u16 csum_size) | 1060 | u16 csum_size) |
1068 | { | 1061 | { |
1069 | int page_num; | 1062 | int page_num; |
1070 | 1063 | ||
@@ -1074,7 +1067,6 @@ static int scrub_recheck_block(struct btrfs_fs_info *fs_info, | |||
1074 | 1067 | ||
1075 | for (page_num = 0; page_num < sblock->page_count; page_num++) { | 1068 | for (page_num = 0; page_num < sblock->page_count; page_num++) { |
1076 | struct bio *bio; | 1069 | struct bio *bio; |
1077 | int ret; | ||
1078 | struct scrub_page *page = sblock->pagev[page_num]; | 1070 | struct scrub_page *page = sblock->pagev[page_num]; |
1079 | DECLARE_COMPLETION_ONSTACK(complete); | 1071 | DECLARE_COMPLETION_ONSTACK(complete); |
1080 | 1072 | ||
@@ -1086,18 +1078,17 @@ static int scrub_recheck_block(struct btrfs_fs_info *fs_info, | |||
1086 | 1078 | ||
1087 | WARN_ON(!page->page); | 1079 | WARN_ON(!page->page); |
1088 | bio = bio_alloc(GFP_NOFS, 1); | 1080 | bio = bio_alloc(GFP_NOFS, 1); |
1089 | if (!bio) | 1081 | if (!bio) { |
1090 | return -EIO; | 1082 | page->io_error = 1; |
1083 | sblock->no_io_error_seen = 0; | ||
1084 | continue; | ||
1085 | } | ||
1091 | bio->bi_bdev = page->dev->bdev; | 1086 | bio->bi_bdev = page->dev->bdev; |
1092 | bio->bi_sector = page->physical >> 9; | 1087 | bio->bi_sector = page->physical >> 9; |
1093 | bio->bi_end_io = scrub_complete_bio_end_io; | 1088 | bio->bi_end_io = scrub_complete_bio_end_io; |
1094 | bio->bi_private = &complete; | 1089 | bio->bi_private = &complete; |
1095 | 1090 | ||
1096 | ret = bio_add_page(bio, page->page, PAGE_SIZE, 0); | 1091 | bio_add_page(bio, page->page, PAGE_SIZE, 0); |
1097 | if (PAGE_SIZE != ret) { | ||
1098 | bio_put(bio); | ||
1099 | return -EIO; | ||
1100 | } | ||
1101 | btrfsic_submit_bio(READ, bio); | 1092 | btrfsic_submit_bio(READ, bio); |
1102 | 1093 | ||
1103 | /* this will also unplug the queue */ | 1094 | /* this will also unplug the queue */ |
@@ -1114,7 +1105,7 @@ static int scrub_recheck_block(struct btrfs_fs_info *fs_info, | |||
1114 | have_csum, csum, generation, | 1105 | have_csum, csum, generation, |
1115 | csum_size); | 1106 | csum_size); |
1116 | 1107 | ||
1117 | return 0; | 1108 | return; |
1118 | } | 1109 | } |
1119 | 1110 | ||
1120 | static void scrub_recheck_block_checksum(struct btrfs_fs_info *fs_info, | 1111 | static void scrub_recheck_block_checksum(struct btrfs_fs_info *fs_info, |