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

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
......@@ -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;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment