On Thu, May 28, 2020 at 02:21:03PM -0500, Goldwyn Rodrigues wrote:
>
> Filesystems such as btrfs are unable to guarantee page invalidation
> because pages could be locked as a part of the extent. Return zero
Locked for what? filemap_write_and_wait_range should have just cleaned
them off.
> in case a page cache invalidation is unsuccessful so filesystems can
> fallback to buffered I/O. This is similar to
> generic_file_direct_write().
>
> This takes care of the following invalidation warning during btrfs
> mixed buffered and direct I/O using iomap_dio_rw():
>
> Page cache invalidation failure on direct I/O. Possible data
> corruption due to collision with buffered I/O!
>
> Signed-off-by: Goldwyn Rodrigues <rgoldwyn@xxxxxxxx>
>
> diff --git a/fs/iomap/direct-io.c b/fs/iomap/direct-io.c
> index e4addfc58107..215315be6233 100644
> --- a/fs/iomap/direct-io.c
> +++ b/fs/iomap/direct-io.c
> @@ -483,9 +483,15 @@ iomap_dio_rw(struct kiocb *iocb, struct iov_iter *iter,
> */
> ret = invalidate_inode_pages2_range(mapping,
> pos >> PAGE_SHIFT, end >> PAGE_SHIFT);
> - if (ret)
> - dio_warn_stale_pagecache(iocb->ki_filp);
> - ret = 0;
> + /*
> + * If a page can not be invalidated, return 0 to fall back
> + * to buffered write.
> + */
> + if (ret) {
> + if (ret == -EBUSY)
> + ret = 0;
> + goto out_free_dio;
XFS doesn't fall back to buffered io when directio fails, which means
this will cause a regression there.
Granted mixing write types is bogus...
--D
> + }
>
> if (iov_iter_rw(iter) == WRITE && !wait_for_completion &&
> !inode->i_sb->s_dio_done_wq) {
>
> --
> Goldwyn