]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
ceph_fs.h: add 32 bits extended num_retry and num_fwd support
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 01:56:04 +0000 (09:56 +0800)
To make sure both the num_retry and num_fwd in all the structs have
the same type, which is 32 bits.

And also for old cephs and clients they still could use the 8 bits
members.

Fixes: https://tracker.ceph.com/issues/57854
Signed-off-by: Xiubo Li <xiubli@redhat.com>
(cherry picked from commit cbd7e3040208a5d89b9a95d4161dbd908da51079)

src/client/Client.cc
src/client/Client.h
src/client/MetaRequest.cc
src/client/MetaRequest.h
src/include/ceph_fs.h
src/mds/cephfs_features.cc
src/mds/cephfs_features.h
src/messages/MClientRequest.h

index 033588876c6ae3f074124e091fb831726b1f33fc..dd9edafda0376b09a1d20883a534c7a0f2546dc2 100644 (file)
@@ -2479,7 +2479,7 @@ void Client::send_request(MetaRequest *request, MetaSession *session,
   mds_rank_t mds = session->mds_num;
   ldout(cct, 10) << __func__ << " rebuilding request " << request->get_tid()
                 << " for mds." << mds << dendl;
-  auto r = build_client_request(request);
+  auto r = build_client_request(request, mds);
   if (!r)
     return;
 
@@ -2524,8 +2524,11 @@ void Client::send_request(MetaRequest *request, MetaSession *session,
   session->con->send_message2(std::move(r));
 }
 
-ref_t<MClientRequest> Client::build_client_request(MetaRequest *request)
+ref_t<MClientRequest> Client::build_client_request(MetaRequest *request, mds_rank_t mds)
 {
+  auto session = mds_sessions.at(mds);
+  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'
@@ -2548,7 +2551,7 @@ ref_t<MClientRequest> Client::build_client_request(MetaRequest *request)
     return nullptr;
   }
 
-  auto req = make_message<MClientRequest>(request->get_op());
+  auto req = make_message<MClientRequest>(request->get_op(), old_version);
   req->set_tid(request->tid);
   req->set_stamp(request->op_stamp);
   memcpy(&req->head, &request->head, sizeof(ceph_mds_request_head));
index c55c20e9a01537c6da4d3f54e86711e0799f4b0f..b0de97ba3e510a2b6ab3d960a4d50b596fe38b10 100644 (file)
@@ -955,7 +955,7 @@ protected:
   void connect_mds_targets(mds_rank_t mds);
   void send_request(MetaRequest *request, MetaSession *session,
                    bool drop_cap_releases=false);
-  MRef<MClientRequest> build_client_request(MetaRequest *request);
+  MRef<MClientRequest> build_client_request(MetaRequest *request, mds_rank_t mds);
   void kick_requests(MetaSession *session);
   void kick_requests_closed(MetaSession *session);
   void handle_client_request_forward(const MConstRef<MClientRequestForward>& reply);
index 2450a1f681c9caf02429ece635d2f3c6c085ce77..3994424e79360800a24badf79f322cb88d691d22 100644 (file)
@@ -46,8 +46,8 @@ void MetaRequest::dump(Formatter *f) const
   f->dump_unsigned("oldest_client_tid", head.oldest_client_tid);
   f->dump_unsigned("mdsmap_epoch", head.mdsmap_epoch);
   f->dump_unsigned("flags", head.flags);
-  f->dump_unsigned("num_retry", head.num_retry);
-  f->dump_unsigned("num_fwd", head.num_fwd);
+  f->dump_unsigned("num_retry", head.ext_num_retry);
+  f->dump_unsigned("num_fwd", head.ext_num_fwd);
   f->dump_unsigned("num_releases", head.num_releases);
 
   f->dump_int("abort_rc", abort_rc);
index 4dc8a53b8723479daa7459631ff36a794be4868b..69240bb8a329b352a2718f745454d5d088cdba45 100644 (file)
@@ -154,8 +154,8 @@ public:
   // normal fields
   void set_tid(ceph_tid_t t) { tid = t; }
   void set_oldest_client_tid(ceph_tid_t t) { head.oldest_client_tid = t; }
-  void inc_num_fwd() { head.num_fwd = head.num_fwd + 1; }
-  void set_retry_attempt(int a) { head.num_retry = a; }
+  void inc_num_fwd() { head.ext_num_fwd = head.ext_num_fwd + 1; }
+  void set_retry_attempt(int a) { head.ext_num_retry = a; }
   void set_filepath(const filepath& fp) { path = fp; }
   void set_filepath2(const filepath& fp) { path2 = fp; }
   void set_alternate_name(std::string an) { alternate_name = an; }
index 3804568b9bdd4a56bb7f791e9069a5faf3c040f7..05c2b8bd0080359a006d6d02af9b7127b630a0c3 100644 (file)
@@ -618,7 +618,7 @@ union ceph_mds_request_args {
        } __attribute__ ((packed)) lookupino;
 } __attribute__ ((packed));
 
-#define CEPH_MDS_REQUEST_HEAD_VERSION  1
+#define CEPH_MDS_REQUEST_HEAD_VERSION  2
 
 /*
  * Note that any change to this structure must ensure that it is compatible
@@ -629,29 +629,42 @@ struct ceph_mds_request_head {
        __le64 oldest_client_tid;
        __le32 mdsmap_epoch;           /* on client */
        __le32 flags;                  /* CEPH_MDS_FLAG_* */
-       __u8 num_retry, num_fwd;       /* count retry, fwd attempts */
+       __u8 num_retry, num_fwd;       /* legacy count retry and fwd attempts */
        __le16 num_releases;           /* # include cap/lease release records */
        __le32 op;                     /* mds op code */
        __le32 caller_uid, caller_gid;
        __le64 ino;                    /* use this ino for openc, mkdir, mknod,
                                          etc. (if replaying) */
        union ceph_mds_request_args args;
+
+       __le32 ext_num_retry;          /* new count retry attempts */
+       __le32 ext_num_fwd;            /* new count fwd attempts */
 } __attribute__ ((packed));
 
-void inline encode(const struct ceph_mds_request_head& h, ceph::buffer::list& bl) {
+void inline encode(const struct ceph_mds_request_head& h, ceph::buffer::list& bl, bool old_version) {
   using ceph::encode;
   encode(h.version, bl);
   encode(h.oldest_client_tid, bl);
   encode(h.mdsmap_epoch, bl);
   encode(h.flags, bl);
-  encode(h.num_retry, bl);
-  encode(h.num_fwd, bl);
+
+  // For old MDS daemons
+  __u8 num_retry = __u32(h.ext_num_retry);
+  __u8 num_fwd = __u32(h.ext_num_fwd);
+  encode(num_retry, bl);
+  encode(num_fwd, bl);
+
   encode(h.num_releases, bl);
   encode(h.op, bl);
   encode(h.caller_uid, bl);
   encode(h.caller_gid, bl);
   encode(h.ino, bl);
   bl.append((char*)&h.args, sizeof(h.args));
+
+  if (!old_version) {
+    encode(h.ext_num_retry, bl);
+    encode(h.ext_num_fwd, bl);
+  }
 }
 
 void inline decode(struct ceph_mds_request_head& h, ceph::buffer::list::const_iterator& bl) {
@@ -668,6 +681,14 @@ void inline decode(struct ceph_mds_request_head& h, ceph::buffer::list::const_it
   decode(h.caller_gid, bl);
   decode(h.ino, bl);
   bl.copy(sizeof(h.args), (char*)&(h.args));
+
+  if (h.version >= 2) {
+    decode(h.ext_num_retry, bl);
+    decode(h.ext_num_fwd, bl);
+  } else {
+    h.ext_num_retry = h.num_retry;
+    h.ext_num_fwd = h.num_fwd;
+  }
 }
 
 /* cap/lease release record */
index dda64edfcd2a6210bbbf32d2c13c40adab957e92..3ea19e93fab492c412768f8c2611f4221039f443 100644 (file)
@@ -25,6 +25,7 @@ static const std::array feature_names
   "alternate_name",
   "notify_session_state",
   "op_getvxattr",
+  "32bits_retry_fwd",
 };
 static_assert(feature_names.size() == CEPHFS_FEATURE_MAX + 1);
 
index 75402f3eb85393589db007828b47ba9978bc430e..44c7b223ab30f087efb2d9ae08f03fd39a0359ee 100644 (file)
@@ -45,7 +45,8 @@ namespace ceph {
 #define CEPHFS_FEATURE_ALTERNATE_NAME       15
 #define CEPHFS_FEATURE_NOTIFY_SESSION_STATE 16
 #define CEPHFS_FEATURE_OP_GETVXATTR         17
-#define CEPHFS_FEATURE_MAX                  17
+#define CEPHFS_FEATURE_32BITS_RETRY_FWD     18
+#define CEPHFS_FEATURE_MAX                  18
 
 #define CEPHFS_FEATURES_ALL {          \
   0, 1, 2, 3, 4,                       \
@@ -64,6 +65,7 @@ namespace ceph {
   CEPHFS_FEATURE_ALTERNATE_NAME,        \
   CEPHFS_FEATURE_NOTIFY_SESSION_STATE,  \
   CEPHFS_FEATURE_OP_GETVXATTR,          \
+  CEPHFS_FEATURE_32BITS_RETRY_FWD,      \
 }
 
 #define CEPHFS_METRIC_FEATURES_ALL {           \
index 1e83ec3af1bdadd483009cab5d9fba16654ceca0..6c05d3d9ecf58f8c80dfa252570bb09703581140 100644 (file)
@@ -73,6 +73,7 @@ private:
 public:
   mutable struct ceph_mds_request_head head; /* XXX HACK! */
   utime_t stamp;
+  bool peer_old_version = false;
 
   struct Release {
     mutable ceph_mds_request_release item;
@@ -108,10 +109,11 @@ protected:
   // cons
   MClientRequest()
     : MMDSOp(CEPH_MSG_CLIENT_REQUEST, HEAD_VERSION, COMPAT_VERSION) {}
-  MClientRequest(int op)
+  MClientRequest(int op, bool over=true)
     : MMDSOp(CEPH_MSG_CLIENT_REQUEST, HEAD_VERSION, COMPAT_VERSION) {
     memset(&head, 0, sizeof(head));
     head.op = op;
+    peer_old_version = over;
   }
   ~MClientRequest() final {}
 
@@ -157,8 +159,8 @@ public:
   // normal fields
   void set_stamp(utime_t t) { stamp = t; }
   void set_oldest_client_tid(ceph_tid_t t) { head.oldest_client_tid = t; }
-  void inc_num_fwd() { head.num_fwd = head.num_fwd + 1; }
-  void set_retry_attempt(int a) { head.num_retry = a; }
+  void inc_num_fwd() { head.ext_num_fwd = head.ext_num_fwd + 1; }
+  void set_retry_attempt(int a) { head.ext_num_retry = a; }
   void set_filepath(const filepath& fp) { path = fp; }
   void set_filepath2(const filepath& fp) { path2 = fp; }
   void set_string2(const char *s) { path2.set_path(std::string_view(s), 0); }
@@ -189,8 +191,8 @@ public:
 
   utime_t get_stamp() const { return stamp; }
   ceph_tid_t get_oldest_client_tid() const { return head.oldest_client_tid; }
-  int get_num_fwd() const { return head.num_fwd; }
-  int get_retry_attempt() const { return head.num_retry; }
+  int get_num_fwd() const { return head.ext_num_fwd; }
+  int get_retry_attempt() const { return head.ext_num_retry; }
   int get_op() const { return head.op; }
   unsigned get_caller_uid() const { return head.caller_uid; }
   unsigned get_caller_gid() const { return head.caller_gid; }
@@ -245,10 +247,20 @@ public:
   void encode_payload(uint64_t features) override {
     using ceph::encode;
     head.num_releases = releases.size();
-    head.version = CEPH_MDS_REQUEST_HEAD_VERSION;
+    /*
+     * If the peer is old version, we must skip all the
+     * new members, because the old version of MDS or
+     * client will just copy the 'head' memory and isn't
+     * that smart to skip them.
+     */
+    if (peer_old_version) {
+      head.version = 1;
+    } else {
+      head.version = CEPH_MDS_REQUEST_HEAD_VERSION;
+    }
 
     if (features & CEPH_FEATURE_FS_BTIME) {
-      encode(head, payload);
+      encode(head, payload, peer_old_version);
     } else {
       struct ceph_mds_request_head_legacy old_mds_head;
 
@@ -303,8 +315,10 @@ public:
       out << " " << get_filepath2();
     if (stamp != utime_t())
       out << " " << stamp;
-    if (head.num_retry)
-      out << " RETRY=" << (int)head.num_retry;
+    if (head.ext_num_fwd)
+      out << " FWD=" << (int)head.ext_num_fwd;
+    if (head.ext_num_retry)
+      out << " RETRY=" << (int)head.ext_num_retry;
     if (is_async())
       out << " ASYNC";
     if (is_replay())