]> git.apps.os.sepia.ceph.com Git - ceph-ci.git/commitdiff
rgw: move a lot of cls_user utility methods into svc_user
authorYehuda Sadeh <yehuda@redhat.com>
Thu, 30 May 2019 22:45:27 +0000 (15:45 -0700)
committerCasey Bodley <cbodley@redhat.com>
Mon, 29 Jul 2019 19:20:47 +0000 (15:20 -0400)
Signed-off-by: Yehuda Sadeh <yehuda@redhat.com>
17 files changed:
src/rgw/rgw_admin.cc
src/rgw/rgw_bucket.cc
src/rgw/rgw_bucket.h
src/rgw/rgw_rados.cc
src/rgw/rgw_rados.h
src/rgw/rgw_service.cc
src/rgw/rgw_service.h
src/rgw/rgw_user.cc
src/rgw/rgw_user.h
src/rgw/services/svc_bi.h
src/rgw/services/svc_bi_rados.cc
src/rgw/services/svc_bi_rados.h
src/rgw/services/svc_bucket.cc
src/rgw/services/svc_bucket.h
src/rgw/services/svc_user.h
src/rgw/services/svc_user_rados.cc
src/rgw/services/svc_user_rados.h

index 11d6c26cc610eea65461f102cd60728953f5714c..3261b262bc4346a8be62bafba3f7058b7b18a282 100644 (file)
@@ -6765,7 +6765,13 @@ next:
 
     if (sync_stats) {
       if (!bucket_name.empty()) {
-        int ret = rgw_bucket_sync_user_stats(store, tenant, bucket_name);
+        RGWBucketInfo bucket_info;
+        int ret = init_bucket(tenant, bucket_name, bucket_id, bucket_info, bucket);
+        if (ret < 0) {
+          cerr << "ERROR: could not init bucket: " << cpp_strerror(-ret) << std::endl;
+          return -ret;
+        }
+        int ret = store->ctl.bucket->sync_user_stats(user_id, bucket_info);
         if (ret < 0) {
           cerr << "ERROR: could not sync bucket stats: " << cpp_strerror(-ret) << std::endl;
           return -ret;
index 2126588f69dc97ed80f5748b2eddbe757d357308..02c4754bd5c1d8376c68e7d231913b7ad5d6efdb 100644 (file)
@@ -135,34 +135,6 @@ int rgw_read_user_buckets(RGWRados * store,
                                        is_truncated, default_amount);
 }
 
-int rgw_bucket_sync_user_stats(RGWRados *store, const rgw_user& user_id, const RGWBucketInfo& bucket_info)
-{
-  string buckets_obj_id;
-  rgw_get_buckets_obj(user_id, buckets_obj_id);
-  rgw_raw_obj obj(store->svc.zone->get_zone_params().user_uid_pool, buckets_obj_id);
-
-  return store->cls_user_sync_bucket_stats(obj, bucket_info);
-}
-
-int rgw_bucket_sync_user_stats(RGWRados *store, const string& tenant_name, const string& bucket_name)
-{
-  RGWBucketInfo bucket_info;
-  RGWSysObjectCtx obj_ctx = store->svc.sysobj->init_obj_ctx();
-  int ret = store->get_bucket_info(obj_ctx, tenant_name, bucket_name, bucket_info, NULL, null_yield);
-  if (ret < 0) {
-    ldout(store->ctx(), 0) << "ERROR: could not fetch bucket info: ret=" << ret << dendl;
-    return ret;
-  }
-
-  ret = rgw_bucket_sync_user_stats(store, bucket_info.owner, bucket_info);
-  if (ret < 0) {
-    ldout(store->ctx(), 0) << "ERROR: could not sync user stats for bucket " << bucket_name << ": ret=" << ret << dendl;
-    return ret;
-  }
-
-  return 0;
-}
-
 int rgw_bucket_parse_bucket_instance(const string& bucket_instance, string *target_bucket_instance, int *shard_id)
 {
   ssize_t pos = bucket_instance.rfind(':');
@@ -383,7 +355,7 @@ int rgw_remove_bucket(RGWRados *store, rgw_bucket& bucket, bool delete_children,
     return ret;
   }
 
-  ret = rgw_bucket_sync_user_stats(store, info.owner, info);
+  ret = store->ctl.bucket->sync_user_stats(info.owner, info);
   if ( ret < 0) {
      dout(1) << "WARNING: failed sync user stats before bucket delete. ret=" <<  ret << dendl;
   }
@@ -548,7 +520,7 @@ int rgw_remove_bucket_bypass_gc(RGWRados *store, rgw_bucket& bucket,
     return ret;
   }
 
-  ret = rgw_bucket_sync_user_stats(store, info.owner, info);
+  ret = store->ctl.bucket->sync_user_stats(info.owner, info);
   if (ret < 0) {
      dout(1) << "WARNING: failed sync user stats before bucket delete. ret=" <<  ret << dendl;
   }
@@ -2716,13 +2688,16 @@ public:
   struct Svc {
     RGWSI_Zone *zone{nullptr};
     RGWSI_Bucket *bucket{nullptr};
+    RGWSI_BucketIndex *bi{nullptr};
   } svc;
 
   RGWBucketInstanceMetadataHandler(RGWSI_Zone *zone_svc,
-                                   RGWSI_Bucket *bucket_svc) : RGWMetadataHandler_GenericMetaBE(bucket_svc->ctx(),
-                                                                                                bucket_svc->get_bi_be_handler()) {
+                                   RGWSI_Bucket *bucket_svc,
+                                   RGWSI_BucketIndex *bi_svc) : RGWMetadataHandler_GenericMetaBE(bucket_svc->ctx(),
+                                                                                                 bucket_svc->get_bi_be_handler()) {
     svc.zone = zone_svc;
     svc.bucket = bucket_svc;
+    svc.bi = bi_svc;
   }
 
   string get_type() override { return "bucket.instance"; }
@@ -2885,7 +2860,7 @@ int RGWMetadataHandlerPut_BucketInstance::put_post()
 
   objv_tracker = bci.info.objv_tracker;
 
-  int ret = store->init_bucket_index(bci.info, bci.info.num_shards);
+  int ret = handler->svc.bi->init_index(bci.info);
   if (ret < 0)
     return ret;
 
@@ -2895,7 +2870,8 @@ int RGWMetadataHandlerPut_BucketInstance::put_post()
 class RGWArchiveBucketInstanceMetadataHandler : public RGWBucketInstanceMetadataHandler {
 public:
   RGWArchiveBucketInstanceMetadataHandler(RGWSI_Zone *zone_svc,
-                                          RGWSI_Bucket *bucket_svc) : RGWBucketInstanceMetadataHandler(zone_svc, bucket_svc) {}
+                                          RGWSI_Bucket *bucket_svc,
+                                          RGWSI_BucketIndex *bi_svc) : RGWBucketInstanceMetadataHandler(zone_svc, bucket_svc, bi_svc) {}
 
   int do_remove(RGWSI_MetaBackend_Handler::Op *op, string& entry, RGWObjVersionTracker& objv_tracker) override {
     ldout(cct, 0) << "SKIP: bucket instance removal is not allowed on archive zone: bucket.instance:" << entry << dendl;
@@ -2905,6 +2881,7 @@ public:
 
 RGWBucketCtl::RGWBucketCtl(RGWSI_Zone *zone_svc,
                            RGWSI_Bucket *bucket_svc,
+                           RGWSI_BucketIndex *bi_svc,
                            RGWBucketMetadataHandler *_bm_handler,
                            RGWBucketInstanceMetadataHandler *_bmi_handler) : cct(zone_svc->ctx()),
                                                                              bm_handler(_bm_handler),
@@ -2913,6 +2890,7 @@ RGWBucketCtl::RGWBucketCtl(RGWSI_Zone *zone_svc,
 {
   svc.zone = zone_svc;
   svc.bucket = bucket_svc;
+  svc.bi = bi_svc;
   bucket_be_handler = bm_handler->get_be_handler();
   bi_be_handler = bmi_handler->get_be_handler();
 }
@@ -3202,21 +3180,44 @@ int RGWBucketCtl::do_unlink_bucket(RGWSI_MetaBackend_Handler::Op *op,
   return svc.bucket->store_bucket_entrypoint_info(op->ctx(), meta_key, ep, false, real_time(), &attrs, &ot);
 }
 
-int RGWBucketCtl::read_buckets_stats(map<string, RGWBucketEnt>& m)
+int RGWBucketCtl::read_bucket_stats(const rgw_bucket& bucket,
+                                    RGWBucketEnt *result,
+                                    optional_yield y)
+{
+  return bi_be_handler->call([&](RGWSI_MetaBackend_Handler::Op *op) {
+    return svc.bucket->read_bucket_stats(op->ctx(), bucket, result, y);
+  });
+}
+
+int RGWBucketCtl::read_buckets_stats(map<string, RGWBucketEnt>& m,
+                                     optional_yield y)
 {
   return bi_be_handler->call([&](RGWSI_MetaBackend_Handler::Op *op) {
-    return svc.bucket->read_buckets_stats(op->ctx(), m);
+    return svc.bucket->read_buckets_stats(op->ctx(), m, y);
   });
 }
 
+int RGWBucketCtl::sync_user_stats(const rgw_user& user_id, const RGWBucketInfo& bucket_info)
+{
+  RGWBucketEnt ent;
+  int r = svc.bi->read_stats(bucket_info, &ent);
+  if (r < 0) {
+    ldout(cct, 20) << __func__ << "(): failed to read bucket stats (r=" << r << ")" << dendl;
+    return r;
+  }
+
+  return ctl.user->flush_bucket_stats(user_id, ent);
+}
+
 RGWMetadataHandler *RGWBucketMetaHandlerAllocator::alloc(RGWSI_Bucket *bucket_svc,
                                                          RGWBucketCtl *bucket_ctl) {
   return new RGWBucketMetadataHandler(bucket_svc, bucket_ctl);
 }
 
 RGWMetadataHandler *RGWBucketInstanceMetaHandlerAllocator::alloc(RGWSI_Zone *zone_svc,
-                                                                 RGWSI_Bucket *bucket_svc) {
-  return new RGWBucketInstanceMetadataHandler(zone_svc, bucket_svc);
+                                                                 RGWSI_Bucket *bucket_svc,
+                                                                 RGWSI_BucketIndex *bi_svc) {
+  return new RGWBucketInstanceMetadataHandler(zone_svc, bucket_svc, bi_svc);
 }
 
 RGWMetadataHandler *RGWArchiveBucketMetaHandlerAllocator::alloc(RGWSI_Bucket *bucket_svc,
@@ -3225,7 +3226,8 @@ RGWMetadataHandler *RGWArchiveBucketMetaHandlerAllocator::alloc(RGWSI_Bucket *bu
 }
 
 RGWMetadataHandler *RGWArchiveBucketInstanceMetaHandlerAllocator::alloc(RGWSI_Zone *zone_svc,
-                                                                        RGWSI_Bucket *bucket_svc) {
-  return new RGWArchiveBucketInstanceMetadataHandler(zone_svc, bucket_svc);
+                                                                        RGWSI_Bucket *bucket_svc,
+                                                                        RGWSI_BucketIndex *bi_svc) {
+  return new RGWArchiveBucketInstanceMetadataHandler(zone_svc, bucket_svc, bi_svc);
 }
 
index 75d014c2651384d53370bd943b2a07fc5005577b..718414c237eb82dcf379523a84e6fc5ad916a253 100644 (file)
@@ -35,9 +35,6 @@ extern int rgw_bucket_parse_bucket_key(CephContext *cct, const string& key,
 extern void rgw_bucket_instance_key_to_oid(string& key);
 extern void rgw_bucket_instance_oid_to_key(string& oid);
 
-extern int rgw_bucket_sync_user_stats(RGWRados *store, const rgw_user& user_id, const RGWBucketInfo& bucket_info);
-extern int rgw_bucket_sync_user_stats(RGWRados *store, const string& tenant_name, const string& bucket_name);
-
 extern std::string rgw_make_bucket_entry_name(const std::string& tenant_name,
                                               const std::string& bucket_name);
 static inline void rgw_make_bucket_entry_name(const string& tenant_name,
@@ -186,7 +183,8 @@ public:
 class RGWBucketInstanceMetaHandlerAllocator {
 public:
   static RGWMetadataHandler *alloc(RGWSI_Zone *zone_svc,
-                                   RGWSI_Bucket *bucket_svc);
+                                   RGWSI_Bucket *bucket_svc,
+                                   RGWSI_BucketIndex *bi_svc);
 };
 
 class RGWArchiveBucketMetaHandlerAllocator {
@@ -198,7 +196,8 @@ public:
 class RGWArchiveBucketInstanceMetaHandlerAllocator {
 public:
   static RGWMetadataHandler *alloc(RGWSI_Zone *zone_svc,
-                                   RGWSI_Bucket *bucket_svc);
+                                   RGWSI_Bucket *bucket_svc,
+                                   RGWSI_BucketIndex *bi_svc);
 };
 
 extern void rgw_bucket_init(RGWMetadataManager *mm);
@@ -583,6 +582,7 @@ class RGWBucketCtl
   struct Svc {
     RGWSI_Zone *zone{nullptr};
     RGWSI_Bucket *bucket{nullptr};
+    RGWSI_BucketIndex *bi{nullptr};
   } svc;
 
   struct Ctl {
@@ -598,6 +598,7 @@ class RGWBucketCtl
 public:
   RGWBucketCtl(RGWSI_Zone *zone_svc,
                RGWSI_Bucket *bucket_svc,
+               RGWSI_BucketIndex *bi_svc,
                RGWBucketMetadataHandler *_bm_handler,
                RGWBucketInstanceMetadataHandler *_bmi_handler);
 
@@ -782,7 +783,15 @@ public:
                     const rgw_bucket& bucket,
                     bool update_entrypoint = true);
 
-  int read_buckets_stats(map<string, RGWBucketEnt>& m);
+  int read_buckets_stats(map<string, RGWBucketEnt>& m,
+                         optional_yield y);
+
+  int read_bucket_stats(const rgw_bucket& bucket,
+                        RGWBucketEnt *result,
+                        optional_yield y);
+
+  /* quota related */
+  int sync_user_stats(const rgw_user& user_id, const RGWBucketInfo& bucket_info);
 
 private:
   int convert_old_bucket_info(RGWSI_MetaBackend_Handler::Op *op,
@@ -803,6 +812,7 @@ private:
                        const rgw_user& user_id,
                        const rgw_bucket& bucket,
                        bool update_entrypoint);
+
 };
 
 
index 11d086b2ba424ce67f64d44dd33331e4e7f3a17a..502adfa1d7f15f36d11c93a53a707cf363129766 100644 (file)
@@ -8984,119 +8984,6 @@ int RGWRados::cls_user_get_header_async(const string& user_id, RGWGetUserHeader_
   return 0;
 }
 
-int RGWRados::cls_user_sync_bucket_stats(rgw_raw_obj& user_obj,
-                                        const RGWBucketInfo& bucket_info)
-{
-  vector<rgw_bucket_dir_header> headers;
-  int r = cls_bucket_head(bucket_info, RGW_NO_SHARD, headers);
-  if (r < 0) {
-    ldout(cct, 20) << "cls_bucket_header() returned " << r << dendl;
-    return r;
-  }
-
-  cls_user_bucket_entry entry;
-
-  bucket_info.bucket.convert(&entry.bucket);
-
-  for (const auto& hiter : headers) {
-    for (const auto& iter : hiter.stats) {
-      if (RGWObjCategory::Main == iter.first ||
-         RGWObjCategory::MultiMeta == iter.first) {
-       const struct rgw_bucket_category_stats& header_stats = iter.second;
-       entry.size += header_stats.total_size;
-       entry.size_rounded += header_stats.total_size_rounded;
-       entry.count += header_stats.num_entries;
-      }
-    }
-  }
-
-  list<cls_user_bucket_entry> entries;
-  entries.push_back(entry);
-
-  r = cls_user_update_buckets(user_obj, entries, false);
-  if (r < 0) {
-    ldout(cct, 20) << "cls_user_update_buckets() returned " << r << dendl;
-    return r;
-  }
-
-  return 0;
-}
-
-int RGWRados::cls_user_get_bucket_stats(const rgw_bucket& bucket, cls_user_bucket_entry& entry)
-{
-  vector<rgw_bucket_dir_header> headers;
-  RGWBucketInfo bucket_info;
-  auto obj_ctx = svc.sysobj->init_obj_ctx();
-  int ret = get_bucket_instance_info(obj_ctx, bucket, bucket_info, NULL, NULL, null_yield);
-  if (ret < 0) {
-    return ret;
-  }
-
-  ret = cls_bucket_head(bucket_info, RGW_NO_SHARD, headers);
-  if (ret < 0) {
-    ldout(cct, 20) << "cls_bucket_header() returned " << ret << dendl;
-    return ret;
-  }
-
-  bucket.convert(&entry.bucket);
-
-  for (const auto& hiter : headers) {
-    for (const auto& iter : hiter.stats) {
-      const struct rgw_bucket_category_stats& header_stats = iter.second;
-      entry.size += header_stats.total_size;
-      entry.size_rounded += header_stats.total_size_rounded;
-      entry.count += header_stats.num_entries;
-    }
-  }
-
-  return 0;
-}
-
-int RGWRados::cls_user_list_buckets(rgw_raw_obj& obj,
-                                    const string& in_marker,
-                                    const string& end_marker,
-                                    const int max_entries,
-                                    list<cls_user_bucket_entry>& entries,
-                                    string * const out_marker,
-                                    bool * const truncated)
-{
-  rgw_rados_ref ref;
-  int r = get_raw_obj_ref(obj, &ref);
-  if (r < 0) {
-    return r;
-  }
-
-  librados::ObjectReadOperation op;
-  int rc;
-
-  cls_user_bucket_list(op, in_marker, end_marker, max_entries, entries, out_marker, truncated, &rc);
-  bufferlist ibl;
-  r = ref.ioctx.operate(ref.obj.oid, &op, &ibl);
-  if (r < 0)
-    return r;
-  if (rc < 0)
-    return rc;
-
-  return 0;
-}
-
-int RGWRados::cls_user_update_buckets(rgw_raw_obj& obj, list<cls_user_bucket_entry>& entries, bool add)
-{
-  rgw_rados_ref ref;
-  int r = get_raw_obj_ref(obj, &ref);
-  if (r < 0) {
-    return r;
-  }
-
-  librados::ObjectWriteOperation op;
-  cls_user_set_buckets(op, entries, add);
-  r = ref.ioctx.operate(ref.obj.oid, &op);
-  if (r < 0)
-    return r;
-
-  return 0;
-}
-
 int RGWRados::complete_sync_user_stats(const rgw_user& user_id)
 {
   string buckets_obj_id;
@@ -9122,23 +9009,6 @@ int RGWRados::cls_user_complete_stats_sync(rgw_raw_obj& obj)
   return 0;
 }
 
-int RGWRados::cls_user_remove_bucket(rgw_raw_obj& obj, const cls_user_bucket& bucket)
-{
-  rgw_rados_ref ref;
-  int r = get_system_obj_ref(obj, &ref);
-  if (r < 0) {
-    return r;
-  }
-
-  librados::ObjectWriteOperation op;
-  ::cls_user_remove_bucket(op, bucket);
-  r = ref.ioctx.operate(ref.obj.oid, &op);
-  if (r < 0)
-    return r;
-
-  return 0;
-}
-
 int RGWRados::check_bucket_shards(const RGWBucketInfo& bucket_info, const rgw_bucket& bucket,
                                  RGWQuotaInfo& bucket_quota)
 {
index dcd4e84f8b89f0f1260039d3b2e33520941d517b..bc05720013ca89fd353e81647e0f9f218fac0c65 100644 (file)
@@ -27,6 +27,7 @@
 #include "rgw_service.h"
 
 #include "services/svc_rados.h"
+#include "services/svc_bi_rados.h"
 
 class RGWWatcher;
 class SafeTimer;
@@ -573,7 +574,7 @@ public:
   int get_max_chunk_size(const rgw_placement_rule& placement_rule, const rgw_obj& obj, uint64_t *max_chunk_size, uint64_t *palignment = nullptr);
 
   uint32_t get_max_bucket_shards() {
-    return rgw_shards_max();
+    return RGWSI_BucketIndex_RADOS::shards_max();
   }
 
 
@@ -1448,19 +1449,8 @@ public:
   int cls_user_get_header(const string& user_id, cls_user_header *header);
   int cls_user_reset_stats(const string& user_id);
   int cls_user_get_header_async(const string& user_id, RGWGetUserHeader_CB *ctx);
-  int cls_user_sync_bucket_stats(rgw_raw_obj& user_obj, const RGWBucketInfo& bucket_info);
-  int cls_user_list_buckets(rgw_raw_obj& obj,
-                            const string& in_marker,
-                            const string& end_marker,
-                            int max_entries,
-                            list<cls_user_bucket_entry>& entries,
-                            string *out_marker,
-                            bool *truncated);
-  int cls_user_update_buckets(rgw_raw_obj& obj, list<cls_user_bucket_entry>& entries, bool add);
   int cls_user_complete_stats_sync(rgw_raw_obj& obj);
   int complete_sync_user_stats(const rgw_user& user_id);
-  int cls_user_remove_bucket(rgw_raw_obj& obj, const cls_user_bucket& bucket);
-  int cls_user_get_bucket_stats(const rgw_bucket& bucket, cls_user_bucket_entry& entry);
 
   int check_quota(const rgw_user& bucket_owner, rgw_bucket& bucket,
                   RGWQuotaInfo& user_quota, RGWQuotaInfo& bucket_quota, uint64_t obj_size, bool check_size_only = false);
index b6ceb0ee762498461bd2cb8750a0e3ba24df3678..f7f7886d0e8e5fd5563ea4f5dffe1f5269353c98 100644 (file)
@@ -4,6 +4,7 @@
 #include "rgw_service.h"
 
 #include "services/svc_finisher.h"
+#include "services/svc_bi_rados.h"
 #include "services/svc_bucket.h"
 #include "services/svc_cls.h"
 #include "services/svc_mdlog.h"
@@ -44,6 +45,7 @@ int RGWServices_Def::init(CephContext *cct,
 {
   finisher = std::make_unique<RGWSI_Finisher>(cct);
   bucket = std::make_unique<RGWSI_Bucket>(cct);
+  bi_rados = std::make_unique<RGWSI_BucketIndex_RADOS>(cct);
   cls = std::make_unique<RGWSI_Cls>(cct);
   mdlog = std::make_unique<RGWSI_MDLog>(cct);
   meta = std::make_unique<RGWSI_Meta>(cct);
@@ -66,7 +68,9 @@ int RGWServices_Def::init(CephContext *cct,
   vector<RGWSI_MetaBackend *> meta_bes{meta_be_sobj.get(), meta_be_otp.get()};
 
   finisher->init();
-  bucket->init(zone.get(), sysobj.get(), sysobj_cache.get(), meta.get(), sync_modules.get());
+  bi_rados->init(zone.get(), rados.get());
+  bucket->init(zone.get(), sysobj.get(), sysobj_cache.get(),
+               bi_rados.get(), meta.get(), sync_modules.get());
   cls->init(zone.get(), rados.get());
   mdlog->init(zone.get(), sysobj.get());
   meta->init(sysobj.get(), mdlog.get(), meta_bes);
@@ -233,6 +237,7 @@ int RGWServices::do_init(CephContext *_cct, bool have_cache, bool raw)
   }
 
   finisher = _svc.finisher.get();
+  bi = _svc.bi_rados.get();
   bucket = _svc.bucket.get();
   cls = _svc.cls.get();
   mdlog = _svc.mdlog.get();
@@ -296,7 +301,7 @@ int RGWCtlDef::init(RGWServices& svc)
   meta.otp.reset(RGWOTPMetaHandlerAllocator::alloc(svc.zone, svc.meta_be_otp));
 
   user.reset(new RGWUserCtl(svc.zone, svc.user, (RGWUserMetadataHandler *)meta.user.get()));
-  bucket.reset(new RGWBucketCtl(svc.zone, svc.bucket,
+  bucket.reset(new RGWBucketCtl(svc.zone, svc.bucket, svc.bi,
                                 (RGWBucketMetadataHandler *)meta.bucket.get()),
                                 (RGWBucketInstanceMetadataHandler *)meta.bucket_instance.get());
 
index 658917420978a7d0cb1b25a056251c50e677540b..e5f967a4d24792dc980da2496f0ff047b918edb9 100644 (file)
@@ -46,6 +46,8 @@ public:
 
 class RGWSI_Finisher;
 class RGWSI_Bucket;
+class RGWSI_BucketIndex;
+class RGWSI_BucketIndex_RADOS;
 class RGWSI_Cls;
 class RGWSI_MDLog;
 class RGWSI_Meta;
@@ -71,6 +73,7 @@ struct RGWServices_Def
 
   std::unique_ptr<RGWSI_Finisher> finisher;
   std::unique_ptr<RGWSI_Bucket> bucket;
+  std::unique_ptr<RGWSI_BucketIndex_RADOS> bi_rados;
   std::unique_ptr<RGWSI_Cls> cls;
   std::unique_ptr<RGWSI_MDLog> mdlog;
   std::unique_ptr<RGWSI_Meta> meta;
@@ -103,6 +106,7 @@ struct RGWServices
 
   RGWSI_Finisher *finisher{nullptr};
   RGWSI_Bucket *bucket{nullptr};
+  RGWSI_BucketIndex *bi{nullptr};
   RGWSI_Cls *cls{nullptr};
   RGWSI_MDLog *mdlog{nullptr};
   RGWSI_Meta *meta{nullptr};
index 1d4426c6f2ae9b4090d7994ed028f46a7f7a0790..a607f55c1c572e944d540b7b3d19d2296efe4b43 100644 (file)
@@ -79,7 +79,7 @@ int rgw_user_sync_all_stats(RGWRados *store, const rgw_user& user_id)
         ldout(cct, 0) << "ERROR: could not read bucket info: bucket=" << bucket_ent.bucket << " ret=" << ret << dendl;
         continue;
       }
-      ret = rgw_bucket_sync_user_stats(store, user_id, bucket_info);
+      ret = store->ctl.bucket->sync_user_stats(user_id, bucket_info);
       if (ret < 0) {
         ldout(cct, 0) << "ERROR: could not sync bucket stats: ret=" << ret << dendl;
         return ret;
@@ -123,12 +123,14 @@ int rgw_user_get_all_buckets_stats(RGWRados *store, const rgw_user& user_id, map
       marker = i.first;
 
       const RGWBucketEnt& bucket_ent = i.second;
-      cls_user_bucket_entry entry;
-      ret = store->cls_user_get_bucket_stats(bucket_ent.bucket, entry);
+      RGWBucketEnt stats;
+      ret = store->ctl.bucket->read_bucket_stats(bucket_ent.bucket, &stats, null_yield);
       if (ret < 0) {
         ldout(cct, 0) << "ERROR: could not get bucket stats: ret=" << ret << dendl;
         return ret;
       }
+      cls_user_bucket_entry entry;
+      stats.convert(&entry);
       buckets_usage_map.emplace(bucket_ent.bucket.name, entry);
     }
     done = (buckets.size() < max_entries);
@@ -2692,7 +2694,7 @@ int RGWUserCtl::list_buckets(const rgw_user& user,
     }
     if (need_stats) {
       map<string, RGWBucketEnt>& m = buckets->get_buckets();
-      ret = ctl.bucket->read_buckets_stats(m);
+      ret = ctl.bucket->read_buckets_stats(m, null_yield);
       if (ret < 0 && ret != -ENOENT) {
         ldout(svc.user->ctx(), 0) << "ERROR: could not get stats for buckets" << dendl;
         return ret;
@@ -2702,6 +2704,14 @@ int RGWUserCtl::list_buckets(const rgw_user& user,
   });
 }
 
+int RGWUserCtl::flush_bucket_stats(const rgw_user& user,
+                                   const RGWBucketEnt& ent)
+{
+  return be_handler->call([&](RGWSI_MetaBackend_Handler::Op *op) {
+    return svc.user->flush_bucket_stats(op->ctx(), user, ent);
+  });
+}
+
 RGWMetadataHandler *RGWUserMetaHandlerAllocator::alloc(RGWSI_User *user_svc) {
   return new RGWUserMetadataHandler(user_svc);
 }
index 64d48059e67ec9a544af3865b1d16d0529795d6b..8d48e27904187e8f232f3d241b73300c416ca4c7 100644 (file)
@@ -935,6 +935,9 @@ public:
                    RGWUserBuckets *buckets,
                    bool *is_truncated,
                    uint64_t default_max);
+
+  int flush_bucket_stats(const rgw_user& user,
+                         const RGWBucketEnt& ent);
 };
 
 class RGWUserMetaHandlerAllocator {
index 09aaeed4e22b1f4f31d3b88e06eecc04b3fd30ff..e288ad957c2e09eca47e9527ba9356c63709302d 100644 (file)
 
 #include "rgw/rgw_service.h"
 
+class RGWBucketInfo;
+struct RGWBucketEnt;
+
 
 class RGWSI_BucketIndex : public RGWServiceInstance
 {
 public:
   RGWSI_BucketIndex(CephContext *cct) : RGWServiceInstance(cct) {}
   virtual ~RGWSI_BucketIndex() {}
+
+  virtual int init_index(RGWBucketInfo& bucket_info) = 0;
+  virtual int clean_index(RGWBucketInfo& bucket_info) = 0;
+
+  virtual int read_stats(const RGWBucketInfo& bucket_info,
+                         RGWBucketEnt *stats) = 0;
 };
 
index a7536231db03eb23b48be860f4cfc39613e5eb0f..fd75da40b860e087bfdada4db95b184260b787cb 100644 (file)
 
 static string dir_oid_prefix = ".dir.";
 
-RGWSI_BucketIndex_RADOS::RGWSI_BucketIndex_RADOS(CephContext *cct,
-                                                 RGWSI_Zone *zone_svc,
-                                                 RGWSI_RADOS *rados_svc) : RGWSI_BucketIndex(cct) {
+RGWSI_BucketIndex_RADOS::RGWSI_BucketIndex_RADOS(CephContext *cct) : RGWSI_BucketIndex(cct)
+{
+}
+
+void RGWSI_BucketIndex_RADOS::init(RGWSI_Zone *zone_svc,
+                                   RGWSI_RADOS *rados_svc)
+{
   svc.zone = zone_svc;
   svc.rados = rados_svc;
 }
@@ -284,7 +288,7 @@ int RGWSI_BucketIndex_RADOS::cls_bucket_head(const RGWBucketInfo& bucket_info,
 }
 
 
-int RGWSI_BucketIndex_RADOS::init_bucket_index(RGWBucketInfo& bucket_info, int num_shards)
+int RGWSI_BucketIndex_RADOS::init_index(RGWBucketInfo& bucket_info)
 {
   RGWSI_RADOS::Pool index_pool;
 
@@ -297,14 +301,14 @@ int RGWSI_BucketIndex_RADOS::init_bucket_index(RGWBucketInfo& bucket_info, int n
   dir_oid.append(bucket_info.bucket.bucket_id);
 
   map<int, string> bucket_objs;
-  get_bucket_index_objects(dir_oid, num_shards, &bucket_objs);
+  get_bucket_index_objects(dir_oid, bucket_info.num_shards, &bucket_objs);
 
   return CLSRGWIssueBucketIndexInit(index_pool.ioctx(),
                                    bucket_objs,
                                    cct->_conf->rgw_bucket_index_max_aio)();
 }
 
-int RGWSI_BucketIndex_RADOS::clean_bucket_index(RGWBucketInfo& bucket_info, int num_shards)
+int RGWSI_BucketIndex_RADOS::clean_index(RGWBucketInfo& bucket_info)
 {
   RGWSI_RADOS::Pool index_pool;
 
@@ -317,10 +321,38 @@ int RGWSI_BucketIndex_RADOS::clean_bucket_index(RGWBucketInfo& bucket_info, int
   dir_oid.append(bucket_info.bucket.bucket_id);
 
   std::map<int, std::string> bucket_objs;
-  get_bucket_index_objects(dir_oid, num_shards, &bucket_objs);
+  get_bucket_index_objects(dir_oid, bucket_info.num_shards, &bucket_objs);
 
   return CLSRGWIssueBucketIndexClean(index_pool.ioctx(),
                                     bucket_objs,
                                     cct->_conf->rgw_bucket_index_max_aio)();
 }
 
+int RGWSI_BucketIndex_RADOS::read_stats(const RGWBucketInfo& bucket_info,
+                                        RGWBucketEnt *result)
+{
+  vector<rgw_bucket_dir_header> headers;
+
+  result->bucket = bucket_info.bucket;
+  int r = cls_bucket_head(bucket_info, RGW_NO_SHARD, &headers, nullptr);
+  if (r < 0) {
+    return r;
+  }
+
+  auto hiter = headers.begin();
+  for (; hiter != headers.end(); ++hiter) {
+    RGWObjCategory category = RGWObjCategory::Main;
+    auto iter = (hiter->stats).find(category);
+    if (iter != hiter->stats.end()) {
+      struct rgw_bucket_category_stats& stats = iter->second;
+      result->count += stats.num_entries;
+      result->size += stats.total_size;
+      result->size_rounded += stats.total_size_rounded;
+    }
+  }
+
+  result->placement_rule = std::move(bucket_info.placement_rule);
+
+  return 0;
+}
+
index 2c6b72faf3ec5dbbec19cc3b5e05e143035ce9a9..d29452264cadb4af3b32cb135ed7e65551ef724c 100644 (file)
@@ -86,9 +86,10 @@ public:
     RGWSI_RADOS *rados{nullptr};
   } svc;
 
-  RGWSI_BucketIndex_RADOS(CephContext *cct,
-                          RGWSI_Zone *zone_svc,
-                          RGWSI_RADOS *rados_svc);
+  RGWSI_BucketIndex_RADOS(CephContext *cct);
+
+  void init(RGWSI_Zone *zone_svc,
+            RGWSI_RADOS *rados_svc);
 
   static int shards_max() {
     return RGW_SHARDS_PRIME_1;
@@ -106,8 +107,11 @@ public:
     return rgw_shards_mod(sid2, num_shards);
   }
 
-  int init_bucket_index(RGWBucketInfo& bucket_info, int num_shards);
-  int clean_bucket_index(RGWBucketInfo& bucket_info, int num_shards);
+  int init_index(RGWBucketInfo& bucket_info);
+  int clean_index(RGWBucketInfo& bucket_info);
+
+  int read_stats(const RGWBucketInfo& bucket_info,
+                 RGWBucketEnt *stats) override;
 };
 
 
index 99a6dcb466e446325f3f5580488655c85984bc2e..3a45633d56093c5574063091d474994a63480b50 100644 (file)
@@ -4,6 +4,7 @@
 #include "svc_zone.h"
 #include "svc_sys_obj.h"
 #include "svc_sys_obj_cache.h"
+#include "svc_bi.h"
 #include "svc_meta.h"
 #include "svc_meta_be_sobj.h"
 #include "svc_sync_modules.h"
@@ -138,13 +139,15 @@ RGWSI_Bucket::~RGWSI_Bucket() {
 }
 
 void RGWSI_Bucket::init(RGWSI_Zone *_zone_svc, RGWSI_SysObj *_sysobj_svc,
-                        RGWSI_SysObj_Cache *_cache_svc, RGWSI_Meta *_meta_svc,
-                        RGWSI_MetaBackend *_meta_be_svc, RGWSI_SyncModules *_sync_modules_svc)
+                        RGWSI_SysObj_Cache *_cache_svc, RGWSI_BucketIndex *_bi,
+                        RGWSI_Meta *_meta_svc, RGWSI_MetaBackend *_meta_be_svc,
+                        RGWSI_SyncModules *_sync_modules_svc)
 {
   svc.bucket = this;
   svc.zone = _zone_svc;
   svc.sysobj = _sysobj_svc;
   svc.cache = _cache_svc;
+  svc.bi = _bi;
   svc.meta = _meta_svc;
   svc.meta_be = _meta_be_svc;
   svc.sync_modules = _sync_modules_svc;
@@ -492,45 +495,53 @@ int RGWSI_Bucket::remove_bucket_instance_info(RGWSI_MetaBackend::Context *ctx,
   return svc.meta_be->remove_entry(ctx, key, params, objv_tracker, y);
 }
 
+int RGWSI_Bucket::read_bucket_stats(const RGWBucketInfo& bucket_info,
+                                    RGWBucketEnt *ent,
+                                    optional_yield y)
+{
+  ent->count = 0;
+  ent->size = 0;
+  ent->size_rounded = 0;
+
+  vector<rgw_bucket_dir_header> headers;
+
+  int r = svc.bi->read_stats(bucket_info, ent, y);
+  if (r < 0) {
+    ldout(cct, 0) << "ERROR: " << __func__ << "(): read_stats returned r=" << r << dendl;
+    return r;
+  }
+
+  return 0;
+}
+
+int RGWSI_Bucket::read_bucket_stats(RGWSI_MetaBackend::Context *ctx,
+                                    const rgw_bucket& bucket,
+                                    RGWBucketEnt *ent,
+                                    optional_yield y)
+{
+  RGWBucketInfo bucket_info;
+  int ret = read_bucket_instance_info(ctx, get_bi_meta_key(bucket),
+                                      &bucket_info, nullptr, nullptr,
+                                      y);
+  if (ret < 0) {
+    return ret;
+  }
+
+  return read_bucket_stats(bucket_info, ent, y);
+}
+
 int RGWSI_Bucket::read_buckets_stats(RGWSI_MetaBackend::Context *ctx,
-                                     map<string, RGWBucketEnt>& m)
+                                     map<string, RGWBucketEnt>& m,
+                                     optional_yield y)
 {
   map<string, RGWBucketEnt>::iterator iter;
   for (iter = m.begin(); iter != m.end(); ++iter) {
     RGWBucketEnt& ent = iter->second;
-    rgw_bucket& bucket = ent.bucket;
-    ent.count = 0;
-    ent.size = 0;
-    ent.size_rounded = 0;
-
-    vector<rgw_bucket_dir_header> headers;
-
-    RGWBucketInfo bucket_info;
-    int ret = read_bucket_instance_info(ctx, get_bi_meta_key(bucket),
-                                        &bucket_info, nullptr, nullptr);
-    if (ret < 0) {
-      return ret;
-    }
-
-    int r = cls_bucket_head(bucket_info, RGW_NO_SHARD, headers);
-    if (r < 0)
+    int r = read_bucket_stats(ctx, ent.bucket, &ent, y);
+    if (r < 0) {
+      ldout(cct, 0) << "ERROR: " << __func__ << "(): read_bucket_stats returned r=" << r << dendl;
       return r;
-
-    auto hiter = headers.begin();
-    for (; hiter != headers.end(); ++hiter) {
-      RGWObjCategory category = main_category;
-      auto iter = (hiter->stats).find(category);
-      if (iter != hiter->stats.end()) {
-        struct rgw_bucket_category_stats& stats = iter->second;
-        ent.count += stats.num_entries;
-        ent.size += stats.total_size;
-        ent.size_rounded += stats.total_size_rounded;
-      }
     }
-
-    // fill in placement_rule from the bucket instance for use in swift's
-    // per-storage policy statistics
-    ent.placement_rule = std::move(bucket_info.placement_rule);
   }
 
   return m.size();
index dff54731bea8eb68992367f30249be4004b47341..5a0bb6563914a430dc652deab56dfd4e71ba4202 100644 (file)
@@ -59,9 +59,15 @@ class RGWSI_Bucket : public RGWServiceInstance
                                    map<string, bufferlist> *pattrs,
                                    rgw_cache_entry_info *cache_info,
                                    boost::optional<obj_version> refresh_version);
+
+  int read_bucket_stats(const RGWBucketInfo& bucket_info,
+                        RGWBucketEnt *ent,
+                        optional_yield y);
+
 public:
   struct Svc {
     RGWSI_Bucket *bucket{nullptr};
+    RGWSI_BucketIndex *bi{nullptr};
     RGWSI_Zone *zone{nullptr};
     RGWSI_SysObj *sysobj{nullptr};
     RGWSI_SysObj_Cache *cache{nullptr};
@@ -84,8 +90,11 @@ public:
     return bi_be_handler;
   }
 
-  void init(RGWSI_Zone *_zone_svc, RGWSI_SysObj *_sysobj_svc,
-           RGWSI_SysObj_Cache *_cache_svc, RGWSI_Meta *_meta_svc,
+  void init(RGWSI_Zone *_zone_svc,
+            RGWSI_SysObj *_sysobj_svc,
+           RGWSI_SysObj_Cache *_cache_svc,
+            RGWSI_BucketIndex *_bi,
+            RGWSI_Meta *_meta_svc,
             RGWSI_MetaBackend *_meta_be_svc,
            RGWSI_SyncModules *_sync_modules);
 
@@ -144,7 +153,13 @@ public:
                                   RGWObjVersionTracker *objv_tracker,
                                   optional_yield y);
 
+  int read_bucket_stats(RGWSI_MetaBackend::Context *ctx,
+                        const rgw_bucket& bucket,
+                        RGWBucketEnt *ent,
+                        optional_yield y);
+
   int read_buckets_stats(RGWSI_MetaBackend::Context *ctx,
-                         map<string, RGWBucketEnt>& m);
+                         map<string, RGWBucketEnt>& m,
+                         optional_yield y);
 };
 
index aef34de23634414edbf9f587dfa22f33b265308d..931029b402b0f28c7ce0678cbae350d251f6d952 100644 (file)
@@ -101,5 +101,9 @@ public:
                            uint64_t max,
                            RGWUserBuckets *buckets,
                            bool *is_truncated) = 0;
+
+  virtual int flush_bucket_stats(RGWSI_MetaBackend::Context *ctx,
+                                 const rgw_user& user,
+                                 const RGWBucketEnt& ent) = 0;
 };
 
index 5551d49291711e518f1a1003f63d878df3ac03f9..861983c7d1e7779e52a973fdc6ad1e0c63015361 100644 (file)
@@ -666,6 +666,52 @@ int RGWSI_User_RADOS::remove_bucket(RGWSI_MetaBackend::Context *ctx,
   return 0;
 }
 
+int RGWSI_User_RADOS::cls_user_flush_bucket_stats(rgw_raw_obj& user_obj,
+                                                  const RGWBucketEnt& ent)
+{
+  cls_user_bucket_entry entry;
+  ent.convert(&entry);
+
+  list<cls_user_bucket_entry> entries;
+  entries.push_back(entry);
+
+  int r = cls_user_update_buckets(user_obj, entries, false);
+  if (r < 0) {
+    ldout(cct, 20) << "cls_user_update_buckets() returned " << r << dendl;
+    return r;
+  }
+
+  return 0;
+}
+
+int RGWSI_User_RADOS::cls_user_list_buckets(rgw_raw_obj& obj,
+                                            const string& in_marker,
+                                            const string& end_marker,
+                                            const int max_entries,
+                                            list<cls_user_bucket_entry>& entries,
+                                            string * const out_marker,
+                                            bool * const truncated)
+{
+  auto rados_obj = svc.rados->obj(obj);
+  int r = rados_obj.open();
+  if (r < 0) {
+    return r;
+  }
+
+  librados::ObjectReadOperation op;
+  int rc;
+
+  cls_user_bucket_list(op, in_marker, end_marker, max_entries, entries, out_marker, truncated, &rc);
+  bufferlist ibl;
+  r = rados_obj.operate(&op, &ibl, null_yield);
+  if (r < 0)
+    return r;
+  if (rc < 0)
+    return rc;
+
+  return 0;
+}
+
 int RGWSI_User_RADOS::list_buckets(RGWSI_MetaBackend::Context *ctx,
                                  const rgw_user& user,
                                  const string& marker,
@@ -709,3 +755,13 @@ int RGWSI_User_RADOS::list_buckets(RGWSI_MetaBackend::Context *ctx,
 
   return 0;
 }
+
+int RGWSI_User_RADOS::flush_bucket_stats(RGWSI_MetaBackend::Context *ctx,
+                                         const rgw_user& user,
+                                         const RGWBucketEnt& ent)
+{
+  rgw_raw_obj obj = get_buckets_obj(user);
+
+  return cls_user_flush_bucket_stats(obj, ent);
+}
+
index 24e193613a2bc1531bcc296d4425ce7d2088c892..dd142f6f4d494da16743abb02b48c522ad605551 100644 (file)
@@ -73,7 +73,16 @@ class RGWSI_User_RADOS : public RGWSI_User
   int cls_user_add_bucket(rgw_raw_obj& obj, const cls_user_bucket_entry& entry);
   int cls_user_remove_bucket(rgw_raw_obj& obj, const cls_user_bucket& bucket);
 
-  /* bucket stats */
+  /* quota stats */
+  int cls_user_flush_bucket_stats(rgw_raw_obj& user_obj,
+                                  const RGWBucketEnt& ent);
+  int cls_user_list_buckets(rgw_raw_obj& obj,
+                            const string& in_marker,
+                            const string& end_marker,
+                            const int max_entries,
+                            list<cls_user_bucket_entry>& entries,
+                            string * const out_marker,
+                            bool * const truncated);
 
   int do_start() override;
 public:
@@ -154,5 +163,10 @@ public:
                    uint64_t max,
                    RGWUserBuckets *buckets,
                    bool *is_truncated) override;
+
+  /* quota related */
+  int flush_bucket_stats(RGWSI_MetaBackend::Context *ctx,
+                         const rgw_user& user,
+                         const RGWBucketEnt& ent) override;
 };