• Josef Bacik's avatar
    btrfs: fix reloc root leak with 0 ref reloc roots on recovery · c78a10ae
    Josef Bacik authored
    When recovering a relocation, if we run into a reloc root that has 0
    refs we simply add it to the reloc_control->reloc_roots list, and then
    clean it up later.  The problem with this is __del_reloc_root() doesn't
    do anything if the root isn't in the radix tree, which in this case it
    won't be because we never call __add_reloc_root() on the reloc_root.
    
    This exit condition simply isn't correct really.  During normal
    operation we can remove ourselves from the rb tree and then we're meant
    to clean up later at merge_reloc_roots() time, and this happens
    correctly.  During recovery we're depending on free_reloc_roots() to
    drop our references, but we're short-circuiting.
    
    Fix this by continuing to check if we're on the list and dropping
    ourselves from the reloc_control root list and dropping our reference
    appropriately.  Change the corresponding BUG_ON() to an ASSERT() that
    does the correct thing if we aren't in the rb tree.
    
    CC: stable@vger.kernel.org # 4.4+
    Signed-off-by: default avatarJosef Bacik <josef@toxicpanda.com>
    Reviewed-by: default avatarDavid Sterba <dsterba@suse.com>
    Signed-off-by: default avatarDavid Sterba <dsterba@suse.com>
    c78a10ae
relocation.c 100 KB