Commit 80e4f252 authored by Hao Xu's avatar Hao Xu Committed by Miklos Szeredi
Browse files

fuse: invalidate page cache pages before direct write



In FOPEN_DIRECT_IO, page cache may still be there for a file since private
mmap is allowed.  Direct write should respect that and invalidate the
corresponding pages so that page cache readers don't get stale data.

Signed-off-by: default avatarHao Xu <howeyxu@tencent.com>
Tested-by: default avatarJiachen Zhang <zhangjiachen.jaycee@bytedance.com>
Signed-off-by: default avatarMiklos Szeredi <mszeredi@redhat.com>
parent b8bd342d
Loading
Loading
Loading
Loading
+11 −1
Original line number Diff line number Diff line
@@ -1428,7 +1428,8 @@ ssize_t fuse_direct_io(struct fuse_io_priv *io, struct iov_iter *iter,
	int write = flags & FUSE_DIO_WRITE;
	int cuse = flags & FUSE_DIO_CUSE;
	struct file *file = io->iocb->ki_filp;
	struct inode *inode = file->f_mapping->host;
	struct address_space *mapping = file->f_mapping;
	struct inode *inode = mapping->host;
	struct fuse_file *ff = file->private_data;
	struct fuse_conn *fc = ff->fm->fc;
	size_t nmax = write ? fc->max_write : fc->max_read;
@@ -1440,6 +1441,7 @@ ssize_t fuse_direct_io(struct fuse_io_priv *io, struct iov_iter *iter,
	int err = 0;
	struct fuse_io_args *ia;
	unsigned int max_pages;
	bool fopen_direct_io = ff->open_flags & FOPEN_DIRECT_IO;

	max_pages = iov_iter_npages(iter, fc->max_pages);
	ia = fuse_io_alloc(io, max_pages);
@@ -1454,6 +1456,14 @@ ssize_t fuse_direct_io(struct fuse_io_priv *io, struct iov_iter *iter,
			inode_unlock(inode);
	}

	if (fopen_direct_io && write) {
		res = invalidate_inode_pages2_range(mapping, idx_from, idx_to);
		if (res) {
			fuse_io_free(ia);
			return res;
		}
	}

	io->should_dirty = !write && user_backed_iter(iter);
	while (count) {
		ssize_t nres;