• Josef Bacik's avatar
    btrfs: do not hold the extent lock for entire read · ac325fc2
    Josef Bacik authored
    Historically we've held the extent lock throughout the entire read.
    There's been a few reasons for this, but it's mostly just caused us
    problems.  For example, this prevents us from allowing page faults
    during direct io reads, because we could deadlock.  This has forced us
    to only allow 4k reads at a time for io_uring NOWAIT requests because we
    have no idea if we'll be forced to page fault and thus have to do a
    whole lot of work.
    
    On the buffered side we are protected by the page lock, as long as we're
    reading things like buffered writes, punch hole, and even direct IO to a
    certain degree will get hung up on the page lock while the page is in
    flight.
    
    On the direct side we have the dio extent lock, which acts much like the
    way the extent lock worked previously to this patch, however just for
    direct reads.  This protects direct reads from concurrent direct writes,
    while we're protected from buffered writes via the inode lock.
    
    Now that we're protected in all cases, narrow the extent lock to the
    part where we're getting the extent map to submit the reads, no longer
    holding the extent lock for the entire read operation.  Push the extent
    lock down into do_readpage() so that we're only grabbing it when looking
    up the extent map.  This portion was contributed by Goldwyn.
    Co-developed-by: default avatarGoldwyn Rodrigues <rgoldwyn@suse.com>
    Reviewed-by: default avatarGoldwyn Rodrigues <rgoldwyn@suse.com>
    Signed-off-by: default avatarJosef Bacik <josef@toxicpanda.com>
    Signed-off-by: default avatarDavid Sterba <dsterba@suse.com>
    ac325fc2
extent_io.c 119 KB