]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
rgw: enable user quota
authorYehuda Sadeh <yehuda@inktank.com>
Fri, 10 Jan 2014 23:38:37 +0000 (15:38 -0800)
committerYehuda Sadeh <yehuda@inktank.com>
Fri, 24 Jan 2014 18:28:50 +0000 (10:28 -0800)
Signed-off-by: Yehuda Sadeh <yehuda@inktank.com>
src/rgw/rgw_op.cc
src/rgw/rgw_quota.cc
src/rgw/rgw_quota.h
src/rgw/rgw_rados.cc
src/rgw/rgw_rados.h

index d07cc1bba1d61779a6f71f41b6b3fc1e9bbe4e82..0694786c3ab82291b2f209cdfa88c452b4766432 100644 (file)
@@ -1415,7 +1415,8 @@ void RGWPutObj::execute()
 
   if (!chunked_upload) { /* with chunked upload we don't know how big is the upload.
                             we also check sizes at the end anyway */
-    ret = store->check_quota(s->bucket_owner.get_id(), s->bucket, bucket_quota, s->content_length);
+    ret = store->check_quota(s->bucket_owner.get_id(), s->bucket,
+                             s->user.user_quota, bucket_quota, s->content_length);
     if (ret < 0) {
       goto done;
     }
@@ -1465,7 +1466,8 @@ void RGWPutObj::execute()
   s->obj_size = ofs;
   perfcounter->inc(l_rgw_put_b, s->obj_size);
 
-  ret = store->check_quota(s->bucket_owner.get_id(), s->bucket, bucket_quota, s->obj_size);
+  ret = store->check_quota(s->bucket_owner.get_id(), s->bucket,
+                           s->user.user_quota, bucket_quota, s->obj_size);
   if (ret < 0) {
     goto done;
   }
index 4286e8bd558f700a666c2fbacf3fb8e3f46b2d66..bf32a0f06becda9f29c79f32728f82717231310c 100644 (file)
@@ -408,44 +408,68 @@ int RGWUserStatsCache::fetch_stats_from_storage(const string& user, rgw_bucket&
 
 class RGWQuotaHandlerImpl : public RGWQuotaHandler {
   RGWRados *store;
-  RGWBucketStatsCache stats_cache;
+  RGWBucketStatsCache bucket_stats_cache;
+  RGWUserStatsCache user_stats_cache;
+
+  int check_quota(const char *entity, RGWQuotaInfo& quota, RGWStorageStats& stats,
+                  uint64_t num_objs, uint64_t size_kb) {
+    ldout(store->ctx(), 20) << entity << " quota: max_objects=" << quota.max_objects
+                            << " max_size_kb=" << quota.max_size_kb << dendl;
+
+    if (quota.max_objects >= 0 &&
+        stats.num_objects + num_objs > (uint64_t)quota.max_objects) {
+      ldout(store->ctx(), 10) << "quota exceeded: stats.num_objects=" << stats.num_objects
+                              << " " << entity << "_quota.max_objects=" << quota.max_objects << dendl;
+
+      return -ERR_QUOTA_EXCEEDED;
+    }
+    if (quota.max_size_kb >= 0 &&
+               stats.num_kb_rounded + size_kb > (uint64_t)quota.max_size_kb) {
+      ldout(store->ctx(), 10) << "quota exceeded: stats.num_kb_rounded=" << stats.num_kb_rounded << " size_kb=" << size_kb
+                              << " " << entity << "_quota.max_size_kb=" << quota.max_size_kb << dendl;
+      return -ERR_QUOTA_EXCEEDED;
+    }
+
+    return 0;
+  }
 public:
-  RGWQuotaHandlerImpl(RGWRados *_store) : store(_store), stats_cache(_store) {}
-  virtual int check_quota(const string& user, rgw_bucket& bucket, RGWQuotaInfo& bucket_quota,
+  RGWQuotaHandlerImpl(RGWRados *_store) : store(_store), bucket_stats_cache(_store), user_stats_cache(_store) {}
+  virtual int check_quota(const string& user, rgw_bucket& bucket,
+                          RGWQuotaInfo& user_quota, RGWQuotaInfo& bucket_quota,
                          uint64_t num_objs, uint64_t size) {
     uint64_t size_kb = rgw_rounded_kb(size);
     if (!bucket_quota.enabled) {
       return 0;
     }
 
-    RGWStorageStats stats;
+    RGWStorageStats bucket_stats;
 
-    int ret = stats_cache.get_stats(user, bucket, stats, bucket_quota);
+    int ret = bucket_stats_cache.get_stats(user, bucket, bucket_stats, bucket_quota);
     if (ret < 0)
       return ret;
 
-    ldout(store->ctx(), 20) << "bucket quota: max_objects=" << bucket_quota.max_objects
-                            << " max_size_kb=" << bucket_quota.max_size_kb << dendl;
+    ret = check_quota("bucket", bucket_quota, bucket_stats, num_objs, size_kb);
+    if (ret < 0)
+      return ret;
+
+    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 (bucket_quota.max_objects >= 0 &&
-        stats.num_objects + num_objs > (uint64_t)bucket_quota.max_objects) {
-      ldout(store->ctx(), 10) << "quota exceeded: stats.num_objects=" << stats.num_objects
-                              << " bucket_quota.max_objects=" << bucket_quota.max_objects << dendl;
 
-      return -ERR_QUOTA_EXCEEDED;
-    }
-    if (bucket_quota.max_size_kb >= 0 &&
-               stats.num_kb_rounded + size_kb > (uint64_t)bucket_quota.max_size_kb) {
-      ldout(store->ctx(), 10) << "quota exceeded: stats.num_kb_rounded=" << stats.num_kb_rounded << " size_kb=" << size_kb
-                              << " bucket_quota.max_size_kb=" << bucket_quota.max_size_kb << dendl;
-      return -ERR_QUOTA_EXCEEDED;
-    }
 
     return 0;
   }
 
   virtual void update_stats(const string& user, rgw_bucket& bucket, int obj_delta, uint64_t added_bytes, uint64_t removed_bytes) {
-    stats_cache.adjust_stats(user, bucket, obj_delta, added_bytes, removed_bytes);
+    bucket_stats_cache.adjust_stats(user, bucket, obj_delta, added_bytes, removed_bytes);
+    user_stats_cache.adjust_stats(user, bucket, obj_delta, added_bytes, removed_bytes);
   };
 };
 
index 4c6b4262a09edd93a237840ffe3dd23e0b913793..5595a73739a640eb3f23dc6d5b4fdf93d6618cce 100644 (file)
@@ -62,7 +62,8 @@ public:
   RGWQuotaHandler() {}
   virtual ~RGWQuotaHandler() {
   }
-  virtual int check_quota(const string& bucket_owner, rgw_bucket& bucket, RGWQuotaInfo& bucket_quota,
+  virtual int check_quota(const string& bucket_owner, rgw_bucket& bucket,
+                          RGWQuotaInfo& user_quota, RGWQuotaInfo& bucket_quota,
                          uint64_t num_objs, uint64_t size) = 0;
 
   virtual void update_stats(const string& bucket_owner, rgw_bucket& bucket, int obj_delta, uint64_t added_bytes, uint64_t removed_bytes) = 0;
index fbedc6feaede87ee2866f46699cdfa99ba1ee27e..8a4927a315c836dd24905913e0c40b66a2d83beb 100644 (file)
@@ -5803,9 +5803,10 @@ int RGWRados::cls_user_remove_bucket(rgw_obj& obj, const cls_user_bucket& bucket
   return 0;
 }
 
-int RGWRados::check_quota(const string& bucket_owner, rgw_bucket& bucket, RGWQuotaInfo& quota_info, uint64_t obj_size)
+int RGWRados::check_quota(const string& bucket_owner, rgw_bucket& bucket,
+                          RGWQuotaInfo& user_quota, RGWQuotaInfo& bucket_quota, uint64_t obj_size)
 {
-  return quota_handler->check_quota(bucket_owner, bucket, quota_info, 1, obj_size);
+  return quota_handler->check_quota(bucket_owner, bucket, user_quota, bucket_quota, 1, obj_size);
 }
 
 class IntentLogNameFilter : public RGWAccessListFilter
index f7a594c41fe1e13d248360532636804ee911a1ad..01da08181e8d6fe1378b69c9d4ee08c3cf1ada6e 100644 (file)
@@ -1447,7 +1447,8 @@ public:
   int cls_user_add_bucket(rgw_obj& obj, list<cls_user_bucket_entry>& entries);
   int cls_user_remove_bucket(rgw_obj& obj, const cls_user_bucket& bucket);
 
-  int check_quota(const string& bucket_owner, rgw_bucket& bucket, RGWQuotaInfo& quota_info, uint64_t obj_size);
+  int check_quota(const string& bucket_owner, rgw_bucket& bucket,
+                  RGWQuotaInfo& user_quota, RGWQuotaInfo& bucket_quota, uint64_t obj_size);
 
   string unique_id(uint64_t unique_num) {
     char buf[32];