• Filipe Manana's avatar
    btrfs: ignore fiemap path cache when there are multiple paths for a node · 2280d425
    Filipe Manana authored
    During fiemap, when walking backreferences to determine if a b+tree
    node/leaf is shared, we may find a tree block (leaf or node) for which
    two parents were added to the references ulist. This happens if we get
    for example one direct ref (shared tree block ref) and one indirect ref
    (non-shared tree block ref) for the tree block at the current level,
    which can happen during relocation.
    
    In that case the fiemap path cache can not be used since it's meant for
    a single path, with one tree block at each possible level, so having
    multiple references for a tree block at any level may result in getting
    the level counter exceed BTRFS_MAX_LEVEL and eventually trigger the
    warning:
    
       WARN_ON_ONCE(level >= BTRFS_MAX_LEVEL)
    
    at lookup_backref_shared_cache() and at store_backref_shared_cache().
    This is harmless since the code ignores any level >= BTRFS_MAX_LEVEL, the
    warning is there just to catch any unexpected case like the one described
    above. However if a user finds this it may be scary and get reported.
    
    So just ignore the path cache once we find a tree block for which there
    are more than one reference, which is the less common case, and update
    the cache with the sharedness check result for all levels below the level
    for which we found multiple references.
    Reported-by: default avatarJarno Pelkonen <jarno.pelkonen@gmail.com>
    Link: https://lore.kernel.org/linux-btrfs/CAKv8qLmDNAGJGCtsevxx_VZ_YOvvs1L83iEJkTgyA4joJertng@mail.gmail.com/
    Fixes: 12a824dc ("btrfs: speedup checking for extent sharedness during fiemap")
    CC: stable@vger.kernel.org # 6.1+
    Signed-off-by: default avatarFilipe Manana <fdmanana@suse.com>
    Signed-off-by: default avatarDavid Sterba <dsterba@suse.com>
    2280d425
backref.c 99.3 KB