]> git.karo-electronics.de Git - karo-tx-linux.git/blobdiff - fs/dax.c
Merge tag 'arm64-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/arm64/linux
[karo-tx-linux.git] / fs / dax.c
index a622961a717c044f36b36e594b508669281456da..7436c98b92c82dc43ad1a80fa5b5e49f26ade500 100644 (file)
--- a/fs/dax.c
+++ b/fs/dax.c
@@ -925,12 +925,11 @@ static int dax_insert_mapping(struct address_space *mapping,
 
 /**
  * dax_pfn_mkwrite - handle first write to DAX page
- * @vma: The virtual memory area where the fault occurred
  * @vmf: The description of the fault
  */
-int dax_pfn_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf)
+int dax_pfn_mkwrite(struct vm_fault *vmf)
 {
-       struct file *file = vma->vm_file;
+       struct file *file = vmf->vma->vm_file;
        struct address_space *mapping = file->f_mapping;
        void *entry, **slot;
        pgoff_t index = vmf->pgoff;
@@ -1082,7 +1081,7 @@ dax_iomap_actor(struct inode *inode, loff_t pos, loff_t length, void *data,
  */
 ssize_t
 dax_iomap_rw(struct kiocb *iocb, struct iov_iter *iter,
-               struct iomap_ops *ops)
+               const struct iomap_ops *ops)
 {
        struct address_space *mapping = iocb->ki_filp->f_mapping;
        struct inode *inode = mapping->host;
@@ -1119,20 +1118,10 @@ static int dax_fault_return(int error)
        return VM_FAULT_SIGBUS;
 }
 
-/**
- * dax_iomap_fault - handle a page fault on a DAX file
- * @vma: The virtual memory area where the fault occurred
- * @vmf: The description of the fault
- * @ops: iomap ops passed from the file system
- *
- * When a page fault occurs, filesystems may call this helper in their fault
- * or mkwrite handler for DAX files. Assumes the caller has done all the
- * necessary locking for the page fault to proceed successfully.
- */
-int dax_iomap_fault(struct vm_area_struct *vma, struct vm_fault *vmf,
-                       struct iomap_ops *ops)
+static int dax_iomap_pte_fault(struct vm_fault *vmf,
+                              const struct iomap_ops *ops)
 {
-       struct address_space *mapping = vma->vm_file->f_mapping;
+       struct address_space *mapping = vmf->vma->vm_file->f_mapping;
        struct inode *inode = mapping->host;
        unsigned long vaddr = vmf->address;
        loff_t pos = (loff_t)vmf->pgoff << PAGE_SHIFT;
@@ -1205,11 +1194,11 @@ int dax_iomap_fault(struct vm_area_struct *vma, struct vm_fault *vmf,
        case IOMAP_MAPPED:
                if (iomap.flags & IOMAP_F_NEW) {
                        count_vm_event(PGMAJFAULT);
-                       mem_cgroup_count_vm_event(vma->vm_mm, PGMAJFAULT);
+                       mem_cgroup_count_vm_event(vmf->vma->vm_mm, PGMAJFAULT);
                        major = VM_FAULT_MAJOR;
                }
                error = dax_insert_mapping(mapping, iomap.bdev, sector,
-                               PAGE_SIZE, &entry, vma, vmf);
+                               PAGE_SIZE, &entry, vmf->vma, vmf);
                /* -EBUSY is fine, somebody else faulted on the same PTE */
                if (error == -EBUSY)
                        error = 0;
@@ -1247,7 +1236,6 @@ int dax_iomap_fault(struct vm_area_struct *vma, struct vm_fault *vmf,
        }
        return vmf_ret;
 }
-EXPORT_SYMBOL_GPL(dax_iomap_fault);
 
 #ifdef CONFIG_FS_DAX_PMD
 /*
@@ -1256,21 +1244,21 @@ EXPORT_SYMBOL_GPL(dax_iomap_fault);
  */
 #define PG_PMD_COLOUR  ((PMD_SIZE >> PAGE_SHIFT) - 1)
 
-static int dax_pmd_insert_mapping(struct vm_area_struct *vma, pmd_t *pmd,
-               struct vm_fault *vmf, unsigned long address,
-               struct iomap *iomap, loff_t pos, bool write, void **entryp)
+static int dax_pmd_insert_mapping(struct vm_fault *vmf, struct iomap *iomap,
+               loff_t pos, void **entryp)
 {
-       struct address_space *mapping = vma->vm_file->f_mapping;
+       struct address_space *mapping = vmf->vma->vm_file->f_mapping;
        struct block_device *bdev = iomap->bdev;
+       struct inode *inode = mapping->host;
        struct blk_dax_ctl dax = {
                .sector = dax_iomap_sector(iomap, pos),
                .size = PMD_SIZE,
        };
        long length = dax_map_atomic(bdev, &dax);
-       void *ret;
+       void *ret = NULL;
 
        if (length < 0) /* dax_map_atomic() failed */
-               return VM_FAULT_FALLBACK;
+               goto fallback;
        if (length < PMD_SIZE)
                goto unmap_fallback;
        if (pfn_t_to_pfn(dax.pfn) & PG_PMD_COLOUR)
@@ -1283,29 +1271,33 @@ static int dax_pmd_insert_mapping(struct vm_area_struct *vma, pmd_t *pmd,
        ret = dax_insert_mapping_entry(mapping, vmf, *entryp, dax.sector,
                        RADIX_DAX_PMD);
        if (IS_ERR(ret))
-               return VM_FAULT_FALLBACK;
+               goto fallback;
        *entryp = ret;
 
-       return vmf_insert_pfn_pmd(vma, address, pmd, dax.pfn, write);
+       trace_dax_pmd_insert_mapping(inode, vmf, length, dax.pfn, ret);
+       return vmf_insert_pfn_pmd(vmf->vma, vmf->address, vmf->pmd,
+                       dax.pfn, vmf->flags & FAULT_FLAG_WRITE);
 
  unmap_fallback:
        dax_unmap_atomic(bdev, &dax);
+fallback:
+       trace_dax_pmd_insert_mapping_fallback(inode, vmf, length,
+                       dax.pfn, ret);
        return VM_FAULT_FALLBACK;
 }
 
-static int dax_pmd_load_hole(struct vm_area_struct *vma, pmd_t *pmd,
-               struct vm_fault *vmf, unsigned long address,
-               struct iomap *iomap, void **entryp)
+static int dax_pmd_load_hole(struct vm_fault *vmf, struct iomap *iomap,
+               void **entryp)
 {
-       struct address_space *mapping = vma->vm_file->f_mapping;
-       unsigned long pmd_addr = address & PMD_MASK;
+       struct address_space *mapping = vmf->vma->vm_file->f_mapping;
+       unsigned long pmd_addr = vmf->address & PMD_MASK;
        struct inode *inode = mapping->host;
        struct page *zero_page;
        void *ret = NULL;
        spinlock_t *ptl;
        pmd_t pmd_entry;
 
-       zero_page = mm_get_huge_zero_page(vma->vm_mm);
+       zero_page = mm_get_huge_zero_page(vmf->vma->vm_mm);
 
        if (unlikely(!zero_page))
                goto fallback;
@@ -1316,36 +1308,36 @@ static int dax_pmd_load_hole(struct vm_area_struct *vma, pmd_t *pmd,
                goto fallback;
        *entryp = ret;
 
-       ptl = pmd_lock(vma->vm_mm, pmd);
-       if (!pmd_none(*pmd)) {
+       ptl = pmd_lock(vmf->vma->vm_mm, vmf->pmd);
+       if (!pmd_none(*(vmf->pmd))) {
                spin_unlock(ptl);
                goto fallback;
        }
 
-       pmd_entry = mk_pmd(zero_page, vma->vm_page_prot);
+       pmd_entry = mk_pmd(zero_page, vmf->vma->vm_page_prot);
        pmd_entry = pmd_mkhuge(pmd_entry);
-       set_pmd_at(vma->vm_mm, pmd_addr, pmd, pmd_entry);
+       set_pmd_at(vmf->vma->vm_mm, pmd_addr, vmf->pmd, pmd_entry);
        spin_unlock(ptl);
-       trace_dax_pmd_load_hole(inode, vma, address, zero_page, ret);
+       trace_dax_pmd_load_hole(inode, vmf, zero_page, ret);
        return VM_FAULT_NOPAGE;
 
 fallback:
-       trace_dax_pmd_load_hole_fallback(inode, vma, address, zero_page, ret);
+       trace_dax_pmd_load_hole_fallback(inode, vmf, zero_page, ret);
        return VM_FAULT_FALLBACK;
 }
 
-int dax_iomap_pmd_fault(struct vm_area_struct *vma, unsigned long address,
-               pmd_t *pmd, unsigned int flags, struct iomap_ops *ops)
+static int dax_iomap_pmd_fault(struct vm_fault *vmf,
+                              const struct iomap_ops *ops)
 {
+       struct vm_area_struct *vma = vmf->vma;
        struct address_space *mapping = vma->vm_file->f_mapping;
-       unsigned long pmd_addr = address & PMD_MASK;
-       bool write = flags & FAULT_FLAG_WRITE;
+       unsigned long pmd_addr = vmf->address & PMD_MASK;
+       bool write = vmf->flags & FAULT_FLAG_WRITE;
        unsigned int iomap_flags = (write ? IOMAP_WRITE : 0) | IOMAP_FAULT;
        struct inode *inode = mapping->host;
        int result = VM_FAULT_FALLBACK;
        struct iomap iomap = { 0 };
        pgoff_t max_pgoff, pgoff;
-       struct vm_fault vmf;
        void *entry;
        loff_t pos;
        int error;
@@ -1358,7 +1350,7 @@ int dax_iomap_pmd_fault(struct vm_area_struct *vma, unsigned long address,
        pgoff = linear_page_index(vma, pmd_addr);
        max_pgoff = (i_size_read(inode) - 1) >> PAGE_SHIFT;
 
-       trace_dax_pmd_fault(inode, vma, address, flags, pgoff, max_pgoff, 0);
+       trace_dax_pmd_fault(inode, vmf, max_pgoff, 0);
 
        /* Fall back to PTEs if we're going to COW */
        if (write && !(vma->vm_flags & VM_SHARED))
@@ -1402,21 +1394,15 @@ int dax_iomap_pmd_fault(struct vm_area_struct *vma, unsigned long address,
        if (IS_ERR(entry))
                goto finish_iomap;
 
-       vmf.pgoff = pgoff;
-       vmf.flags = flags;
-       vmf.gfp_mask = mapping_gfp_mask(mapping) | __GFP_IO;
-
        switch (iomap.type) {
        case IOMAP_MAPPED:
-               result = dax_pmd_insert_mapping(vma, pmd, &vmf, address,
-                               &iomap, pos, write, &entry);
+               result = dax_pmd_insert_mapping(vmf, &iomap, pos, &entry);
                break;
        case IOMAP_UNWRITTEN:
        case IOMAP_HOLE:
                if (WARN_ON_ONCE(write))
                        goto unlock_entry;
-               result = dax_pmd_load_hole(vma, pmd, &vmf, address, &iomap,
-                               &entry);
+               result = dax_pmd_load_hole(vmf, &iomap, &entry);
                break;
        default:
                WARN_ON_ONCE(1);
@@ -1442,13 +1428,41 @@ int dax_iomap_pmd_fault(struct vm_area_struct *vma, unsigned long address,
        }
  fallback:
        if (result == VM_FAULT_FALLBACK) {
-               split_huge_pmd(vma, pmd, address);
+               split_huge_pmd(vma, vmf->pmd, vmf->address);
                count_vm_event(THP_FAULT_FALLBACK);
        }
 out:
-       trace_dax_pmd_fault_done(inode, vma, address, flags, pgoff, max_pgoff,
-                       result);
+       trace_dax_pmd_fault_done(inode, vmf, max_pgoff, result);
        return result;
 }
-EXPORT_SYMBOL_GPL(dax_iomap_pmd_fault);
+#else
+static int dax_iomap_pmd_fault(struct vm_fault *vmf,
+                              const struct iomap_ops *ops)
+{
+       return VM_FAULT_FALLBACK;
+}
 #endif /* CONFIG_FS_DAX_PMD */
+
+/**
+ * dax_iomap_fault - handle a page fault on a DAX file
+ * @vmf: The description of the fault
+ * @ops: iomap ops passed from the file system
+ *
+ * When a page fault occurs, filesystems may call this helper in
+ * their fault handler for DAX files. dax_iomap_fault() assumes the caller
+ * has done all the necessary locking for page fault to proceed
+ * successfully.
+ */
+int dax_iomap_fault(struct vm_fault *vmf, enum page_entry_size pe_size,
+                   const struct iomap_ops *ops)
+{
+       switch (pe_size) {
+       case PE_SIZE_PTE:
+               return dax_iomap_pte_fault(vmf, ops);
+       case PE_SIZE_PMD:
+               return dax_iomap_pmd_fault(vmf, ops);
+       default:
+               return VM_FAULT_FALLBACK;
+       }
+}
+EXPORT_SYMBOL_GPL(dax_iomap_fault);