aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorStefan Behrens <sbehrens@giantdisaster.de>2012-11-02 11:16:26 -0400
committerJosef Bacik <jbacik@fusionio.com>2012-12-12 17:15:31 -0500
commit34f5c8e90b3f002672cd6b4e6e7c5b959fd981ae (patch)
tree64fc8e75af8e7d91b7392c2b99445c48ca23bdba
parentcb2ced73d8c7a38b5f699e267deadf2a2cfe911c (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.c61
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);
154static int scrub_recheck_block(struct btrfs_fs_info *fs_info, 154static 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);
158static void scrub_recheck_block_checksum(struct btrfs_fs_info *fs_info, 158static 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 */
1064static int scrub_recheck_block(struct btrfs_fs_info *fs_info, 1057static 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
1120static void scrub_recheck_block_checksum(struct btrfs_fs_info *fs_info, 1111static void scrub_recheck_block_checksum(struct btrfs_fs_info *fs_info,