mirror of
https://github.com/ceph/ceph
synced 2025-01-04 02:02:36 +00:00
client: switch to use 32 bits ext_num_retry
Check the CEPHFS_FEATURE_32BITS_RETRY_FWD feature bit and if not set, that means it's connecting to an old MDS and will limit the max retry to 256 times. Fixes: https://tracker.ceph.com/issues/57854 Signed-off-by: Xiubo Li <xiubli@redhat.com>
This commit is contained in:
parent
cbd7e30402
commit
4fb04172ba
@ -2528,25 +2528,22 @@ ref_t<MClientRequest> Client::build_client_request(MetaRequest *request, mds_ran
|
||||
bool old_version = !session->mds_features.test(CEPHFS_FEATURE_32BITS_RETRY_FWD);
|
||||
|
||||
/*
|
||||
* 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.
|
||||
* Avoid inifinite retrying after overflow.
|
||||
*
|
||||
* 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.
|
||||
* The client will increase the retry count and if the MDS is
|
||||
* old version, so we limit to retry at most 256 times.
|
||||
*/
|
||||
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(-CEPHFS_EMULTIHOP);
|
||||
request->caller_cond->notify_all();
|
||||
ldout(cct, 1) << __func__ << " request tid " << request->tid
|
||||
<< " seq overflow" << ", abort it" << dendl;
|
||||
return nullptr;
|
||||
if (request->retry_attempt) {
|
||||
int old_max_retry = sizeof(((struct ceph_mds_request_head*)0)->num_retry);
|
||||
old_max_retry = 1 << (old_max_retry * CHAR_BIT);
|
||||
if ((old_version && request->retry_attempt >= old_max_retry) ||
|
||||
(uint32_t)request->retry_attempt >= UINT32_MAX) {
|
||||
request->abort(-CEPHFS_EMULTIHOP);
|
||||
request->caller_cond->notify_all();
|
||||
ldout(cct, 1) << __func__ << " request tid " << request->tid
|
||||
<< " retry seq overflow" << ", abort it" << dendl;
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
auto req = make_message<MClientRequest>(request->get_op(), old_version);
|
||||
|
Loading…
Reference in New Issue
Block a user