• Filipe Manana's avatar
    btrfs: release upper nodes when reading stale btree node from disk · b246666e
    Filipe Manana authored
    When reading a btree node (or leaf), at read_block_for_search(), if we
    can't find its extent buffer in the cache (the fs_info->buffer_radix
    radix tree), then we unlock all upper level nodes before reading the
    btree node/leaf from disk, to prevent blocking other tasks for too long.
    
    However if we find that the extent buffer is in the cache but it is not
    up to date, we don't unlock upper level nodes before reading it from disk,
    potentially blocking other tasks on upper level nodes for too long.
    
    Fix this inconsistent behaviour by unlocking upper level nodes if we need
    to read a node/leaf from disk because its in-memory extent buffer is not
    up to date. If we unlocked upper level nodes then we must return -EAGAIN
    to the caller, just like the case where the extent buffer is not cached in
    memory. And like that case, we determine if upper level nodes are locked
    by checking only if the parent node is locked - if it isn't, then no other
    upper level nodes are locked.
    
    This is actually a rare case, as if we have an extent buffer in memory,
    it typically has the uptodate flag set and passes all the checks done by
    btrfs_buffer_uptodate().
    Reviewed-by: default avatarJosef Bacik <josef@toxicpanda.com>
    Signed-off-by: default avatarFilipe Manana <fdmanana@suse.com>
    Reviewed-by: default avatarDavid Sterba <dsterba@suse.com>
    Signed-off-by: default avatarDavid Sterba <dsterba@suse.com>
    b246666e
ctree.c 125 KB