Skip to content

Commit 546a5d6

Browse files
lxbszidryomov
authored andcommitted
ceph: stop retrying the request when exceeding 256 times
The type of 'r_attempts' in kernel 'ceph_mds_request' 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. For now let's limit it to 256. In future this could be fixed in ceph code, so avoid using the hardcode here. Signed-off-by: Xiubo Li <[email protected]> Reviewed-by: Jeff Layton <[email protected]> Signed-off-by: Ilya Dryomov <[email protected]>
1 parent 1980b1b commit 546a5d6

File tree

1 file changed

+23
-2
lines changed

1 file changed

+23
-2
lines changed

fs/ceph/mds_client.c

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2651,7 +2651,28 @@ static int __prepare_send_request(struct ceph_mds_session *session,
26512651
struct ceph_mds_client *mdsc = session->s_mdsc;
26522652
struct ceph_mds_request_head_old *rhead;
26532653
struct ceph_msg *msg;
2654-
int flags = 0;
2654+
int flags = 0, max_retry;
2655+
2656+
/*
2657+
* The type of 'r_attempts' in kernel 'ceph_mds_request'
2658+
* is 'int', while in 'ceph_mds_request_head' the type of
2659+
* 'num_retry' is '__u8'. So in case the request retries
2660+
* exceeding 256 times, the MDS will receive a incorrect
2661+
* retry seq.
2662+
*
2663+
* In this case it's ususally a bug in MDS and continue
2664+
* retrying the request makes no sense.
2665+
*
2666+
* In future this could be fixed in ceph code, so avoid
2667+
* using the hardcode here.
2668+
*/
2669+
max_retry = sizeof_field(struct ceph_mds_request_head, num_retry);
2670+
max_retry = 1 << (max_retry * BITS_PER_BYTE);
2671+
if (req->r_attempts >= max_retry) {
2672+
pr_warn_ratelimited("%s request tid %llu seq overflow\n",
2673+
__func__, req->r_tid);
2674+
return -EMULTIHOP;
2675+
}
26552676

26562677
req->r_attempts++;
26572678
if (req->r_inode) {
@@ -2663,7 +2684,7 @@ static int __prepare_send_request(struct ceph_mds_session *session,
26632684
else
26642685
req->r_sent_on_mseq = -1;
26652686
}
2666-
dout("prepare_send_request %p tid %lld %s (attempt %d)\n", req,
2687+
dout("%s %p tid %lld %s (attempt %d)\n", __func__, req,
26672688
req->r_tid, ceph_mds_op_name(req->r_op), req->r_attempts);
26682689

26692690
if (test_bit(CEPH_MDS_R_GOT_UNSAFE, &req->r_req_flags)) {

0 commit comments

Comments
 (0)