• Josef Bacik's avatar
    btrfs: check commit root generation in should_ignore_root · 4d4225fc
    Josef Bacik authored
    Previously we would set the reloc root's last snapshot to transid - 1.
    However there was a problem with doing this, and we changed it to
    setting the last snapshot to the generation of the commit node of the fs
    root.
    
    This however broke should_ignore_root().  The assumption is that if we
    are in a generation newer than when the reloc root was created, then we
    would find the reloc root through normal backref lookups, and thus can
    ignore any fs roots we find with an old enough reloc root.
    
    Now that the last snapshot could be considerably further in the past
    than before, we'd end up incorrectly ignoring an fs root.  Thus we'd
    find no nodes for the bytenr we were searching for, and we'd fail to
    relocate anything.  We'd loop through the relocate code again and see
    that there were still used space in that block group, attempt to
    relocate those bytenr's again, fail in the same way, and just loop like
    this forever.  This is tricky in that we have to not modify the fs root
    at all during this time, so we need to have a block group that has data
    in this fs root that is not shared by any other root, which is why this
    has been difficult to reproduce.
    
    Fixes: 054570a1 ("Btrfs: fix relocation incorrectly dropping data references")
    CC: stable@vger.kernel.org # 4.9+
    Reviewed-by: default avatarFilipe Manana <fdmanana@suse.com>
    Signed-off-by: default avatarJosef Bacik <josef@toxicpanda.com>
    Signed-off-by: default avatarDavid Sterba <dsterba@suse.com>
    4d4225fc
relocation.c 116 KB