Whamcloud - gitweb
LU-687 clio: retry if fault page was truncated
authorJinshan Xiong <jay@whamcloud.com>
Wed, 5 Oct 2011 05:54:48 +0000 (22:54 -0700)
committerOleg Drokin <green@whamcloud.com>
Thu, 20 Oct 2011 23:29:01 +0000 (19:29 -0400)
In vvp_io_fault_start, if a page was truncated we should retry it in
ll_fault() instead of return -EFAULT because it will cause fake OOM.

Change-Id: Ia2ba40ca4ecd67170e6c2eb81ddc0ee34d9379a8
Signed-off-by: Jinshan Xiong <jay@whamcloud.com>
Reviewed-on: http://review.whamcloud.com/1453
Tested-by: Hudson
Reviewed-by: Niu Yawei <niu@whamcloud.com>
Tested-by: Maloo <whamcloud.maloo@gmail.com>
Reviewed-by: Fan Yong <yong.fan@whamcloud.com>
Reviewed-by: Oleg Drokin <green@whamcloud.com>
lustre/include/obd_support.h
lustre/llite/llite_mmap.c
lustre/llite/vvp_io.c
lustre/tests/sanity.sh

index 46a2bd1..85537da 100644 (file)
@@ -422,6 +422,9 @@ int obd_alloc_fail(const void *ptr, const char *name, const char *type,
 #define OBD_FAIL_MDS_SYNC_CAPA_SL                   0x1310
 #define OBD_FAIL_SEQ_ALLOC                          0x1311
 
+#define OBD_FAIL_LLITE                              0x1400
+#define OBD_FAIL_LLITE_FAULT_TRUNC_RACE             0x1401
+
 /* Assign references to moved code to reduce code changes */
 #define OBD_FAIL_PRECHECK(id)                   CFS_FAIL_PRECHECK(id)
 #define OBD_FAIL_CHECK(id)                      CFS_FAIL_CHECK(id)
index dc032c0..4424382 100644 (file)
@@ -234,13 +234,10 @@ struct page *ll_nopage(struct vm_area_struct *vma, unsigned long address,
         result = cl_io_loop(env, io);
 
 out_err:
-        if (result == 0) {
-                LASSERT(io->u.ci_fault.ft_page != NULL);
+        if (result == 0)
                 page = vio->u.fault.ft_vmpage;
-        } else {
-                if (result == -ENOMEM)
-                        page = NOPAGE_OOM;
-        }
+        else if (result == -ENOMEM)
+                page = NOPAGE_OOM;
 
         vma->vm_flags &= ~VM_RAND_READ;
         vma->vm_flags |= ra_flags;
index 77351dc..cbf02cd 100644 (file)
@@ -716,14 +716,28 @@ static int vvp_io_fault_start(const struct lu_env *env,
         if (kernel_result != 0)
                 return kernel_result;
 
+        if (OBD_FAIL_CHECK(OBD_FAIL_LLITE_FAULT_TRUNC_RACE)) {
+                truncate_inode_pages_range(inode->i_mapping,
+                                         cl_offset(obj, fio->ft_index), offset);
+        }
+
         /* Temporarily lock vmpage to keep cl_page_find() happy. */
         lock_page(cfio->ft_vmpage);
+
         /* Though we have already held a cl_lock upon this page, but
          * it still can be truncated locally. */
-        page = ERR_PTR(-EFAULT);
-        if (likely(cfio->ft_vmpage->mapping != NULL))
-                page = cl_page_find(env, obj, fio->ft_index, cfio->ft_vmpage,
-                                    CPT_CACHEABLE);
+        if (unlikely(cfio->ft_vmpage->mapping == NULL)) {
+                unlock_page(cfio->ft_vmpage);
+
+                CDEBUG(D_PAGE, "llite: fault and truncate race happened!\n");
+
+                /* return +1 to stop cl_io_loop() and ll_fault() will catch
+                 * and retry. */
+                return +1;
+        }
+
+        page = cl_page_find(env, obj, fio->ft_index, cfio->ft_vmpage,
+                            CPT_CACHEABLE);
         unlock_page(cfio->ft_vmpage);
         if (IS_ERR(page)) {
                 page_cache_release(cfio->ft_vmpage);
index e54a142..052a207 100644 (file)
@@ -8281,6 +8281,17 @@ test_220() { #LU-325
 }
 run_test 220 "the preallocated objects in MDS still can be used if ENOSPC is returned by OST with enough disk space"
 
+test_221() {
+        cp `which date` $MOUNT
+
+        #define OBD_FAIL_LLITE_FAULT_TRUNC_RACE  0x1401
+        $LCTL set_param fail_loc=0x80001401
+
+        $MOUNT/date > /dev/null
+        rm -f $MOUNT/date
+}
+run_test 221 "make sure fault and truncate race to not cause OOM"
+
 #
 # tests that do cleanup/setup should be run at the end
 #