Commit 6f034ece authored by Liu Bo's avatar Liu Bo Committed by David Sterba

Btrfs: cleanup BUG_ON in merge_bio

One can use btrfs-corrupt-block to hit BUG_ON() in merge_bio(),
thus this aims to stop anyone to panic the whole system by using
 their btrfs.

Since the error in merge_bio can only come from __btrfs_map_block()
when chunk tree mapping has something insane and __btrfs_map_block()
has already had printed the reason, we can just return errors in
merge_bio.
Signed-off-by: default avatarLiu Bo <bo.li.liu@oracle.com>
Reviewed-by: default avatarDavid Sterba <dsterba@suse.com>
Signed-off-by: default avatarDavid Sterba <dsterba@suse.com>
parent fba4b697
...@@ -2756,7 +2756,6 @@ static int merge_bio(int rw, struct extent_io_tree *tree, struct page *page, ...@@ -2756,7 +2756,6 @@ static int merge_bio(int rw, struct extent_io_tree *tree, struct page *page,
if (tree->ops && tree->ops->merge_bio_hook) if (tree->ops && tree->ops->merge_bio_hook)
ret = tree->ops->merge_bio_hook(rw, page, offset, size, bio, ret = tree->ops->merge_bio_hook(rw, page, offset, size, bio,
bio_flags); bio_flags);
BUG_ON(ret < 0);
return ret; return ret;
} }
......
...@@ -1822,6 +1822,10 @@ static void btrfs_clear_bit_hook(struct inode *inode, ...@@ -1822,6 +1822,10 @@ static void btrfs_clear_bit_hook(struct inode *inode,
/* /*
* extent_io.c merge_bio_hook, this must check the chunk tree to make sure * extent_io.c merge_bio_hook, this must check the chunk tree to make sure
* we don't create bios that span stripes or chunks * we don't create bios that span stripes or chunks
*
* return 1 if page cannot be merged to bio
* return 0 if page can be merged to bio
* return error otherwise
*/ */
int btrfs_merge_bio_hook(int rw, struct page *page, unsigned long offset, int btrfs_merge_bio_hook(int rw, struct page *page, unsigned long offset,
size_t size, struct bio *bio, size_t size, struct bio *bio,
...@@ -1840,8 +1844,8 @@ int btrfs_merge_bio_hook(int rw, struct page *page, unsigned long offset, ...@@ -1840,8 +1844,8 @@ int btrfs_merge_bio_hook(int rw, struct page *page, unsigned long offset,
map_length = length; map_length = length;
ret = btrfs_map_block(root->fs_info, rw, logical, ret = btrfs_map_block(root->fs_info, rw, logical,
&map_length, NULL, 0); &map_length, NULL, 0);
/* Will always return 0 with map_multi == NULL */ if (ret < 0)
BUG_ON(ret < 0); return ret;
if (map_length < length + size) if (map_length < length + size)
return 1; return 1;
return 0; return 0;
......
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