/* bulk request, sent to server, but uncommitted */
rq_unstable:1,
rq_early_free_repbuf:1, /* free reply buffer in advance */
- rq_allow_intr:1;
+ rq_allow_intr:1,
+ rq_pause_after_reply:1;
/** @} */
/** server-side flags are serialized by rq_lock @{ */
int ptlrpc_unregister_service(struct ptlrpc_service *service);
int ptlrpc_service_health_check(struct ptlrpc_service *service);
void ptlrpc_server_drop_request(struct ptlrpc_request *req);
+void ptlrpc_del_exp_list(struct ptlrpc_request *req);
void ptlrpc_request_change_export(struct ptlrpc_request *req,
struct obd_export *export);
void ptlrpc_update_export_timer(struct ptlrpc_request *req);
/* continuation of MDS related constants */
#define OBD_FAIL_MDS_PAUSE_CREATE_AFTER_LOOKUP 0x2401
#define OBD_FAIL_MDS_CONNECT_ACCESS 0x2402
+#define OBD_FAIL_MDS_PAUSE_GETATTR 0x2403
/* PLEASE, KEEP NUMBERS UP TO 0x3000 RESERVED FOR OBD_FAIL_MDS_* */
if (info->mti_mdt->mdt_enable_dir_auto_split)
ma_need |= MA_DIRENT_CNT;
+ if (CFS_FAIL_TIMEOUT(OBD_FAIL_MDS_PAUSE_GETATTR, cfs_fail_val))
+ req->rq_pause_after_reply = 1;
+
if (info->mti_cross_ref) {
/* Only getattr on the child. Parent is on another node. */
mdt_set_disposition(info, ldlm_rep,
if (unlikely(rc))
goto out;
+ /*
+ * remove from the export list so quick
+ * resend won't find the original one.
+ */
+ ptlrpc_del_exp_list(req);
+
req->rq_sent = ktime_get_real_seconds();
rc = ptl_send_buf(&rs->rs_md_h, rs->rs_repbuf, rs->rs_repdata_len,
set_bit(tag - 1, export->exp_used_slots);
}
-static void ptlrpc_del_exp_list(struct ptlrpc_request *req)
+void ptlrpc_del_exp_list(struct ptlrpc_request *req)
{
- __u16 tag = lustre_msg_get_tag(req->rq_reqmsg);
+ __u16 tag = 0;
+
+ if (unlikely(!req->rq_export))
+ return;
+ if (likely(req->rq_reqmsg))
+ tag = lustre_msg_get_tag(req->rq_reqmsg);
spin_lock(&req->rq_export->exp_rpc_lock);
list_del_init(&req->rq_exp_list);
lustre_msg_get_handle(reqcopy->rq_reqmsg));
if (reqcopy->rq_export == NULL)
GOTO(out, rc = -ENODEV);
+ INIT_LIST_HEAD(&reqcopy->rq_exp_list);
/* RPC ref */
class_export_rpc_inc(reqcopy->rq_export);
request->rq_early_count,
div_u64(arrived_usecs, USEC_PER_SEC));
}
+ if (unlikely(request->rq_pause_after_reply)) {
+ DEBUG_REQ(D_WARNING, request, "pause req after reply");
+ schedule_timeout_uninterruptible(cfs_time_seconds(3));
+ DEBUG_REQ(D_WARNING, request, "continue");
+ }
ptlrpc_server_finish_active_request(svcpt, request);
}
run_test 202 "pfl replay should recovery layout generation"
+test_203() {
+ mount_client $MOUNT2
+ stack_trap "umount_client $MOUNT2"
+
+ local start=$SECONDS
+#define OBD_FAIL_MDS_PAUSE_GETATTR 0x2403
+ do_facet mds1 "$LCTL set_param fail_loc=0x80002403 fail_val=2"
+ echo "STAT"
+ stat $MOUNT/$tfile &
+ local PID=$!
+
+ sleep 0.5
+
+ echo "SETSTRIPE"
+ $LFS setstripe -E 1MB -c -1 -E 2MB -c -1 -E 3MB -c -1 -E 4MB -c -1 \
+ -E 5MB -c -1 -E 6MB -c -1 -E 7MB -c -1 -E 8MB -c -1 \
+ -E 9MB -c -1 -E 10MB -c -1 -E 11MB -c -1 -E eof -c -1 \
+ $MOUNT2/$tfile
+
+ wait $PID
+ do_facet mds1 "$LCTL set_param fail_loc=0 fail_val=0"
+ (( SECONDS-start < TIMEOUT/2 )) ||
+ error "took too long: $((SECONDS-start)) >= $((TIMEOUT/2))"
+}
+run_test 203 "resend can hit original request"
complete_test $SECONDS
check_and_cleanup_lustre