• Qu Wenruo's avatar
    btrfs: extent-tree: kill BUG_ON() in __btrfs_free_extent() · 1c2a07f5
    Qu Wenruo authored
    __btrfs_free_extent() is doing two things:
    
    1. Reduce the refs number of an extent backref
       Either it's an inline extent backref (inside EXTENT/METADATA item) or
       a keyed extent backref (SHARED_* item).
       We only need to locate that backref line, either reduce the number or
       remove the backref line completely.
    
    2. Update the refs count in EXTENT/METADATA_ITEM
    
    During step 1), we will try to locate the EXTENT/METADATA_ITEM without
    triggering another btrfs_search_slot() as fast path.
    
    Only when we fail to locate that item, we will trigger another
    btrfs_search_slot() to get that EXTENT/METADATA_ITEM after we
    updated/deleted the backref line.
    
    And we have a lot of strict checks on things like refs_to_drop against
    extent refs and special case checks for single ref extents.
    
    There are 7 BUG_ON()s, although they're doing correct checks, they can
    be triggered by crafted images.
    
    This patch improves the function:
    
    - Introduce two examples to show what __btrfs_free_extent() is doing
      One inline backref case and one keyed case.  Should cover most cases.
    
    - Kill all BUG_ON()s with proper error message and optional leaf dump
    
    - Add comment to show the overall flow
    
    Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=202819
    [ The report triggers one BUG_ON() in __btrfs_free_extent() ]
    Reviewed-by: default avatarNikolay Borisov <nborisov@suse.com>
    Reviewed-by: default avatarJosef Bacik <josef@toxicpanda.com>
    Signed-off-by: default avatarQu Wenruo <wqu@suse.com>
    Signed-off-by: default avatarDavid Sterba <dsterba@suse.com>
    1c2a07f5
extent-tree.c 160 KB