diff options
author | Liu Bo <bo.li.liu@oracle.com> | 2016-06-22 18:31:49 -0700 |
---|---|---|
committer | David Sterba <dsterba@suse.com> | 2016-07-26 13:52:25 +0200 |
commit | 6f034ece3422d8d4fbe0afe7cd8c2ac6438e651e (patch) | |
tree | 6fdb039ab1960d335bb981df75a8839d5421933b /fs/btrfs | |
parent | fba4b697710eb2a4bee456b9d39e9239c66f8bee (diff) | |
download | linux-6f034ece3422d8d4fbe0afe7cd8c2ac6438e651e.tar.gz linux-6f034ece3422d8d4fbe0afe7cd8c2ac6438e651e.tar.bz2 linux-6f034ece3422d8d4fbe0afe7cd8c2ac6438e651e.zip |
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: Liu Bo <bo.li.liu@oracle.com>
Reviewed-by: David Sterba <dsterba@suse.com>
Signed-off-by: David Sterba <dsterba@suse.com>
Diffstat (limited to 'fs/btrfs')
-rw-r--r-- | fs/btrfs/extent_io.c | 1 | ||||
-rw-r--r-- | fs/btrfs/inode.c | 8 |
2 files changed, 6 insertions, 3 deletions
diff --git a/fs/btrfs/extent_io.c b/fs/btrfs/extent_io.c index 9aaa544e65a9..ea12d0ee684f 100644 --- a/fs/btrfs/extent_io.c +++ b/fs/btrfs/extent_io.c @@ -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) ret = tree->ops->merge_bio_hook(rw, page, offset, size, bio, bio_flags); - BUG_ON(ret < 0); return ret; } diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c index 01c6fca925f7..f935fad17838 100644 --- a/fs/btrfs/inode.c +++ b/fs/btrfs/inode.c @@ -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 * 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, size_t size, struct bio *bio, @@ -1840,8 +1844,8 @@ int btrfs_merge_bio_hook(int rw, struct page *page, unsigned long offset, map_length = length; ret = btrfs_map_block(root->fs_info, rw, logical, &map_length, NULL, 0); - /* Will always return 0 with map_multi == NULL */ - BUG_ON(ret < 0); + if (ret < 0) + return ret; if (map_length < length + size) return 1; return 0; |