--- zzzz-none-000/linux-3.10.107/fs/ext2/file.c 2017-06-27 09:49:32.000000000 +0000 +++ scorpion-7490-727/linux-3.10.107/fs/ext2/file.c 2021-02-04 17:41:59.000000000 +0000 @@ -20,11 +20,126 @@ #include #include +#include #include #include "ext2.h" #include "xattr.h" #include "acl.h" +#ifdef CONFIG_FS_DAX +/* + * The lock ordering for ext2 DAX fault paths is: + * + * mmap_sem (MM) + * sb_start_pagefault (vfs, freeze) + * ext2_inode_info->dax_sem + * address_space->i_mmap_rwsem or page_lock (mutually exclusive in DAX) + * ext2_inode_info->truncate_mutex + * + * The default page_lock and i_size verification done by non-DAX fault paths + * is sufficient because ext2 doesn't support hole punching. + */ +static int ext2_dax_fault(struct vm_area_struct *vma, struct vm_fault *vmf) +{ + struct inode *inode = file_inode(vma->vm_file); + struct ext2_inode_info *ei = EXT2_I(inode); + int ret; + + if (vmf->flags & FAULT_FLAG_WRITE) { + sb_start_pagefault(inode->i_sb); + file_update_time(vma->vm_file); + } + down_read(&ei->dax_sem); + + ret = __dax_fault(vma, vmf, ext2_get_block, NULL); + + up_read(&ei->dax_sem); + if (vmf->flags & FAULT_FLAG_WRITE) + sb_end_pagefault(inode->i_sb); + return ret; +} + +static int ext2_dax_pmd_fault(struct vm_area_struct *vma, unsigned long addr, + pmd_t *pmd, unsigned int flags) +{ + struct inode *inode = file_inode(vma->vm_file); + struct ext2_inode_info *ei = EXT2_I(inode); + int ret; + + if (flags & FAULT_FLAG_WRITE) { + sb_start_pagefault(inode->i_sb); + file_update_time(vma->vm_file); + } + down_read(&ei->dax_sem); + + ret = __dax_pmd_fault(vma, addr, pmd, flags, ext2_get_block, NULL); + + up_read(&ei->dax_sem); + if (flags & FAULT_FLAG_WRITE) + sb_end_pagefault(inode->i_sb); + return ret; +} + +static int ext2_dax_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf) +{ + struct inode *inode = file_inode(vma->vm_file); + struct ext2_inode_info *ei = EXT2_I(inode); + int ret; + + sb_start_pagefault(inode->i_sb); + file_update_time(vma->vm_file); + down_read(&ei->dax_sem); + + ret = __dax_mkwrite(vma, vmf, ext2_get_block, NULL); + + up_read(&ei->dax_sem); + sb_end_pagefault(inode->i_sb); + return ret; +} + +static int ext2_dax_pfn_mkwrite(struct vm_area_struct *vma, + struct vm_fault *vmf) +{ + struct inode *inode = file_inode(vma->vm_file); + struct ext2_inode_info *ei = EXT2_I(inode); + int ret = VM_FAULT_NOPAGE; + loff_t size; + + sb_start_pagefault(inode->i_sb); + file_update_time(vma->vm_file); + down_read(&ei->dax_sem); + + /* check that the faulting page hasn't raced with truncate */ + size = (i_size_read(inode) + PAGE_SIZE - 1) >> PAGE_SHIFT; + if (vmf->pgoff >= size) + ret = VM_FAULT_SIGBUS; + + up_read(&ei->dax_sem); + sb_end_pagefault(inode->i_sb); + return ret; +} + +static const struct vm_operations_struct ext2_dax_vm_ops = { + .fault = ext2_dax_fault, + .pmd_fault = ext2_dax_pmd_fault, + .page_mkwrite = ext2_dax_mkwrite, + .pfn_mkwrite = ext2_dax_pfn_mkwrite, +}; + +static int ext2_file_mmap(struct file *file, struct vm_area_struct *vma) +{ + if (!IS_DAX(file_inode(file))) + return generic_file_mmap(file, vma); + + file_accessed(file); + vma->vm_ops = &ext2_dax_vm_ops; + vma->vm_flags |= VM_MIXEDMAP | VM_HUGEPAGE; + return 0; +} +#else +#define ext2_file_mmap generic_file_mmap +#endif + /* * Called when filp is released. This happens when all file descriptors * for a single struct file are closed. Note that different open() calls @@ -62,38 +177,20 @@ */ const struct file_operations ext2_file_operations = { .llseek = generic_file_llseek, - .read = do_sync_read, - .write = do_sync_write, - .aio_read = generic_file_aio_read, - .aio_write = generic_file_aio_write, + .read_iter = generic_file_read_iter, + .write_iter = generic_file_write_iter, .unlocked_ioctl = ext2_ioctl, #ifdef CONFIG_COMPAT .compat_ioctl = ext2_compat_ioctl, #endif - .mmap = generic_file_mmap, + .mmap = ext2_file_mmap, .open = dquot_file_open, .release = ext2_release_file, .fsync = ext2_fsync, .splice_read = generic_file_splice_read, - .splice_write = generic_file_splice_write, + .splice_write = iter_file_splice_write, }; -#ifdef CONFIG_EXT2_FS_XIP -const struct file_operations ext2_xip_file_operations = { - .llseek = generic_file_llseek, - .read = xip_file_read, - .write = xip_file_write, - .unlocked_ioctl = ext2_ioctl, -#ifdef CONFIG_COMPAT - .compat_ioctl = ext2_compat_ioctl, -#endif - .mmap = xip_file_mmap, - .open = dquot_file_open, - .release = ext2_release_file, - .fsync = ext2_fsync, -}; -#endif - const struct inode_operations ext2_file_inode_operations = { #ifdef CONFIG_EXT2_FS_XATTR .setxattr = generic_setxattr, @@ -103,5 +200,6 @@ #endif .setattr = ext2_setattr, .get_acl = ext2_get_acl, + .set_acl = ext2_set_acl, .fiemap = ext2_fiemap, };