|
|
@@ -26,6 +26,7 @@
|
|
|
#include <linux/quotaops.h>
|
|
|
#include <linux/pagevec.h>
|
|
|
#include <linux/uio.h>
|
|
|
+#include <linux/mman.h>
|
|
|
#include "ext4.h"
|
|
|
#include "ext4_jbd2.h"
|
|
|
#include "xattr.h"
|
|
|
@@ -295,6 +296,7 @@ static int ext4_dax_huge_fault(struct vm_fault *vmf,
|
|
|
*/
|
|
|
bool write = (vmf->flags & FAULT_FLAG_WRITE) &&
|
|
|
(vmf->vma->vm_flags & VM_SHARED);
|
|
|
+ pfn_t pfn;
|
|
|
|
|
|
if (write) {
|
|
|
sb_start_pagefault(sb);
|
|
|
@@ -310,9 +312,12 @@ static int ext4_dax_huge_fault(struct vm_fault *vmf,
|
|
|
} else {
|
|
|
down_read(&EXT4_I(inode)->i_mmap_sem);
|
|
|
}
|
|
|
- result = dax_iomap_fault(vmf, pe_size, NULL, &ext4_iomap_ops);
|
|
|
+ result = dax_iomap_fault(vmf, pe_size, &pfn, &ext4_iomap_ops);
|
|
|
if (write) {
|
|
|
ext4_journal_stop(handle);
|
|
|
+ /* Handling synchronous page fault? */
|
|
|
+ if (result & VM_FAULT_NEEDDSYNC)
|
|
|
+ result = dax_finish_sync_fault(vmf, pe_size, pfn);
|
|
|
up_read(&EXT4_I(inode)->i_mmap_sem);
|
|
|
sb_end_pagefault(sb);
|
|
|
} else {
|
|
|
@@ -350,6 +355,13 @@ static int ext4_file_mmap(struct file *file, struct vm_area_struct *vma)
|
|
|
if (unlikely(ext4_forced_shutdown(EXT4_SB(inode->i_sb))))
|
|
|
return -EIO;
|
|
|
|
|
|
+ /*
|
|
|
+ * We don't support synchronous mappings for non-DAX files. At least
|
|
|
+ * until someone comes with a sensible use case.
|
|
|
+ */
|
|
|
+ if (!IS_DAX(file_inode(file)) && (vma->vm_flags & VM_SYNC))
|
|
|
+ return -EOPNOTSUPP;
|
|
|
+
|
|
|
file_accessed(file);
|
|
|
if (IS_DAX(file_inode(file))) {
|
|
|
vma->vm_ops = &ext4_dax_vm_ops;
|
|
|
@@ -719,6 +731,7 @@ const struct file_operations ext4_file_operations = {
|
|
|
.compat_ioctl = ext4_compat_ioctl,
|
|
|
#endif
|
|
|
.mmap = ext4_file_mmap,
|
|
|
+ .mmap_supported_flags = MAP_SYNC,
|
|
|
.open = ext4_file_open,
|
|
|
.release = ext4_release_file,
|
|
|
.fsync = ext4_sync_file,
|