]> git.kernelconcepts.de Git - karo-tx-linux.git/blobdiff - fs/dax.c
Merge branch 'for-4.13-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/tj/wq
[karo-tx-linux.git] / fs / dax.c
index c22eaf162f95c1456563b31a8362da9e531c9185..306c2b603fb8aa8845558a2bf8226523e5282cdb 100644 (file)
--- a/fs/dax.c
+++ b/fs/dax.c
@@ -25,7 +25,6 @@
 #include <linux/mm.h>
 #include <linux/mutex.h>
 #include <linux/pagevec.h>
-#include <linux/pmem.h>
 #include <linux/sched.h>
 #include <linux/sched/signal.h>
 #include <linux/uio.h>
@@ -84,7 +83,7 @@ struct exceptional_entry_key {
 };
 
 struct wait_exceptional_entry_queue {
-       wait_queue_t wait;
+       wait_queue_entry_t wait;
        struct exceptional_entry_key key;
 };
 
@@ -108,7 +107,7 @@ static wait_queue_head_t *dax_entry_waitqueue(struct address_space *mapping,
        return wait_table + hash;
 }
 
-static int wake_exceptional_entry_func(wait_queue_t *wait, unsigned int mode,
+static int wake_exceptional_entry_func(wait_queue_entry_t *wait, unsigned int mode,
                                       int sync, void *keyp)
 {
        struct exceptional_entry_key *key = keyp;
@@ -784,7 +783,7 @@ static int dax_writeback_one(struct block_device *bdev,
        }
 
        dax_mapping_entry_mkclean(mapping, index, pfn_t_to_pfn(pfn));
-       wb_cache_pmem(kaddr, size);
+       dax_flush(dax_dev, pgoff, kaddr, size);
        /*
         * After we have flushed the cache, we can clear the dirty tag. There
         * cannot be new dirty data in the pfn after the flush has completed as
@@ -856,9 +855,12 @@ int dax_writeback_mapping_range(struct address_space *mapping,
 
                        ret = dax_writeback_one(bdev, dax_dev, mapping,
                                        indices[i], pvec.pages[i]);
-                       if (ret < 0)
+                       if (ret < 0) {
+                               mapping_set_error(mapping, ret);
                                goto out;
+                       }
                }
+               start_index = indices[pvec.nr - 1] + 1;
        }
 out:
        put_dax(dax_dev);
@@ -975,7 +977,8 @@ int __dax_zero_page_range(struct block_device *bdev,
                        dax_read_unlock(id);
                        return rc;
                }
-               clear_pmem(kaddr + offset, size);
+               memset(kaddr + offset, 0, size);
+               dax_flush(dax_dev, pgoff, kaddr + offset, size);
                dax_read_unlock(id);
        }
        return 0;
@@ -1054,7 +1057,8 @@ dax_iomap_actor(struct inode *inode, loff_t pos, loff_t length, void *data,
                        map_len = end - pos;
 
                if (iov_iter_rw(iter) == WRITE)
-                       map_len = copy_from_iter_pmem(kaddr, map_len, iter);
+                       map_len = dax_copy_from_iter(dax_dev, pgoff, kaddr,
+                                       map_len, iter);
                else
                        map_len = copy_to_iter(kaddr, map_len, iter);
                if (map_len <= 0) {
@@ -1154,6 +1158,17 @@ static int dax_iomap_pte_fault(struct vm_fault *vmf,
                goto out;
        }
 
+       /*
+        * It is possible, particularly with mixed reads & writes to private
+        * mappings, that we have raced with a PMD fault that overlaps with
+        * the PTE we need to set up.  If so just return and the fault will be
+        * retried.
+        */
+       if (pmd_trans_huge(*vmf->pmd) || pmd_devmap(*vmf->pmd)) {
+               vmf_ret = VM_FAULT_NOPAGE;
+               goto unlock_entry;
+       }
+
        /*
         * Note that we don't bother to use iomap_apply here: DAX required
         * the file system block size to be equal the page size, which means
@@ -1201,7 +1216,7 @@ static int dax_iomap_pte_fault(struct vm_fault *vmf,
        case IOMAP_MAPPED:
                if (iomap.flags & IOMAP_F_NEW) {
                        count_vm_event(PGMAJFAULT);
-                       mem_cgroup_count_vm_event(vmf->vma->vm_mm, PGMAJFAULT);
+                       count_memcg_event_mm(vmf->vma->vm_mm, PGMAJFAULT);
                        major = VM_FAULT_MAJOR;
                }
                error = dax_insert_mapping(mapping, iomap.bdev, iomap.dax_dev,
@@ -1397,6 +1412,18 @@ static int dax_iomap_pmd_fault(struct vm_fault *vmf,
        if (IS_ERR(entry))
                goto fallback;
 
+       /*
+        * It is possible, particularly with mixed reads & writes to private
+        * mappings, that we have raced with a PTE fault that overlaps with
+        * the PMD we need to set up.  If so just return and the fault will be
+        * retried.
+        */
+       if (!pmd_none(*vmf->pmd) && !pmd_trans_huge(*vmf->pmd) &&
+                       !pmd_devmap(*vmf->pmd)) {
+               result = 0;
+               goto unlock_entry;
+       }
+
        /*
         * Note that we don't use iomap_apply here.  We aren't doing I/O, only
         * setting up a mapping, so really we're using iomap_begin() as a way