]> git.proxmox.com Git - ceph.git/blobdiff - ceph/src/include/ceph_fs.h
update ceph source to reef 18.2.1
[ceph.git] / ceph / src / include / ceph_fs.h
index 1a75a519333600ea78218f85850e90252b690045..28440c820dcfb8f17d0a04fcc301401025ec80fd 100644 (file)
@@ -418,6 +418,7 @@ enum {
        CEPH_MDS_OP_RMSNAP     = 0x01401,
        CEPH_MDS_OP_LSSNAP     = 0x00402,
        CEPH_MDS_OP_RENAMESNAP = 0x01403,
+       CEPH_MDS_OP_READDIR_SNAPDIFF   = 0x01404,
 
        // internal op
        CEPH_MDS_OP_FRAGMENTDIR= 0x01500,
@@ -429,6 +430,11 @@ enum {
        CEPH_MDS_OP_RDLOCK_FRAGSSTATS = 0x01507
 };
 
+#define IS_CEPH_MDS_OP_NEWINODE(op) (op == CEPH_MDS_OP_CREATE     || \
+                                    op == CEPH_MDS_OP_MKNOD      || \
+                                    op == CEPH_MDS_OP_MKDIR      || \
+                                    op == CEPH_MDS_OP_SYMLINK)
+
 extern const char *ceph_mds_op_name(int op);
 
 // setattr mask is an int
@@ -473,12 +479,12 @@ int ceph_flags_sys2wire(int flags);
 #define CEPH_XATTR_REMOVE  (1 << 31)
 
 /*
- * readdir request flags;
+ * readdir/readdir_snapdiff request flags;
  */
 #define CEPH_READDIR_REPLY_BITFLAGS    (1<<0)
 
 /*
- * readdir reply flags.
+ * readdir/readdir_snapdiff reply flags.
  */
 #define CEPH_READDIR_FRAG_END          (1<<0)
 #define CEPH_READDIR_FRAG_COMPLETE     (1<<8)
@@ -622,9 +628,17 @@ union ceph_mds_request_args {
                __le64 parent;
                __le32 hash;
        } __attribute__ ((packed)) lookupino;
+       struct {
+               __le32 frag;                 /* which dir fragment */
+               __le32 max_entries;          /* how many dentries to grab */
+               __le32 max_bytes;
+               __le16 flags;
+                __le32 offset_hash;
+               __le64 snap_other;
+       } __attribute__ ((packed)) snapdiff;
 } __attribute__ ((packed));
 
-#define CEPH_MDS_REQUEST_HEAD_VERSION  2
+#define CEPH_MDS_REQUEST_HEAD_VERSION  3
 
 /*
  * Note that any change to this structure must ensure that it is compatible
@@ -645,9 +659,12 @@ struct ceph_mds_request_head {
 
        __le32 ext_num_retry;          /* new count retry attempts */
        __le32 ext_num_fwd;            /* new count fwd attempts */
+
+       __le32 struct_len;             /* to store size of struct ceph_mds_request_head */
+       __le32 owner_uid, owner_gid;   /* used for OPs which create inodes */
 } __attribute__ ((packed));
 
-void inline encode(const struct ceph_mds_request_head& h, ceph::buffer::list& bl, bool old_version) {
+void inline encode(const struct ceph_mds_request_head& h, ceph::buffer::list& bl) {
   using ceph::encode;
   encode(h.version, bl);
   encode(h.oldest_client_tid, bl);
@@ -667,14 +684,30 @@ void inline encode(const struct ceph_mds_request_head& h, ceph::buffer::list& bl
   encode(h.ino, bl);
   bl.append((char*)&h.args, sizeof(h.args));
 
-  if (!old_version) {
+  if (h.version >= 2) {
     encode(h.ext_num_retry, bl);
     encode(h.ext_num_fwd, bl);
   }
+
+  if (h.version >= 3) {
+    __u32 struct_len = sizeof(struct ceph_mds_request_head);
+    encode(struct_len, bl);
+    encode(h.owner_uid, bl);
+    encode(h.owner_gid, bl);
+
+    /*
+     * Please, add new fields handling here.
+     * You don't need to check h.version as we do it
+     * in decode(), because decode can properly skip
+     * all unsupported fields if h.version >= 3.
+     */
+  }
 }
 
 void inline decode(struct ceph_mds_request_head& h, ceph::buffer::list::const_iterator& bl) {
   using ceph::decode;
+  unsigned struct_end = bl.get_off();
+
   decode(h.version, bl);
   decode(h.oldest_client_tid, bl);
   decode(h.mdsmap_epoch, bl);
@@ -695,6 +728,42 @@ void inline decode(struct ceph_mds_request_head& h, ceph::buffer::list::const_it
     h.ext_num_retry = h.num_retry;
     h.ext_num_fwd = h.num_fwd;
   }
+
+  if (h.version >= 3) {
+    decode(h.struct_len, bl);
+    struct_end += h.struct_len;
+
+    decode(h.owner_uid, bl);
+    decode(h.owner_gid, bl);
+  } else {
+    /*
+     * client is old: let's take caller_{u,g}id as owner_{u,g}id
+     * this is how it worked before adding of owner_{u,g}id fields.
+     */
+    h.owner_uid = h.caller_uid;
+    h.owner_gid = h.caller_gid;
+  }
+
+  /* add new fields handling here */
+
+  /*
+   * From version 3 we have struct_len field.
+   * It allows us to properly handle a case
+   * when client send struct ceph_mds_request_head
+   * bigger in size than MDS supports. In this
+   * case we just want to skip all remaining bytes
+   * at the end.
+   *
+   * See also DECODE_FINISH macro. Unfortunately,
+   * we can't start using it right now as it will be
+   * an incompatible protocol change.
+   */
+  if (h.version >= 3) {
+    if (bl.get_off() > struct_end)
+      throw ::ceph::buffer::malformed_input(DECODE_ERR_PAST(__PRETTY_FUNCTION__));
+    if (bl.get_off() < struct_end)
+      bl += struct_end - bl.get_off();
+  }
 }
 
 /* cap/lease release record */