]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
client: switch to use 32 bits ext_num_fwd
authorXiubo Li <xiubli@redhat.com>
Tue, 5 Jul 2022 04:59:11 +0000 (12:59 +0800)
committerXiubo Li <xiubli@redhat.com>
Thu, 30 Mar 2023 02:00:08 +0000 (10:00 +0800)
The MDS will increase the forward count, and if the forward count
is less than the one saved in request in client side, that means
the MDS is old version and it was overflowed. Then just stop
forwarding.

Fixes: https://tracker.ceph.com/issues/57854
Signed-off-by: Xiubo Li <xiubli@redhat.com>
(cherry picked from commit 3584ecc876b981b2204fbd7f720867e454639c58)
Conflicts:
- src/client/Client.cc: there is no -CEPHFS_EMULTIHOP

src/client/Client.cc

index c2880e16464f8088a8f2df90701efa639b8a3727..84ed6e1a5e4f355d8bf70550a95ce556137697aa 100644 (file)
@@ -2570,7 +2570,7 @@ ref_t<MClientRequest> Client::build_client_request(MetaRequest *request, mds_ran
   req->set_alternate_name(request->alternate_name);
   req->set_data(request->data);
   req->set_retry_attempt(request->retry_attempt++);
-  req->head.num_fwd = request->num_fwd;
+  req->head.ext_num_fwd = request->num_fwd;
   const gid_t *_gids;
   int gid_count = request->perms.get_gids(&_gids);
   req->set_gid_list(gid_count, _gids);
@@ -2599,32 +2599,20 @@ void Client::handle_client_request_forward(const MConstRef<MClientRequestForward
   ceph_assert(request);
 
   /*
-   * The type of 'num_fwd' in ceph 'MClientRequestForward'
-   * is 'int32_t', while in 'ceph_mds_request_head' the
-   * type is '__u8'. So in case the request bounces between
-   * MDSes exceeding 256 times, the client will get stuck.
-   *
-   * In this case it's ususally a bug in MDS and continue
-   * bouncing the request makes no sense.
+   * Avoid inifinite retrying after overflow.
    *
-   * In future this could be fixed in ceph code, so avoid
-   * using the hardcode here.
+   * The MDS will increase the fwd count and in client side
+   * if the num_fwd is less than the one saved in request
+   * that means the MDS is an old version and overflowed of
+   * 8 bits.
    */
-  int max_fwd = sizeof(((struct ceph_mds_request_head*)0)->num_fwd);
-  max_fwd = (1 << (max_fwd * CHAR_BIT)) - 1;
   auto num_fwd = fwd->get_num_fwd();
-  if (num_fwd <= request->num_fwd || num_fwd >= max_fwd) {
-    if (request->num_fwd >= max_fwd || num_fwd >= max_fwd) {
-      request->abort(-EMULTIHOP);
-      request->caller_cond->notify_all();
-      ldout(cct, 1) << __func__ << " tid " << tid << " seq overflow"
-                    << ", abort it" << dendl;
-    } else {
-      ldout(cct, 10) << __func__ << " tid " << tid
-                     << " old fwd seq " << fwd->get_num_fwd()
-                     << " <= req fwd " << request->num_fwd
-                     << ", ignore it" << dendl;
-    }
+  if (num_fwd <= request->num_fwd || (uint32_t)num_fwd >= UINT32_MAX) {
+    request->abort(-EMULTIHOP);
+    request->caller_cond->notify_all();
+    ldout(cct, 0) << __func__ << " request tid " << tid << " new num_fwd "
+      << num_fwd << " old num_fwd " << request->num_fwd << ", fwd seq overflow"
+      << ", abort it" << dendl;
     return;
   }