Fix that when scrub tries to repair an I/O or checksum error and one of the devices containing the mirror is missing, it crashes in bio_add_page because the bdev is a NULL pointer for missing devices.
Unified · Split
| @@ -998,6 +998,7 @@ static int scrub_setup_recheck_block(struct scrub_dev *sdev, · 997 unmodified lines | ||
| 998 | 998 | page = sblock->pagev + page_index; |
| 999 | 999 | page->logical = logical; |
| 1000 | 1000 | page->physical = bbio->stripes[mirror_index].physical; |
| 1001 | + /* for missing devices, bdev is NULL */ | |
| 1001 | 1002 | page->bdev = bbio->stripes[mirror_index].dev->bdev; |
| 1002 | 1003 | page->mirror_num = mirror_index + 1; |
| 1003 | 1004 | page->page = alloc_page(GFP_NOFS); |
| @@ -1042,6 +1043,12 @@ static int scrub_recheck_block(struct btrfs_fs_info *fs_info, · 38 unmodified lines | ||
| 1042 | 1043 | struct scrub_page *page = sblock->pagev + page_num; |
| 1043 | 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 | 1052 | BUG_ON(!page->page); |
| 1046 | 1053 | bio = bio_alloc(GFP_NOFS, 1); |
| 1047 | 1054 | if (!bio) |