|
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
|