diff options
author | Yehuda Sadeh <yehuda@inktank.com> | 2013-09-27 14:51:43 -0700 |
---|---|---|
committer | Yehuda Sadeh <yehuda@inktank.com> | 2013-09-27 14:51:43 -0700 |
commit | 434ad764a1fae9715bfbec1667e73856021d24d2 (patch) | |
tree | 79b76d0e43172907391ba2c9e714644a4c160920 | |
parent | 28949d5d43beba7cef37cb2f83e3399d978061a6 (diff) | |
download | ceph-434ad764a1fae9715bfbec1667e73856021d24d2.tar.gz |
rgw: add bucket quota config to entities
Add bucket quota fields to various entities: regionmap (for global
configuration), user info, bucket info.
Signed-off-by: Yehuda Sadeh <yehuda@inktank.com>
-rw-r--r-- | src/rgw/Makefile.am | 4 | ||||
-rw-r--r-- | src/rgw/rgw_common.h | 14 | ||||
-rw-r--r-- | src/rgw/rgw_json_enc.cc | 22 | ||||
-rw-r--r-- | src/rgw/rgw_quota.cc | 20 | ||||
-rw-r--r-- | src/rgw/rgw_quota.h | 42 | ||||
-rw-r--r-- | src/rgw/rgw_rados.cc | 8 | ||||
-rw-r--r-- | src/rgw/rgw_rados.h | 2 |
7 files changed, 78 insertions, 34 deletions
diff --git a/src/rgw/Makefile.am b/src/rgw/Makefile.am index 27891efd124..b92c35e08d6 100644 --- a/src/rgw/Makefile.am +++ b/src/rgw/Makefile.am @@ -31,7 +31,8 @@ librgw_la_SOURCES = \ rgw/rgw_auth_s3.cc \ rgw/rgw_metadata.cc \ rgw/rgw_replica_log.cc \ - rgw/rgw_keystone.cc + rgw/rgw_keystone.cc \ + rgw/rgw_quota.cc librgw_la_CXXFLAGS = -Woverloaded-virtual ${AM_CXXFLAGS} noinst_LTLIBRARIES += librgw.la @@ -50,7 +51,6 @@ LIBRGW_DEPS += \ -lfcgi radosgw_SOURCES = \ - rgw/rgw_quota.cc \ rgw/rgw_resolve.cc \ rgw/rgw_rest.cc \ rgw/rgw_rest_swift.cc \ diff --git a/src/rgw/rgw_common.h b/src/rgw/rgw_common.h index e514a9b8079..689fabf4c78 100644 --- a/src/rgw/rgw_common.h +++ b/src/rgw/rgw_common.h @@ -29,6 +29,7 @@ #include "include/utime.h" #include "rgw_acl.h" #include "rgw_cors.h" +#include "rgw_quota.h" #include "cls/version/cls_version_types.h" #include "include/rados/librados.hpp" @@ -423,11 +424,12 @@ struct RGWUserInfo __u8 system; string default_placement; list<string> placement_tags; + RGWQuotaInfo bucket_quota; RGWUserInfo() : auid(0), suspended(0), max_buckets(RGW_DEFAULT_MAX_BUCKETS), op_mask(RGW_OP_TYPE_ALL), system(0) {} void encode(bufferlist& bl) const { - ENCODE_START(13, 9, bl); + ENCODE_START(14, 9, bl); ::encode(auid, bl); string access_key; string secret_key; @@ -462,6 +464,7 @@ struct RGWUserInfo ::encode(system, bl); ::encode(default_placement, bl); ::encode(placement_tags, bl); + ::encode(bucket_quota, bl); ENCODE_FINISH(bl); } void decode(bufferlist::iterator& bl) { @@ -518,6 +521,9 @@ struct RGWUserInfo ::decode(default_placement, bl); ::decode(placement_tags, bl); /* tags of allowed placement rules */ } + if (struct_v >= 14) { + ::decode(bucket_quota, bl); + } DECODE_FINISH(bl); } void dump(Formatter *f) const; @@ -665,9 +671,10 @@ struct RGWBucketInfo bool has_instance_obj; RGWObjVersionTracker objv_tracker; /* we don't need to serialize this, for runtime tracking */ obj_version ep_objv; /* entry point object version, for runtime tracking only */ + RGWQuotaInfo quota; void encode(bufferlist& bl) const { - ENCODE_START(8, 4, bl); + ENCODE_START(9, 4, bl); ::encode(bucket, bl); ::encode(owner, bl); ::encode(flags, bl); @@ -676,6 +683,7 @@ struct RGWBucketInfo ::encode(ct, bl); ::encode(placement_rule, bl); ::encode(has_instance_obj, bl); + ::encode(quota, bl); ENCODE_FINISH(bl); } void decode(bufferlist::iterator& bl) { @@ -696,6 +704,8 @@ struct RGWBucketInfo ::decode(placement_rule, bl); if (struct_v >= 8) ::decode(has_instance_obj, bl); + if (struct_v >= 9) + ::decode(quota, bl); DECODE_FINISH(bl); } void dump(Formatter *f) const; diff --git a/src/rgw/rgw_json_enc.cc b/src/rgw/rgw_json_enc.cc index 189e9ae961e..596c31cf8b3 100644 --- a/src/rgw/rgw_json_enc.cc +++ b/src/rgw/rgw_json_enc.cc @@ -396,6 +396,7 @@ void RGWUserInfo::dump(Formatter *f) const } encode_json("default_placement", default_placement, f); encode_json("placement_tags", placement_tags, f); + encode_json("bucket_quota", bucket_quota, f); } @@ -446,6 +447,23 @@ void RGWUserInfo::decode_json(JSONObj *obj) system = (__u8)sys; JSONDecoder::decode_json("default_placement", default_placement, obj); JSONDecoder::decode_json("placement_tags", placement_tags, obj); + JSONDecoder::decode_json("bucket_quota", bucket_quota, obj); +} + +void RGWQuotaInfo::dump(Formatter *f) const +{ + f->dump_bool("enabled", enabled); + if (enabled) { + f->dump_int("max_size_kb", max_size_kb); + f->dump_int("max_objects", max_objects); + } +} + +void RGWQuotaInfo::decode_json(JSONObj *obj) +{ + JSONDecoder::decode_json("max_size_kb", max_size_kb, obj); + JSONDecoder::decode_json("max_objects", max_objects, obj); + JSONDecoder::decode_json("enabled", enabled, obj); } void rgw_bucket::dump(Formatter *f) const @@ -497,6 +515,7 @@ void RGWBucketInfo::dump(Formatter *f) const encode_json("region", region, f); encode_json("placement_rule", placement_rule, f); encode_json("has_instance_obj", has_instance_obj, f); + encode_json("quota", quota, f); } void RGWBucketInfo::decode_json(JSONObj *obj) { @@ -507,6 +526,7 @@ void RGWBucketInfo::decode_json(JSONObj *obj) { JSONDecoder::decode_json("region", region, obj); JSONDecoder::decode_json("placement_rule", placement_rule, obj); JSONDecoder::decode_json("has_instance_obj", has_instance_obj, obj); + JSONDecoder::decode_json("quota", quota, obj); } void RGWObjEnt::dump(Formatter *f) const @@ -673,12 +693,14 @@ void RGWRegionMap::dump(Formatter *f) const { encode_json("regions", regions, f); encode_json("master_region", master_region, f); + encode_json("bucket_quota", bucket_quota, f); } void RGWRegionMap::decode_json(JSONObj *obj) { JSONDecoder::decode_json("regions", regions, obj); JSONDecoder::decode_json("master_region", master_region, obj); + JSONDecoder::decode_json("bucket_quota", bucket_quota, obj); } void RGWMetadataLogInfo::dump(Formatter *f) const diff --git a/src/rgw/rgw_quota.cc b/src/rgw/rgw_quota.cc index 18f9d5efd3d..8bbe905c6d0 100644 --- a/src/rgw/rgw_quota.cc +++ b/src/rgw/rgw_quota.cc @@ -9,6 +9,26 @@ #define dout_subsys ceph_subsys_rgw +struct RGWQuotaBucketStats { + RGWBucketStats stats; + utime_t expiration; +}; + +class RGWBucketStatsCache { + RGWRados *store; + lru_map<rgw_bucket, RGWQuotaBucketStats> stats_map; + + int fetch_bucket_totals(rgw_bucket& bucket, RGWBucketStats& stats); + +public: +#warning FIXME configurable stats_map size + RGWBucketStatsCache(RGWRados *_store) : store(_store), stats_map(10000) {} + + int get_bucket_stats(rgw_bucket& bucket, RGWBucketStats& stats); + void adjust_bucket_stats(rgw_bucket& bucket, int objs_delta, uint64_t added_bytes, uint64_t removed_bytes); +}; + + int RGWBucketStatsCache::fetch_bucket_totals(rgw_bucket& bucket, RGWBucketStats& stats) { RGWBucketInfo bucket_info; diff --git a/src/rgw/rgw_quota.h b/src/rgw/rgw_quota.h index 66e1d832075..939490f7505 100644 --- a/src/rgw/rgw_quota.h +++ b/src/rgw/rgw_quota.h @@ -6,50 +6,36 @@ #include "common/lru_map.h" class RGWRados; - -struct RGWQuotaBucketStats { - RGWBucketStats stats; - utime_t expiration; -}; +class JSONObj; struct RGWQuotaInfo { - uint64_t max_kb; - uint64_t max_objs; - bool is_set; + uint64_t max_size_kb; + uint64_t max_objects; + bool enabled; - RGWQuotaInfo() : max_kb(0), max_objs(0), is_set(false) {} + RGWQuotaInfo() : max_size_kb(0), max_objects(0), enabled(false) {} void encode(bufferlist& bl) const { ENCODE_START(1, 1, bl); - ::encode(max_kb, bl); - ::encode(max_objs, bl); - ::encode(is_set, bl); + ::encode(max_size_kb, bl); + ::encode(max_objects, bl); + ::encode(enabled, bl); ENCODE_FINISH(bl); } void decode(bufferlist::iterator& bl) { DECODE_START(1, bl); - ::decode(max_kb, bl); - ::decode(max_objs, bl); - ::decode(is_set, bl); + ::decode(max_size_kb, bl); + ::decode(max_objects, bl); + ::decode(enabled, bl); DECODE_FINISH(bl); } -}; -WRITE_CLASS_ENCODER(RGWQuotaInfo) -class RGWBucketStatsCache { - RGWRados *store; - lru_map<rgw_bucket, RGWQuotaBucketStats> stats_map; + void dump(Formatter *f) const; - int fetch_bucket_totals(rgw_bucket& bucket, RGWBucketStats& stats); + void decode_json(JSONObj *obj); -public: -#warning FIXME configurable stats_map size - RGWBucketStatsCache(RGWRados *_store) : store(_store), stats_map(10000) {} - - int get_bucket_stats(rgw_bucket& bucket, RGWBucketStats& stats); - void adjust_bucket_stats(rgw_bucket& bucket, int objs_delta, uint64_t added_bytes, uint64_t removed_bytes); }; - +WRITE_CLASS_ENCODER(RGWQuotaInfo) #endif diff --git a/src/rgw/rgw_rados.cc b/src/rgw/rgw_rados.cc index 3db7c719a82..9ffb7b56264 100644 --- a/src/rgw/rgw_rados.cc +++ b/src/rgw/rgw_rados.cc @@ -357,16 +357,20 @@ int RGWZoneParams::store_info(CephContext *cct, RGWRados *store, RGWRegion& regi } void RGWRegionMap::encode(bufferlist& bl) const { - ENCODE_START(1, 1, bl); + ENCODE_START(2, 1, bl); ::encode(regions, bl); ::encode(master_region, bl); + ::encode(bucket_quota, bl); ENCODE_FINISH(bl); } void RGWRegionMap::decode(bufferlist::iterator& bl) { - DECODE_START(1, bl); + DECODE_START(2, bl); ::decode(regions, bl); ::decode(master_region, bl); + + if (struct_v >= 2) + ::decode(bucket_quota, bl); DECODE_FINISH(bl); regions_by_api.clear(); diff --git a/src/rgw/rgw_rados.h b/src/rgw/rgw_rados.h index 65765c414aa..0da686ced83 100644 --- a/src/rgw/rgw_rados.h +++ b/src/rgw/rgw_rados.h @@ -636,6 +636,8 @@ struct RGWRegionMap { string master_region; + RGWQuotaInfo bucket_quota; + RGWRegionMap() : lock("RGWRegionMap") {} void encode(bufferlist& bl) const; |