Josef Bacik 8ce292
Hello,
Josef Bacik 8ce292
Josef Bacik 8ce292
Started running valgrind against btrfsck since e2fsck seemed to have a myriad of
Josef Bacik 8ce292
problems.  btrfsck was actually not in too bad shape, only like 5 or 6 normal
Josef Bacik 8ce292
errors and maybe 5 leaks.  The big leak is the "seen" extent cache that we don't
Josef Bacik 8ce292
seem to do anything with.  Since I'm not sure what Yan is up to I just made it
Josef Bacik 8ce292
so we free that cache before we return in case he wants it for something.  With
Josef Bacik 8ce292
these changes btrfsck doesn't spit out any errors while running valgrind and has
Josef Bacik 8ce292
no leaks.  This should also help any of the other utilities that use the generic
Josef Bacik 8ce292
stuff.  Thanks,
Josef Bacik 8ce292
Josef Bacik 8ce292
Signed-off-by: Josef Bacik <jbacik@redhat.com>
Josef Bacik 8ce292
---
Josef Bacik 8ce292
 btrfsck.c      |    2 ++
Josef Bacik 8ce292
 disk-io.c      |   29 ++++++++++++++++++-----------
Josef Bacik 8ce292
 extent-cache.c |   11 +++++++++++
Josef Bacik 8ce292
 extent-cache.h |    1 +
Josef Bacik 8ce292
 extent-tree.c  |   10 ++++++++++
Josef Bacik 8ce292
 extent_io.c    |    1 +
Josef Bacik 8ce292
 volumes.c      |   16 +++++++++++++++-
Josef Bacik 8ce292
 volumes.h      |    1 +
Josef Bacik 8ce292
 8 files changed, 59 insertions(+), 12 deletions(-)
Josef Bacik 8ce292
Josef Bacik 8ce292
diff --git a/btrfsck.c b/btrfsck.c
Josef Bacik 8ce292
index 40c90f8..9dd777f 100644
Josef Bacik 8ce292
--- a/btrfsck.c
Josef Bacik 8ce292
+++ b/btrfsck.c
Josef Bacik 8ce292
@@ -2431,6 +2431,8 @@ static int check_extents(struct btrfs_root *root)
Josef Bacik 8ce292
 			break;
Josef Bacik 8ce292
 	}
Josef Bacik 8ce292
 	ret = check_extent_refs(root, &extent_cache);
Josef Bacik 8ce292
+	free_cache_tree(&seen);
Josef Bacik 8ce292
+	free(bits);
Josef Bacik 8ce292
 	return ret;
Josef Bacik 8ce292
 }
Josef Bacik 8ce292
 
Josef Bacik 8ce292
diff --git a/disk-io.c b/disk-io.c
Josef Bacik 8ce292
index addebe1..4d4e902 100644
Josef Bacik 8ce292
--- a/disk-io.c
Josef Bacik 8ce292
+++ b/disk-io.c
Josef Bacik 8ce292
@@ -425,8 +425,10 @@ static int find_and_setup_log_root(struct btrfs_root *tree_root,
Josef Bacik 8ce292
 	u64 blocknr = btrfs_super_log_root(disk_super);
Josef Bacik 8ce292
 	struct btrfs_root *log_root = malloc(sizeof(struct btrfs_root));
Josef Bacik 8ce292
 
Josef Bacik 8ce292
-	if (blocknr == 0)
Josef Bacik 8ce292
+	if (blocknr == 0) {
Josef Bacik 8ce292
+		free(log_root);
Josef Bacik 8ce292
 		return 0;
Josef Bacik 8ce292
+	}
Josef Bacik 8ce292
 
Josef Bacik 8ce292
 	blocksize = btrfs_level_size(tree_root,
Josef Bacik 8ce292
 			     btrfs_super_log_root_level(disk_super));
Josef Bacik 8ce292
@@ -605,7 +607,7 @@ struct btrfs_root *open_ctree_fd(int fp, const char *path, u64 sb_bytenr,
Josef Bacik 8ce292
 	struct btrfs_root *chunk_root = malloc(sizeof(struct btrfs_root));
Josef Bacik 8ce292
 	struct btrfs_root *dev_root = malloc(sizeof(struct btrfs_root));
Josef Bacik 8ce292
 	struct btrfs_root *csum_root = malloc(sizeof(struct btrfs_root));
Josef Bacik 8ce292
-	struct btrfs_fs_info *fs_info = malloc(sizeof(*fs_info));
Josef Bacik 8ce292
+	struct btrfs_fs_info *fs_info = malloc(sizeof(struct btrfs_fs_info));
Josef Bacik 8ce292
 	int ret;
Josef Bacik 8ce292
 	struct btrfs_super_block *disk_super;
Josef Bacik 8ce292
 	struct btrfs_fs_devices *fs_devices = NULL;
Josef Bacik 8ce292
@@ -628,7 +630,7 @@ struct btrfs_root *open_ctree_fd(int fp, const char *path, u64 sb_bytenr,
Josef Bacik 8ce292
 		BUG_ON(ret);
Josef Bacik 8ce292
 	}
Josef Bacik 8ce292
 
Josef Bacik 8ce292
-	memset(fs_info, 0, sizeof(*fs_info));
Josef Bacik 8ce292
+	memset(fs_info, 0, sizeof(struct btrfs_fs_info));
Josef Bacik 8ce292
 	fs_info->tree_root = tree_root;
Josef Bacik 8ce292
 	fs_info->extent_root = extent_root;
Josef Bacik 8ce292
 	fs_info->chunk_root = chunk_root;
Josef Bacik 8ce292
@@ -928,15 +930,19 @@ static int close_all_devices(struct btrfs_fs_info *fs_info)
Josef Bacik 8ce292
 {
Josef Bacik 8ce292
 	struct list_head *list;
Josef Bacik 8ce292
 	struct list_head *next;
Josef Bacik 8ce292
+	struct list_head *tmp;
Josef Bacik 8ce292
 	struct btrfs_device *device;
Josef Bacik 8ce292
 
Josef Bacik 8ce292
-	return 0;
Josef Bacik 8ce292
-
Josef Bacik 8ce292
 	list = &fs_info->fs_devices->devices;
Josef Bacik 8ce292
-	list_for_each(next, list) {
Josef Bacik 8ce292
+	list_for_each_safe(next, tmp, list) {
Josef Bacik 8ce292
 		device = list_entry(next, struct btrfs_device, dev_list);
Josef Bacik 8ce292
 		close(device->fd);
Josef Bacik 8ce292
+		list_del(&device->dev_list);
Josef Bacik 8ce292
+		free(device->name);
Josef Bacik 8ce292
+		free(device->label);
Josef Bacik 8ce292
+		free(device);
Josef Bacik 8ce292
 	}
Josef Bacik 8ce292
+	free(fs_info->fs_devices);
Josef Bacik 8ce292
 	return 0;
Josef Bacik 8ce292
 }
Josef Bacik 8ce292
 
Josef Bacik 8ce292
@@ -970,25 +976,26 @@ int close_ctree(struct btrfs_root *root)
Josef Bacik 8ce292
 	if (fs_info->csum_root->node)
Josef Bacik 8ce292
 		free_extent_buffer(fs_info->csum_root->node);
Josef Bacik 8ce292
 
Josef Bacik 8ce292
-	if (root->fs_info->log_root_tree) {
Josef Bacik 8ce292
-		if (root->fs_info->log_root_tree->node)
Josef Bacik 8ce292
-			free_extent_buffer(root->fs_info->log_root_tree->node);
Josef Bacik 8ce292
-		free(root->fs_info->log_root_tree);
Josef Bacik 8ce292
+	if (fs_info->log_root_tree) {
Josef Bacik 8ce292
+		if (fs_info->log_root_tree->node)
Josef Bacik 8ce292
+			free_extent_buffer(fs_info->log_root_tree->node);
Josef Bacik 8ce292
 	}
Josef Bacik 8ce292
 
Josef Bacik 8ce292
-	close_all_devices(root->fs_info);
Josef Bacik 8ce292
+	close_all_devices(fs_info);
Josef Bacik 8ce292
 	extent_io_tree_cleanup(&fs_info->extent_cache);
Josef Bacik 8ce292
 	extent_io_tree_cleanup(&fs_info->free_space_cache);
Josef Bacik 8ce292
 	extent_io_tree_cleanup(&fs_info->block_group_cache);
Josef Bacik 8ce292
 	extent_io_tree_cleanup(&fs_info->pinned_extents);
Josef Bacik 8ce292
 	extent_io_tree_cleanup(&fs_info->pending_del);
Josef Bacik 8ce292
 	extent_io_tree_cleanup(&fs_info->extent_ins);
Josef Bacik 8ce292
+	btrfs_mapping_tree_free(&fs_info->mapping_tree);
Josef Bacik 8ce292
 
Josef Bacik 8ce292
 	free(fs_info->tree_root);
Josef Bacik 8ce292
 	free(fs_info->extent_root);
Josef Bacik 8ce292
 	free(fs_info->chunk_root);
Josef Bacik 8ce292
 	free(fs_info->dev_root);
Josef Bacik 8ce292
 	free(fs_info->csum_root);
Josef Bacik 8ce292
+	free(fs_info->log_root_tree);
Josef Bacik 8ce292
 	free(fs_info);
Josef Bacik 8ce292
 
Josef Bacik 8ce292
 	return 0;
Josef Bacik 8ce292
diff --git a/extent-cache.c b/extent-cache.c
Josef Bacik 8ce292
index b871e18..b424975 100644
Josef Bacik 8ce292
--- a/extent-cache.c
Josef Bacik 8ce292
+++ b/extent-cache.c
Josef Bacik 8ce292
@@ -170,3 +170,14 @@ void remove_cache_extent(struct cache_tree *tree,
Josef Bacik 8ce292
 	rb_erase(&pe->rb_node, &tree->root);
Josef Bacik 8ce292
 }
Josef Bacik 8ce292
 
Josef Bacik 8ce292
+void free_cache_tree(struct cache_tree *tree)
Josef Bacik 8ce292
+{
Josef Bacik 8ce292
+	struct rb_node *node;
Josef Bacik 8ce292
+	struct cache_extent *cache;
Josef Bacik 8ce292
+
Josef Bacik 8ce292
+	while ((node = rb_last(&tree->root)) != NULL) {
Josef Bacik 8ce292
+		cache = rb_entry(node, struct cache_extent, rb_node);
Josef Bacik 8ce292
+		remove_cache_extent(tree, cache);
Josef Bacik 8ce292
+		free(cache);
Josef Bacik 8ce292
+	}
Josef Bacik 8ce292
+}
Josef Bacik 8ce292
diff --git a/extent-cache.h b/extent-cache.h
Josef Bacik 8ce292
index 7f2f2a6..1696bc2 100644
Josef Bacik 8ce292
--- a/extent-cache.h
Josef Bacik 8ce292
+++ b/extent-cache.h
Josef Bacik 8ce292
@@ -43,6 +43,7 @@ struct cache_extent *find_cache_extent(struct cache_tree *tree,
Josef Bacik 8ce292
 int insert_cache_extent(struct cache_tree *tree, u64 start, u64 size);
Josef Bacik 8ce292
 int insert_existing_cache_extent(struct cache_tree *tree,
Josef Bacik 8ce292
 				 struct cache_extent *pe);
Josef Bacik 8ce292
+void free_cache_tree(struct cache_tree *tree);
Josef Bacik 8ce292
 
Josef Bacik 8ce292
 static inline int cache_tree_empty(struct cache_tree *tree)
Josef Bacik 8ce292
 {
Josef Bacik 8ce292
diff --git a/extent-tree.c b/extent-tree.c
Josef Bacik 8ce292
index b2f9bb2..e1d7ffd 100644
Josef Bacik 8ce292
--- a/extent-tree.c
Josef Bacik 8ce292
+++ b/extent-tree.c
Josef Bacik 8ce292
@@ -2985,6 +2985,7 @@ out:
Josef Bacik 8ce292
 
Josef Bacik 8ce292
 int btrfs_free_block_groups(struct btrfs_fs_info *info)
Josef Bacik 8ce292
 {
Josef Bacik 8ce292
+	struct btrfs_space_info *space_info;
Josef Bacik 8ce292
 	u64 start;
Josef Bacik 8ce292
 	u64 end;
Josef Bacik 8ce292
 	u64 ptr;
Josef Bacik 8ce292
@@ -3008,6 +3009,15 @@ int btrfs_free_block_groups(struct btrfs_fs_info *info)
Josef Bacik 8ce292
 		clear_extent_dirty(&info->free_space_cache, start,
Josef Bacik 8ce292
 				   end, GFP_NOFS);
Josef Bacik 8ce292
 	}
Josef Bacik 8ce292
+
Josef Bacik 8ce292
+	while (!list_empty(&info->space_info)) {
Josef Bacik 8ce292
+		space_info = list_entry(info->space_info.next,
Josef Bacik 8ce292
+					struct btrfs_space_info,
Josef Bacik 8ce292
+					list);
Josef Bacik 8ce292
+		list_del(&space_info->list);
Josef Bacik 8ce292
+		kfree(space_info);
Josef Bacik 8ce292
+	}
Josef Bacik 8ce292
+
Josef Bacik 8ce292
 	return 0;
Josef Bacik 8ce292
 }
Josef Bacik 8ce292
 
Josef Bacik 8ce292
diff --git a/extent_io.c b/extent_io.c
Josef Bacik 8ce292
index 069c199..71e6826 100644
Josef Bacik 8ce292
--- a/extent_io.c
Josef Bacik 8ce292
+++ b/extent_io.c
Josef Bacik 8ce292
@@ -572,6 +572,7 @@ static struct extent_buffer *__alloc_extent_buffer(struct extent_io_tree *tree,
Josef Bacik 8ce292
 		BUG();
Josef Bacik 8ce292
 		return NULL;
Josef Bacik 8ce292
 	}
Josef Bacik 8ce292
+	memset(eb, 0, sizeof(struct extent_buffer) + blocksize);
Josef Bacik 8ce292
 
Josef Bacik 8ce292
 	eb->start = bytenr;
Josef Bacik 8ce292
 	eb->len = blocksize;
Josef Bacik 8ce292
diff --git a/volumes.c b/volumes.c
Josef Bacik 8ce292
index 7671855..eee66a7 100644
Josef Bacik 8ce292
--- a/volumes.c
Josef Bacik 8ce292
+++ b/volumes.c
Josef Bacik 8ce292
@@ -862,6 +862,20 @@ void btrfs_mapping_init(struct btrfs_mapping_tree *tree)
Josef Bacik 8ce292
 	cache_tree_init(&tree->cache_tree);
Josef Bacik 8ce292
 }
Josef Bacik 8ce292
 
Josef Bacik 8ce292
+void btrfs_mapping_tree_free(struct btrfs_mapping_tree *tree)
Josef Bacik 8ce292
+{
Josef Bacik 8ce292
+	struct cache_extent *cache;
Josef Bacik 8ce292
+	struct rb_node *node;
Josef Bacik 8ce292
+	struct map_lookup *map;
Josef Bacik 8ce292
+
Josef Bacik 8ce292
+	while ((node = rb_last(&tree->cache_tree.root)) != NULL) {
Josef Bacik 8ce292
+		cache = rb_entry(node, struct cache_extent, rb_node);
Josef Bacik 8ce292
+		map = container_of(cache, struct map_lookup, ce);
Josef Bacik 8ce292
+		remove_cache_extent(&tree->cache_tree, cache);
Josef Bacik 8ce292
+		free(map);
Josef Bacik 8ce292
+	}
Josef Bacik 8ce292
+}
Josef Bacik 8ce292
+
Josef Bacik 8ce292
 int btrfs_num_copies(struct btrfs_mapping_tree *map_tree, u64 logical, u64 len)
Josef Bacik 8ce292
 {
Josef Bacik 8ce292
 	struct cache_extent *ce;
Josef Bacik 8ce292
@@ -1340,7 +1354,7 @@ int btrfs_read_sys_array(struct btrfs_root *root)
Josef Bacik 8ce292
 	if (!sb)
Josef Bacik 8ce292
 		return -ENOMEM;
Josef Bacik 8ce292
 	btrfs_set_buffer_uptodate(sb);
Josef Bacik 8ce292
-	write_extent_buffer(sb, super_copy, 0, BTRFS_SUPER_INFO_SIZE);
Josef Bacik 8ce292
+	write_extent_buffer(sb, super_copy, 0, sizeof(*super_copy));
Josef Bacik 8ce292
 	array_size = btrfs_super_sys_array_size(super_copy);
Josef Bacik 8ce292
 
Josef Bacik 8ce292
 	/*
Josef Bacik 8ce292
diff --git a/volumes.h b/volumes.h
Josef Bacik 8ce292
index bb78751..e466b31 100644
Josef Bacik 8ce292
--- a/volumes.h
Josef Bacik 8ce292
+++ b/volumes.h
Josef Bacik 8ce292
@@ -130,4 +130,5 @@ int btrfs_add_system_chunk(struct btrfs_trans_handle *trans,
Josef Bacik 8ce292
 			   struct btrfs_root *root, struct btrfs_key *key,
Josef Bacik 8ce292
 			   struct btrfs_chunk *chunk, int item_size);
Josef Bacik 8ce292
 int btrfs_chunk_readonly(struct btrfs_root *root, u64 chunk_offset);
Josef Bacik 8ce292
+void btrfs_mapping_tree_free(struct btrfs_mapping_tree *tree);
Josef Bacik 8ce292
 #endif
Josef Bacik 8ce292
-- 
Josef Bacik 8ce292
1.5.4.3
Josef Bacik 8ce292
Josef Bacik 8ce292
--
Josef Bacik 8ce292
To unsubscribe from this list: send the line "unsubscribe linux-btrfs" in
Josef Bacik 8ce292
the body of a message to majordomo@vger.kernel.org
Josef Bacik 8ce292
More majordomo info at  http://vger.kernel.org/majordomo-info.html