mirror of https://gitee.com/openkylin/linux.git
btrfs: extent_io: Handle errors better in extent_write_full_page()
Since now flush_write_bio() could return error, kill the BUG_ON() first. Then don't call flush_write_bio() unconditionally, instead we check the return value from __extent_writepage() first. If __extent_writepage() fails, we do cleanup, and return error without submitting the possible corrupted or half-baked bio. If __extent_writepage() successes, then we call flush_write_bio() and return the result. Signed-off-by: Qu Wenruo <wqu@suse.com> Reviewed-by: David Sterba <dsterba@suse.com> Signed-off-by: David Sterba <dsterba@suse.com>
This commit is contained in:
parent
f4340622e0
commit
3065976b04
|
@ -170,6 +170,16 @@ static int __must_check submit_one_bio(struct bio *bio, int mirror_num,
|
|||
return blk_status_to_errno(ret);
|
||||
}
|
||||
|
||||
/* Cleanup unsubmitted bios */
|
||||
static void end_write_bio(struct extent_page_data *epd, int ret)
|
||||
{
|
||||
if (epd->bio) {
|
||||
epd->bio->bi_status = errno_to_blk_status(ret);
|
||||
bio_endio(epd->bio);
|
||||
epd->bio = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Submit bio from extent page data via submit_one_bio
|
||||
*
|
||||
|
@ -3397,6 +3407,9 @@ static noinline_for_stack int __extent_writepage_io(struct inode *inode,
|
|||
* records are inserted to lock ranges in the tree, and as dirty areas
|
||||
* are found, they are marked writeback. Then the lock bits are removed
|
||||
* and the end_io handler clears the writeback ranges
|
||||
*
|
||||
* Return 0 if everything goes well.
|
||||
* Return <0 for error.
|
||||
*/
|
||||
static int __extent_writepage(struct page *page, struct writeback_control *wbc,
|
||||
struct extent_page_data *epd)
|
||||
|
@ -3466,6 +3479,7 @@ static int __extent_writepage(struct page *page, struct writeback_control *wbc,
|
|||
end_extent_writepage(page, ret, start, page_end);
|
||||
}
|
||||
unlock_page(page);
|
||||
ASSERT(ret <= 0);
|
||||
return ret;
|
||||
|
||||
done_unlocked:
|
||||
|
@ -4007,7 +4021,6 @@ static int extent_write_cache_pages(struct address_space *mapping,
|
|||
int extent_write_full_page(struct page *page, struct writeback_control *wbc)
|
||||
{
|
||||
int ret;
|
||||
int flush_ret;
|
||||
struct extent_page_data epd = {
|
||||
.bio = NULL,
|
||||
.tree = &BTRFS_I(page->mapping->host)->io_tree,
|
||||
|
@ -4016,9 +4029,14 @@ int extent_write_full_page(struct page *page, struct writeback_control *wbc)
|
|||
};
|
||||
|
||||
ret = __extent_writepage(page, wbc, &epd);
|
||||
ASSERT(ret <= 0);
|
||||
if (ret < 0) {
|
||||
end_write_bio(&epd, ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
flush_ret = flush_write_bio(&epd);
|
||||
BUG_ON(flush_ret < 0);
|
||||
ret = flush_write_bio(&epd);
|
||||
ASSERT(ret <= 0);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue