diff options
author | Stefan Behrens <sbehrens@giantdisaster.de> | 2012-05-04 15:16:07 -0400 |
---|---|---|
committer | Chris Mason <chris.mason@oracle.com> | 2012-05-04 15:16:07 -0400 |
commit | ea9947b4395fa34666086b2fa6f686e94903e047 (patch) | |
tree | 086ab5150fc7f37b2070ab1200bf8b5275c85f06 /fs | |
parent | d04b1debc92535453df2494d0b019edf0bb91003 (diff) |
Btrfs: fix crash in scrub repair code when device is missing
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.
Reported-by: Marco L. Crociani <marco.crociani@gmail.com>
Signed-off-by: Stefan Behrens <sbehrens@giantdisaster.de>
Signed-off-by: Chris Mason <chris.mason@oracle.com>
Diffstat (limited to 'fs')
-rw-r--r-- | fs/btrfs/scrub.c | 7 |
1 files changed, 7 insertions, 0 deletions
diff --git a/fs/btrfs/scrub.c b/fs/btrfs/scrub.c index b679bf68861e..7e487be0094e 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,6 +1043,12 @@ 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); |
1047 | if (!bio) | 1054 | if (!bio) |