Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit ea9947b4 authored by Stefan Behrens's avatar Stefan Behrens Committed by Chris Mason
Browse files

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: default avatarMarco L. Crociani <marco.crociani@gmail.com>
Signed-off-by: default avatarStefan Behrens <sbehrens@giantdisaster.de>
Signed-off-by: default avatarChris Mason <chris.mason@oracle.com>
parent d04b1deb
Loading
Loading
Loading
Loading
+7 −0
Original line number Original line Diff line number Diff line
@@ -998,6 +998,7 @@ static int scrub_setup_recheck_block(struct scrub_dev *sdev,
			page = sblock->pagev + page_index;
			page = sblock->pagev + page_index;
			page->logical = logical;
			page->logical = logical;
			page->physical = bbio->stripes[mirror_index].physical;
			page->physical = bbio->stripes[mirror_index].physical;
			/* for missing devices, bdev is NULL */
			page->bdev = bbio->stripes[mirror_index].dev->bdev;
			page->bdev = bbio->stripes[mirror_index].dev->bdev;
			page->mirror_num = mirror_index + 1;
			page->mirror_num = mirror_index + 1;
			page->page = alloc_page(GFP_NOFS);
			page->page = alloc_page(GFP_NOFS);
@@ -1042,6 +1043,12 @@ static int scrub_recheck_block(struct btrfs_fs_info *fs_info,
		struct scrub_page *page = sblock->pagev + page_num;
		struct scrub_page *page = sblock->pagev + page_num;
		DECLARE_COMPLETION_ONSTACK(complete);
		DECLARE_COMPLETION_ONSTACK(complete);


		if (page->bdev == NULL) {
			page->io_error = 1;
			sblock->no_io_error_seen = 0;
			continue;
		}

		BUG_ON(!page->page);
		BUG_ON(!page->page);
		bio = bio_alloc(GFP_NOFS, 1);
		bio = bio_alloc(GFP_NOFS, 1);
		if (!bio)
		if (!bio)