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(mutex_perf_counter, OPT_BOOL, false) // enable/disable mutex perf counter
async_refcount->put_wait(); /* wait for all pending async requests to complete */
}
- int get_bucket_stats(rgw_bucket& bucket, RGWBucketStats& stats);
+ int get_bucket_stats(rgw_bucket& bucket, RGWBucketStats& stats, RGWQuotaInfo& quota);
void adjust_bucket_stats(rgw_bucket& bucket, int objs_delta, uint64_t added_bytes, uint64_t removed_bytes);
+ bool can_use_cached_stats(RGWQuotaInfo& quota, RGWBucketStats& stats);
+
void set_stats(rgw_bucket& bucket, RGWQuotaBucketStats& qs, RGWBucketStats& stats);
int async_refresh(rgw_bucket& bucket, RGWQuotaBucketStats& qs);
void async_refresh_response(rgw_bucket& bucket, RGWBucketStats& stats);
};
+bool RGWBucketStatsCache::can_use_cached_stats(RGWQuotaInfo& quota, RGWBucketStats& cached_stats)
+{
+ if (quota.max_size_kb >= 0) {
+ if (quota.max_size_soft_threshold < 0) {
+ quota.max_size_soft_threshold = quota.max_size_kb * store->ctx()->_conf->rgw_bucket_quota_soft_threshold;
+ }
+
+ if (cached_stats.num_kb_rounded >= (uint64_t)quota.max_size_soft_threshold) {
+ ldout(store->ctx(), 20) << "quota: can't use cached stats, exceeded soft threshold (size): "
+ << cached_stats.num_kb_rounded << " >= " << quota.max_size_soft_threshold << dendl;
+ return false;
+ }
+ }
+
+ if (quota.max_objects >= 0) {
+ if (quota.max_objs_soft_threshold < 0) {
+ quota.max_objs_soft_threshold = quota.max_objects * store->ctx()->_conf->rgw_bucket_quota_soft_threshold;
+ }
+
+ if (cached_stats.num_objects >= (uint64_t)quota.max_objs_soft_threshold) {
+ ldout(store->ctx(), 20) << "quota: can't use cached stats, exceeded soft threshold (num objs): "
+ << cached_stats.num_objects << " >= " << quota.max_objs_soft_threshold << dendl;
+ return false;
+ }
+ }
+
+ return true;
+}
+
int RGWBucketStatsCache::fetch_bucket_totals(rgw_bucket& bucket, RGWBucketStats& stats)
{
RGWBucketInfo bucket_info;
stats_map.add(bucket, qs);
}
-int RGWBucketStatsCache::get_bucket_stats(rgw_bucket& bucket, RGWBucketStats& stats) {
+int RGWBucketStatsCache::get_bucket_stats(rgw_bucket& bucket, RGWBucketStats& stats, RGWQuotaInfo& quota) {
RGWQuotaBucketStats qs;
utime_t now = ceph_clock_now(store->ctx());
if (stats_map.find(bucket, qs)) {
/* continue processing, might be a transient error, async refresh is just optimization */
}
}
- if (qs.expiration > ceph_clock_now(store->ctx())) {
+
+ if (can_use_cached_stats(quota, qs.stats) && qs.expiration > ceph_clock_now(store->ctx())) {
stats = qs.stats;
return 0;
}
RGWBucketStats stats;
- int ret = stats_cache.get_bucket_stats(bucket, stats);
+ int ret = stats_cache.get_bucket_stats(bucket, stats, bucket_quota);
if (ret < 0)
return ret;