Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

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

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
Loading
Loading
Loading
Loading
+8 −1
Original line number Diff line number Diff line
@@ -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)
		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);
		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)
		__btrfs_remove_free_space_cache(root->free_ino_pinned);