template<class T>
static void decode_json(const char *name, T& val, const T& default_val, JSONObj *obj);
+
+ template<class T>
+ static bool decode_json(const char *name, boost::optional<T>& val, JSONObj *obj, bool mandatory = false);
+
};
template<class T>
}
}
+template<class T>
+bool JSONDecoder::decode_json(const char *name, boost::optional<T>& val, JSONObj *obj, bool mandatory)
+{
+ JSONObjIter iter = obj->find_first(name);
+ if (iter.end()) {
+ if (mandatory) {
+ string s = "missing mandatory field " + string(name);
+ throw err(s);
+ }
+ val = boost::none;
+ return false;
+ }
+
+ try {
+ val.reset(T());
+ decode_json_obj(val.get(), *iter);
+ } catch (err& e) {
+ val.reset();
+ string s = string(name) + ": ";
+ s.append(e.message);
+ throw err(s);
+ }
+
+ return true;
+}
+
template<class T>
static void encode_json(const char *name, const T& val, ceph::Formatter *f)
{
long long val_long_long() const;
bool val_bool() const;
+ const map<std::string, JSONFormattable> object() const {
+ return obj;
+ }
+
const vector<JSONFormattable>& array() const {
return arr;
}
RGWZonePlacementInfo& info = zone.placement_pools[placement_id];
info.index_pool = *index_pool;
- if (storage_class.empty()) {
- info.data_pools[RGW_STORAGE_CLASS_STANDARD] = *data_pool;
- } else {
- info.data_pools[storage_class] = *data_pool;
- }
+ rgw_pool dp = data_pool.get();
+ info.storage_classes.set_storage_class(storage_class, &dp, compression_type.get_ptr());
+
if (data_extra_pool) {
info.data_extra_pool = *data_extra_pool;
}
if (index_type_specified) {
info.index_type = placement_index_type;
}
- if (compression_type) {
- info.compression_type = *compression_type;
- }
ret = check_pool_support_omap(info.get_data_extra_pool());
if (ret < 0) {
if (index_pool && !index_pool->empty()) {
info.index_pool = *index_pool;
}
- if (data_pool && !data_pool->empty()) {
- if (storage_class.empty()) {
- info.data_pools[RGW_STORAGE_CLASS_STANDARD] = *data_pool;
- } else {
- info.data_pools[storage_class] = *data_pool;
- }
- }
+ rgw_pool dp = data_pool.get();
+ info.storage_classes.set_storage_class(storage_class, &dp, compression_type.get_ptr());
+
if (data_extra_pool) {
info.data_extra_pool = *data_extra_pool;
}
if (index_type_specified) {
info.index_type = placement_index_type;
}
- if (compression_type) {
- info.compression_type = *compression_type;
- }
ret = check_pool_support_omap(info.get_data_extra_pool());
if (ret < 0) {
encode_json("realm_id", realm_id, f);
}
+void RGWZoneStorageClass::dump(Formatter *f) const
+{
+ if (data_pool) {
+ encode_json("data_pool", data_pool.get(), f);
+ }
+ if (compression_type) {
+ encode_json("compression_type", compression_type.get(), f);
+ }
+}
+
+void RGWZoneStorageClass::decode_json(JSONObj *obj)
+{
+ JSONDecoder::decode_json("data_pool", data_pool, obj);
+ JSONDecoder::decode_json("compression_type", compression_type, obj);
+}
+
+void RGWZoneStorageClasses::dump(Formatter *f) const
+{
+ for (auto& i : m) {
+ encode_json(i.first.c_str(), i.second, f);
+ }
+}
+
+void RGWZoneStorageClasses::decode_json(JSONObj *obj)
+{
+ JSONFormattable f;
+ decode_json_obj(f, obj);
+
+ for (auto& field : f.object()) {
+ JSONObj *field_obj = obj->find_obj(field.first);
+ assert(field_obj);
+
+ decode_json_obj(m[field.first], field_obj);
+ }
+}
+
void RGWZonePlacementInfo::dump(Formatter *f) const
{
encode_json("index_pool", index_pool, f);
- encode_json("data_pools", data_pools, f);
+ encode_json("storage_classes", storage_classes, f);
encode_json("data_extra_pool", data_extra_pool, f);
encode_json("index_type", (uint32_t)index_type, f);
- encode_json("compression", compression_type, f);
+
+ /* no real need for backward compatibility of compression_type and data_pool in here,
+ * rather not clutter the output */
}
void RGWZonePlacementInfo::decode_json(JSONObj *obj)
{
JSONDecoder::decode_json("index_pool", index_pool, obj);
- JSONDecoder::decode_json("data_pools", data_pools, obj);
- if (JSONDecoder::decode_json("data_pool", standard_data_pool, obj)) {
- data_pools[RGW_STORAGE_CLASS_STANDARD] = standard_data_pool;
- } else {
- auto iter = data_pools.find(RGW_STORAGE_CLASS_STANDARD);
- if (iter != data_pools.end()) {
- standard_data_pool = iter->second;
- }
- }
+ JSONDecoder::decode_json("storage_classes", storage_classes, obj);
JSONDecoder::decode_json("data_extra_pool", data_extra_pool, obj);
uint32_t it;
JSONDecoder::decode_json("index_type", it, obj);
index_type = (RGWBucketIndexType)it;
- JSONDecoder::decode_json("compression", compression_type, obj);
+
+ /* backward compatibility, these are now defined in storage_classes */
+ string standard_compression_type;
+ string *pcompression = nullptr;
+ if (JSONDecoder::decode_json("compression", standard_compression_type, obj)) {
+ pcompression = &standard_compression_type;
+ }
+ rgw_pool standard_data_pool;
+ rgw_pool *ppool = nullptr;
+ if (JSONDecoder::decode_json("data_pool", standard_data_pool, obj)) {
+ ppool = &standard_data_pool;
+ }
+ if (ppool || pcompression) {
+ storage_classes.set_storage_class(RGW_STORAGE_CLASS_STANDARD, ppool, pcompression);
+ }
}
void RGWZoneParams::decode_json(JSONObj *obj)
filter = encrypt.get();
} else {
const auto& compression_type = store->svc.zone->get_zone_params().get_compression_type(
- s->bucket_info.placement_rule.name);
+ s->bucket_info.placement_rule);
if (compression_type != "none") {
plugin = Compressor::create(s->cct, compression_type);
if (!plugin) {
/* No filters by default. */
DataProcessor *filter = &processor;
-#warning add storage_class compression
const auto& compression_type = store->svc.zone->get_zone_params().get_compression_type(
- binfo.placement_rule.name);
+ binfo.placement_rule);
CompressorRef plugin;
boost::optional<RGWPutObj_Compress> compressor;
if (compression_type != "none") {
return -ENOENT;
}
-bool RGWRados::get_obj_data_pool(const string& placement_rule, const rgw_obj& obj, rgw_pool *pool)
+bool RGWRados::get_obj_data_pool(const rgw_placement_rule& placement_rule, const rgw_obj& obj, rgw_pool *pool)
{
return rgw_get_obj_data_pool(svc.zone->get_zonegroup(), svc.zone->get_zone_params(), placement_rule, obj, pool);
}
boost::optional<RGWPutObj_Compress> compressor;
CompressorRef plugin;
-#warning compression type
const auto& compression_type = svc.zone->get_zone_params().get_compression_type(
- dest_bucket_info.placement_rule.name);
+ dest_bucket_info.placement_rule);
if (compression_type != "none") {
plugin = Compressor::create(cct, compression_type);
if (!plugin) {
pool_names.insert(zone.reshard_pool);
for(auto& iter : zone.placement_pools) {
pool_names.insert(iter.second.index_pool);
- for (auto& pi : iter.second.data_pools) {
- pool_names.insert(pi.second);
+ for (auto& pi : iter.second.storage_classes.get_all()) {
+ if (pi.second.data_pool) {
+ pool_names.insert(pi.second.data_pool.get());
+ }
}
pool_names.insert(iter.second.data_extra_pool);
}
for(auto& iter : placement_pools) {
iter.second.index_pool = fix_zone_pool_dup(pools, name, "." + default_bucket_index_pool_suffix,
iter.second.index_pool);
- for (auto& pi : iter.second.data_pools) {
- pi.second = fix_zone_pool_dup(pools, name, "." + default_storage_pool_suffix,
- pi.second);
+ for (auto& pi : iter.second.storage_classes.get_all()) {
+ if (pi.second.data_pool) {
+ rgw_pool& pool = pi.second.data_pool.get();
+ pool = fix_zone_pool_dup(pools, name, "." + default_storage_pool_suffix,
+ pool);
+ }
}
iter.second.data_extra_pool= fix_zone_pool_dup(pools, name, "." + default_storage_extra_pool_suffix,
iter.second.data_extra_pool);
/* a new system, let's set new placement info */
RGWZonePlacementInfo default_placement;
default_placement.index_pool = name + "." + default_bucket_index_pool_suffix;
- default_placement.data_pools[RGW_STORAGE_CLASS_STANDARD] = name + "." + default_storage_pool_suffix;
+ rgw_pool pool = name + "." + default_storage_pool_suffix;
+ default_placement.storage_classes.set_storage_class(RGW_STORAGE_CLASS_STANDARD, &pool, nullptr);
default_placement.data_extra_pool = name + "." + default_storage_extra_pool_suffix;
placement_pools["default-placement"] = default_placement;
}
return RGWSystemMetaObj::set_as_default(exclusive);
}
-const string& RGWZoneParams::get_compression_type(const string& placement_rule) const
+const string& RGWZoneParams::get_compression_type(const rgw_placement_rule& placement_rule) const
{
static const std::string NONE{"none"};
- auto p = placement_pools.find(placement_rule);
+ auto p = placement_pools.find(placement_rule.name);
if (p == placement_pools.end()) {
return NONE;
}
- const auto& type = p->second.compression_type;
+ const auto& type = p->second.get_compression_type(placement_rule.storage_class);
return !type.empty() ? type : NONE;
}
};
WRITE_CLASS_ENCODER(RGWSystemMetaObj)
+struct RGWZoneStorageClass {
+ boost::optional<rgw_pool> data_pool;
+ boost::optional<std::string> compression_type;
+
+ void encode(bufferlist& bl) const {
+ ENCODE_START(1, 1, bl);
+ encode(data_pool, bl);
+ encode(compression_type, bl);
+ ENCODE_FINISH(bl);
+ }
+
+ void decode(bufferlist::const_iterator& bl) {
+ DECODE_START(1, bl);
+ decode(data_pool, bl);
+ decode(compression_type, bl);
+ DECODE_FINISH(bl);
+ }
+
+ void dump(Formatter *f) const;
+ void decode_json(JSONObj *obj);
+};
+WRITE_CLASS_ENCODER(RGWZoneStorageClass)
+
+
+class RGWZoneStorageClasses {
+ map<string, RGWZoneStorageClass> m;
+
+ /* in memory only */
+ RGWZoneStorageClass *standard_class{&m[RGW_STORAGE_CLASS_STANDARD]};
+
+public:
+ RGWZoneStorageClasses() {}
+ RGWZoneStorageClasses(const RGWZoneStorageClasses& rhs) {
+ m = rhs.m;
+ standard_class = &m[RGW_STORAGE_CLASS_STANDARD];
+ }
+ RGWZoneStorageClasses& operator=(const RGWZoneStorageClasses& rhs) {
+ m = rhs.m;
+ standard_class = &m[RGW_STORAGE_CLASS_STANDARD];
+ return *this;
+ }
+
+ const RGWZoneStorageClass& get_standard() const {
+ return *standard_class;
+ }
+
+ bool find(const string& sc, const RGWZoneStorageClass **pstorage_class) const {
+ auto iter = m.find(sc);
+ if (iter == m.end()) {
+ return false;
+ }
+ *pstorage_class = &iter->second;
+ return true;
+ }
+
+ const map<string, RGWZoneStorageClass>& get_all() const {
+ return m;
+ }
+
+ map<string, RGWZoneStorageClass>& get_all() {
+ return m;
+ }
+
+ void set_storage_class(const string& sc, const rgw_pool *data_pool, const string *compression_type) {
+ const string *psc = ≻
+ if (sc.empty()) {
+ psc = &RGW_STORAGE_CLASS_STANDARD;
+ }
+ RGWZoneStorageClass& storage_class = m[*psc];
+ if (data_pool) {
+ storage_class.data_pool = *data_pool;
+ }
+ if (compression_type) {
+ storage_class.compression_type = *compression_type;
+ }
+ }
+
+ void encode(bufferlist& bl) const {
+ ENCODE_START(1, 1, bl);
+ encode(m, bl);
+ ENCODE_FINISH(bl);
+ }
+
+ void decode(bufferlist::const_iterator& bl) {
+ DECODE_START(1, bl);
+ decode(m, bl);
+ DECODE_FINISH(bl);
+ }
+
+ void dump(Formatter *f) const;
+ void decode_json(JSONObj *obj);
+};
+WRITE_CLASS_ENCODER(RGWZoneStorageClasses)
+
struct RGWZonePlacementInfo {
rgw_pool index_pool;
- rgw_pool standard_data_pool;
rgw_pool data_extra_pool; /* if not set we should use data_pool */
- map<string, rgw_pool> data_pools;
+ RGWZoneStorageClasses storage_classes;
RGWBucketIndexType index_type;
- std::string compression_type;
RGWZonePlacementInfo() : index_type(RGWBIType_Normal) {}
void encode(bufferlist& bl) const {
ENCODE_START(7, 1, bl);
encode(index_pool.to_str(), bl);
- encode(data_pool.to_str(), bl);
+ rgw_pool standard_data_pool = get_data_pool(RGW_STORAGE_CLASS_STANDARD);
+ encode(standard_data_pool.to_str(), bl);
encode(data_extra_pool.to_str(), bl);
encode((uint32_t)index_type, bl);
- encode(compression_type, bl);
+ string standard_compression_type = get_compression_type(RGW_STORAGE_CLASS_STANDARD);
+ encode(standard_compression_type, bl);
+ encode(storage_classes, bl);
ENCODE_FINISH(bl);
}
void decode(bufferlist::const_iterator& bl) {
- DECODE_START(6, bl);
- std::string index_pool_str;
- std::string data_pool_str;
+ DECODE_START(7, bl);
+ string index_pool_str;
+ string data_pool_str;
decode(index_pool_str, bl);
index_pool = rgw_pool(index_pool_str);
decode(data_pool_str, bl);
- data_pool = rgw_pool(data_pool_str);
+ rgw_pool standard_data_pool(data_pool_str);
if (struct_v >= 4) {
- std::string data_extra_pool_str;
+ string data_extra_pool_str;
decode(data_extra_pool_str, bl);
data_extra_pool = rgw_pool(data_extra_pool_str);
}
decode(it, bl);
index_type = (RGWBucketIndexType)it;
}
+ string standard_compression_type;
if (struct_v >= 6) {
- decode(compression_type, bl);
+ decode(standard_compression_type, bl);
+ }
+ if (struct_v >= 7) {
+ decode(storage_classes, bl);
+ } else {
+ storage_classes.set_storage_class(RGW_STORAGE_CLASS_STANDARD, &standard_data_pool,
+ (!standard_compression_type.empty() ? &standard_compression_type : nullptr));
}
DECODE_FINISH(bl);
}
const rgw_pool& get_data_extra_pool() const {
+ static rgw_pool no_pool;
if (data_extra_pool.empty()) {
- return data_pool;
+ return storage_classes.get_standard().data_pool.get_value_or(no_pool);
}
return data_extra_pool;
}
+ const rgw_pool& get_data_pool(const string& sc) const {
+ const RGWZoneStorageClass *storage_class;
+ static rgw_pool no_pool;
+
+ if (!storage_classes.find(sc, &storage_class)) {
+ return storage_classes.get_standard().data_pool.get_value_or(no_pool);
+ }
+
+ return storage_class->data_pool.get_value_or(no_pool);
+ }
+
+ const string& get_compression_type(const string& sc) const {
+ const RGWZoneStorageClass *storage_class;
+ static string no_compression;
+
+ if (!storage_classes.find(sc, &storage_class)) {
+ return no_compression;
+ }
+ return storage_class->compression_type.get_value_or(no_compression);
+ }
+
void dump(Formatter *f) const;
void decode_json(JSONObj *obj);
+
};
WRITE_CLASS_ENCODER(RGWZonePlacementInfo)
int create(bool exclusive = true) override;
int fix_pool_names();
- const std::string& get_compression_type(const std::string& placement_rule) const;
+ const string& get_compression_type(const rgw_placement_rule& placement_rule) const;
void encode(bufferlist& bl) const override {
ENCODE_START(12, 1, bl);
}
pool_name = miter->first;
- rule_info->data_pools[RGW_STORAGE_CLASS_STANDARD] = pool_name;
+ rgw_pool pool = pool_name;
+
+ rule_info->storage_classes.set_storage_class(RGW_STORAGE_CLASS_STANDARD, &pool, nullptr);
rule_info->data_extra_pool = pool_name;
rule_info->index_pool = pool_name;
rule_info->index_type = RGWBIType_Normal;