diff options
author | Josef Bacik <jbacik@fusionio.com> | 2013-04-23 22:17:42 +0400 |
---|---|---|
committer | Josef Bacik <jbacik@fusionio.com> | 2013-05-06 23:55:07 +0400 |
commit | 416bc6580bb01ddf67befaaeb94f087b392e7f47 (patch) | |
tree | 28a781ba1559a3021cb2aea8bbeebcfb20653115 /fs/btrfs/backref.c | |
parent | 51bf5f0bc4d132a3646ce36061e83fdc8b77f302 (diff) | |
download | linux-416bc6580bb01ddf67befaaeb94f087b392e7f47.tar.xz |
Btrfs: fix all callers of read_tree_block
We kept leaking extent buffers when mounting a broken file system and it turns
out it's because not everybody uses read_tree_block properly. You need to check
and make sure the extent_buffer is uptodate before you use it. This patch fixes
everybody who calls read_tree_block directly to make sure they check that it is
uptodate and free it and return an error if it is not. With this we no longer
leak EB's when things go horribly wrong. Thanks,
Signed-off-by: Josef Bacik <jbacik@fusionio.com>
Diffstat (limited to 'fs/btrfs/backref.c')
-rw-r--r-- | fs/btrfs/backref.c | 10 |
1 files changed, 8 insertions, 2 deletions
diff --git a/fs/btrfs/backref.c b/fs/btrfs/backref.c index 23e927b191c9..04b5b3093893 100644 --- a/fs/btrfs/backref.c +++ b/fs/btrfs/backref.c @@ -423,7 +423,10 @@ static int __add_missing_keys(struct btrfs_fs_info *fs_info, BUG_ON(!ref->wanted_disk_byte); eb = read_tree_block(fs_info->tree_root, ref->wanted_disk_byte, fs_info->tree_root->leafsize, 0); - BUG_ON(!eb); + if (!eb || !extent_buffer_uptodate(eb)) { + free_extent_buffer(eb); + return -EIO; + } btrfs_tree_read_lock(eb); if (btrfs_header_level(eb) == 0) btrfs_item_key_to_cpu(eb, &ref->key_for_search, 0); @@ -913,7 +916,10 @@ again: info_level); eb = read_tree_block(fs_info->extent_root, ref->parent, bsz, 0); - BUG_ON(!eb); + if (!eb || !extent_buffer_uptodate(eb)) { + free_extent_buffer(eb); + return -EIO; + } ret = find_extent_in_eb(eb, bytenr, *extent_item_pos, &eie); ref->inode_list = eie; |