ldout(cct, 10) << __func__ << " rebuilding request " << request->get_tid()
<< " for mds." << mds << dendl;
auto r = build_client_request(request);
+ if (!r)
+ return;
+
if (request->dentry()) {
r->set_dentry_wanted();
}
ref_t<MClientRequest> Client::build_client_request(MetaRequest *request)
{
+ /*
+ * The type of 'retry_attempt' in 'MetaRequest' is 'int',
+ * while in 'ceph_mds_request_head' the type of 'num_retry'
+ * is '__u8'. So in case the request retries exceeding 256
+ * times, the MDS will receive a incorrect retry seq.
+ *
+ * In this case it's ususally a bug in MDS and continue
+ * retrying the request makes no sense.
+ *
+ * In future this could be fixed in ceph code, so avoid
+ * using the hardcode here.
+ */
+ int max_retry = sizeof(((struct ceph_mds_request_head*)0)->num_retry);
+ max_retry = 1 << (max_retry * CHAR_BIT);
+ if (request->retry_attempt >= max_retry) {
+ request->abort(-EMULTIHOP);
+ request->caller_cond->notify_all();
+ ldout(cct, 1) << __func__ << " request tid " << request->tid
+ << " seq overflow" << ", abort it" << dendl;
+ return nullptr;
+ }
+
auto req = make_message<MClientRequest>(request->get_op());
req->set_tid(request->tid);
req->set_stamp(request->op_stamp);