UPSTREAM: virtiofs: add DAX mmap support

Add DAX mmap() support.

Change-Id: I80e46a9054db40ae56e797c070bf7ecc3c84e343
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
Signed-off-by: Miklos Szeredi <mszeredi@redhat.com>
This commit is contained in:
Stefan Hajnoczi 2020-08-19 18:19:52 -04:00 • committed by Alexander Martinz
commit f0e895b3e9
No known key found for this signature in database
GPG key ID: CF15BDD9A321A9B2
2 changed files with 64 additions and 0 deletions

View file

@ -575,6 +575,65 @@ out:
return ret;
}
static vm_fault_t __fuse_dax_fault(struct vm_fault *vmf,
enum page_entry_size pe_size, bool write)
{
vm_fault_t ret;
struct inode *inode = file_inode(vmf->vma->vm_file);
struct super_block *sb = inode->i_sb;
pfn_t pfn;
if (write)
sb_start_pagefault(sb);
ret = dax_iomap_fault(vmf, pe_size, &pfn, NULL, &fuse_iomap_ops);
if (ret & VM_FAULT_NEEDDSYNC)
ret = dax_finish_sync_fault(vmf, pe_size, pfn);
if (write)
sb_end_pagefault(sb);
return ret;
}
static vm_fault_t fuse_dax_fault(struct vm_fault *vmf)
{
return __fuse_dax_fault(vmf, PE_SIZE_PTE,
vmf->flags & FAULT_FLAG_WRITE);
}
static vm_fault_t fuse_dax_huge_fault(struct vm_fault *vmf,
enum page_entry_size pe_size)
{
return __fuse_dax_fault(vmf, pe_size, vmf->flags & FAULT_FLAG_WRITE);
}
static vm_fault_t fuse_dax_page_mkwrite(struct vm_fault *vmf)
{
return __fuse_dax_fault(vmf, PE_SIZE_PTE, true);
}
static vm_fault_t fuse_dax_pfn_mkwrite(struct vm_fault *vmf)
{
return __fuse_dax_fault(vmf, PE_SIZE_PTE, true);
}
static const struct vm_operations_struct fuse_dax_vm_ops = {
.fault = fuse_dax_fault,
.huge_fault = fuse_dax_huge_fault,
.page_mkwrite = fuse_dax_page_mkwrite,
.pfn_mkwrite = fuse_dax_pfn_mkwrite,
};
int fuse_dax_mmap(struct file *file, struct vm_area_struct *vma)
{
file_accessed(file);
vma->vm_ops = &fuse_dax_vm_ops;
vma->vm_flags |= VM_MIXEDMAP | VM_HUGEPAGE;
return 0;
}
static void fuse_free_dax_mem_ranges(struct list_head *mem_list)
{
struct fuse_dax_mapping *range, *temp;

View file

@ -2405,6 +2405,10 @@ static int fuse_file_mmap(struct file *file, struct vm_area_struct *vma)
{
struct fuse_file *ff = file->private_data;
/* DAX mmap is superior to direct_io mmap */
if (FUSE_IS_DAX(file_inode(file)))
return fuse_dax_mmap(file, vma);
if (ff->passthrough.filp)
return fuse_passthrough_mmap(file, vma);
@ -3496,6 +3500,7 @@ static const struct file_operations fuse_file_operations = {
.release = fuse_release,
.fsync = fuse_fsync,
.lock = fuse_file_lock,
.get_unmapped_area = thp_get_unmapped_area,
.flock = fuse_file_flock,
.splice_read = generic_file_splice_read,
.splice_write = iter_file_splice_write,