#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)
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;
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);
}
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
#