Commit 1c1ea4f7 authored by Liu Bo's avatar Liu Bo Committed by Chris Mason

Btrfs: fix memory leak of reloc_root

When some critical errors occur and FS would be flipped into RO,
if we have an on-going balance, we can end up with a memory leak
of root->reloc_root since btrfs_drop_snapshots() bails out
without freeing reloc_root at the very early start.

However, we're not able to free reloc_root in btrfs_drop_snapshots()
because its caller, merge_reloc_roots(), still needs to access it to
cleanup reloc_root's rbtree.

This makes us free reloc_root when we're going to free fs/file roots.
Signed-off-by: default avatarLiu Bo <bo.li.liu@oracle.com>
Reviewed-by: default avatarDavid Sterba <dsterba@suse.com>
Signed-off-by: default avatarDavid Sterba <dsterba@suse.com>
Signed-off-by: default avatarChris Mason <clm@fb.com>
parent 10838816
...@@ -3744,8 +3744,15 @@ void btrfs_drop_and_free_fs_root(struct btrfs_fs_info *fs_info, ...@@ -3744,8 +3744,15 @@ void btrfs_drop_and_free_fs_root(struct btrfs_fs_info *fs_info,
if (btrfs_root_refs(&root->root_item) == 0) if (btrfs_root_refs(&root->root_item) == 0)
synchronize_srcu(&fs_info->subvol_srcu); synchronize_srcu(&fs_info->subvol_srcu);
if (test_bit(BTRFS_FS_STATE_ERROR, &fs_info->fs_state)) if (test_bit(BTRFS_FS_STATE_ERROR, &fs_info->fs_state)) {
btrfs_free_log(NULL, root); btrfs_free_log(NULL, root);
if (root->reloc_root) {
free_extent_buffer(root->reloc_root->node);
free_extent_buffer(root->reloc_root->commit_root);
btrfs_put_fs_root(root->reloc_root);
root->reloc_root = NULL;
}
}
if (root->free_ino_pinned) if (root->free_ino_pinned)
__btrfs_remove_free_space_cache(root->free_ino_pinned); __btrfs_remove_free_space_cache(root->free_ino_pinned);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment