diff options
Diffstat (limited to 'fs/btrfs/scrub.c')
-rw-r--r-- | fs/btrfs/scrub.c | 26 |
1 files changed, 11 insertions, 15 deletions
diff --git a/fs/btrfs/scrub.c b/fs/btrfs/scrub.c index 90acc82046c3..2f3d6f917fb3 100644 --- a/fs/btrfs/scrub.c +++ b/fs/btrfs/scrub.c | |||
@@ -998,6 +998,7 @@ static int scrub_setup_recheck_block(struct scrub_dev *sdev, | |||
998 | page = sblock->pagev + page_index; | 998 | page = sblock->pagev + page_index; |
999 | page->logical = logical; | 999 | page->logical = logical; |
1000 | page->physical = bbio->stripes[mirror_index].physical; | 1000 | page->physical = bbio->stripes[mirror_index].physical; |
1001 | /* for missing devices, bdev is NULL */ | ||
1001 | page->bdev = bbio->stripes[mirror_index].dev->bdev; | 1002 | page->bdev = bbio->stripes[mirror_index].dev->bdev; |
1002 | page->mirror_num = mirror_index + 1; | 1003 | page->mirror_num = mirror_index + 1; |
1003 | page->page = alloc_page(GFP_NOFS); | 1004 | page->page = alloc_page(GFP_NOFS); |
@@ -1042,8 +1043,16 @@ static int scrub_recheck_block(struct btrfs_fs_info *fs_info, | |||
1042 | struct scrub_page *page = sblock->pagev + page_num; | 1043 | struct scrub_page *page = sblock->pagev + page_num; |
1043 | DECLARE_COMPLETION_ONSTACK(complete); | 1044 | DECLARE_COMPLETION_ONSTACK(complete); |
1044 | 1045 | ||
1046 | if (page->bdev == NULL) { | ||
1047 | page->io_error = 1; | ||
1048 | sblock->no_io_error_seen = 0; | ||
1049 | continue; | ||
1050 | } | ||
1051 | |||
1045 | BUG_ON(!page->page); | 1052 | BUG_ON(!page->page); |
1046 | bio = bio_alloc(GFP_NOFS, 1); | 1053 | bio = bio_alloc(GFP_NOFS, 1); |
1054 | if (!bio) | ||
1055 | return -EIO; | ||
1047 | bio->bi_bdev = page->bdev; | 1056 | bio->bi_bdev = page->bdev; |
1048 | bio->bi_sector = page->physical >> 9; | 1057 | bio->bi_sector = page->physical >> 9; |
1049 | bio->bi_end_io = scrub_complete_bio_end_io; | 1058 | bio->bi_end_io = scrub_complete_bio_end_io; |
@@ -1171,6 +1180,8 @@ static int scrub_repair_page_from_good_copy(struct scrub_block *sblock_bad, | |||
1171 | DECLARE_COMPLETION_ONSTACK(complete); | 1180 | DECLARE_COMPLETION_ONSTACK(complete); |
1172 | 1181 | ||
1173 | bio = bio_alloc(GFP_NOFS, 1); | 1182 | bio = bio_alloc(GFP_NOFS, 1); |
1183 | if (!bio) | ||
1184 | return -EIO; | ||
1174 | bio->bi_bdev = page_bad->bdev; | 1185 | bio->bi_bdev = page_bad->bdev; |
1175 | bio->bi_sector = page_bad->physical >> 9; | 1186 | bio->bi_sector = page_bad->physical >> 9; |
1176 | bio->bi_end_io = scrub_complete_bio_end_io; | 1187 | bio->bi_end_io = scrub_complete_bio_end_io; |
@@ -1253,12 +1264,6 @@ static int scrub_checksum_data(struct scrub_block *sblock) | |||
1253 | if (memcmp(csum, on_disk_csum, sdev->csum_size)) | 1264 | if (memcmp(csum, on_disk_csum, sdev->csum_size)) |
1254 | fail = 1; | 1265 | fail = 1; |
1255 | 1266 | ||
1256 | if (fail) { | ||
1257 | spin_lock(&sdev->stat_lock); | ||
1258 | ++sdev->stat.csum_errors; | ||
1259 | spin_unlock(&sdev->stat_lock); | ||
1260 | } | ||
1261 | |||
1262 | return fail; | 1267 | return fail; |
1263 | } | 1268 | } |
1264 | 1269 | ||
@@ -1331,15 +1336,6 @@ static int scrub_checksum_tree_block(struct scrub_block *sblock) | |||
1331 | if (memcmp(calculated_csum, on_disk_csum, sdev->csum_size)) | 1336 | if (memcmp(calculated_csum, on_disk_csum, sdev->csum_size)) |
1332 | ++crc_fail; | 1337 | ++crc_fail; |
1333 | 1338 | ||
1334 | if (crc_fail || fail) { | ||
1335 | spin_lock(&sdev->stat_lock); | ||
1336 | if (crc_fail) | ||
1337 | ++sdev->stat.csum_errors; | ||
1338 | if (fail) | ||
1339 | ++sdev->stat.verify_errors; | ||
1340 | spin_unlock(&sdev->stat_lock); | ||
1341 | } | ||
1342 | |||
1343 | return fail || crc_fail; | 1339 | return fail || crc_fail; |
1344 | } | 1340 | } |
1345 | 1341 | ||