• Dave Chinner's avatar
    iomap: Only invalidate page cache pages on direct IO writes · 54752de9
    Dave Chinner authored
    The historic requirement for XFS to invalidate cached pages on
    direct IO reads has been lost in the twisty pages of history - it was
    inherited from Irix, which implemented page cache invalidation on
    read as a method of working around problems synchronising page
    cache state with uncached IO.
    
    XFS has carried this ever since. In the initial linux ports it was
    necessary to get mmap and DIO to play "ok" together and not
    immediately corrupt data. This was the state of play until the linux
    kernel had infrastructure to track unwritten extents and synchronise
    page faults with allocations and unwritten extent conversions
    (->page_mkwrite infrastructure). IOws, the page cache invalidation
    on DIO read was necessary to prevent trivial data corruptions. This
    didn't solve all the problems, though.
    
    There were peformance problems if we didn't invalidate the entire
    page cache over the file on read - we couldn't easily determine if
    the cached pages were over the range of the IO, and invalidation
    required taking a serialising lock (i_mutex) on the inode. This
    serialising lock was an issue for XFS, as it was the only exclusive
    lock in the direct Io read path.
    
    Hence if there were any cached pages, we'd just invalidate the
    entire file in one go so that subsequent IOs didn't need to take the
    serialising lock. This was a problem that prevented ranged
    invalidation from being particularly useful for avoiding the
    remaining coherency issues. This was solved with the conversion of
    i_mutex to i_rwsem and the conversion of the XFS inode IO lock to
    use i_rwsem. Hence we could now just do ranged invalidation and the
    performance problem went away.
    
    However, page cache invalidation was still needed to serialise
    sub-page/sub-block zeroing via direct IO against buffered IO because
    bufferhead state attached to the cached page could get out of whack
    when direct IOs were issued.  We've removed bufferheads from the
    XFS code, and we don't carry any extent state on the cached pages
    anymore, and so this problem has gone away, too.
    
    IOWs, it would appear that we don't have any good reason to be
    invalidating the page cache on DIO reads anymore. Hence remove the
    invalidation on read because it is unnecessary overhead,
    not needed to maintain coherency between mmap/buffered access and
    direct IO anymore, and prevents anyone from using direct IO reads
    from intentionally invalidating the page cache of a file.
    Signed-off-by: default avatarDave Chinner <dchinner@redhat.com>
    Reviewed-by: default avatarDarrick J. Wong <darrick.wong@oracle.com>
    Reviewed-by: default avatarMatthew Wilcox (Oracle) <willy@infradead.org>
    Signed-off-by: default avatarChristoph Hellwig <hch@lst.de>
    Signed-off-by: default avatarDarrick J. Wong <darrick.wong@oracle.com>
    54752de9
direct-io.c 15.6 KB