Whamcloud - gitweb
LU-122 Revert the patch on bug 21122 and come up with a new fix
[fs/lustre-release.git] / lustre / llite / llite_mmap.c
index ae43a07..9611d6b 100644 (file)
@@ -259,7 +259,7 @@ out_err:
  * \retval VM_FAULT_ERROR on general error
  * \retval NOPAGE_OOM not have memory for allocate new page
  */
-int ll_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
+int ll_fault0(struct vm_area_struct *vma, struct vm_fault *vmf)
 {
         struct lu_env           *env;
         struct cl_io            *io;
@@ -279,8 +279,8 @@ int ll_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
                 goto out_err;
 
         vio = vvp_env_io(env);
-
         vio->u.fault.ft_vma       = vma;
+        vio->u.fault.ft_vmpage    = NULL;
         vio->u.fault.fault.ft_vmf = vmf;
 
         result = cl_io_loop(env, io);
@@ -298,6 +298,39 @@ out_err:
         RETURN(fault_ret);
 }
 
+int ll_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
+{
+        int count = 0;
+        bool printed = false;
+        int result;
+
+restart:
+        result = ll_fault0(vma, vmf);
+        LASSERT(!(result & VM_FAULT_LOCKED));
+        if (result == 0) {
+                struct page *vmpage = vmf->page;
+
+                /* check if this page has been truncated */
+                lock_page(vmpage);
+                if (unlikely(vmpage->mapping == NULL)) { /* unlucky */
+                        unlock_page(vmpage);
+                        page_cache_release(vmpage);
+                        vmf->page = NULL;
+
+                        if (!printed && ++count > 16) {
+                                CWARN("the page is under heavy contention,"
+                                      "maybe your app(%s) needs revising :-)\n",
+                                      current->comm);
+                                printed = true;
+                        }
+
+                        goto restart;
+                }
+
+                result |= VM_FAULT_LOCKED;
+        }
+        return result;
+}
 #endif
 
 /**