• Josef Bacik's avatar
    Btrfs: fix build_backref_tree issue with multiple shared blocks · b341d2a4
    Josef Bacik authored
    commit bbe90514 upstream.
    
    Marc Merlin sent me a broken fs image months ago where it would blow up in the
    upper->checked BUG_ON() in build_backref_tree.  This is because we had a
    scenario like this
    
    block a -- level 4 (not shared)
       |
    block b -- level 3 (reloc block, shared)
       |
    block c -- level 2 (not shared)
       |
    block d -- level 1 (shared)
       |
    block e -- level 0 (shared)
    
    We go to build a backref tree for block e, we notice block d is shared and add
    it to the list of blocks to lookup it's backrefs for.  Now when we loop around
    we will check edges for the block, so we will see we looked up block c last
    time.  So we lookup block d and then see that the block that points to it is
    block c and we can just skip that edge since we've already been up this path.
    The problem is because we clear need_check when we see block d (as it is shared)
    we never add block b as needing to be checked.  And because block c is in...
    b341d2a4
relocation.c 110 KB