This is preparation for dropping the mmap_sem in page_mkwrite.  We need
to know if we used our cached page so we can be sure it is the page we
already did the page_mkwrite stuff on so we don't have to redo all of
that work.

Signed-off-by: Josef Bacik <jo...@toxicpanda.com>
---
 include/linux/mm.h | 6 +++++-
 mm/filemap.c       | 5 ++++-
 2 files changed, 9 insertions(+), 2 deletions(-)

diff --git a/include/linux/mm.h b/include/linux/mm.h
index 724514be03b2..10a0118f5485 100644
--- a/include/linux/mm.h
+++ b/include/linux/mm.h
@@ -318,6 +318,9 @@ extern pgprot_t protection_map[16];
 #define FAULT_FLAG_USER                0x40    /* The fault originated in 
userspace */
 #define FAULT_FLAG_REMOTE      0x80    /* faulting for non current tsk/mm */
 #define FAULT_FLAG_INSTRUCTION  0x100  /* The fault was during an instruction 
fetch */
+#define FAULT_FLAG_USED_CACHED 0x200   /* Our vmf->page was from a previous
+                                        * loop through the fault handler.
+                                        */
 
 #define FAULT_FLAG_TRACE \
        { FAULT_FLAG_WRITE,             "WRITE" }, \
@@ -328,7 +331,8 @@ extern pgprot_t protection_map[16];
        { FAULT_FLAG_TRIED,             "TRIED" }, \
        { FAULT_FLAG_USER,              "USER" }, \
        { FAULT_FLAG_REMOTE,            "REMOTE" }, \
-       { FAULT_FLAG_INSTRUCTION,       "INSTRUCTION" }
+       { FAULT_FLAG_INSTRUCTION,       "INSTRUCTION" }, \
+       { FAULT_FLAG_USED_CACHED,       "USED_CACHED" }
 
 /*
  * vm_fault is filled by the the pagefault handler and passed to the vma's
diff --git a/mm/filemap.c b/mm/filemap.c
index 49b35293fa95..75a8b252814a 100644
--- a/mm/filemap.c
+++ b/mm/filemap.c
@@ -2556,6 +2556,7 @@ vm_fault_t filemap_fault(struct vm_fault *vmf)
                if (cached_page->mapping == mapping &&
                    cached_page->index == offset) {
                        page = cached_page;
+                       vmf->flags |= FAULT_FLAG_USED_CACHED;
                        goto have_cached_page;
                }
                unlock_page(cached_page);
@@ -2618,8 +2619,10 @@ vm_fault_t filemap_fault(struct vm_fault *vmf)
         * We have a locked page in the page cache, now we need to check
         * that it's up-to-date. If not, it is going to be due to an error.
         */
-       if (unlikely(!PageUptodate(page)))
+       if (unlikely(!PageUptodate(page))) {
+               vmf->flags &= ~(FAULT_FLAG_USED_CACHED);
                goto page_not_uptodate;
+       }
 
        /*
         * Found the page and have a reference on it.
-- 
2.14.3

Reply via email to