Commit 8cbc3001 authored by Josef Bacik's avatar Josef Bacik Committed by David Sterba

btrfs: do not clean up repair bio if submit fails

The submit helper will always run bio_endio() on the bio if it fails to
submit, so cleaning up the bio just leads to a variety of use-after-free
and NULL pointer dereference bugs because we race with the endio
function that is cleaning up the bio.  Instead just return BLK_STS_OK as
the repair function has to continue to process the rest of the pages,
and the endio for the repair bio will do the appropriate cleanup for the
page that it was given.
Reviewed-by: default avatarBoris Burkov <boris@bur.io>
Signed-off-by: default avatarJosef Bacik <josef@toxicpanda.com>
Signed-off-by: default avatarDavid Sterba <dsterba@suse.com>
parent 510671d2
...@@ -2640,7 +2640,6 @@ int btrfs_repair_one_sector(struct inode *inode, ...@@ -2640,7 +2640,6 @@ int btrfs_repair_one_sector(struct inode *inode,
const int icsum = bio_offset >> fs_info->sectorsize_bits; const int icsum = bio_offset >> fs_info->sectorsize_bits;
struct bio *repair_bio; struct bio *repair_bio;
struct btrfs_bio *repair_bbio; struct btrfs_bio *repair_bbio;
blk_status_t status;
btrfs_debug(fs_info, btrfs_debug(fs_info,
"repair read error: read error at %llu", start); "repair read error: read error at %llu", start);
...@@ -2679,13 +2678,13 @@ int btrfs_repair_one_sector(struct inode *inode, ...@@ -2679,13 +2678,13 @@ int btrfs_repair_one_sector(struct inode *inode,
"repair read error: submitting new read to mirror %d", "repair read error: submitting new read to mirror %d",
failrec->this_mirror); failrec->this_mirror);
status = submit_bio_hook(inode, repair_bio, failrec->this_mirror, /*
failrec->bio_flags); * At this point we have a bio, so any errors from submit_bio_hook()
if (status) { * will be handled by the endio on the repair_bio, so we can't return an
free_io_failure(failure_tree, tree, failrec); * error here.
bio_put(repair_bio); */
} submit_bio_hook(inode, repair_bio, failrec->this_mirror, failrec->bio_flags);
return blk_status_to_errno(status); return BLK_STS_OK;
} }
static void end_page_read(struct page *page, bool uptodate, u64 start, u32 len) static void end_page_read(struct page *page, bool uptodate, u64 start, u32 len)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment