diff --git a/disk-io.c b/disk-io.c index 6ef35bbf..be4abb8b 100644 --- a/disk-io.c +++ b/disk-io.c @@ -1278,24 +1278,39 @@ int write_ctree_super(struct btrfs_trans_handle *trans, static int close_all_devices(struct btrfs_fs_info *fs_info) { struct list_head *list; - struct list_head *next; struct btrfs_device *device; - return 0; - list = &fs_info->fs_devices->devices; - list_for_each(next, list) { - device = list_entry(next, struct btrfs_device, dev_list); + while (!list_empty(list)) { + device = list_entry(list->next, struct btrfs_device, dev_list); + list_del_init(&device->dev_list); if (device->fd) { fsync(device->fd); if (posix_fadvise(device->fd, 0, 0, POSIX_FADV_DONTNEED)) fprintf(stderr, "Warning, could not drop caches\n"); } close(device->fd); + kfree(device->name); + kfree(device->label); + kfree(device); } + kfree(fs_info->fs_devices); return 0; } +static void free_mapping_cache(struct btrfs_fs_info *fs_info) +{ + struct cache_tree *cache_tree = &fs_info->mapping_tree.cache_tree; + struct cache_extent *ce; + struct map_lookup *map; + + while ((ce = find_first_cache_extent(cache_tree, 0))) { + map = container_of(ce, struct map_lookup, ce); + remove_cache_extent(cache_tree, ce); + kfree(map); + } +} + int close_ctree(struct btrfs_root *root) { int ret; @@ -1336,6 +1351,7 @@ int close_ctree(struct btrfs_root *root) } close_all_devices(fs_info); + free_mapping_cache(fs_info); extent_io_tree_cleanup(&fs_info->extent_cache); extent_io_tree_cleanup(&fs_info->free_space_cache); extent_io_tree_cleanup(&fs_info->block_group_cache); diff --git a/extent-tree.c b/extent-tree.c index da93cb17..2d829777 100644 --- a/extent-tree.c +++ b/extent-tree.c @@ -3003,10 +3003,12 @@ out: int btrfs_free_block_groups(struct btrfs_fs_info *info) { + struct btrfs_space_info *sinfo; u64 start; u64 end; u64 ptr; int ret; + while(1) { ret = find_first_extent_bit(&info->block_group_cache, 0, &start, &end, (unsigned int)-1); @@ -3026,6 +3028,13 @@ int btrfs_free_block_groups(struct btrfs_fs_info *info) clear_extent_dirty(&info->free_space_cache, start, end, GFP_NOFS); } + + while (!list_empty(&info->space_info)) { + sinfo = list_entry(info->space_info.next, + struct btrfs_space_info, list); + list_del_init(&sinfo->list); + kfree(sinfo); + } return 0; }