]> git.apps.os.sepia.ceph.com Git - ceph-ci.git/commitdiff
rgw/sal: move list_buckets() to Driver
authorCasey Bodley <cbodley@redhat.com>
Sat, 16 Dec 2023 15:47:44 +0000 (10:47 -0500)
committerCasey Bodley <cbodley@redhat.com>
Wed, 10 Apr 2024 17:09:14 +0000 (13:09 -0400)
move User::list_buckets() to Driver and take rgw_owner to serve bucket
listings for account owners

also unifies the user/account stats interfaces around rgw_owner in
Driver

Signed-off-by: Casey Bodley <cbodley@redhat.com>
28 files changed:
src/rgw/driver/daos/rgw_sal_daos.cc
src/rgw/driver/daos/rgw_sal_daos.h
src/rgw/driver/motr/rgw_sal_motr.cc
src/rgw/driver/motr/rgw_sal_motr.h
src/rgw/driver/posix/rgw_sal_posix.cc
src/rgw/driver/posix/rgw_sal_posix.h
src/rgw/driver/rados/rgw_bucket.cc
src/rgw/driver/rados/rgw_bucket.h
src/rgw/driver/rados/rgw_sal_rados.cc
src/rgw/driver/rados/rgw_sal_rados.h
src/rgw/driver/rados/rgw_user.cc
src/rgw/driver/rados/rgw_user.h
src/rgw/rgw_account.cc
src/rgw/rgw_account.h
src/rgw/rgw_admin.cc
src/rgw/rgw_auth.cc
src/rgw/rgw_op.cc
src/rgw/rgw_quota.cc
src/rgw/rgw_sal.h
src/rgw/rgw_sal_dbstore.cc
src/rgw/rgw_sal_dbstore.h
src/rgw/rgw_sal_filter.cc
src/rgw/rgw_sal_filter.h
src/rgw/rgw_user.cc
src/rgw/services/svc_user.h
src/rgw/services/svc_user_rados.cc
src/rgw/services/svc_user_rados.h
src/test/rgw/test_rgw_lua.cc

index 765655d7430f90e8a4026dfea22329c868ef0f32..e62495c3ac94c37c2e29de2b96eaec5b8bab8d62 100644 (file)
@@ -45,10 +45,11 @@ namespace rgw::sal {
 using ::ceph::decode;
 using ::ceph::encode;
 
-int DaosUser::list_buckets(const DoutPrefixProvider* dpp, const string& marker,
-                           const string& end_marker, uint64_t max,
-                           bool need_stats, BucketList& buckets,
-                           optional_yield y) {
+int DaosStore::list_buckets(const DoutPrefixProvider* dpp,
+                            const rgw_owner& owner, const std::string& tenant,
+                            const string& marker, const string& end_marker,
+                            uint64_t max, bool need_stats, BucketList& buckets,
+                            optional_yield y) {
   ldpp_dout(dpp, 20) << "DEBUG: list_user_buckets: marker=" << marker
                      << " end_marker=" << end_marker << " max=" << max << dendl;
   int ret = 0;
@@ -65,7 +66,7 @@ int DaosUser::list_buckets(const DoutPrefixProvider* dpp, const string& marker,
   char daos_marker[DS3_MAX_BUCKET_NAME];
   std::strncpy(daos_marker, marker.c_str(), sizeof(daos_marker));
   ret = ds3_bucket_list(&bcount, bucket_infos.data(), daos_marker,
-                        &is_truncated, store->ds3, nullptr);
+                        &is_truncated, ds3, nullptr);
   ldpp_dout(dpp, 20) << "DEBUG: ds3_bucket_list: bcount=" << bcount
                      << " ret=" << ret << dendl;
   if (ret != 0) {
@@ -82,7 +83,7 @@ int DaosUser::list_buckets(const DoutPrefixProvider* dpp, const string& marker,
     bl.append(reinterpret_cast<char*>(bi.encoded), bi.encoded_length);
     auto iter = bl.cbegin();
     dbinfo.decode(iter);
-    buckets.add(std::make_unique<DaosBucket>(this->store, dbinfo.info, this));
+    buckets.add(std::make_unique<DaosBucket>(this, dbinfo.info, this));
   }
 
   buckets.set_truncated(is_truncated);
index b4f65c5d82fe71253e721e27a650d4181b873624..04263e50dd805de0d2d4338b30ebe03253189ed6 100644 (file)
@@ -168,9 +168,6 @@ class DaosUser : public StoreUser {
   virtual std::unique_ptr<User> clone() override {
     return std::make_unique<DaosUser>(*this);
   }
-  int list_buckets(const DoutPrefixProvider* dpp, const std::string& marker,
-                   const std::string& end_marker, uint64_t max, bool need_stats,
-                   BucketList& buckets, optional_yield y) override;
   virtual int create_bucket(
       const DoutPrefixProvider* dpp, const rgw_bucket& b,
       const std::string& zonegroup_id, rgw_placement_rule& placement_rule,
@@ -903,6 +900,11 @@ class DaosStore : public StoreDriver {
   int load_bucket(const DoutPrefixProvider* dpp, User* u,
                   const rgw_bucket& b, std::unique_ptr<Bucket>* bucket,
                   optional_yield y) override;
+  int list_buckets(const DoutPrefixProvider* dpp,
+                   const rgw_owner& owner, const std::string& tenant,
+                   const std::string& marker, const std::string& end_marker,
+                   uint64_t max, bool need_stats,
+                   BucketList& buckets, optional_yield y) override;
   virtual bool is_meta_master() override;
   virtual Zone* get_zone() { return &zone; }
   virtual std::string zone_unique_id(uint64_t unique_num) override;
index 32ede60d8df86317615d8245ea0c15c3107f6eb0..ee90ba42a38a67e93aac87ad8f42c95676423b43 100644 (file)
@@ -157,9 +157,10 @@ void MotrMetaCache::set_enabled(bool status)
 // TODO: properly handle the number of key/value pairs to get in
 // one query. Now the POC simply tries to retrieve all `max` number of pairs
 // with starting key `marker`.
-int MotrUser::list_buckets(const DoutPrefixProvider *dpp, const string& marker,
-    const string& end_marker, uint64_t max, bool need_stats,
-    BucketList &buckets, optional_yield y)
+int MotrStore::list_buckets(const DoutPrefixProvider *dpp,
+    const rgw_owner& owner, const std::string& tenant,
+    const string& marker, const string& end_marker, uint64_t max,
+    bool need_stats, BucketList &buckets, optional_yield y)
 {
   int rc;
   vector<string> keys(max);
@@ -172,9 +173,9 @@ int MotrUser::list_buckets(const DoutPrefixProvider *dpp, const string& marker,
 
   // Retrieve all `max` number of pairs.
   buckets.clear();
-  string user_info_iname = "motr.rgw.user.info." + info.user_id.to_str();
+  string user_info_iname = "motr.rgw.user.info." + to_string(owner);
   keys[0] = marker;
-  rc = store->next_query_by_name(user_info_iname, keys, vals);
+  rc = next_query_by_name(user_info_iname, keys, vals);
   if (rc < 0) {
     ldpp_dout(dpp, 0) << "ERROR: NEXT query failed. " << rc << dendl;
     return rc;
@@ -197,7 +198,7 @@ int MotrUser::list_buckets(const DoutPrefixProvider *dpp, const string& marker,
          end_marker.compare(ent.bucket.marker) <= 0)
       break;
 
-    buckets.add(std::make_unique<MotrBucket>(this->store, ent, this));
+    buckets.add(std::make_unique<MotrBucket>(this, ent, this));
     bcount++;
   }
   if (bcount == max)
index 8865b93be880443cf1a86036dc283811dead169f..c9ffcffc2d40ceaace38d16729ea06650597cf19 100644 (file)
@@ -219,8 +219,6 @@ class MotrUser : public StoreUser {
     virtual std::unique_ptr<User> clone() override {
       return std::unique_ptr<User>(new MotrUser(*this));
     }
-    int list_buckets(const DoutPrefixProvider *dpp, const std::string& marker, const std::string& end_marker,
-        uint64_t max, bool need_stats, BucketList& buckets, optional_yield y) override;
     virtual int create_bucket(const DoutPrefixProvider* dpp,
                             const rgw_bucket& b,
                             const std::string& zonegroup_id,
@@ -999,6 +997,10 @@ class MotrStore : public StoreDriver {
     std::unique_ptr<Bucket> get_bucket(User* u, const RGWBucketInfo& i) override;
     int load_bucket(const DoutPrefixProvider *dpp, User* u, const rgw_bucket& b,
                     std::unique_ptr<Bucket>* bucket, optional_yield y) override;
+    int list_buckets(const DoutPrefixProvider *dpp,
+        const rgw_owner& owner, const std::string& tenant,
+        const std::string& marker, const std::string& end_marker,
+        uint64_t max, bool need_stats, BucketList& buckets, optional_yield y) override;
     virtual bool is_meta_master() override;
     virtual Zone* get_zone() { return &zone; }
     virtual std::string zone_unique_id(uint64_t unique_num) override;
index 1dc548c360cd04b301b344a08f354fc03e0a531a..9b1b34fa9e4e0dcda73663175129241e2debc30e 100644 (file)
@@ -444,7 +444,8 @@ int POSIXDriver::close()
 }
 
 // TODO: marker and other params
-int POSIXUser::list_buckets(const DoutPrefixProvider* dpp, const std::string& marker,
+int POSIXDriver::list_buckets(const DoutPrefixProvider* dpp, const rgw_owner& owner,
+                            const std::string& tenant, const std::string& marker,
                             const std::string& end_marker, uint64_t max,
                             bool need_stats, BucketList &result, optional_yield y)
 {
@@ -457,7 +458,7 @@ int POSIXUser::list_buckets(const DoutPrefixProvider* dpp, const std::string& ma
 
   /* it's not sufficient to dup(root_fd), as as the new fd would share
    * the file position of root_fd */
-  dfd = copy_dir_fd(driver->get_root_fd());
+  dfd = copy_dir_fd(get_root_fd());
   if (dfd == -1) {
     ret = errno;
     ldpp_dout(dpp, 0) << "ERROR: could not open root to list buckets: "
@@ -470,7 +471,7 @@ int POSIXUser::list_buckets(const DoutPrefixProvider* dpp, const std::string& ma
     ret = errno;
     ldpp_dout(dpp, 0) << "ERROR: could not open root to list buckets: "
       << cpp_strerror(ret) << dendl;
-    close(dfd);
+    ::close(dfd);
     return -ret;
   }
 
@@ -486,7 +487,7 @@ int POSIXUser::list_buckets(const DoutPrefixProvider* dpp, const std::string& ma
   while ((entry = readdir(dir)) != NULL) {
     struct statx stx;
 
-    ret = statx(driver->get_root_fd(), entry->d_name, AT_SYMLINK_NOFOLLOW, STATX_ALL, &stx);
+    ret = statx(get_root_fd(), entry->d_name, AT_SYMLINK_NOFOLLOW, STATX_ALL, &stx);
     if (ret < 0) {
       ret = errno;
       ldpp_dout(dpp, 0) << "ERROR: could not stat object " << entry->d_name << ": "
@@ -516,7 +517,7 @@ int POSIXUser::list_buckets(const DoutPrefixProvider* dpp, const std::string& ma
   }
   ret = errno;
   if (ret != 0) {
-    ldpp_dout(dpp, 0) << "ERROR: could not list buckets for " << get_display_name() << ": "
+    ldpp_dout(dpp, 0) << "ERROR: could not list buckets for " << owner << ": "
       << cpp_strerror(ret) << dendl;
     return -ret;
   }
index 785192afee1607a273022bbfd82c5c468b63eca7..587bf783e9018d163b09f22f884479fef22f41b9 100644 (file)
@@ -55,6 +55,11 @@ public:
   virtual std::unique_ptr<Bucket> get_bucket(const RGWBucketInfo& i)  override;
   virtual int load_bucket(const DoutPrefixProvider* dpp, const rgw_bucket& b,
                           std::unique_ptr<Bucket>* bucket, optional_yield y) override;
+  virtual int list_buckets(const DoutPrefixProvider* dpp,
+                          const rgw_owner& owner, const std::string& tenant,
+                          const std::string& marker, const std::string& end_marker,
+                          uint64_t max, bool need_stats, BucketList& buckets,
+                          optional_yield y) override;
   virtual std::string zone_unique_trans_id(const uint64_t unique_num) override;
 
   virtual std::unique_ptr<Writer> get_append_writer(const DoutPrefixProvider *dpp,
@@ -116,10 +121,6 @@ public:
     driver(_driver) {}
   virtual ~POSIXUser() = default;
 
-  virtual int list_buckets(const DoutPrefixProvider* dpp,
-                          const std::string& marker, const std::string& end_marker,
-                          uint64_t max, bool need_stats, BucketList& buckets,
-                          optional_yield y) override;
   virtual Attrs& get_attrs() override { return next->get_attrs(); }
   virtual void set_attrs(Attrs& _attrs) override { next->set_attrs(_attrs); }
   virtual int read_attrs(const DoutPrefixProvider* dpp, optional_yield y) override;
index 5af2230a024d3d89a075bb432c6ef802a3a8f96c..e6c30497adb6abc0f278d07e9602bff4e207d828 100644 (file)
@@ -93,17 +93,18 @@ static void dump_mulipart_index_results(list<rgw_obj_index_key>& objs_to_unlink,
   }
 }
 
-void check_bad_user_bucket_mapping(rgw::sal::Driver* driver, rgw::sal::User& user,
-                                  bool fix,
-                                  optional_yield y,
-                                   const DoutPrefixProvider *dpp)
+void check_bad_owner_bucket_mapping(rgw::sal::Driver* driver,
+                                    const rgw_owner& owner,
+                                    const std::string& tenant,
+                                    bool fix, optional_yield y,
+                                    const DoutPrefixProvider *dpp)
 {
   size_t max_entries = dpp->get_cct()->_conf->rgw_list_buckets_max_chunk;
 
   rgw::sal::BucketList listing;
   do {
-    int ret = user.list_buckets(dpp, listing.next_marker, string(),
-                                max_entries, false, listing, y);
+    int ret = driver->list_buckets(dpp, owner, tenant, listing.next_marker,
+                                   string(), max_entries, false, listing, y);
     if (ret < 0) {
       ldpp_dout(dpp, 0) << "failed to read user buckets: "
           << cpp_strerror(-ret) << dendl;
@@ -112,7 +113,7 @@ void check_bad_user_bucket_mapping(rgw::sal::Driver* driver, rgw::sal::User& use
 
     for (const auto& ent : listing.buckets) {
       std::unique_ptr<rgw::sal::Bucket> bucket;
-      int r = driver->load_bucket(dpp, rgw_bucket(user.get_tenant(), ent.bucket.name),
+      int r = driver->load_bucket(dpp, rgw_bucket(tenant, ent.bucket.name),
                                   &bucket, y);
       if (r < 0) {
         ldpp_dout(dpp, 0) << "could not get bucket info for bucket=" << bucket << dendl;
@@ -124,7 +125,7 @@ void check_bad_user_bucket_mapping(rgw::sal::Driver* driver, rgw::sal::User& use
             << " got " << bucket << std::endl;
         if (fix) {
           cout << "fixing" << std::endl;
-         r = bucket->chown(dpp, user.get_id(), y);
+         r = bucket->chown(dpp, owner, y);
           if (r < 0) {
             cerr << "failed to fix bucket: " << cpp_strerror(-r) << std::endl;
           }
@@ -1383,7 +1384,7 @@ int RGWBucketAdminOp::limit_check(rgw::sal::Driver* driver,
   formatter->open_array_section("users");
 
   for (const auto& user_id : user_ids) {
-    std::unique_ptr<rgw::sal::User> user = driver->get_user(rgw_user(user_id));
+    const auto user = rgw_user{user_id};
 
     formatter->open_object_section("user");
     formatter->dump_string("user_id", user_id);
@@ -1391,8 +1392,8 @@ int RGWBucketAdminOp::limit_check(rgw::sal::Driver* driver,
 
     rgw::sal::BucketList listing;
     do {
-      ret = user->list_buckets(dpp, listing.next_marker, string(),
-                               max_entries, false, listing, y);
+      ret = driver->list_buckets(dpp, user, user.tenant, listing.next_marker,
+                                 string(), max_entries, false, listing, y);
       if (ret < 0)
         return ret;
 
@@ -1466,6 +1467,47 @@ int RGWBucketAdminOp::limit_check(rgw::sal::Driver* driver,
   return ret;
 } /* RGWBucketAdminOp::limit_check */
 
+static int list_owner_bucket_info(const DoutPrefixProvider* dpp,
+                                  optional_yield y,
+                                  rgw::sal::Driver* driver,
+                                  const rgw_owner& owner,
+                                  const std::string& tenant,
+                                  const std::string& marker,
+                                  bool show_stats,
+                                  RGWFormatterFlusher& flusher)
+{
+  Formatter* formatter = flusher.get_formatter();
+  formatter->open_array_section("buckets");
+
+  const std::string empty_end_marker;
+  const size_t max_entries = dpp->get_cct()->_conf->rgw_list_buckets_max_chunk;
+  constexpr bool no_need_stats = false; // set need_stats to false
+
+  rgw::sal::BucketList listing;
+  listing.next_marker = marker;
+  do {
+    int ret = driver->list_buckets(dpp, owner, tenant, listing.next_marker,
+                                   empty_end_marker, max_entries, no_need_stats,
+                                   listing, y);
+    if (ret < 0) {
+      return ret;
+    }
+
+    for (const auto& ent : listing.buckets) {
+      if (show_stats) {
+        bucket_stats(driver, tenant, ent.bucket.name, formatter, dpp, y);
+      } else {
+        formatter->dump_string("bucket", ent.bucket.name);
+      }
+    } // for loop
+
+    flusher.flush();
+  } while (!listing.next_marker.empty());
+
+  formatter->close_section();
+  return 0;
+}
+
 int RGWBucketAdminOp::info(rgw::sal::Driver* driver,
                           RGWBucketAdminOpState& op_state,
                           RGWFormatterFlusher& flusher,
@@ -1494,34 +1536,30 @@ int RGWBucketAdminOp::info(rgw::sal::Driver* driver,
       return ret;
     }
   } else if (op_state.is_user_op()) {
-    formatter->open_array_section("buckets");
-
-    std::unique_ptr<rgw::sal::User> user = driver->get_user(op_state.get_user_id());
-    const std::string empty_end_marker;
-    const size_t max_entries = dpp->get_cct()->_conf->rgw_list_buckets_max_chunk;
-    constexpr bool no_need_stats = false; // set need_stats to false
-
-    rgw::sal::BucketList listing;
-    listing.next_marker = op_state.marker;
-    do {
-      ret = user->list_buckets(dpp, listing.next_marker, empty_end_marker,
-                               max_entries, no_need_stats, listing, y);
-      if (ret < 0) {
-        return ret;
-      }
-
-      for (const auto& ent : listing.buckets) {
-        if (show_stats) {
-          bucket_stats(driver, user_id.tenant, ent.bucket.name, formatter, dpp, y);
-       } else {
-          formatter->dump_string("bucket", ent.bucket.name);
-       }
-      } // for loop
-
-      flusher.flush();
-    } while (!listing.next_marker.empty());
+    const rgw_user& uid = op_state.get_user_id();
+    ret = list_owner_bucket_info(dpp, y, driver, uid, uid.tenant,
+                                 op_state.marker, show_stats, flusher);
+    if (ret < 0) {
+      return ret;
+    }
+  } else if (op_state.is_account_op()) {
+    // look up the account's tenant
+    const rgw_account_id& account_id = op_state.get_account_id();
+    RGWAccountInfo info;
+    rgw::sal::Attrs attrs; // ignored
+    RGWObjVersionTracker objv; // ignored
+    int ret = driver->load_account_by_id(dpp, y, account_id, info, attrs, objv);
+    if (ret < 0) {
+      ldpp_dout(dpp, 1) << "failed to load account " << account_id
+          << ": " << cpp_strerror(ret) << dendl;
+      return ret;
+    }
 
-    formatter->close_section();
+    ret = list_owner_bucket_info(dpp, y, driver, account_id, info.tenant,
+                                 op_state.marker, show_stats, flusher);
+    if (ret < 0) {
+      return ret;
+    }
   } else {
     void *handle = nullptr;
     bool truncated = true;
index d4acaeb41414349a74c467d3fbd1f6769d0d3d10..e91c0d7e13953bbac9e3c0c7c04fe2bf6ce46957 100644 (file)
@@ -213,10 +213,15 @@ extern int rgw_object_get_attr(rgw::sal::Driver* driver, rgw::sal::Object* obj,
                               const char* attr_name, bufferlist& out_bl,
                               optional_yield y);
 
-extern void check_bad_user_bucket_mapping(rgw::sal::Driver* driver, rgw::sal::User& user, bool fix, optional_yield y, const DoutPrefixProvider *dpp);
+void check_bad_owner_bucket_mapping(rgw::sal::Driver* driver,
+                                    const rgw_owner& owner,
+                                    const std::string& tenant,
+                                    bool fix, optional_yield y,
+                                    const DoutPrefixProvider *dpp);
 
 struct RGWBucketAdminOpState {
   rgw_user uid;
+  rgw_account_id account_id;
   std::string display_name;
   std::string bucket_name;
   std::string bucket_id;
@@ -278,6 +283,7 @@ struct RGWBucketAdminOpState {
   void set_sync_bucket(bool value) { sync_bucket = value; }
 
   rgw_user& get_user_id() { return uid; }
+  rgw_account_id& get_account_id() { return account_id; }
   std::string& get_user_display_name() { return display_name; }
   std::string& get_bucket_name() { return bucket_name; }
   std::string& get_object_name() { return object_name; }
@@ -299,6 +305,7 @@ struct RGWBucketAdminOpState {
   bool will_delete_children() { return delete_child_objects; }
   bool will_check_objects() { return check_objects; }
   bool is_user_op() { return !uid.empty(); }
+  bool is_account_op() { return !account_id.empty(); }
   bool is_system_op() { return uid.empty(); }
   bool has_bucket_stored() { return bucket_stored; }
   int get_max_aio() { return max_aio; }
index a25a4a58d913d047a1a384a95b973a3e03343631..c9808d1a9c755a03875e55f288a14a0f340f068d 100644 (file)
@@ -102,12 +102,49 @@ static int drain_aio(std::list<librados::AioCompletion*>& handles)
   return ret;
 }
 
-int RadosUser::list_buckets(const DoutPrefixProvider* dpp, const std::string& marker,
-                              const std::string& end_marker, uint64_t max, bool need_stats,
-                              BucketList &result, optional_yield y)
+// return the {user}.buckets or {account}.buckets object
+static rgw_raw_obj get_owner_buckets_obj(RGWSI_User* svc_user,
+                                         RGWSI_Zone* svc_zone,
+                                         const rgw_owner& owner)
 {
-  return store->ctl()->user->list_buckets(dpp, get_id(), marker, end_marker,
-                                          max, need_stats, result, y);
+  struct visitor {
+    RGWSI_User* svc_user;
+    RGWSI_Zone* svc_zone;
+
+    rgw_raw_obj operator()(const rgw_user& user) {
+      return svc_user->get_buckets_obj(user);
+    }
+    rgw_raw_obj operator()(const rgw_account_id& id) {
+      const RGWZoneParams& zone = svc_zone->get_zone_params();
+      return rgwrados::account::get_buckets_obj(zone, id);
+    }
+  };
+  return std::visit(visitor{svc_user, svc_zone}, owner);
+}
+
+int RadosStore::list_buckets(const DoutPrefixProvider* dpp,
+                             const rgw_owner& owner, const std::string& tenant,
+                             const std::string& marker, const std::string& end_marker,
+                             uint64_t max, bool need_stats,
+                             BucketList& listing, optional_yield y)
+{
+  librados::Rados& rados = *getRados()->get_rados_handle();
+  const rgw_raw_obj& obj = get_owner_buckets_obj(svc()->user, svc()->zone, owner);
+
+  int ret = rgwrados::buckets::list(dpp, y, rados, obj, tenant,
+                                    marker, end_marker, max, listing);
+  if (ret < 0) {
+    return ret;
+  }
+
+  if (need_stats) {
+    ret = ctl()->bucket->read_buckets_stats(listing.buckets, y, dpp);
+    if (ret < 0 && ret != -ENOENT) {
+      ldpp_dout(dpp, 0) << "ERROR: could not get stats for buckets" << dendl;
+      return ret;
+    }
+  }
+  return 0;
 }
 
 int RadosBucket::create(const DoutPrefixProvider* dpp,
@@ -169,24 +206,6 @@ int RadosUser::merge_and_store_attrs(const DoutPrefixProvider* dpp, Attrs& new_a
   return store_user(dpp, y, false);
 }
 
-int RadosUser::read_stats(const DoutPrefixProvider *dpp,
-                             optional_yield y, RGWStorageStats* stats,
-                            ceph::real_time* last_stats_sync,
-                            ceph::real_time* last_stats_update)
-{
-  return store->ctl()->user->read_stats(dpp, get_id(), stats, y, last_stats_sync, last_stats_update);
-}
-
-int RadosUser::read_stats_async(const DoutPrefixProvider *dpp, boost::intrusive_ptr<ReadStatsCB> cb)
-{
-  return store->svc()->user->read_stats_async(dpp, get_id(), cb);
-}
-
-int RadosUser::complete_flush_stats(const DoutPrefixProvider *dpp, optional_yield y)
-{
-  return store->svc()->user->complete_flush_stats(dpp, get_id(), y);
-}
-
 int RadosUser::read_usage(const DoutPrefixProvider *dpp, uint64_t start_epoch, uint64_t end_epoch,
                               uint32_t max_entries, bool* is_truncated,
                               RGWUsageIter& usage_iter,
@@ -1097,29 +1116,46 @@ int RadosStore::delete_account(const DoutPrefixProvider* dpp,
   return write_mdlog_entry(dpp, y, *svc()->mdlog, "account", info.id, objv);
 }
 
-int RadosStore::load_account_stats(const DoutPrefixProvider* dpp,
-                                   optional_yield y, std::string_view id,
-                                   RGWStorageStats& stats,
-                                   ceph::real_time& last_synced,
-                                   ceph::real_time& last_updated)
+int RadosStore::load_stats(const DoutPrefixProvider* dpp,
+                           optional_yield y,
+                           const rgw_owner& owner,
+                           RGWStorageStats& stats,
+                           ceph::real_time& last_synced,
+                           ceph::real_time& last_updated)
 {
-  const RGWZoneParams& zone = svc()->zone->get_zone_params();
-  const rgw_raw_obj& obj = rgwrados::account::get_buckets_obj(zone, id);
   librados::Rados& rados = *getRados()->get_rados_handle();
+  const rgw_raw_obj& obj = get_owner_buckets_obj(svc()->user, svc()->zone, owner);
   return rgwrados::buckets::read_stats(dpp, y, rados, obj, stats,
                                        &last_synced, &last_updated);
 }
 
-int RadosStore::load_account_stats_async(const DoutPrefixProvider* dpp,
-                                         std::string_view id,
-                                         boost::intrusive_ptr<ReadStatsCB> cb)
+int RadosStore::load_stats_async(const DoutPrefixProvider* dpp,
+                                 const rgw_owner& owner,
+                                 boost::intrusive_ptr<ReadStatsCB> cb)
 {
-  const RGWZoneParams& zone = svc()->zone->get_zone_params();
-  const rgw_raw_obj& obj = rgwrados::account::get_buckets_obj(zone, id);
   librados::Rados& rados = *getRados()->get_rados_handle();
+  const rgw_raw_obj& obj = get_owner_buckets_obj(svc()->user, svc()->zone, owner);
   return rgwrados::buckets::read_stats_async(dpp, rados, obj, std::move(cb));
 }
 
+int RadosStore::reset_stats(const DoutPrefixProvider *dpp,
+                            optional_yield y,
+                            const rgw_owner& owner)
+{
+  librados::Rados& rados = *getRados()->get_rados_handle();
+  const rgw_raw_obj& obj = get_owner_buckets_obj(svc()->user, svc()->zone, owner);
+  return rgwrados::buckets::reset_stats(dpp, y, rados, obj);
+}
+
+int RadosStore::complete_flush_stats(const DoutPrefixProvider* dpp,
+                                     optional_yield y,
+                                     const rgw_owner& owner)
+{
+  librados::Rados& rados = *getRados()->get_rados_handle();
+  const rgw_raw_obj& obj = get_owner_buckets_obj(svc()->user, svc()->zone, owner);
+  return rgwrados::buckets::complete_flush_stats(dpp, y, rados, obj);
+}
+
 std::unique_ptr<Object> RadosStore::get_object(const rgw_obj_key& k)
 {
   return std::make_unique<RadosObject>(this, k);
index 5aebda3d32ed6c0c00e7e591a7c49f0aae75ae3e..7839a54c262419ff728e0bdf0df405d806ee2644 100644 (file)
@@ -174,19 +174,32 @@ class RadosStore : public StoreDriver {
                        optional_yield y,
                        const RGWAccountInfo& info,
                        RGWObjVersionTracker& objv) override;
-    int load_account_stats(const DoutPrefixProvider* dpp,
-                           optional_yield y, std::string_view id,
-                           RGWStorageStats& stats,
-                           ceph::real_time& last_synced,
-                           ceph::real_time& last_updated) override;
-    int load_account_stats_async(const DoutPrefixProvider* dpp,
-                                 std::string_view id,
-                                 boost::intrusive_ptr<ReadStatsCB> cb) override;
+
+    int load_stats(const DoutPrefixProvider* dpp,
+                   optional_yield y,
+                   const rgw_owner& owner,
+                   RGWStorageStats& stats,
+                   ceph::real_time& last_synced,
+                   ceph::real_time& last_updated) override;
+    int load_stats_async(const DoutPrefixProvider* dpp,
+                         const rgw_owner& owner,
+                         boost::intrusive_ptr<ReadStatsCB> cb) override;
+    int reset_stats(const DoutPrefixProvider *dpp,
+                    optional_yield y,
+                    const rgw_owner& owner) override;
+    int complete_flush_stats(const DoutPrefixProvider* dpp,
+                             optional_yield y,
+                             const rgw_owner& owner) override;
 
     virtual std::unique_ptr<Object> get_object(const rgw_obj_key& k) override;
     std::unique_ptr<Bucket> get_bucket(const RGWBucketInfo& i) override;
     int load_bucket(const DoutPrefixProvider* dpp, const rgw_bucket& b,
                     std::unique_ptr<Bucket>* bucket, optional_yield y) override;
+    int list_buckets(const DoutPrefixProvider* dpp,
+                    const rgw_owner& owner, const std::string& tenant,
+                    const std::string& marker, const std::string& end_marker,
+                    uint64_t max, bool need_stats, BucketList& buckets,
+                    optional_yield y) override;
     virtual bool is_meta_master() override;
     virtual Zone* get_zone() { return zone.get(); }
     virtual std::string zone_unique_id(uint64_t unique_num) override;
@@ -349,17 +362,8 @@ class RadosUser : public StoreUser {
     virtual std::unique_ptr<User> clone() override {
       return std::unique_ptr<User>(new RadosUser(*this));
     }
-    int list_buckets(const DoutPrefixProvider* dpp, const std::string& marker, const std::string& end_marker,
-                    uint64_t max, bool need_stats, BucketList& buckets,
-                    optional_yield y) override;
     virtual int read_attrs(const DoutPrefixProvider* dpp, optional_yield y) override;
     virtual int merge_and_store_attrs(const DoutPrefixProvider* dpp, Attrs& new_attrs, optional_yield y) override;
-    virtual int read_stats(const DoutPrefixProvider *dpp,
-                           optional_yield y, RGWStorageStats* stats,
-                          ceph::real_time* last_stats_sync = nullptr,
-                          ceph::real_time* last_stats_update = nullptr) override;
-    virtual int read_stats_async(const DoutPrefixProvider *dpp, boost::intrusive_ptr<ReadStatsCB> cb) override;
-    virtual int complete_flush_stats(const DoutPrefixProvider *dpp, optional_yield y) override;
     virtual int read_usage(const DoutPrefixProvider *dpp, uint64_t start_epoch, uint64_t end_epoch, uint32_t max_entries,
                           bool* is_truncated, RGWUsageIter& usage_iter,
                           std::map<rgw_user_bucket, rgw_usage_log_entry>& usage) override;
index 712e6bdffd644cbc98d105523314df964547afe0..1a7d43079b88485a28ed7eabdf88a9c950a72b78 100644 (file)
@@ -1572,8 +1572,9 @@ int RGWUser::execute_rename(const DoutPrefixProvider *dpp, RGWUserAdminOpState&
 
   rgw::sal::BucketList listing;
   do {
-    ret = old_user->list_buckets(dpp, listing.next_marker, "",
-                                 max_entries, false, listing, y);
+    ret = driver->list_buckets(dpp, old_user->get_id(), old_user->get_tenant(),
+                               listing.next_marker, "", max_entries, false,
+                               listing, y);
     if (ret < 0) {
       set_err_msg(err_msg, "unable to list user buckets");
       return ret;
@@ -1813,8 +1814,9 @@ int RGWUser::execute_remove(const DoutPrefixProvider *dpp, RGWUserAdminOpState&
 
   rgw::sal::BucketList listing;
   do {
-    ret = user->list_buckets(dpp, listing.next_marker, string(),
-                             max_buckets, false, listing, y);
+    ret = driver->list_buckets(dpp, user->get_id(), user->get_tenant(),
+                               listing.next_marker, string(),
+                               max_buckets, false, listing, y);
     if (ret < 0) {
       set_err_msg(err_msg, "unable to list user buckets");
       return ret;
@@ -1969,8 +1971,9 @@ int RGWUser::execute_modify(const DoutPrefixProvider *dpp, RGWUserAdminOpState&
 
     rgw::sal::BucketList listing;
     do {
-      ret = user->list_buckets(dpp, listing.next_marker, string(),
-                               max_buckets, false, listing, y);
+      ret = driver->list_buckets(dpp, user->get_id(), user->get_tenant(),
+                                 listing.next_marker, string(),
+                                 max_buckets, false, listing, y);
       if (ret < 0) {
         set_err_msg(err_msg, "could not get buckets for uid:  " + user_id.to_str());
         return ret;
@@ -2182,7 +2185,7 @@ int RGWUserAdminOp_User::info(const DoutPrefixProvider *dpp,
   ruser = driver->get_user(info.user_id);
 
   if (op_state.sync_stats) {
-    ret = rgw_user_sync_all_stats(dpp, driver, ruser.get(), y);
+    ret = rgw_sync_all_stats(dpp, y, driver, ruser->get_id(), ruser->get_tenant());
     if (ret < 0) {
       return ret;
     }
@@ -2191,7 +2194,10 @@ int RGWUserAdminOp_User::info(const DoutPrefixProvider *dpp,
   RGWStorageStats stats;
   RGWStorageStats *arg_stats = NULL;
   if (op_state.fetch_stats) {
-    int ret = ruser->read_stats(dpp, y, &stats);
+    ceph::real_time last_synced; // ignored
+    ceph::real_time last_updated; // ignored
+    int ret = driver->load_stats(dpp, y, ruser->get_id(), stats,
+                                 last_synced, last_updated);
     if (ret < 0 && ret != -ENOENT) {
       return ret;
     }
@@ -2787,47 +2793,6 @@ int RGWUserCtl::remove_info(const DoutPrefixProvider *dpp,
   });
 }
 
-int RGWUserCtl::list_buckets(const DoutPrefixProvider *dpp, 
-                             const rgw_user& user,
-                             const string& marker,
-                             const string& end_marker,
-                             uint64_t max,
-                             bool need_stats,
-                             rgw::sal::BucketList& listing,
-                            optional_yield y,
-                             uint64_t default_max)
-{
-  if (!max) {
-    max = default_max;
-  }
-
-  int ret = svc.user->list_buckets(dpp, user, marker, end_marker,
-                                   max, listing, y);
-  if (ret < 0) {
-    return ret;
-  }
-  if (need_stats) {
-    ret = ctl.bucket->read_buckets_stats(listing.buckets, y, dpp);
-    if (ret < 0 && ret != -ENOENT) {
-      ldpp_dout(dpp, 0) << "ERROR: could not get stats for buckets" << dendl;
-      return ret;
-    }
-  }
-  return 0;
-}
-
-int RGWUserCtl::read_stats(const DoutPrefixProvider *dpp, 
-                           const rgw_user& user, RGWStorageStats *stats,
-                          optional_yield y,
-                          ceph::real_time *last_stats_sync,
-                          ceph::real_time *last_stats_update)
-{
-  return be_handler->call([&](RGWSI_MetaBackend_Handler::Op *op) {
-    return svc.user->read_stats(dpp, op->ctx(), user, stats,
-                               last_stats_sync, last_stats_update, y);
-  });
-}
-
 RGWMetadataHandler *RGWUserMetaHandlerAllocator::alloc(RGWSI_User *user_svc) {
   return new RGWUserMetadataHandler(user_svc);
 }
index 7947b3094bd853e8a8b8ddbe8b2ac09178e52f13..906917e01e6d909a8672b9e4b6b00e943c31ec28 100644 (file)
@@ -65,7 +65,9 @@ struct bucket_meta_entry {
   uint64_t count;
 };
 
-extern int rgw_user_sync_all_stats(const DoutPrefixProvider *dpp, rgw::sal::Driver* driver, rgw::sal::User* user, optional_yield y);
+int rgw_sync_all_stats(const DoutPrefixProvider *dpp,
+                       optional_yield y, rgw::sal::Driver* driver,
+                       const rgw_owner& owner, const std::string& tenant);
 extern int rgw_user_get_all_buckets_stats(const DoutPrefixProvider *dpp,
   rgw::sal::Driver* driver, rgw::sal::User* user,
   std::map<std::string, bucket_meta_entry>& buckets_usage_map, optional_yield y);
@@ -873,22 +875,6 @@ public:
   int remove_info(const DoutPrefixProvider *dpp, 
                   const RGWUserInfo& info, optional_yield y,
                   const RemoveParams& params = {});
-
-  int list_buckets(const DoutPrefixProvider *dpp, 
-                   const rgw_user& user,
-                   const std::string& marker,
-                   const std::string& end_marker,
-                   uint64_t max,
-                   bool need_stats,
-                   rgw::sal::BucketList& listing,
-                  optional_yield y,
-                   uint64_t default_max = 1000);
-
-  int read_stats(const DoutPrefixProvider *dpp, 
-                 const rgw_user& user, RGWStorageStats *stats,
-                optional_yield y,
-                ceph::real_time *last_stats_sync = nullptr,     /* last time a full stats sync completed */
-                ceph::real_time *last_stats_update = nullptr);   /* last time a stats update was done */
 };
 
 class RGWUserMetaHandlerAllocator {
index 5d5371b963d6b548da12a788fb297f42b31cb28c..ee7b4aafa6df5aef8d38a57029dd144cd10ddece 100644 (file)
@@ -312,37 +312,56 @@ int info(const DoutPrefixProvider* dpp,
 int stats(const DoutPrefixProvider* dpp,
           rgw::sal::Driver* driver,
           AdminOpState& op_state,
+          bool sync_stats,
+          bool reset_stats,
           std::string& err_msg,
           RGWFormatterFlusher& flusher,
           optional_yield y)
 {
   int ret = 0;
-  std::string account_id;
+  RGWAccountInfo info;
+  rgw::sal::Attrs attrs; // ignored
+  RGWObjVersionTracker objv; // ignored
 
   if (!op_state.account_id.empty()) {
-    account_id = op_state.account_id;
+    // look up account by id
+    ret = driver->load_account_by_id(dpp, y, op_state.account_id,
+                                     info, attrs, objv);
   } else if (!op_state.account_name.empty()) {
-    // look up account id by name
-    RGWAccountInfo info;
-    rgw::sal::Attrs attrs;
-    RGWObjVersionTracker objv;
+    // look up account by tenant/name
     ret = driver->load_account_by_name(dpp, y, op_state.tenant,
                                        op_state.account_name,
                                        info, attrs, objv);
-    if (ret < 0) {
-      return ret;
-    }
-    account_id = std::move(info.id);
   } else {
     err_msg = "requires account id or name";
     return -EINVAL;
   }
+  if (ret < 0) {
+    err_msg = "failed to load account";
+    return ret;
+  }
+
+  const rgw_owner owner = rgw_account_id{info.id};
+
+  if (sync_stats) {
+    ret = rgw_sync_all_stats(dpp, y, driver, owner, info.tenant);
+    if (ret < 0) {
+      err_msg = "failed to sync account stats";
+      return ret;
+    }
+  } else if (reset_stats) {
+    ret = driver->reset_stats(dpp, y, owner);
+    if (ret < 0) {
+      err_msg = "failed to reset account stats";
+      return ret;
+    }
+  }
 
   RGWStorageStats stats;
   ceph::real_time last_synced;
   ceph::real_time last_updated;
-  ret = driver->load_account_stats(dpp, y, account_id, stats,
-                                   last_synced, last_updated);
+  ret = driver->load_stats(dpp, y, owner, stats,
+                           last_synced, last_updated);
   if (ret < 0) {
     return ret;
   }
index 77969363261d7d45394a4845d3fe67c4efd2777f..04af0b31817c01d19cf713f2346897c719c21561 100644 (file)
@@ -73,7 +73,8 @@ int info(const DoutPrefixProvider* dpp, rgw::sal::Driver* driver,
 
 /// dump account storage stats
 int stats(const DoutPrefixProvider* dpp, rgw::sal::Driver* driver,
-          AdminOpState& op_state, std::string& err_msg,
+          AdminOpState& op_state, bool sync_stats,
+          bool reset_stats, std::string& err_msg,
           RGWFormatterFlusher& flusher, optional_yield y);
 
 } // namespace rgw::account
index e693d1288deb795d983e537c64ca5356b3334416..c60b068bc7f80419888b28e3e26ec8c961de62f6 100644 (file)
@@ -6548,6 +6548,7 @@ int main(int argc, const char **argv)
   }
 
   user_op.account_id = account_id;
+  bucket_op.account_id = account_id;
 
   // RGWUser to use for user operations
   RGWUser ruser;
@@ -8852,7 +8853,8 @@ next:
   }
 
   if (opt_cmd == OPT::USER_CHECK) {
-    check_bad_user_bucket_mapping(driver, *user.get(), fix, null_yield, dpp());
+    check_bad_owner_bucket_mapping(driver, user->get_id(), user->get_tenant(),
+                                   fix, null_yield, dpp());
   }
 
   if (opt_cmd == OPT::USER_STATS) {
@@ -8871,7 +8873,7 @@ next:
          "so at most one of the two should be specified" << std::endl;
        return EINVAL;
       }
-      ret = static_cast<rgw::sal::RadosStore*>(driver)->svc()->user->reset_bucket_stats(dpp(), user->get_id(), null_yield);
+      ret = driver->reset_stats(dpp(), null_yield, user->get_id());
       if (ret < 0) {
        cerr << "ERROR: could not reset user stats: " << cpp_strerror(-ret) <<
          std::endl;
@@ -8893,7 +8895,8 @@ next:
           return -ret;
         }
       } else {
-        int ret = rgw_user_sync_all_stats(dpp(), driver, user.get(), null_yield);
+        int ret = rgw_sync_all_stats(dpp(), null_yield, driver,
+                                     user->get_id(), user->get_tenant());
         if (ret < 0) {
           cerr << "ERROR: could not sync user stats: " <<
            cpp_strerror(-ret) << std::endl;
@@ -8906,7 +8909,8 @@ next:
     RGWStorageStats stats(omit_utilized_stats);
     ceph::real_time last_stats_sync;
     ceph::real_time last_stats_update;
-    int ret = user->read_stats(dpp(), null_yield, &stats, &last_stats_sync, &last_stats_update);
+    int ret = driver->load_stats(dpp(), null_yield, user->get_id(),
+                                 stats, last_stats_sync, last_stats_update);
     if (ret < 0) {
       if (ret == -ENOENT) { /* in case of ENOENT */
         cerr << "User has not been initialized or user does not exist" << std::endl;
@@ -11133,7 +11137,8 @@ next:
     }
 
     if (opt_cmd == OPT::ACCOUNT_STATS) {
-      ret = rgw::account::stats(dpp(), driver, op_state, err_msg,
+      ret = rgw::account::stats(dpp(), driver, op_state,
+                                sync_stats, reset_stats, err_msg,
                                 stream_flusher, null_yield);
       if (ret < 0) {
         cerr << "ERROR: failed to read account stats with " << cpp_strerror(-ret)
index d8a16fba3f266b6eaa523f8166aa3a3c10aa98e2..6f0cb5d80a21fd3e1036a1c25174b1635deef218 100644 (file)
@@ -457,7 +457,10 @@ void rgw::auth::WebIdentityApplier::load_acct_info(const DoutPrefixProvider* dpp
 
   //Check if user_id.buckets already exists, may have been from the time, when shadow users didnt exist
   RGWStorageStats stats;
-  int ret = user->read_stats(dpp, null_yield, &stats);
+  ceph::real_time last_synced;
+  ceph::real_time last_updated;
+  int ret = driver->load_stats(dpp, null_yield, federated_user, stats,
+                               last_synced, last_updated);
   if (ret < 0 && ret != -ENOENT) {
     ldpp_dout(dpp, 0) << "ERROR: reading stats for the user returned error " << ret << dendl;
     return;
index 04f432c43036c2ed88121d3faa6a3cd13b2500de..6dbac832d914670c97442ba84ceee785fbd99e68 100644 (file)
@@ -2604,13 +2604,20 @@ void RGWListBuckets::execute(optional_yield y)
       read_count = max_buckets;
     }
 
-    op_ret = s->user->list_buckets(this, marker, end_marker, read_count, should_get_stats(), listing, y);
+    if (s->auth.identity->is_anonymous()) {
+      ldpp_dout(this, 20) << "skipping list_buckets() for anonymous user" << dendl;
+      marker.clear();
+      break;
+    }
+
+    op_ret = driver->list_buckets(this, s->owner.id, s->auth.identity->get_tenant(),
+                                  marker, end_marker, read_count, should_get_stats(), listing, y);
 
     if (op_ret < 0) {
       /* hmm.. something wrong here.. the user was authenticated, so it
          should exist */
-      ldpp_dout(this, 10) << "WARNING: failed on rgw_get_user_buckets uid="
-                       << s->user->get_id() << dendl;
+      ldpp_dout(this, 10) << "WARNING: failed on list_buckets owner="
+                       << s->owner.id << dendl;
       break;
     }
 
@@ -2688,7 +2695,8 @@ void RGWGetUsage::execute(optional_yield y)
     }    
   }
 
-  op_ret = rgw_user_sync_all_stats(this, driver, s->user.get(), y);
+  op_ret = rgw_sync_all_stats(this, y, driver, s->user->get_id(),
+                              s->user->get_tenant());
   if (op_ret < 0) {
     ldpp_dout(this, 0) << "ERROR: failed to sync user stats" << dendl;
     return;
@@ -2700,7 +2708,10 @@ void RGWGetUsage::execute(optional_yield y)
     return;
   }
 
-  op_ret = s->user->read_stats(this, y, &stats);
+  ceph::real_time synced; // ignored
+  ceph::real_time updated; // ignored
+  op_ret = driver->load_stats(this, y, s->user->get_id(),
+                              stats, synced, updated);
   if (op_ret < 0) {
     ldpp_dout(this, 0) << "ERROR: can't read user header"  << dendl;
     return;
@@ -2733,13 +2744,14 @@ void RGWStatAccount::execute(optional_yield y)
 
   rgw::sal::BucketList listing;
   do {
-    op_ret = s->user->list_buckets(this, listing.next_marker, string(),
-                                   max_buckets, true, listing, y);
+    op_ret = driver->list_buckets(this, s->owner.id, s->auth.identity->get_tenant(),
+                                  listing.next_marker, string(),
+                                  max_buckets, true, listing, y);
     if (op_ret < 0) {
       /* hmm.. something wrong here.. the user was authenticated, so it
          should exist */
-      ldpp_dout(this, 10) << "WARNING: failed on list_buckets uid="
-                       << s->user->get_id() << " ret=" << op_ret << dendl;
+      ldpp_dout(this, 10) << "WARNING: failed on list_buckets owner="
+                       << s->owner.id << " ret=" << op_ret << dendl;
       return;
     }
 
@@ -3152,23 +3164,59 @@ int RGWGetBucketLocation::verify_permission(optional_yield y)
   return verify_bucket_owner_or_policy(s, rgw::IAM::s3GetBucketLocation);
 }
 
+static int get_account_max_buckets(const DoutPrefixProvider* dpp,
+                                   optional_yield y,
+                                   rgw::sal::Driver* driver,
+                                   const rgw_account_id& id,
+                                   int32_t& max_buckets)
+{
+  RGWAccountInfo info;
+  rgw::sal::Attrs attrs;
+  RGWObjVersionTracker objv;
+
+  int ret = driver->load_account_by_id(dpp, y, id, info, attrs, objv);
+  if (ret < 0) {
+    ldpp_dout(dpp, 4) << "failed to load account owner: " << cpp_strerror(ret) << dendl;
+    return ret;
+  }
+
+  max_buckets = info.max_buckets;
+  return 0;
+}
+
 // list the user's buckets to check whether they're at their maximum
-static int check_user_max_buckets(const DoutPrefixProvider* dpp,
-                                  rgw::sal::User& user, optional_yield y)
+static int check_owner_max_buckets(const DoutPrefixProvider* dpp,
+                                   rgw::sal::Driver* driver, req_state* s,
+                                   optional_yield y)
 {
-  int32_t remaining = user.get_max_buckets();
+  int32_t remaining = 0;
+
+  const rgw_account_id* account = std::get_if<rgw_account_id>(&s->owner.id);
+  if (account) {
+    int ret = get_account_max_buckets(dpp, y, driver, *account, remaining);
+    if (ret < 0) {
+      return ret;
+    }
+  } else {
+    remaining = s->user->get_max_buckets();
+  }
+
+  if (remaining < 0) {
+    return -EPERM;
+  }
   if (!remaining) { // unlimited
     return 0;
   }
 
-  uint64_t max_buckets = dpp->get_cct()->_conf->rgw_list_buckets_max_chunk;
+  const uint64_t chunk_size = dpp->get_cct()->_conf->rgw_list_buckets_max_chunk;
+  const std::string& tenant = s->auth.identity->get_tenant();
 
   rgw::sal::BucketList listing;
   do {
-    size_t to_read = std::max<size_t>(max_buckets, remaining);
+    size_t to_read = std::max<size_t>(chunk_size, remaining);
 
-    int ret = user.list_buckets(dpp, listing.next_marker, string(),
-                                to_read, false, listing, y);
+    int ret = driver->list_buckets(dpp, s->owner.id, tenant, listing.next_marker,
+                                   "", to_read, false, listing, y);
     if (ret < 0) {
       return ret;
     }
@@ -3210,11 +3258,7 @@ int RGWCreateBucket::verify_permission(optional_yield y)
     }
   }
 
-  if (s->user->get_max_buckets() < 0) {
-    return -EPERM;
-  }
-
-  return check_user_max_buckets(this, *s->user, y);
+  return check_owner_max_buckets(this, driver, s, y);
 }
 
 void RGWCreateBucket::pre_exec()
@@ -7671,7 +7715,7 @@ RGWBulkUploadOp::handle_upload_path(req_state *s)
 
 int RGWBulkUploadOp::handle_dir_verify_permission(optional_yield y)
 {
-  return check_user_max_buckets(this, *s->user, y);
+  return check_owner_max_buckets(this, driver, s, y);
 }
 
 static void forward_req_info(const DoutPrefixProvider *dpp, CephContext *cct, req_info& info, const std::string& bucket_name)
index ca9eb6a2294fe3f9becc68684305854b88e219b4..eadd712d664f4176fb2eaa02ed3089417a6a0572 100644 (file)
@@ -398,23 +398,27 @@ class RGWOwnerStatsCache : public RGWQuotaCache<rgw_owner> {
    * users that didn't have quota turned on before (or existed before the user objclass
    * tracked stats) need to get their backend stats up to date.
    */
-  class UserSyncThread : public Thread {
+  class OwnerSyncThread : public Thread {
     CephContext *cct;
     RGWOwnerStatsCache *stats;
+    const std::string metadata_section;
 
-    ceph::mutex lock = ceph::make_mutex("RGWOwnerStatsCache::UserSyncThread");
+    ceph::mutex lock = ceph::make_mutex("RGWOwnerStatsCache::OwnerSyncThread");
     ceph::condition_variable cond;
   public:
 
-    UserSyncThread(CephContext *_cct, RGWOwnerStatsCache *_s) : cct(_cct), stats(_s) {}
+    OwnerSyncThread(CephContext *_cct, RGWOwnerStatsCache *_s,
+                    const std::string& metadata_section)
+      : cct(_cct), stats(_s), metadata_section(metadata_section)
+    {}
 
     void *entry() override {
-      ldout(cct, 20) << "UserSyncThread: start" << dendl;
+      ldout(cct, 20) << "OwnerSyncThread: start" << dendl;
       do {
         const DoutPrefix dp(cct, dout_subsys, "rgw user sync thread: ");
-        int ret = stats->sync_all_users(&dp, null_yield);
+        int ret = stats->sync_all_owners(&dp, metadata_section);
         if (ret < 0) {
-          ldout(cct, 5) << "ERROR: sync_all_users() returned ret=" << ret << dendl;
+          ldout(cct, 5) << "ERROR: sync_all_owners() returned ret=" << ret << dendl;
         }
 
         if (stats->going_down())
@@ -423,7 +427,7 @@ class RGWOwnerStatsCache : public RGWQuotaCache<rgw_owner> {
        std::unique_lock l{lock};
         cond.wait_for(l, std::chrono::seconds(cct->_conf->rgw_user_quota_sync_interval));
       } while (!stats->going_down());
-      ldout(cct, 20) << "UserSyncThread: done" << dendl;
+      ldout(cct, 20) << "OwnerSyncThread: done" << dendl;
 
       return NULL;
     }
@@ -436,8 +440,9 @@ class RGWOwnerStatsCache : public RGWQuotaCache<rgw_owner> {
 
   // TODO: AccountSyncThread and sync_all_accounts()
 
-  BucketsSyncThread *buckets_sync_thread;
-  UserSyncThread *user_sync_thread;
+  BucketsSyncThread* buckets_sync_thread = nullptr;
+  OwnerSyncThread* user_sync_thread = nullptr;
+  OwnerSyncThread* account_sync_thread = nullptr;
 protected:
   bool map_find(const rgw_owner& owner,const rgw_bucket& bucket, RGWQuotaCacheStats& qs) override {
     return stats_map.find(owner, qs);
@@ -453,9 +458,9 @@ protected:
 
   int fetch_stats_from_storage(const rgw_owner& owner, const rgw_bucket& bucket, RGWStorageStats& stats, optional_yield y, const DoutPrefixProvider *dpp) override;
   int sync_bucket(const rgw_owner& owner, const rgw_bucket& bucket, optional_yield y, const DoutPrefixProvider *dpp);
-  int sync_user(const DoutPrefixProvider *dpp, const rgw_user& user, optional_yield y);
-  int sync_all_users(const DoutPrefixProvider *dpp, optional_yield y);
-  // TODO: sync_account/sync_all_accounts
+  int sync_owner(const DoutPrefixProvider *dpp, const rgw_owner& owner, optional_yield y);
+  int sync_all_owners(const DoutPrefixProvider *dpp,
+                      const std::string& metadata_section);
 
   void data_modified(const rgw_owner& owner, const rgw_bucket& bucket) override;
 
@@ -483,11 +488,10 @@ public:
     if (quota_threads) {
       buckets_sync_thread = new BucketsSyncThread(driver->ctx(), this);
       buckets_sync_thread->create("rgw_buck_st_syn");
-      user_sync_thread = new UserSyncThread(driver->ctx(), this);
+      user_sync_thread = new OwnerSyncThread(driver->ctx(), this, "user");
       user_sync_thread->create("rgw_user_st_syn");
-    } else {
-      buckets_sync_thread = NULL;
-      user_sync_thread = NULL;
+      account_sync_thread = new OwnerSyncThread(driver->ctx(), this, "account");
+      account_sync_thread->create("rgw_acct_st_syn");
     }
   }
   ~RGWOwnerStatsCache() override {
@@ -508,6 +512,7 @@ public:
       stop_thread(&buckets_sync_thread);
     }
     stop_thread(&user_sync_thread);
+    stop_thread(&account_sync_thread);
   }
 };
 
@@ -534,14 +539,7 @@ int RGWOwnerStatsCache::init_refresh(const rgw_owner& owner, const rgw_bucket& b
 
   ldpp_dout(dpp, 20) << "initiating async quota refresh for owner=" << owner << dendl;
 
-  int r = std::visit(fu2::overload(
-      [&] (const rgw_user& user) {
-        std::unique_ptr<rgw::sal::User> ruser = driver->get_user(user);
-        return ruser->read_stats_async(dpp, std::move(cb));
-      },
-      [&] (const rgw_account_id& accountid) {
-        return driver->load_account_stats_async(dpp, accountid, std::move(cb));
-      }), owner);
+  int r = driver->load_stats_async(dpp, owner, std::move(cb));
   if (r < 0) {
     ldpp_dout(dpp, 0) << "could not read stats for owner=" << owner << dendl;
     return r;
@@ -566,16 +564,9 @@ int RGWOwnerStatsCache::fetch_stats_from_storage(const rgw_owner& owner,
                                                  optional_yield y,
                                                  const DoutPrefixProvider *dpp)
 {
-  int r = std::visit(fu2::overload(
-      [&] (const rgw_user& user) {
-        std::unique_ptr<rgw::sal::User> u = driver->get_user(user);
-        return u->read_stats(dpp, y, &stats);
-      },
-      [&] (const rgw_account_id& acct) {
-        ceph::real_time synced; // ignored
-        ceph::real_time updated; // ignored
-        return driver->load_account_stats(dpp, y, acct, stats, synced, updated);
-      }), owner);
+  ceph::real_time synced; // ignored
+  ceph::real_time updated; // ignored
+  int r = driver->load_stats(dpp, y, owner, stats, synced, updated);
   if (r < 0) {
     ldpp_dout(dpp, 0) << "could not read stats for owner " << owner << dendl;
     return r;
@@ -605,22 +596,46 @@ int RGWOwnerStatsCache::sync_bucket(const rgw_owner& owner, const rgw_bucket& b,
   return bucket->check_bucket_shards(dpp, ent.count, y);
 }
 
-int RGWOwnerStatsCache::sync_user(const DoutPrefixProvider *dpp, const rgw_user& _u, optional_yield y)
+// for account owners, we need to look up the tenant name by account id
+static int get_owner_tenant(const DoutPrefixProvider* dpp,
+                            optional_yield y,
+                            rgw::sal::Driver* driver,
+                            const rgw_owner& owner,
+                            std::string& tenant)
+{
+  return std::visit(fu2::overload(
+      [&] (const rgw_user& user) {
+        tenant = user.tenant;
+        return 0;
+      },
+      [&] (const rgw_account_id& account) {
+        RGWAccountInfo info;
+        rgw::sal::Attrs attrs;
+        RGWObjVersionTracker objv;
+        int ret = driver->load_account_by_id(dpp, y, account, info, attrs, objv);
+        if (ret >= 0) {
+          tenant = std::move(info.tenant);
+        }
+        return ret;
+      }), owner);
+}
+
+int RGWOwnerStatsCache::sync_owner(const DoutPrefixProvider *dpp,
+                                   const rgw_owner& owner, optional_yield y)
 {
   RGWStorageStats stats;
   ceph::real_time last_stats_sync;
   ceph::real_time last_stats_update;
-  std::unique_ptr<rgw::sal::User> user = driver->get_user(_u);
 
-  int ret = user->read_stats(dpp, y, &stats, &last_stats_sync, &last_stats_update);
+  int ret = driver->load_stats(dpp, y, owner, stats, last_stats_sync, last_stats_update);
   if (ret < 0) {
-    ldpp_dout(dpp, 5) << "ERROR: can't read user header: ret=" << ret << dendl;
+    ldpp_dout(dpp, 5) << "ERROR: can't read owner stats: ret=" << ret << dendl;
     return ret;
   }
 
   if (!driver->ctx()->_conf->rgw_user_quota_sync_idle_users &&
       last_stats_update < last_stats_sync) {
-    ldpp_dout(dpp, 20) << "user is idle, not doing a full sync (user=" << user << ")" << dendl;
+    ldpp_dout(dpp, 20) << "owner is idle, not doing a full sync (owner=" << owner << ")" << dendl;
     return 0;
   }
 
@@ -628,9 +643,17 @@ int RGWOwnerStatsCache::sync_user(const DoutPrefixProvider *dpp, const rgw_user&
   when_need_full_sync += make_timespan(driver->ctx()->_conf->rgw_user_quota_sync_wait_time);
   
   // check if enough time passed since last full sync
-  /* FIXME: missing check? */
+  if (when_need_full_sync > ceph::real_clock::now()) {
+    return 0;
+  }
+
+  std::string tenant;
+  ret = get_owner_tenant(dpp, y, driver, owner, tenant);
+  if (ret < 0) {
+    return ret;
+  }
 
-  ret = rgw_user_sync_all_stats(dpp, driver, user.get(), y);
+  ret = rgw_sync_all_stats(dpp, y, driver, owner, tenant);
   if (ret < 0) {
     ldpp_dout(dpp, 0) << "ERROR: failed user stats sync, ret=" << ret << dendl;
     return ret;
@@ -639,12 +662,11 @@ int RGWOwnerStatsCache::sync_user(const DoutPrefixProvider *dpp, const rgw_user&
   return 0;
 }
 
-int RGWOwnerStatsCache::sync_all_users(const DoutPrefixProvider *dpp, optional_yield y)
+int RGWOwnerStatsCache::sync_all_owners(const DoutPrefixProvider *dpp,
+                                        const std::string& metadata_section)
 {
-  string key = "user";
   void *handle;
-
-  int ret = driver->meta_list_keys_init(dpp, key, string(), &handle);
+  int ret = driver->meta_list_keys_init(dpp, metadata_section, string(), &handle);
   if (ret < 0) {
     ldpp_dout(dpp, 10) << "ERROR: can't get key: ret=" << ret << dendl;
     return ret;
@@ -658,25 +680,23 @@ int RGWOwnerStatsCache::sync_all_users(const DoutPrefixProvider *dpp, optional_y
     ret = driver->meta_list_keys_next(dpp, handle, max, keys, &truncated);
     if (ret < 0) {
       ldpp_dout(dpp, 0) << "ERROR: lists_keys_next(): ret=" << ret << dendl;
-      goto done;
+      break;
     }
     for (list<string>::iterator iter = keys.begin();
          iter != keys.end() && !going_down(); 
          ++iter) {
-      rgw_user user(*iter);
-      ldpp_dout(dpp, 20) << "RGWOwnerStatsCache: sync user=" << user << dendl;
-      int ret = sync_user(dpp, user, y);
-      if (ret < 0) {
-        ldpp_dout(dpp, 5) << "ERROR: sync_user() failed, user=" << user << " ret=" << ret << dendl;
-
-        /* continuing to next user */
+      const rgw_owner owner = parse_owner(*iter);
+      ldpp_dout(dpp, 20) << "RGWOwnerStatsCache: sync owner=" << owner << dendl;
+      int r = sync_owner(dpp, owner, null_yield);
+      if (r < 0) {
+        ldpp_dout(dpp, 5) << "ERROR: sync_owner() failed, owner=" << owner
+            << " ret=" << r << dendl;
+        /* continuing to next owner */
         continue;
       }
     }
   } while (truncated);
 
-  ret = 0;
-done:
   driver->meta_list_keys_complete(handle);
   return ret;
 }
index 5a49610513259081421b2cd03474feaf20d81417..f43f261d2e98deef332db98c71e82aae7efc62b7 100644 (file)
@@ -231,6 +231,18 @@ class ObjectProcessor : public DataProcessor {
                        uint32_t flags) = 0;
 };
 
+/**
+ * @brief A list of buckets
+ *
+ * This is the result from a bucket listing operation.
+ */
+struct BucketList {
+  /// The list of results, sorted by bucket name
+  std::vector<RGWBucketEnt> buckets;
+  /// The next marker to resume listing, or empty
+  std::string next_marker;
+};
+
 /** A list of key-value attributes */
   using Attrs = std::map<std::string, ceph::buffer::list>;
 
@@ -304,17 +316,25 @@ class Driver {
                                const RGWAccountInfo& info,
                                RGWObjVersionTracker& objv) = 0;
 
-    /** Load account storage stats */
-    virtual int load_account_stats(const DoutPrefixProvider* dpp,
-                                   optional_yield y, std::string_view id,
-                                   RGWStorageStats& stats,
-                                   ceph::real_time& last_synced,
-                                   ceph::real_time& last_updated) = 0;
-    /** Load account storage stats asynchronously */
-    virtual int load_account_stats_async(const DoutPrefixProvider* dpp,
-                                         std::string_view id,
-                                         boost::intrusive_ptr<ReadStatsCB> cb) = 0;
-
+    /** Load cumulative bucket storage stats for the given owner */
+    virtual int load_stats(const DoutPrefixProvider* dpp,
+                           optional_yield y,
+                           const rgw_owner& owner,
+                           RGWStorageStats& stats,
+                           ceph::real_time& last_synced,
+                           ceph::real_time& last_updated) = 0;
+    /** Load owner storage stats asynchronously */
+    virtual int load_stats_async(const DoutPrefixProvider* dpp,
+                                 const rgw_owner& owner,
+                                 boost::intrusive_ptr<ReadStatsCB> cb) = 0;
+    /** Recalculate the sum of bucket stats */
+    virtual int reset_stats(const DoutPrefixProvider *dpp,
+                            optional_yield y,
+                            const rgw_owner& owner) = 0;
+    /** Finish syncing owner stats by updating last_synced timestamp */
+    virtual int complete_flush_stats(const DoutPrefixProvider* dpp,
+                                     optional_yield y,
+                                     const rgw_owner& owner) = 0;
 
     /** Get a basic Object.  This Object is not looked up, and is incomplete, since is
      * does not have a bucket.  This should only be used when an Object is needed before
@@ -326,6 +346,12 @@ class Driver {
      * bucket must still be allocated to support bucket->create(). */
     virtual int load_bucket(const DoutPrefixProvider* dpp, const rgw_bucket& b,
                             std::unique_ptr<Bucket>* bucket, optional_yield y) = 0;
+    /** List the buckets of a given owner */
+    virtual int list_buckets(const DoutPrefixProvider* dpp,
+                            const rgw_owner& owner, const std::string& tenant,
+                            const std::string& marker, const std::string& end_marker,
+                            uint64_t max, bool need_stats, BucketList& buckets,
+                            optional_yield y) = 0;
     /** For multisite, this driver is the zone's master */
     virtual bool is_meta_master() = 0;
     /** Get zone info for this driver */
@@ -535,18 +561,6 @@ class ReadStatsCB : public boost::intrusive_ref_counter<ReadStatsCB> {
   virtual void handle_response(int r, const RGWStorageStats& stats) = 0;
 };
 
-/**
- * @brief A list of buckets
- *
- * This is the result from a bucket listing operation.
- */
-struct BucketList {
-  /// The list of results, sorted by bucket name
-  std::vector<RGWBucketEnt> buckets;
-  /// The next marker to resume listing, or empty
-  std::string next_marker;
-};
-
 /**
  * @brief User abstraction
  *
@@ -563,11 +577,6 @@ class User {
 
     /** Clone a copy of this user.  Used when modification is necessary of the copy */
     virtual std::unique_ptr<User> clone() = 0;
-    /** List the buckets owned by a user */
-    virtual int list_buckets(const DoutPrefixProvider* dpp,
-                            const std::string& marker, const std::string& end_marker,
-                            uint64_t max, bool need_stats, BucketList& buckets,
-                            optional_yield y) = 0;
 
     /** Get the display name for this User */
     virtual std::string& get_display_name() = 0;
@@ -610,16 +619,6 @@ class User {
     /** Set the attributes in attrs, leaving any other existing attrs set, and
      * write them to the backing store; a merge operation */
     virtual int merge_and_store_attrs(const DoutPrefixProvider* dpp, Attrs& new_attrs, optional_yield y) = 0;
-    /** Read the User stats from the backing Store, synchronous */
-    virtual int read_stats(const DoutPrefixProvider *dpp,
-                           optional_yield y, RGWStorageStats* stats,
-                          ceph::real_time* last_stats_sync = nullptr,
-                          ceph::real_time* last_stats_update = nullptr) = 0;
-    /** Read the User stats from the backing Store, asynchronous */
-    virtual int read_stats_async(const DoutPrefixProvider *dpp,
-                                 boost::intrusive_ptr<ReadStatsCB> cb) = 0;
-    /** Flush accumulated stat changes for this User to the backing store */
-    virtual int complete_flush_stats(const DoutPrefixProvider *dpp, optional_yield y) = 0;
     /** Read detailed usage stats for this User from the backing store */
     virtual int read_usage(const DoutPrefixProvider *dpp, uint64_t start_epoch,
                           uint64_t end_epoch, uint32_t max_entries,
index fd7a268fb7a37f839bbb0f7adbe2c01846c19a9e..5bcb906e32a94835bc75d557a981aa2ec79e0c33 100644 (file)
@@ -32,16 +32,17 @@ using namespace std;
 
 namespace rgw::sal {
 
-  int DBUser::list_buckets(const DoutPrefixProvider *dpp, const string& marker,
-      const string& end_marker, uint64_t max, bool need_stats,
-      BucketList &result, optional_yield y)
+  int DBStore::list_buckets(const DoutPrefixProvider *dpp,
+      const rgw_owner& owner, const std::string& tenant,
+      const string& marker, const string& end_marker, uint64_t max,
+      bool need_stats, BucketList &result, optional_yield y)
   {
     RGWUserBuckets ulist;
     bool is_truncated = false;
 
-    std::string owner = info.user_id.to_str();
-    int ret = store->getDB()->list_buckets(dpp, "", owner, marker,
-        end_marker, max, need_stats, &ulist, &is_truncated);
+    std::string ownerstr = to_string(owner);
+    int ret = getDB()->list_buckets(dpp, "", ownerstr,
+        marker, end_marker, max, need_stats, &ulist, &is_truncated);
     if (ret < 0)
       return ret;
 
@@ -82,25 +83,6 @@ namespace rgw::sal {
     return ret;
   }
 
-  int DBUser::read_stats(const DoutPrefixProvider *dpp,
-      optional_yield y, RGWStorageStats* stats,
-      ceph::real_time *last_stats_sync,
-      ceph::real_time *last_stats_update)
-  {
-    return 0;
-  }
-
-  /* stats - Not for first pass */
-  int DBUser::read_stats_async(const DoutPrefixProvider *dpp, boost::intrusive_ptr<ReadStatsCB> cb)
-  {
-    return 0;
-  }
-
-  int DBUser::complete_flush_stats(const DoutPrefixProvider *dpp, optional_yield y)
-  {
-    return 0;
-  }
-
   int DBUser::read_usage(const DoutPrefixProvider *dpp, uint64_t start_epoch, uint64_t end_epoch, uint32_t max_entries,
       bool *is_truncated, RGWUsageIter& usage_iter,
       map<rgw_user_bucket, rgw_usage_log_entry>& usage)
@@ -1592,21 +1574,33 @@ namespace rgw::sal {
     return -ENOTSUP;
   }
 
-  int DBStore::load_account_stats(const DoutPrefixProvider* dpp,
-                                  optional_yield y, std::string_view id,
-                                  RGWStorageStats& stats,
-                                  ceph::real_time& last_synced,
-                                  ceph::real_time& last_updated)
+  int DBStore::load_stats(const DoutPrefixProvider* dpp,
+                          optional_yield y,
+                          const rgw_owner& owner,
+                          RGWStorageStats& stats,
+                          ceph::real_time& last_synced,
+                          ceph::real_time& last_updated)
+  {
+    return 0;
+  }
+  int DBStore::load_stats_async(const DoutPrefixProvider* dpp,
+                                const rgw_owner& owner,
+                                boost::intrusive_ptr<ReadStatsCB> cb)
   {
     return -ENOTSUP;
   }
-
-  int DBStore::load_account_stats_async(const DoutPrefixProvider* dpp,
-                                        std::string_view id,
-                                        boost::intrusive_ptr<ReadStatsCB> cb)
+  int DBStore::reset_stats(const DoutPrefixProvider *dpp,
+                           optional_yield y,
+                           const rgw_owner& owner)
   {
     return -ENOTSUP;
   }
+  int DBStore::complete_flush_stats(const DoutPrefixProvider* dpp,
+                                    optional_yield y,
+                                    const rgw_owner& owner)
+  {
+    return 0;
+  }
 
   std::string DBStore::get_cluster_id(const DoutPrefixProvider* dpp,  optional_yield y)
   {
index 8df568e3c9d1434ed46e9c33d75a834e861fc954..67033ed9f70fe5c6fb8880506dd51188f1dbebe1 100644 (file)
@@ -88,15 +88,7 @@ protected:
       virtual std::unique_ptr<User> clone() override {
         return std::unique_ptr<User>(new DBUser(*this));
       }
-      int list_buckets(const DoutPrefixProvider *dpp, const std::string& marker, const std::string& end_marker,
-          uint64_t max, bool need_stats, BucketList& buckets, optional_yield y) override;
       virtual int read_attrs(const DoutPrefixProvider* dpp, optional_yield y) override;
-      virtual int read_stats(const DoutPrefixProvider *dpp,
-          optional_yield y, RGWStorageStats* stats,
-          ceph::real_time *last_stats_sync = nullptr,
-          ceph::real_time *last_stats_update = nullptr) override;
-      virtual int read_stats_async(const DoutPrefixProvider *dpp, boost::intrusive_ptr<ReadStatsCB> cb) override;
-      virtual int complete_flush_stats(const DoutPrefixProvider *dpp, optional_yield y) override;
       virtual int read_usage(const DoutPrefixProvider *dpp, uint64_t start_epoch, uint64_t end_epoch, uint32_t max_entries,
           bool* is_truncated, RGWUsageIter& usage_iter,
           std::map<rgw_user_bucket, rgw_usage_log_entry>& usage) override;
@@ -781,20 +773,32 @@ public:
                          optional_yield y,
                          const RGWAccountInfo& info,
                          RGWObjVersionTracker& objv) override;
-      int load_account_stats(const DoutPrefixProvider* dpp,
-                             optional_yield y, std::string_view id,
-                             RGWStorageStats& stats,
-                             ceph::real_time& last_synced,
-                             ceph::real_time& last_updated) override;
-      int load_account_stats_async(const DoutPrefixProvider* dpp,
-                                   std::string_view id,
-                                   boost::intrusive_ptr<ReadStatsCB> cb) override;
+
+      int load_stats(const DoutPrefixProvider* dpp,
+                     optional_yield y,
+                     const rgw_owner& owner,
+                     RGWStorageStats& stats,
+                     ceph::real_time& last_synced,
+                     ceph::real_time& last_updated) override;
+      int load_stats_async(const DoutPrefixProvider* dpp,
+                           const rgw_owner& owner,
+                           boost::intrusive_ptr<ReadStatsCB> cb) override;
+      int reset_stats(const DoutPrefixProvider *dpp,
+                      optional_yield y,
+                      const rgw_owner& owner) override;
+      int complete_flush_stats(const DoutPrefixProvider* dpp,
+                               optional_yield y,
+                               const rgw_owner& owner) override;
 
       virtual std::unique_ptr<Object> get_object(const rgw_obj_key& k) override;
       virtual std::string get_cluster_id(const DoutPrefixProvider* dpp, optional_yield y);
       std::unique_ptr<Bucket> get_bucket(const RGWBucketInfo& i) override;
       int load_bucket(const DoutPrefixProvider *dpp, const rgw_bucket& b,
                       std::unique_ptr<Bucket>* bucket, optional_yield y) override;
+      int list_buckets(const DoutPrefixProvider *dpp,
+          const rgw_owner& owner, const std::string& tenant,
+          const std::string& marker, const std::string& end_marker,
+          uint64_t max, bool need_stats, BucketList& buckets, optional_yield y) override;
       virtual bool is_meta_master() override;
       virtual Zone* get_zone() { return &zone; }
       virtual std::string zone_unique_id(uint64_t unique_num) override;
index 358f3a9ae38e09249f5d36150d8dadf3690b15f4..3032bdbedadfd3d6acbb3c1c5c486cef95dff950 100644 (file)
@@ -204,20 +204,35 @@ int FilterDriver::delete_account(const DoutPrefixProvider* dpp,
   return next->delete_account(dpp, y, info, objv);
 }
 
-int FilterDriver::load_account_stats(const DoutPrefixProvider* dpp,
-                                     optional_yield y, std::string_view id,
-                                     RGWStorageStats& stats,
-                                     ceph::real_time& last_synced,
-                                     ceph::real_time& last_updated)
+int FilterDriver::load_stats(const DoutPrefixProvider* dpp,
+                             optional_yield y,
+                             const rgw_owner& owner,
+                             RGWStorageStats& stats,
+                             ceph::real_time& last_synced,
+                             ceph::real_time& last_updated)
 {
-  return next->load_account_stats(dpp, y, id, stats, last_synced, last_updated);
+  return next->load_stats(dpp, y, owner, stats, last_synced, last_updated);
 }
 
-int FilterDriver::load_account_stats_async(const DoutPrefixProvider* dpp,
-                                           std::string_view id,
-                                           boost::intrusive_ptr<ReadStatsCB> cb)
+int FilterDriver::load_stats_async(const DoutPrefixProvider* dpp,
+                                   const rgw_owner& owner,
+                                   boost::intrusive_ptr<ReadStatsCB> cb)
 {
-  return next->load_account_stats_async(dpp, id, std::move(cb));
+  return next->load_stats_async(dpp, owner, std::move(cb));
+}
+
+int FilterDriver::reset_stats(const DoutPrefixProvider *dpp,
+                              optional_yield y,
+                              const rgw_owner& owner)
+{
+  return next->reset_stats(dpp, y, owner);
+}
+
+int FilterDriver::complete_flush_stats(const DoutPrefixProvider* dpp,
+                                       optional_yield y,
+                                       const rgw_owner& owner)
+{
+  return next->complete_flush_stats(dpp, y, owner);
 }
 
 std::unique_ptr<Object> FilterDriver::get_object(const rgw_obj_key& k)
@@ -240,6 +255,15 @@ int FilterDriver::load_bucket(const DoutPrefixProvider* dpp, const rgw_bucket& b
   return ret;
 }
 
+int FilterDriver::list_buckets(const DoutPrefixProvider* dpp,
+                               const rgw_owner& owner, const std::string& tenant,
+                               const std::string& marker, const std::string& end_marker,
+                               uint64_t max, bool need_stats, BucketList &buckets, optional_yield y)
+{
+  return next->list_buckets(dpp, owner, tenant, marker, end_marker,
+                            max, need_stats, buckets, y);
+}
+
 bool FilterDriver::is_meta_master()
 {
   return next->is_meta_master();
@@ -545,14 +569,6 @@ CephContext* FilterDriver::ctx(void)
   return next->ctx();
 }
 
-int FilterUser::list_buckets(const DoutPrefixProvider* dpp, const std::string& marker,
-                            const std::string& end_marker, uint64_t max,
-                            bool need_stats, BucketList &buckets, optional_yield y)
-{
-  return next->list_buckets(dpp, marker, end_marker, max,
-                            need_stats, buckets, y);
-}
-
 int FilterUser::read_attrs(const DoutPrefixProvider* dpp, optional_yield y)
 {
   return next->read_attrs(dpp, y);
@@ -564,24 +580,6 @@ int FilterUser::merge_and_store_attrs(const DoutPrefixProvider* dpp,
   return next->merge_and_store_attrs(dpp, new_attrs, y);
 }
 
-int FilterUser::read_stats(const DoutPrefixProvider *dpp,
-                          optional_yield y, RGWStorageStats* stats,
-                          ceph::real_time* last_stats_sync,
-                          ceph::real_time* last_stats_update)
-{
-  return next->read_stats(dpp, y, stats, last_stats_sync, last_stats_update);
-}
-
-int FilterUser::read_stats_async(const DoutPrefixProvider *dpp, boost::intrusive_ptr<ReadStatsCB> cb)
-{
-  return next->read_stats_async(dpp, cb);
-}
-
-int FilterUser::complete_flush_stats(const DoutPrefixProvider *dpp, optional_yield y)
-{
-  return next->complete_flush_stats(dpp, y);
-}
-
 int FilterUser::read_usage(const DoutPrefixProvider *dpp, uint64_t start_epoch,
                           uint64_t end_epoch, uint32_t max_entries,
                           bool* is_truncated, RGWUsageIter& usage_iter,
index d896f9999235d7a9d9ff428118ff7c0d8715d28e..ffe7955c71cc61fc514c741065d0ddf9977c1b3a 100644 (file)
@@ -186,19 +186,33 @@ public:
                      optional_yield y,
                      const RGWAccountInfo& info,
                      RGWObjVersionTracker& objv) override;
-  int load_account_stats(const DoutPrefixProvider* dpp,
-                         optional_yield y, std::string_view id,
-                         RGWStorageStats& stats,
-                         ceph::real_time& last_synced,
-                         ceph::real_time& last_updated) override;
-  int load_account_stats_async(const DoutPrefixProvider* dpp,
-                               std::string_view id,
-                               boost::intrusive_ptr<ReadStatsCB> cb) override;
+
+  int load_stats(const DoutPrefixProvider* dpp,
+                 optional_yield y,
+                 const rgw_owner& owner,
+                 RGWStorageStats& stats,
+                 ceph::real_time& last_synced,
+                 ceph::real_time& last_updated) override;
+  int load_stats_async(const DoutPrefixProvider* dpp,
+                       const rgw_owner& owner,
+                       boost::intrusive_ptr<ReadStatsCB> cb) override;
+  int reset_stats(const DoutPrefixProvider *dpp,
+                  optional_yield y,
+                  const rgw_owner& owner) override;
+  int complete_flush_stats(const DoutPrefixProvider* dpp,
+                           optional_yield y,
+                           const rgw_owner& owner) override;
 
   virtual std::unique_ptr<Object> get_object(const rgw_obj_key& k) override;
   std::unique_ptr<Bucket> get_bucket(const RGWBucketInfo& i) override;
   int load_bucket(const DoutPrefixProvider* dpp, const rgw_bucket& b,
                   std::unique_ptr<Bucket>* bucket, optional_yield y) override;
+  int list_buckets(const DoutPrefixProvider* dpp,
+                   const rgw_owner& owner, const std::string& tenant,
+                   const std::string& marker, const std::string& end_marker,
+                   uint64_t max, bool need_stats, BucketList& buckets,
+                   optional_yield y) override;
+
   virtual bool is_meta_master() override;
   virtual Zone* get_zone() override { return zone.get(); }
   virtual std::string zone_unique_id(uint64_t unique_num) override;
@@ -395,11 +409,6 @@ public:
   virtual std::unique_ptr<User> clone() override {
     return std::make_unique<FilterUser>(*this);
   }
-  virtual int list_buckets(const DoutPrefixProvider* dpp,
-                          const std::string& marker, const std::string& end_marker,
-                          uint64_t max, bool need_stats, BucketList& buckets,
-                          optional_yield y) override;
-
   virtual std::string& get_display_name() override { return next->get_display_name(); }
   virtual const std::string& get_tenant() override { return next->get_tenant(); }
   virtual void set_tenant(std::string& _t) override { next->set_tenant(_t); }
@@ -421,13 +430,6 @@ public:
   virtual int read_attrs(const DoutPrefixProvider* dpp, optional_yield y) override;
   virtual int merge_and_store_attrs(const DoutPrefixProvider* dpp, Attrs&
                                    new_attrs, optional_yield y) override;
-  virtual int read_stats(const DoutPrefixProvider *dpp,
-                        optional_yield y, RGWStorageStats* stats,
-                        ceph::real_time* last_stats_sync = nullptr,
-                        ceph::real_time* last_stats_update = nullptr) override;
-  virtual int read_stats_async(const DoutPrefixProvider *dpp,
-                              boost::intrusive_ptr<ReadStatsCB> cb) override;
-  virtual int complete_flush_stats(const DoutPrefixProvider *dpp, optional_yield y) override;
   virtual int read_usage(const DoutPrefixProvider *dpp, uint64_t start_epoch,
                         uint64_t end_epoch, uint32_t max_entries,
                         bool* is_truncated, RGWUsageIter& usage_iter,
index d77b50a111737f6e540bd949714d4862734b5352..6636d8bea19b16901eba422217533cb3f64c1921 100644 (file)
 
 using namespace std;
 
-int rgw_user_sync_all_stats(const DoutPrefixProvider *dpp, rgw::sal::Driver* driver,
-                           rgw::sal::User* user, optional_yield y)
+int rgw_sync_all_stats(const DoutPrefixProvider *dpp,
+                       optional_yield y, rgw::sal::Driver* driver,
+                       const rgw_owner& owner, const std::string& tenant)
 {
   size_t max_entries = dpp->get_cct()->_conf->rgw_list_buckets_max_chunk;
 
   rgw::sal::BucketList listing;
   int ret = 0;
   do {
-    ret = user->list_buckets(dpp, listing.next_marker, string(),
-                             max_entries, false, listing, y);
+    ret = driver->list_buckets(dpp, owner, tenant, listing.next_marker,
+                               string(), max_entries, false, listing, y);
     if (ret < 0) {
-      ldpp_dout(dpp, 0) << "failed to read user buckets: ret=" << ret << dendl;
+      ldpp_dout(dpp, 0) << "failed to list buckets: " << cpp_strerror(ret) << dendl;
       return ret;
     }
 
@@ -47,9 +48,9 @@ int rgw_user_sync_all_stats(const DoutPrefixProvider *dpp, rgw::sal::Driver* dri
     }
   } while (!listing.next_marker.empty());
 
-  ret = user->complete_flush_stats(dpp, y);
+  ret = driver->complete_flush_stats(dpp, y, owner);
   if (ret < 0) {
-    cerr << "ERROR: failed to complete syncing user stats: ret=" << ret << std::endl;
+    ldpp_dout(dpp, 0) << "ERROR: failed to complete syncing owner stats: ret=" << ret << dendl;
     return ret;
   }
 
@@ -66,8 +67,9 @@ int rgw_user_get_all_buckets_stats(const DoutPrefixProvider *dpp,
 
   rgw::sal::BucketList listing;
   do {
-    int ret = user->list_buckets(dpp, listing.next_marker, string(),
-                                 max_entries, false, listing, y);
+    int ret = driver->list_buckets(dpp, user->get_id(), user->get_tenant(),
+                                   listing.next_marker, string(),
+                                   max_entries, false, listing, y);
     if (ret < 0) {
       ldpp_dout(dpp, 0) << "failed to read user buckets: ret=" << ret << dendl;
       return ret;
index 6ff412a8a2649602723433cfc91383fbab2395ad..6cb377b7007f8958f282b1854dd733948a4a7af1 100644 (file)
@@ -90,40 +90,5 @@ public:
                                   real_time *pmtime,
                                   optional_yield y,
                                   const DoutPrefixProvider *dpp) = 0;
-
-  virtual int add_bucket(const DoutPrefixProvider *dpp, 
-                         const rgw_user& user,
-                         const rgw_bucket& bucket,
-                         ceph::real_time creation_time,
-                         optional_yield y) = 0;
-  virtual int remove_bucket(const DoutPrefixProvider *dpp, 
-                            const rgw_user& user,
-                            const rgw_bucket& _bucket, optional_yield) = 0;
-  virtual int list_buckets(const DoutPrefixProvider *dpp, 
-                           const rgw_user& user,
-                           const std::string& marker,
-                           const std::string& end_marker,
-                           uint64_t max,
-                           rgw::sal::BucketList& listing,
-                           optional_yield y) = 0;
-
-  virtual int flush_bucket_stats(const DoutPrefixProvider *dpp, 
-                                 const rgw_user& user,
-                                 const RGWBucketEnt& ent, optional_yield y) = 0;
-  virtual int complete_flush_stats(const DoutPrefixProvider *dpp,
-                                  const rgw_user& user, optional_yield y) = 0;
-  virtual int reset_bucket_stats(const DoutPrefixProvider *dpp, 
-                                const rgw_user& user,
-                                 optional_yield y) = 0;
-  virtual int read_stats(const DoutPrefixProvider *dpp, 
-                         RGWSI_MetaBackend::Context *ctx,
-                        const rgw_user& user, RGWStorageStats *stats,
-                        ceph::real_time *last_stats_sync,         /* last time a full stats sync completed */
-                        ceph::real_time *last_stats_update,
-                         optional_yield y) = 0;  /* last time a stats update was done */
-
-  virtual int read_stats_async(const DoutPrefixProvider *dpp,
-                              const rgw_user& user,
-                              boost::intrusive_ptr<rgw::sal::ReadStatsCB> cb) = 0;
 };
 
index b8fdd3212fd80b5e77de48911e96cfca623e5472..83322b042496c1731f49858cb569503be388bea2 100644 (file)
@@ -623,100 +623,3 @@ int RGWSI_User_RADOS::get_user_info_by_access_key(RGWSI_MetaBackend::Context *ct
                                   svc.zone->get_zone_params().user_keys_pool,
                                   info, objv_tracker, pmtime, y, dpp);
 }
-
-int RGWSI_User_RADOS::add_bucket(const DoutPrefixProvider *dpp, 
-                                 const rgw_user& user,
-                                 const rgw_bucket& bucket,
-                                 ceph::real_time creation_time,
-                                optional_yield y)
-{
-  rgw_raw_obj obj = get_buckets_obj(user);
-  int ret = rgwrados::buckets::add(dpp, y, *rados, obj,
-                                   bucket, creation_time);
-  if (ret < 0) {
-    ldpp_dout(dpp, 0) << "ERROR: error adding bucket to user: ret=" << ret << dendl;
-    return ret;
-  }
-
-  return 0;
-}
-
-
-int RGWSI_User_RADOS::remove_bucket(const DoutPrefixProvider *dpp, 
-                                    const rgw_user& user,
-                                    const rgw_bucket& bucket,
-                                   optional_yield y)
-{
-  rgw_raw_obj obj = get_buckets_obj(user);
-  int ret = rgwrados::buckets::remove(dpp, y, *rados, obj, bucket);
-  if (ret < 0) {
-    ldpp_dout(dpp, 0) << "ERROR: error removing bucket from user: ret=" << ret << dendl;
-  }
-
-  return 0;
-}
-
-int RGWSI_User_RADOS::list_buckets(const DoutPrefixProvider *dpp, 
-                                  const rgw_user& user,
-                                  const string& marker,
-                                  const string& end_marker,
-                                  uint64_t max,
-                                  rgw::sal::BucketList& listing,
-                                  optional_yield y)
-{
-  if (user.id == RGW_USER_ANON_ID) {
-    ldpp_dout(dpp, 20) << "RGWSI_User_RADOS::list_buckets(): anonymous user" << dendl;
-    listing.next_marker.clear();
-    return 0;
-  }
-
-  rgw_raw_obj obj = get_buckets_obj(user);
-  return rgwrados::buckets::list(dpp, y, *rados, obj, user.tenant,
-                                 marker, end_marker, max, listing);
-}
-
-int RGWSI_User_RADOS::flush_bucket_stats(const DoutPrefixProvider *dpp, 
-                                         const rgw_user& user,
-                                         const RGWBucketEnt& ent,
-                                        optional_yield y)
-{
-  rgw_raw_obj obj = get_buckets_obj(user);
-  return rgwrados::buckets::write_stats(dpp, y, *rados, obj, ent);
-}
-
-int RGWSI_User_RADOS::reset_bucket_stats(const DoutPrefixProvider *dpp, 
-                                         const rgw_user& user,
-                                        optional_yield y)
-{
-  rgw_raw_obj obj = get_buckets_obj(user);
-  return rgwrados::buckets::reset_stats(dpp, y, *rados, obj);
-}
-
-int RGWSI_User_RADOS::complete_flush_stats(const DoutPrefixProvider *dpp, 
-                                           const rgw_user& user, optional_yield y)
-{
-  rgw_raw_obj obj = get_buckets_obj(user);
-  return rgwrados::buckets::complete_flush_stats(dpp, y, *rados, obj);
-}
-
-int RGWSI_User_RADOS::read_stats(const DoutPrefixProvider *dpp, 
-                                 RGWSI_MetaBackend::Context *ctx,
-                                 const rgw_user& user, RGWStorageStats *stats,
-                                 ceph::real_time *last_stats_sync,
-                                 ceph::real_time *last_stats_update,
-                                optional_yield y)
-{
-  rgw_raw_obj obj = get_buckets_obj(user);
-  return rgwrados::buckets::read_stats(
-      dpp, y, *rados, obj, *stats,
-      last_stats_sync, last_stats_update);
-}
-
-int RGWSI_User_RADOS::read_stats_async(const DoutPrefixProvider *dpp,
-                                       const rgw_user& user,
-                                       boost::intrusive_ptr<rgw::sal::ReadStatsCB> cb)
-{
-  rgw_raw_obj obj = get_buckets_obj(user);
-  return rgwrados::buckets::read_stats_async(dpp, *rados, obj, std::move(cb));
-}
-
index aa43f9c0c18a040fb4b82c42f1f6320a7b9d22e2..69851d1db75d0cedd4ee391cf31f92a6e6a9d02a 100644 (file)
@@ -144,45 +144,4 @@ public:
                                   real_time *pmtime,
                                   optional_yield y,
                                   const DoutPrefixProvider *dpp) override;
-
-  /* user buckets directory */
-
-  int add_bucket(const DoutPrefixProvider *dpp, 
-                 const rgw_user& user,
-                 const rgw_bucket& bucket,
-                 ceph::real_time creation_time,
-                 optional_yield y) override;
-  int remove_bucket(const DoutPrefixProvider *dpp, 
-                    const rgw_user& user,
-                    const rgw_bucket& _bucket,
-                    optional_yield y) override;
-  int list_buckets(const DoutPrefixProvider *dpp, 
-                   const rgw_user& user,
-                   const std::string& marker,
-                   const std::string& end_marker,
-                   uint64_t max,
-                   rgw::sal::BucketList& listing,
-                   optional_yield y) override;
-
-  /* quota related */
-  int flush_bucket_stats(const DoutPrefixProvider *dpp, 
-                         const rgw_user& user,
-                         const RGWBucketEnt& ent, optional_yield y) override;
-
-  int complete_flush_stats(const DoutPrefixProvider *dpp, 
-                          const rgw_user& user, optional_yield y) override;
-
-  int reset_bucket_stats(const DoutPrefixProvider *dpp, 
-                        const rgw_user& user,
-                         optional_yield y) override;
-  int read_stats(const DoutPrefixProvider *dpp, 
-                 RGWSI_MetaBackend::Context *ctx,
-                const rgw_user& user, RGWStorageStats *stats,
-                ceph::real_time *last_stats_sync,              /* last time a full stats sync completed */
-                ceph::real_time *last_stats_update,
-                 optional_yield y) override;  /* last time a stats update was done */
-
-  int read_stats_async(const DoutPrefixProvider *dpp, const rgw_user& user,
-                       boost::intrusive_ptr<rgw::sal::ReadStatsCB> cb) override;
 };
-
index 57bfc08ea3503b310184d7cd482e60fa043734ec..a1343e10b15c6e531e06fd2d648ff4bab8449703 100644 (file)
@@ -93,18 +93,6 @@ public:
     return 0;
   }
 
-  virtual int read_stats(const DoutPrefixProvider *dpp, optional_yield y, RGWStorageStats* stats, ceph::real_time *last_stats_sync, ceph::real_time *last_stats_update) override {
-    return 0;
-  }
-
-  virtual int read_stats_async(const DoutPrefixProvider *dpp, boost::intrusive_ptr<sal::ReadStatsCB> cb) override {
-    return 0;
-  }
-
-  virtual int complete_flush_stats(const DoutPrefixProvider *dpp, optional_yield y) override {
-    return 0;
-  }
-
   virtual int read_usage(const DoutPrefixProvider *dpp, uint64_t start_epoch, uint64_t end_epoch, uint32_t max_entries, bool *is_truncated, RGWUsageIter& usage_iter, map<rgw_user_bucket, rgw_usage_log_entry>& usage) override {
     return 0;
   }