• Filipe Manana's avatar
    btrfs: make sure we cache next state in find_first_extent_bit() · efba1454
    Filipe Manana authored
    Currently, at find_first_extent_bit(), when we are given a cached extent
    state that happens to have its end offset match the desired range start,
    we find the next extent state using that cached state, with next_state()
    calls, and then return it.
    
    We then try to cache that next state by calling cache_state_if_flags(),
    but that will not cache the state because we haven't reset *cached_state
    to NULL, so we end up with the cached_state unchanged, and if the caller
    is iterating over extent states in the io tree, its next call to
    find_first_extent_bit() will not use the current cached state as its end
    offset does not match the minimum start range offset, therefore the cached
    state is reset and we have to search the rbtree to find the next suitable
    extent state record.
    
    So fix this by resetting the cached state to NULL (and dropping our ref
    on it) when we have a suitable cached state and we found a next state by
    using next_state() starting from the cached state. This makes use cases
    of calling find_first_extent_bit() to go over all ranges in the io tree
    to do a single rbtree full search, only on the first call, and the next
    calls will just do next_state() (rb_next() wrapper) calls, which is more
    efficient.
    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>
    efba1454
extent-io-tree.c 48.7 KB