diff options
author | Zhao Lei <zhaolei@cn.fujitsu.com> | 2015-01-20 02:11:40 -0500 |
---|---|---|
committer | Chris Mason <clm@fb.com> | 2015-01-21 21:06:49 -0500 |
commit | 8d6738c1bd74a27ff6a5043c5211c7bff7745420 (patch) | |
tree | 5a62834b17957c5ec0bb274799864e4274a11eb6 /fs | |
parent | dc5f7a3bd820883793bb0d9789e938a34aa4da5f (diff) |
Btrfs: Separate finding-right-mirror and writing-to-target's process in scrub_handle_errored_block()
In corrent code, code of finding-right-mirror and writing-to-target
are mixed in logic, if we find a right mirror but failed in writing
to target, it will treat as "hadn't found right block", and fill the
target with sblock_bad.
Actually, "failed in writing to target" does not mean "source
block is wrong", this patch separate above two condition in logic,
and do some cleanup to make code clean.
Signed-off-by: Zhao Lei <zhaolei@cn.fujitsu.com>
Signed-off-by: Miao Xie <miaox@cn.fujitsu.com>
Signed-off-by: Chris Mason <clm@fb.com>
Diffstat (limited to 'fs')
-rw-r--r-- | fs/btrfs/scrub.c | 44 |
1 files changed, 17 insertions, 27 deletions
diff --git a/fs/btrfs/scrub.c b/fs/btrfs/scrub.c index 68867b2e4620..c40ffbc9581f 100644 --- a/fs/btrfs/scrub.c +++ b/fs/btrfs/scrub.c | |||
@@ -1114,35 +1114,21 @@ nodatasum_case: | |||
1114 | success = 1; | 1114 | success = 1; |
1115 | for (page_num = 0; page_num < sblock_bad->page_count; | 1115 | for (page_num = 0; page_num < sblock_bad->page_count; |
1116 | page_num++) { | 1116 | page_num++) { |
1117 | int sub_success; | 1117 | struct scrub_block *sblock_other = NULL; |
1118 | 1118 | ||
1119 | sub_success = 0; | ||
1120 | for (mirror_index = 0; | 1119 | for (mirror_index = 0; |
1121 | mirror_index < BTRFS_MAX_MIRRORS && | 1120 | mirror_index < BTRFS_MAX_MIRRORS && |
1122 | sblocks_for_recheck[mirror_index].page_count > 0; | 1121 | sblocks_for_recheck[mirror_index].page_count > 0; |
1123 | mirror_index++) { | 1122 | mirror_index++) { |
1124 | struct scrub_block *sblock_other = | 1123 | if (!sblocks_for_recheck[mirror_index]. |
1125 | sblocks_for_recheck + mirror_index; | 1124 | pagev[page_num]->io_error) { |
1126 | struct scrub_page *page_other = | 1125 | sblock_other = sblocks_for_recheck + |
1127 | sblock_other->pagev[page_num]; | 1126 | mirror_index; |
1128 | 1127 | break; | |
1129 | if (!page_other->io_error) { | ||
1130 | ret = scrub_write_page_to_dev_replace( | ||
1131 | sblock_other, page_num); | ||
1132 | if (ret == 0) { | ||
1133 | /* succeeded for this page */ | ||
1134 | sub_success = 1; | ||
1135 | break; | ||
1136 | } else { | ||
1137 | btrfs_dev_replace_stats_inc( | ||
1138 | &sctx->dev_root-> | ||
1139 | fs_info->dev_replace. | ||
1140 | num_write_errors); | ||
1141 | } | ||
1142 | } | 1128 | } |
1143 | } | 1129 | } |
1144 | 1130 | ||
1145 | if (!sub_success) { | 1131 | if (!sblock_other) { |
1146 | /* | 1132 | /* |
1147 | * did not find a mirror to fetch the page | 1133 | * did not find a mirror to fetch the page |
1148 | * from. scrub_write_page_to_dev_replace() | 1134 | * from. scrub_write_page_to_dev_replace() |
@@ -1150,13 +1136,17 @@ nodatasum_case: | |||
1150 | * filling the block with zeros before | 1136 | * filling the block with zeros before |
1151 | * submitting the write request | 1137 | * submitting the write request |
1152 | */ | 1138 | */ |
1139 | sblock_other = sblock_bad; | ||
1140 | success = 0; | ||
1141 | } | ||
1142 | |||
1143 | if (scrub_write_page_to_dev_replace(sblock_other, | ||
1144 | page_num) != 0) { | ||
1145 | btrfs_dev_replace_stats_inc( | ||
1146 | &sctx->dev_root-> | ||
1147 | fs_info->dev_replace. | ||
1148 | num_write_errors); | ||
1153 | success = 0; | 1149 | success = 0; |
1154 | ret = scrub_write_page_to_dev_replace( | ||
1155 | sblock_bad, page_num); | ||
1156 | if (ret) | ||
1157 | btrfs_dev_replace_stats_inc( | ||
1158 | &sctx->dev_root->fs_info-> | ||
1159 | dev_replace.num_write_errors); | ||
1160 | } | 1150 | } |
1161 | } | 1151 | } |
1162 | 1152 | ||