diff options
author | Josef Bacik <jbacik@fusionio.com> | 2013-04-23 14:17:42 -0400 |
---|---|---|
committer | Josef Bacik <jbacik@fusionio.com> | 2013-05-06 15:55:07 -0400 |
commit | 416bc6580bb01ddf67befaaeb94f087b392e7f47 (patch) | |
tree | 28a781ba1559a3021cb2aea8bbeebcfb20653115 /fs/btrfs/extent-tree.c | |
parent | 51bf5f0bc4d132a3646ce36061e83fdc8b77f302 (diff) |
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/extent-tree.c')
-rw-r--r-- | fs/btrfs/extent-tree.c | 4 |
1 files changed, 3 insertions, 1 deletions
diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c index 94bed61b799f..6526f1faf6c2 100644 --- a/fs/btrfs/extent-tree.c +++ b/fs/btrfs/extent-tree.c | |||
@@ -7087,8 +7087,10 @@ static noinline int do_walk_down(struct btrfs_trans_handle *trans, | |||
7087 | if (reada && level == 1) | 7087 | if (reada && level == 1) |
7088 | reada_walk_down(trans, root, wc, path); | 7088 | reada_walk_down(trans, root, wc, path); |
7089 | next = read_tree_block(root, bytenr, blocksize, generation); | 7089 | next = read_tree_block(root, bytenr, blocksize, generation); |
7090 | if (!next) | 7090 | if (!next || !extent_buffer_uptodate(next)) { |
7091 | free_extent_buffer(next); | ||
7091 | return -EIO; | 7092 | return -EIO; |
7093 | } | ||
7092 | btrfs_tree_lock(next); | 7094 | btrfs_tree_lock(next); |
7093 | btrfs_set_lock_blocking(next); | 7095 | btrfs_set_lock_blocking(next); |
7094 | } | 7096 | } |