#define OBD_FAIL_LDLM_SRV_GL_AST 0x326
#define OBD_FAIL_LDLM_WATERMARK_LOW 0x327
#define OBD_FAIL_LDLM_WATERMARK_HIGH 0x328
+#define OBD_FAIL_LDLM_PAUSE_CANCEL_LOCAL 0x329
/* LOCKLESS IO */
#define OBD_FAIL_LDLM_SET_CONTENTION 0x385
*
* This only can happen on client side.
*/
-static void ldlm_handle_cp_callback(struct ptlrpc_request *req,
+static int ldlm_handle_cp_callback(struct ptlrpc_request *req,
struct ldlm_namespace *ns,
struct ldlm_request *dlm_req,
struct ldlm_lock *lock)
}
lock_res_and_lock(lock);
+ if (ldlm_is_failed(lock)) {
+ unlock_res_and_lock(lock);
+ LDLM_LOCK_RELEASE(lock);
+ RETURN(-EINVAL);
+ }
if (ldlm_is_destroyed(lock) ||
lock->l_granted_mode == lock->l_req_mode) {
/* bug 11300: the lock has already been granted */
wake_up(&lock->l_waitq);
}
LDLM_LOCK_RELEASE(lock);
+
+ return 0;
}
/**
ldlm_handle_bl_callback(ns, &dlm_req->lock_desc, lock);
break;
case LDLM_CP_CALLBACK:
- CDEBUG(D_INODE, "completion ast\n");
- req_capsule_extend(&req->rq_pill, &RQF_LDLM_CP_CALLBACK);
- ldlm_callback_reply(req, 0);
- ldlm_handle_cp_callback(req, ns, dlm_req, lock);
+ CDEBUG(D_INODE, "completion ast\n");
+ req_capsule_extend(&req->rq_pill, &RQF_LDLM_CP_CALLBACK);
+ rc = ldlm_handle_cp_callback(req, ns, dlm_req, lock);
+ ldlm_callback_reply(req, rc);
break;
case LDLM_GL_CALLBACK:
CDEBUG(D_INODE, "glimpse ast\n");
if (lock->l_conn_export) {
bool local_only;
- LDLM_DEBUG(lock, "client-side cancel");
+ LDLM_DEBUG(lock, "client-side cancel");
+ OBD_FAIL_TIMEOUT(OBD_FAIL_LDLM_PAUSE_CANCEL_LOCAL,
+ cfs_fail_val);
+
/* Set this flag to prevent others from getting new references*/
lock_res_and_lock(lock);
ldlm_set_cbpending(lock);
}
run_test 92 "create remote directory under orphan directory"
+test_93() {
+ dd if=/dev/zero of=$DIR2/$tfile bs=4k count=2 conv=fsync
+
+ local before=$(date +%s)
+ local evict
+
+ $LCTL mark write
+#define OBD_FAIL_LDLM_PAUSE_CANCEL 0x312
+ $LCTL set_param fail_val=5 fail_loc=0x80000312
+ dd if=/dev/zero of=$DIR/$tfile conv=notrunc oflag=append bs=4k count=1 &
+ local pid=$!
+ sleep 2
+
+#define OBD_FAIL_LDLM_PAUSE_CANCEL_LOCAL 0x329
+ $LCTL set_param fail_val=6 fail_loc=0x80000329
+ $LCTL mark kill $pid
+ kill -ALRM $pid
+
+ dd if=/dev/zero of=$DIR2/$tfile conv=notrunc oflag=append bs=4k count=1
+
+ wait $pid
+ dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 conv=fsync
+
+ evict=$(do_facet client $LCTL get_param \
+ osc.$FSNAME-OST*-osc-*/state | \
+ awk -F"[ [,]" '/EVICTED ]$/ { if (t<$5) {t=$5;} } END { print t }')
+
+ [ -z "$evict" ] || [[ $evict -le $before ]] ||
+ (do_facet client $LCTL get_param \
+ osc.$FSNAME-OST*-osc-*/state;
+ error "eviction happened: $evict before:$before")
+}
+run_test 93 "signal vs CP callback race"
+
log "cleanup: ======================================================"
# kill and wait in each test only guarentee script finish, but command in script