]> git.apps.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, 16 Feb 2023 00:44:29 +0000 (08:44 +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>
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 3ebc3413903d5278fca659def9fa140e2f021e3f..2c4ec30342f878eb928dc62555e9939e10c1de02 100644 (file)
@@ -2477,7 +2477,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;
 
@@ -2522,8 +2522,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'
@@ -2546,7 +2549,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 6c1132f75883e6101f98cc31d360f4969c7cdf01..73a603397afdee4523137b5e698ccfc21cad9d88 100644 (file)
@@ -956,7 +956,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 86722902a6d685c01ee7ad6e393903b8f7f4fb7c..ea39306608254e371003b055d4d5aae7f65120a8 100644 (file)
@@ -156,8 +156,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 f2d8a2d242e832b848c319ee8dded8692078a1c8..124eba6320c6ad0e8f2476c01dad8711d7358204 100644 (file)
@@ -621,7 +621,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
@@ -632,29 +632,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) {
@@ -671,6 +684,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 61c442699a5d27d3806b8acf85ffffe24f430a5e..6102a9b1652c22c0678dd3c93c804431018c170a 100644 (file)
@@ -29,6 +29,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 c73ac1e8397a48f70118a1f60f752c8c15930b33..cd6fde1a574352410ce0a15846b99f18e4958896 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 5a3f2ce74c8ceeaee6c6c26b67c06aa86e9b6b73..4835be2edff7d7bc2df4a4349fe8eca22639caa2 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;
@@ -111,10 +112,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 {}
 
@@ -160,8 +162,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); }
@@ -192,8 +194,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; }
@@ -252,10 +254,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;
 
@@ -312,8 +324,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())