summaryrefslogtreecommitdiff
path: root/extent-tree.c
diff options
context:
space:
mode:
authorQu Wenruo <quwenruo@cn.fujitsu.com>2017-04-25 16:01:17 +0800
committerDavid Sterba <dsterba@suse.com>2017-05-02 16:13:37 +0200
commit795e9c0981c427928edb9cc1966903f699ce1b11 (patch)
treef238f82125237c5f76cf0f88a876c4f117b8c998 /extent-tree.c
parent467b49ccbbb132d4d2ff4fe43d9581b89f349cea (diff)
btrfs-progs: Fix memory leak when 0 sized block group item is found
When a 0 sized block group item is found, set_extent_bits() will not really set any bits. While set_state_private() still inserts allocated block group cache into block group extent_io_tree. So at close_ctree() time, we won't free the private block group cache stored since we can't find any bit set for the 0 sized block group. To fix it, at btrfs_read_block_groups() we skip any 0 sized block group, so such leak won't happen. Signed-off-by: Qu Wenruo <quwenruo@cn.fujitsu.com> Signed-off-by: David Sterba <dsterba@suse.com>
Diffstat (limited to 'extent-tree.c')
-rw-r--r--extent-tree.c12
1 files changed, 12 insertions, 0 deletions
diff --git a/extent-tree.c b/extent-tree.c
index 3e32e43b..b12ee290 100644
--- a/extent-tree.c
+++ b/extent-tree.c
@@ -3250,6 +3250,7 @@ int btrfs_read_block_groups(struct btrfs_root *root)
}
leaf = path->nodes[0];
btrfs_item_key_to_cpu(leaf, &found_key, path->slots[0]);
+
cache = kzalloc(sizeof(*cache), GFP_NOFS);
if (!cache) {
ret = -ENOMEM;
@@ -3266,6 +3267,17 @@ int btrfs_read_block_groups(struct btrfs_root *root)
if (found_key.offset == 0)
key.objectid++;
btrfs_release_path(path);
+
+ /*
+ * Skip 0 sized block group, don't insert them into block
+ * group cache tree, as its length is 0, it won't get
+ * freed at close_ctree() time.
+ */
+ if (found_key.offset == 0) {
+ free(cache);
+ continue;
+ }
+
cache->flags = btrfs_block_group_flags(&cache->item);
bit = 0;
if (cache->flags & BTRFS_BLOCK_GROUP_DATA) {