From 3047b5690eebb7fcd2d7a26acd20105e016a44c4 Mon Sep 17 00:00:00 2001 From: Daniel Gryniewicz Date: Fri, 25 Sep 2015 11:02:20 -0400 Subject: [PATCH] rgw: Add default quota config Add a default quota config that is applied when no specific quota is enabled. There are both per-bucket and per-user defaults. Defaults are enabled if either max count or max size is enabled. This fixes issues 12912 and 12997. Signed-off-by: Daniel Gryniewicz --- src/common/config_opts.h | 4 ++++ src/rgw/rgw_quota.cc | 46 ++++++++++++++++++++++++++++++++++------ 2 files changed, 44 insertions(+), 6 deletions(-) diff --git a/src/common/config_opts.h b/src/common/config_opts.h index 9c1a3c2f6761c..031e13c48c932 100644 --- a/src/common/config_opts.h +++ b/src/common/config_opts.h @@ -1123,6 +1123,8 @@ OPTION(rgw_replica_log_obj_prefix, OPT_STR, "replica_log") // OPTION(rgw_bucket_quota_ttl, OPT_INT, 600) // time for cached bucket stats to be cached within rgw instance OPTION(rgw_bucket_quota_soft_threshold, OPT_DOUBLE, 0.95) // threshold from which we don't rely on cached info for quota decisions OPTION(rgw_bucket_quota_cache_size, OPT_INT, 10000) // number of entries in bucket quota cache +OPTION(rgw_bucket_default_quota_max_objects, OPT_INT, -1) // number of objects allowed +OPTION(rgw_bucket_default_quota_max_size, OPT_LONGLONG, -1) // Max size of object in kB OPTION(rgw_expose_bucket, OPT_BOOL, false) // Return the bucket name in the 'Bucket' response header @@ -1132,6 +1134,8 @@ OPTION(rgw_user_quota_bucket_sync_interval, OPT_INT, 180) // time period for acc OPTION(rgw_user_quota_sync_interval, OPT_INT, 3600 * 24) // time period for accumulating modified buckets before syncing entire user stats OPTION(rgw_user_quota_sync_idle_users, OPT_BOOL, false) // whether stats for idle users be fully synced OPTION(rgw_user_quota_sync_wait_time, OPT_INT, 3600 * 24) // min time between two full stats sync for non-idle users +OPTION(rgw_user_default_quota_max_objects, OPT_INT, -1) // number of objects allowed +OPTION(rgw_user_default_quota_max_size, OPT_LONGLONG, -1) // Max size of object in kB OPTION(rgw_multipart_min_part_size, OPT_INT, 5 * 1024 * 1024) // min size for each part (except for last one) in multipart upload OPTION(rgw_multipart_part_upload_limit, OPT_INT, 10000) // parts limit in multipart upload diff --git a/src/rgw/rgw_quota.cc b/src/rgw/rgw_quota.cc index 85536bf8bfb49..d29cdd2d60ad8 100644 --- a/src/rgw/rgw_quota.cc +++ b/src/rgw/rgw_quota.cc @@ -664,9 +664,14 @@ class RGWQuotaHandlerImpl : public RGWQuotaHandler { RGWRados *store; RGWBucketStatsCache bucket_stats_cache; RGWUserStatsCache user_stats_cache; + RGWQuotaInfo def_bucket_quota; + RGWQuotaInfo def_user_quota; int check_quota(const char *entity, RGWQuotaInfo& quota, RGWStorageStats& stats, uint64_t num_objs, uint64_t size_kb) { + if (!quota.enabled) + return 0; + ldout(store->ctx(), 20) << entity << " quota: max_objects=" << quota.max_objects << " max_size_kb=" << quota.max_size_kb << dendl; @@ -687,12 +692,29 @@ class RGWQuotaHandlerImpl : public RGWQuotaHandler { return 0; } public: - RGWQuotaHandlerImpl(RGWRados *_store, bool quota_threads) : store(_store), bucket_stats_cache(_store), user_stats_cache(_store, quota_threads) {} + RGWQuotaHandlerImpl(RGWRados *_store, bool quota_threads) : store(_store), bucket_stats_cache(_store), user_stats_cache(_store, quota_threads) { + if (store->ctx()->_conf->rgw_bucket_default_quota_max_objects >= 0) { + def_bucket_quota.max_objects = store->ctx()->_conf->rgw_bucket_default_quota_max_objects; + def_bucket_quota.enabled = true; + } + if (store->ctx()->_conf->rgw_bucket_default_quota_max_size >= 0) { + def_bucket_quota.max_size_kb = store->ctx()->_conf->rgw_bucket_default_quota_max_size; + def_bucket_quota.enabled = true; + } + if (store->ctx()->_conf->rgw_user_default_quota_max_objects >= 0) { + def_user_quota.max_objects = store->ctx()->_conf->rgw_user_default_quota_max_objects; + def_user_quota.enabled = true; + } + if (store->ctx()->_conf->rgw_user_default_quota_max_size >= 0) { + def_user_quota.max_size_kb = store->ctx()->_conf->rgw_user_default_quota_max_size; + def_user_quota.enabled = true; + } + } virtual int check_quota(const string& user, rgw_bucket& bucket, RGWQuotaInfo& user_quota, RGWQuotaInfo& bucket_quota, uint64_t num_objs, uint64_t size) { - if (!bucket_quota.enabled && !user_quota.enabled) + if (!bucket_quota.enabled && !user_quota.enabled && !def_bucket_quota.enabled && !def_user_quota.enabled) return 0; uint64_t size_kb = rgw_rounded_objsize_kb(size); @@ -715,16 +737,28 @@ public: return ret; } - if (user_quota.enabled) { + if (def_bucket_quota.enabled) { + ret = check_quota("def_bucket", def_bucket_quota, bucket_stats, num_objs, size_kb); + if (ret < 0) + return ret; + } + + if (user_quota.enabled || def_user_quota.enabled) { RGWStorageStats user_stats; ret = user_stats_cache.get_stats(user, bucket, user_stats, user_quota); if (ret < 0) return ret; - ret = check_quota("user", user_quota, user_stats, num_objs, size_kb); - if (ret < 0) - return ret; + if (user_quota.enabled) { + ret = check_quota("user", user_quota, user_stats, num_objs, size_kb); + if (ret < 0) + return ret; + } else if (def_user_quota.enabled) { + ret = check_quota("def_user", def_user_quota, user_stats, num_objs, size_kb); + if (ret < 0) + return ret; + } } return 0; -- 2.39.5