]> git.proxmox.com Git - ceph.git/blobdiff - ceph/src/cls/rgw/cls_rgw_types.h
import 15.2.5
[ceph.git] / ceph / src / cls / rgw / cls_rgw_types.h
index ee15fbc0e6a542aa6b2ac6f62379f4949634f6fa..620811dbc4a25925a12561f531826749c2d4b0f7 100644 (file)
@@ -4,6 +4,7 @@
 #ifndef CEPH_CLS_RGW_TYPES_H
 #define CEPH_CLS_RGW_TYPES_H
 
+#include <boost/container/flat_map.hpp>
 #include "common/ceph_time.h"
 #include "common/Formatter.h"
 
@@ -22,7 +23,60 @@ namespace ceph {
 }
 using ceph::operator <<;
 
-using rgw_zone_set = std::set<std::string>;
+struct rgw_zone_set_entry {
+  string zone;
+  std::optional<std::string> location_key;
+
+  bool operator<(const rgw_zone_set_entry& e) const {
+    if (zone < e.zone) {
+      return true;
+    }
+    if (zone > e.zone) {
+      return false;
+    }
+    return (location_key < e.location_key);
+  }
+
+  rgw_zone_set_entry() {}
+  rgw_zone_set_entry(const string& _zone,
+                     std::optional<std::string> _location_key) : zone(_zone),
+                                                                location_key(_location_key) {}
+  rgw_zone_set_entry(const string& s) {
+    from_str(s);
+  }
+
+  void from_str(const string& s);
+  string to_str() const;
+
+  void encode(bufferlist &bl) const;
+  void decode(bufferlist::const_iterator &bl);
+
+  void dump(Formatter *f) const;
+  void decode_json(JSONObj *obj);
+};
+WRITE_CLASS_ENCODER(rgw_zone_set_entry)
+
+struct rgw_zone_set {
+  std::set<rgw_zone_set_entry> entries;
+
+  void encode(bufferlist &bl) const {
+    /* no ENCODE_START, ENCODE_END for backward compatibility */
+    ceph::encode(entries, bl);
+  }
+  void decode(bufferlist::const_iterator &bl) {
+    /* no DECODE_START, DECODE_END for backward compatibility */
+    ceph::decode(entries, bl);
+  }
+
+  void insert(const string& zone, std::optional<string> location_key);
+  bool exists(const string& zone, std::optional<string> location_key) const;
+};
+WRITE_CLASS_ENCODER(rgw_zone_set)
+
+/* backward compatibility, rgw_zone_set needs to encode/decode the same as std::set */
+void encode_json(const char *name, const rgw_zone_set& zs, ceph::Formatter *f);
+void decode_json_obj(rgw_zone_set& zs, JSONObj *obj);
+
 
 enum RGWPendingState {
   CLS_RGW_STATE_PENDING_MODIFY = 0,
@@ -56,11 +110,23 @@ enum RGWCheckMTimeType {
 
 #define ROUND_BLOCK_SIZE 4096
 
-static inline uint64_t cls_rgw_get_rounded_size(uint64_t size)
-{
+static inline uint64_t cls_rgw_get_rounded_size(uint64_t size) {
   return (size + ROUND_BLOCK_SIZE - 1) & ~(ROUND_BLOCK_SIZE - 1);
 }
 
+/*
+ * This takes a string that either wholly contains a delimiter or is a
+ * path that ends with a delimiter and appends a new character to the
+ * end such that when a we request bucket-index entries *after* this,
+ * we'll get the next object after the "subdirectory". This works
+ * because we append a '\xFF' charater, and no valid UTF-8 character
+ * can contain that byte, so no valid entries can be skipped.
+ */
+static inline std::string cls_rgw_after_delim(const std::string& path) {
+  // assert: ! path.empty()
+  return path + '\xFF';
+}
+
 struct rgw_bucket_pending_info {
   RGWPendingState state;
   ceph::real_time timestamp;
@@ -325,12 +391,22 @@ struct cls_rgw_obj_key {
 WRITE_CLASS_ENCODER(cls_rgw_obj_key)
 
 
-#define RGW_BUCKET_DIRENT_FLAG_VER           0x1    /* a versioned object instance */
-#define RGW_BUCKET_DIRENT_FLAG_CURRENT       0x2    /* the last object instance of a versioned object */
-#define RGW_BUCKET_DIRENT_FLAG_DELETE_MARKER 0x4    /* delete marker */
-#define RGW_BUCKET_DIRENT_FLAG_VER_MARKER    0x8    /* object is versioned, a placeholder for the plain entry */
-
 struct rgw_bucket_dir_entry {
+  /* a versioned object instance */
+  static constexpr uint16_t FLAG_VER =                0x1;
+  /* the last object instance of a versioned object */
+  static constexpr uint16_t FLAG_CURRENT =            0x2;
+  /* delete marker */
+  static constexpr uint16_t FLAG_DELETE_MARKER =      0x4;
+  /* object is versioned, a placeholder for the plain entry */
+  static constexpr uint16_t FLAG_VER_MARKER =         0x8;
+  /* object is a proxy; it is not listed in the bucket index but is a
+   * prefix ending with a delimiter, perhaps common to multiple
+   * entries; it is only useful when a delimiter is used and
+   * represents a "subdirectory" (again, ending in a delimiter) that
+   * may contain one or more actual entries/objects */
+  static constexpr uint16_t FLAG_COMMON_PREFIX =   0x8000;
+
   cls_rgw_obj_key key;
   rgw_bucket_entry_ver ver;
   std::string locator;
@@ -392,16 +468,24 @@ struct rgw_bucket_dir_entry {
     DECODE_FINISH(bl);
   }
 
-  bool is_current() {
-    int test_flags = RGW_BUCKET_DIRENT_FLAG_VER | RGW_BUCKET_DIRENT_FLAG_CURRENT;
-    return (flags & RGW_BUCKET_DIRENT_FLAG_VER) == 0 ||
+  bool is_current() const {
+    int test_flags =
+      rgw_bucket_dir_entry::FLAG_VER | rgw_bucket_dir_entry::FLAG_CURRENT;
+    return (flags & rgw_bucket_dir_entry::FLAG_VER) == 0 ||
            (flags & test_flags) == test_flags;
   }
-  bool is_delete_marker() { return (flags & RGW_BUCKET_DIRENT_FLAG_DELETE_MARKER) != 0; }
-  bool is_visible() {
+  bool is_delete_marker() const {
+    return (flags & rgw_bucket_dir_entry::FLAG_DELETE_MARKER) != 0;
+  }
+  bool is_visible() const {
     return is_current() && !is_delete_marker();
   }
-  bool is_valid() { return (flags & RGW_BUCKET_DIRENT_FLAG_VER_MARKER) == 0; }
+  bool is_valid() const {
+    return (flags & rgw_bucket_dir_entry::FLAG_VER_MARKER) == 0;
+  }
+  bool is_common_prefix() const {
+    return flags & rgw_bucket_dir_entry::FLAG_COMMON_PREFIX;
+  }
 
   void dump(Formatter *f) const;
   void decode_json(JSONObj *obj);
@@ -637,32 +721,32 @@ struct rgw_bucket_category_stats {
 };
 WRITE_CLASS_ENCODER(rgw_bucket_category_stats)
 
-enum cls_rgw_reshard_status {
-  CLS_RGW_RESHARD_NONE        = 0,
-  CLS_RGW_RESHARD_IN_PROGRESS = 1,
-  CLS_RGW_RESHARD_DONE        = 2,
+enum class cls_rgw_reshard_status : uint8_t {
+  NOT_RESHARDING  = 0,
+  IN_PROGRESS     = 1,
+  DONE            = 2
 };
 
-static inline std::string to_string(const enum cls_rgw_reshard_status status)
+static inline std::string to_string(const cls_rgw_reshard_status status)
 {
   switch (status) {
-  case CLS_RGW_RESHARD_NONE:
-    return "CLS_RGW_RESHARD_NONE";
+  case cls_rgw_reshard_status::NOT_RESHARDING:
+    return "not-resharding";
     break;
-  case CLS_RGW_RESHARD_IN_PROGRESS:
-    return "CLS_RGW_RESHARD_IN_PROGRESS";
+  case cls_rgw_reshard_status::IN_PROGRESS:
+    return "in-progress";
     break;
-  case CLS_RGW_RESHARD_DONE:
-    return "CLS_RGW_RESHARD_DONE";
-    break;
-  default:
+  case cls_rgw_reshard_status::DONE:
+    return "done";
     break;
   };
   return "Unknown reshard status";
 }
 
 struct cls_rgw_bucket_instance_entry {
-  cls_rgw_reshard_status reshard_status{CLS_RGW_RESHARD_NONE};
+  using RESHARD_STATUS = cls_rgw_reshard_status;
+  
+  cls_rgw_reshard_status reshard_status{RESHARD_STATUS::NOT_RESHARDING};
   string new_bucket_instance_id;
   int32_t num_shards{-1};
 
@@ -688,21 +772,23 @@ struct cls_rgw_bucket_instance_entry {
   static void generate_test_instances(list<cls_rgw_bucket_instance_entry*>& o);
 
   void clear() {
-    reshard_status = CLS_RGW_RESHARD_NONE;
+    reshard_status = RESHARD_STATUS::NOT_RESHARDING;
     new_bucket_instance_id.clear();
   }
 
-  void set_status(const string& new_instance_id, int32_t new_num_shards, cls_rgw_reshard_status s) {
+  void set_status(const string& new_instance_id,
+                 int32_t new_num_shards,
+                 cls_rgw_reshard_status s) {
     reshard_status = s;
     new_bucket_instance_id = new_instance_id;
     num_shards = new_num_shards;
   }
 
   bool resharding() const {
-    return reshard_status != CLS_RGW_RESHARD_NONE;
+    return reshard_status != RESHARD_STATUS::NOT_RESHARDING;
   }
   bool resharding_in_progress() const {
-    return reshard_status == CLS_RGW_RESHARD_IN_PROGRESS;
+    return reshard_status == RESHARD_STATUS::IN_PROGRESS;
   }
 };
 WRITE_CLASS_ENCODER(cls_rgw_bucket_instance_entry)
@@ -770,7 +856,7 @@ WRITE_CLASS_ENCODER(rgw_bucket_dir_header)
 
 struct rgw_bucket_dir {
   rgw_bucket_dir_header header;
-  std::map<string, rgw_bucket_dir_entry> m;
+  boost::container::flat_map<string, rgw_bucket_dir_entry> m;
 
   void encode(bufferlist &bl) const {
     ENCODE_START(2, 2, bl);
@@ -1093,7 +1179,7 @@ struct cls_rgw_gc_obj_info
     ls.push_back(new cls_rgw_gc_obj_info);
     ls.push_back(new cls_rgw_gc_obj_info);
     ls.back()->tag = "footag";
-    ceph_timespec ts{21, 32};
+    ceph_timespec ts{init_le32(21), init_le32(32)};
     ls.back()->time = ceph::real_clock::from_ceph_timespec(ts);
   }
 };
@@ -1128,6 +1214,37 @@ struct cls_rgw_lc_obj_head
 };
 WRITE_CLASS_ENCODER(cls_rgw_lc_obj_head)
 
+struct cls_rgw_lc_entry {
+  std::string bucket;
+  uint64_t start_time; // if in_progress
+  uint32_t status;
+
+  cls_rgw_lc_entry()
+    : start_time(0), status(0) {}
+
+  cls_rgw_lc_entry(const cls_rgw_lc_entry& rhs) = default;
+
+  cls_rgw_lc_entry(const std::string& b, uint64_t t, uint32_t s)
+    : bucket(b), start_time(t), status(s) {};
+
+  void encode(bufferlist& bl) const {
+    ENCODE_START(1, 1, bl);
+    encode(bucket, bl);
+    encode(start_time, bl);
+    encode(status, bl);
+    ENCODE_FINISH(bl);
+  }
+
+  void decode(bufferlist::const_iterator& bl) {
+    DECODE_START(1, bl);
+    decode(bucket, bl);
+    decode(start_time, bl);
+    decode(status, bl);
+    DECODE_FINISH(bl);
+  }
+};
+WRITE_CLASS_ENCODER(cls_rgw_lc_entry);
+
 struct cls_rgw_reshard_entry
 {
   ceph::real_time time;