diff options
Diffstat (limited to 'src/rgw/driver/rados/rgw_bucket.cc')
-rw-r--r-- | src/rgw/driver/rados/rgw_bucket.cc | 302 |
1 files changed, 210 insertions, 92 deletions
diff --git a/src/rgw/driver/rados/rgw_bucket.cc b/src/rgw/driver/rados/rgw_bucket.cc index ce869f399d6..c51e61a2755 100644 --- a/src/rgw/driver/rados/rgw_bucket.cc +++ b/src/rgw/driver/rados/rgw_bucket.cc @@ -1,6 +1,7 @@ // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- // vim: ts=8 sw=2 smarttab ft=cpp +#include "include/function2.hpp" #include "rgw_acl_s3.h" #include "rgw_tag_s3.h" @@ -12,6 +13,8 @@ #include "services/svc_bucket.h" #include "services/svc_user.h" +#include "account.h" +#include "buckets.h" #include "rgw_reshard.h" #include "rgw_pubsub.h" @@ -90,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; @@ -109,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; @@ -121,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; } @@ -983,15 +987,21 @@ int RGWBucketAdminOp::dump_s3_policy(rgw::sal::Driver* driver, RGWBucketAdminOpS return 0; } -int RGWBucketAdminOp::unlink(rgw::sal::Driver* driver, RGWBucketAdminOpState& op_state, const DoutPrefixProvider *dpp, optional_yield y) +int RGWBucketAdminOp::unlink(rgw::sal::Driver* driver, RGWBucketAdminOpState& op_state, const DoutPrefixProvider *dpp, optional_yield y, string *err) { - RGWBucket bucket; + auto radosdriver = dynamic_cast<rgw::sal::RadosStore*>(driver); + if (!radosdriver) { + set_err_msg(err, "rados store only"); + return -ENOTSUP; + } + RGWBucket bucket; int ret = bucket.init(driver, op_state, y, dpp); if (ret < 0) return ret; - return static_cast<rgw::sal::RadosStore*>(driver)->ctl()->bucket->unlink_bucket(op_state.get_user_id(), op_state.get_bucket()->get_info().bucket, y, dpp, true); + auto* rados = radosdriver->getRados()->get_rados_handle(); + return radosdriver->ctl()->bucket->unlink_bucket(*rados, op_state.get_user_id(), op_state.get_bucket()->get_info().bucket, y, dpp, true); } int RGWBucketAdminOp::link(rgw::sal::Driver* driver, RGWBucketAdminOpState& op_state, const DoutPrefixProvider *dpp, optional_yield y, string *err) @@ -1000,6 +1010,11 @@ int RGWBucketAdminOp::link(rgw::sal::Driver* driver, RGWBucketAdminOpState& op_s set_err_msg(err, "empty user id"); return -EINVAL; } + auto radosdriver = dynamic_cast<rgw::sal::RadosStore*>(driver); + if (!radosdriver) { + set_err_msg(err, "rados store only"); + return -ENOTSUP; + } RGWBucket bucket; int ret = bucket.init(driver, op_state, y, dpp, err); @@ -1057,9 +1072,10 @@ int RGWBucketAdminOp::link(rgw::sal::Driver* driver, RGWBucketAdminOpState& op_s return -EIO; } - int r = static_cast<rgw::sal::RadosStore*>(driver)->ctl()->bucket->unlink_bucket(owner.id, old_bucket->get_info().bucket, y, dpp, false); + auto* rados = radosdriver->getRados()->get_rados_handle(); + int r = radosdriver->ctl()->bucket->unlink_bucket(*rados, owner.id, old_bucket->get_info().bucket, y, dpp, false); if (r < 0) { - set_err_msg(err, "could not unlink policy from user " + owner.id.to_str()); + set_err_msg(err, "could not unlink bucket from owner " + to_string(owner.id)); return r; } @@ -1098,7 +1114,7 @@ int RGWBucketAdminOp::link(rgw::sal::Driver* driver, RGWBucketAdminOpState& op_s rgw::sal::Attrs ep_attrs; rgw_ep_info ep_data{ep, ep_attrs}; - r = static_cast<rgw::sal::RadosStore*>(driver)->ctl()->bucket->link_bucket(op_state.get_user_id(), loc_bucket->get_info().bucket, loc_bucket->get_info().creation_time, y, dpp, true, &ep_data); + r = radosdriver->ctl()->bucket->link_bucket(*rados, op_state.get_user_id(), loc_bucket->get_info().bucket, loc_bucket->get_info().creation_time, y, dpp, true, &ep_data); if (r < 0) { set_err_msg(err, "failed to relink bucket"); return r; @@ -1106,7 +1122,7 @@ int RGWBucketAdminOp::link(rgw::sal::Driver* driver, RGWBucketAdminOpState& op_s if (*loc_bucket != *old_bucket) { // like RGWRados::delete_bucket -- excepting no bucket_index work. - r = static_cast<rgw::sal::RadosStore*>(driver)->ctl()->bucket->remove_bucket_entrypoint_info( + r = radosdriver->ctl()->bucket->remove_bucket_entrypoint_info( old_bucket->get_key(), y, dpp, RGWBucketCtl::Bucket::RemoveParams() .set_objv_tracker(&ep_data.ep_objv)); @@ -1114,7 +1130,7 @@ int RGWBucketAdminOp::link(rgw::sal::Driver* driver, RGWBucketAdminOpState& op_s set_err_msg(err, "failed to unlink old bucket " + old_bucket->get_tenant() + "/" + old_bucket->get_name()); return r; } - r = static_cast<rgw::sal::RadosStore*>(driver)->ctl()->bucket->remove_bucket_instance_info( + r = radosdriver->ctl()->bucket->remove_bucket_instance_info( old_bucket->get_key(), old_bucket->get_info(), y, dpp, RGWBucketCtl::BucketInstance::RemoveParams() @@ -1368,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); @@ -1376,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; @@ -1451,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, @@ -1479,34 +1536,43 @@ 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(); + auto user = driver->get_user(uid); + ret = user->load_user(dpp, y); + if (ret < 0) { + return ret; + } + const RGWUserInfo& info = user->get_info(); + if (!info.account_id.empty()) { + ldpp_dout(dpp, 1) << "Listing buckets in user account " + << info.account_id << dendl; + ret = list_owner_bucket_info(dpp, y, driver, info.account_id, uid.tenant, + op_state.marker, show_stats, flusher); + } else { + 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; @@ -1934,6 +2000,7 @@ void RGWBucketCompleteInfo::decode_json(JSONObj *obj) { class RGWBucketMetadataHandler : public RGWBucketMetadataHandlerBase { public: + librados::Rados& rados; struct Svc { RGWSI_Bucket *bucket{nullptr}; } svc; @@ -1942,7 +2009,8 @@ public: RGWBucketCtl *bucket{nullptr}; } ctl; - RGWBucketMetadataHandler() {} + explicit RGWBucketMetadataHandler(librados::Rados& rados) + : rados(rados) {} void init(RGWSI_Bucket *bucket_svc, RGWBucketCtl *bucket_ctl) override { @@ -2010,7 +2078,7 @@ public: * it immediately and don't want to invalidate our cached objv_version or the bucket obj removal * will incorrectly fail. */ - ret = ctl.bucket->unlink_bucket(be.owner, be.bucket, y, dpp, false); + ret = ctl.bucket->unlink_bucket(rados, be.owner, be.bucket, y, dpp, false); if (ret < 0) { ldpp_dout(dpp, -1) << "could not unlink bucket=" << entry << " owner=" << be.owner << dendl; } @@ -2039,17 +2107,19 @@ public: class RGWMetadataHandlerPut_Bucket : public RGWMetadataHandlerPut_SObj { RGWBucketMetadataHandler *bhandler; + librados::Rados& rados; RGWBucketEntryMetadataObject *obj; public: - RGWMetadataHandlerPut_Bucket(RGWBucketMetadataHandler *_handler, + RGWMetadataHandlerPut_Bucket(RGWBucketMetadataHandler *_handler, librados::Rados& rados, RGWSI_MetaBackend_Handler::Op *op, string& entry, RGWMetadataObject *_obj, RGWObjVersionTracker& objv_tracker, optional_yield y, - RGWMDLogSyncType type, bool from_remote_zone) : RGWMetadataHandlerPut_SObj(_handler, op, entry, _obj, objv_tracker, y, type, from_remote_zone), - bhandler(_handler) { - obj = static_cast<RGWBucketEntryMetadataObject *>(_obj); - } - ~RGWMetadataHandlerPut_Bucket() {} + RGWMDLogSyncType type, bool from_remote_zone) + : RGWMetadataHandlerPut_SObj(_handler, op, entry, _obj, objv_tracker, y, type, from_remote_zone), + bhandler(_handler), + rados(rados), + obj(static_cast<RGWBucketEntryMetadataObject *>(_obj)) + {} void encode_obj(bufferlist *bl) override { obj->get_ep().encode(*bl); @@ -2066,7 +2136,8 @@ int RGWBucketMetadataHandler::do_put(RGWSI_MetaBackend_Handler::Op *op, string& const DoutPrefixProvider *dpp, RGWMDLogSyncType type, bool from_remote_zone) { - RGWMetadataHandlerPut_Bucket put_op(this, op, entry, obj, objv_tracker, y, type, from_remote_zone); + RGWMetadataHandlerPut_Bucket put_op(this, rados, op, entry, obj, objv_tracker, + y, type, from_remote_zone); return do_put_operate(&put_op, dpp); } @@ -2096,18 +2167,32 @@ int RGWMetadataHandlerPut_Bucket::put_checked(const DoutPrefixProvider *dpp) int RGWMetadataHandlerPut_Bucket::put_post(const DoutPrefixProvider *dpp) { - auto& be = obj->get_ep(); + auto* orig_obj = static_cast<RGWBucketEntryMetadataObject *>(old_obj); + auto* old_be = orig_obj ? &orig_obj->get_ep() : nullptr; + auto& new_be = obj->get_ep(); - int ret; + RGWBucketCtl& ctl = *bhandler->ctl.bucket; + constexpr bool update_entrypoint = false; - /* link bucket */ - if (be.linked) { - ret = bhandler->ctl.bucket->link_bucket(be.owner, be.bucket, be.creation_time, y, dpp, false); - } else { - ret = bhandler->ctl.bucket->unlink_bucket(be.owner, be.bucket, y, dpp, false); + if (old_be && (old_be->owner != new_be.owner || // owner changed + (old_be->linked && !new_be.linked))) { // linked -> false + int ret = ctl.unlink_bucket(rados, old_be->owner, old_be->bucket, + y, dpp, update_entrypoint); + if (ret < 0) { + return ret; + } } - return ret; + if (new_be.linked && (!old_be || !old_be->linked || // linked -> true + old_be->owner != new_be.owner)) { // owner changed + int ret = ctl.link_bucket(rados, new_be.owner, new_be.bucket, + new_be.creation_time, y, dpp, update_entrypoint); + if (ret < 0) { + return ret; + } + } + + return 0; } int update_bucket_topic_mappings(const DoutPrefixProvider* dpp, @@ -2261,7 +2346,8 @@ WRITE_CLASS_ENCODER(archive_meta_info) class RGWArchiveBucketMetadataHandler : public RGWBucketMetadataHandler { public: - RGWArchiveBucketMetadataHandler() {} + explicit RGWArchiveBucketMetadataHandler(librados::Rados& rados) + : RGWBucketMetadataHandler(rados) {} int do_remove(RGWSI_MetaBackend_Handler::Op *op, string& entry, RGWObjVersionTracker& objv_tracker, optional_yield y, const DoutPrefixProvider *dpp) override { @@ -2356,7 +2442,7 @@ public: /* link new bucket */ - ret = ctl.bucket->link_bucket(new_be.owner, new_be.bucket, new_be.creation_time, y, dpp, false); + ret = ctl.bucket->link_bucket(rados, new_be.owner, new_be.bucket, new_be.creation_time, y, dpp, false); if (ret < 0) { ldpp_dout(dpp, 0) << "ERROR: failed to link new bucket for bucket=" << new_be.bucket << " ret=" << ret << dendl; return ret; @@ -2364,7 +2450,7 @@ public: /* clean up old stuff */ - ret = ctl.bucket->unlink_bucket(be.owner, entry_bucket, y, dpp, false); + ret = ctl.bucket->unlink_bucket(rados, be.owner, entry_bucket, y, dpp, false); if (ret < 0) { ldpp_dout(dpp, -1) << "could not unlink bucket=" << entry << " owner=" << be.owner << dendl; } @@ -3096,7 +3182,8 @@ int RGWBucketCtl::set_bucket_instance_attrs(RGWBucketInfo& bucket_info, } -int RGWBucketCtl::link_bucket(const rgw_user& user_id, +int RGWBucketCtl::link_bucket(librados::Rados& rados, + const rgw_owner& owner, const rgw_bucket& bucket, ceph::real_time creation_time, optional_yield y, @@ -3105,13 +3192,28 @@ int RGWBucketCtl::link_bucket(const rgw_user& user_id, rgw_ep_info *pinfo) { return bm_handler->call([&](RGWSI_Bucket_EP_Ctx& ctx) { - return do_link_bucket(ctx, user_id, bucket, creation_time, + return do_link_bucket(ctx, rados, owner, bucket, creation_time, update_entrypoint, pinfo, y, dpp); }); } +static rgw_raw_obj get_owner_buckets_obj(RGWSI_User* svc_user, + RGWSI_Zone* svc_zone, + const rgw_owner& owner) +{ + return std::visit(fu2::overload( + [&] (const rgw_user& uid) { + return svc_user->get_buckets_obj(uid); + }, + [&] (const rgw_account_id& account_id) { + const RGWZoneParams& zone = svc_zone->get_zone_params(); + return rgwrados::account::get_buckets_obj(zone, account_id); + }), owner); +} + int RGWBucketCtl::do_link_bucket(RGWSI_Bucket_EP_Ctx& ctx, - const rgw_user& user_id, + librados::Rados& rados, + const rgw_owner& owner, const rgw_bucket& bucket, ceph::real_time creation_time, bool update_entrypoint, @@ -3146,10 +3248,12 @@ int RGWBucketCtl::do_link_bucket(RGWSI_Bucket_EP_Ctx& ctx, } } - ret = svc.user->add_bucket(dpp, user_id, bucket, creation_time, y); + const auto& buckets_obj = get_owner_buckets_obj(svc.user, svc.zone, owner); + ret = rgwrados::buckets::add(dpp, y, rados, buckets_obj, + bucket, creation_time); if (ret < 0) { - ldpp_dout(dpp, 0) << "ERROR: error adding bucket to user directory:" - << " user=" << user_id + ldpp_dout(dpp, 0) << "ERROR: error adding bucket to owner directory:" + << " owner=" << owner << " bucket=" << bucket << " err=" << cpp_strerror(-ret) << dendl; @@ -3160,7 +3264,7 @@ int RGWBucketCtl::do_link_bucket(RGWSI_Bucket_EP_Ctx& ctx, return 0; ep.linked = true; - ep.owner = user_id; + ep.owner = owner; ep.bucket = bucket; ret = svc.bucket->store_bucket_entrypoint_info( ctx, meta_key, ep, false, real_time(), pattrs, &rot, y, dpp); @@ -3170,7 +3274,7 @@ int RGWBucketCtl::do_link_bucket(RGWSI_Bucket_EP_Ctx& ctx, return 0; done_err: - int r = do_unlink_bucket(ctx, user_id, bucket, true, y, dpp); + int r = do_unlink_bucket(ctx, rados, owner, bucket, true, y, dpp); if (r < 0) { ldpp_dout(dpp, 0) << "ERROR: failed unlinking bucket on error cleanup: " << cpp_strerror(-r) << dendl; @@ -3178,21 +3282,25 @@ done_err: return ret; } -int RGWBucketCtl::unlink_bucket(const rgw_user& user_id, const rgw_bucket& bucket, optional_yield y, const DoutPrefixProvider *dpp, bool update_entrypoint) +int RGWBucketCtl::unlink_bucket(librados::Rados& rados, const rgw_owner& owner, + const rgw_bucket& bucket, optional_yield y, + const DoutPrefixProvider *dpp, bool update_entrypoint) { return bm_handler->call([&](RGWSI_Bucket_EP_Ctx& ctx) { - return do_unlink_bucket(ctx, user_id, bucket, update_entrypoint, y, dpp); + return do_unlink_bucket(ctx, rados, owner, bucket, update_entrypoint, y, dpp); }); } int RGWBucketCtl::do_unlink_bucket(RGWSI_Bucket_EP_Ctx& ctx, - const rgw_user& user_id, + librados::Rados& rados, + const rgw_owner& owner, const rgw_bucket& bucket, bool update_entrypoint, optional_yield y, const DoutPrefixProvider *dpp) { - int ret = svc.user->remove_bucket(dpp, user_id, bucket, y); + const auto& buckets_obj = get_owner_buckets_obj(svc.user, svc.zone, owner); + int ret = rgwrados::buckets::remove(dpp, y, rados, buckets_obj, bucket); if (ret < 0) { ldpp_dout(dpp, 0) << "ERROR: error removing bucket from directory: " << cpp_strerror(-ret)<< dendl; @@ -3214,8 +3322,8 @@ int RGWBucketCtl::do_unlink_bucket(RGWSI_Bucket_EP_Ctx& ctx, if (!ep.linked) return 0; - if (ep.owner != user_id) { - ldpp_dout(dpp, 0) << "bucket entry point user mismatch, can't unlink bucket: " << ep.owner << " != " << user_id << dendl; + if (ep.owner != owner) { + ldpp_dout(dpp, 0) << "bucket entry point owner mismatch, can't unlink bucket: " << ep.owner << " != " << owner << dendl; return -EINVAL; } @@ -3233,19 +3341,20 @@ int RGWBucketCtl::read_bucket_stats(const rgw_bucket& bucket, }); } -int RGWBucketCtl::read_buckets_stats(map<string, RGWBucketEnt>& m, +int RGWBucketCtl::read_buckets_stats(std::vector<RGWBucketEnt>& buckets, optional_yield y, const DoutPrefixProvider *dpp) { return call([&](RGWSI_Bucket_X_Ctx& ctx) { - return svc.bucket->read_buckets_stats(ctx, m, y, dpp); + return svc.bucket->read_buckets_stats(ctx, buckets, y, dpp); }); } -int RGWBucketCtl::sync_user_stats(const DoutPrefixProvider *dpp, - const rgw_user& user_id, - const RGWBucketInfo& bucket_info, - optional_yield y, - RGWBucketEnt* pent) +int RGWBucketCtl::sync_owner_stats(const DoutPrefixProvider *dpp, + librados::Rados& rados, + const rgw_owner& owner, + const RGWBucketInfo& bucket_info, + optional_yield y, + RGWBucketEnt* pent) { RGWBucketEnt ent; if (!pent) { @@ -3257,7 +3366,16 @@ int RGWBucketCtl::sync_user_stats(const DoutPrefixProvider *dpp, return r; } - return svc.user->flush_bucket_stats(dpp, user_id, *pent, y); + // flush stats to the user/account owner object + const rgw_raw_obj& obj = std::visit(fu2::overload( + [&] (const rgw_user& user) { + return svc.user->get_buckets_obj(user); + }, + [&] (const rgw_account_id& id) { + const RGWZoneParams& zone = svc.zone->get_zone_params(); + return rgwrados::account::get_buckets_obj(zone, id); + }), owner); + return rgwrados::buckets::write_stats(dpp, y, rados, obj, *pent); } int RGWBucketCtl::get_sync_policy_handler(std::optional<rgw_zone_id> zone, @@ -3305,9 +3423,9 @@ int RGWBucketCtl::bucket_imports_data(const rgw_bucket& bucket, return handler->bucket_imports_data(); } -RGWBucketMetadataHandlerBase* RGWBucketMetaHandlerAllocator::alloc() +RGWBucketMetadataHandlerBase* RGWBucketMetaHandlerAllocator::alloc(librados::Rados& rados) { - return new RGWBucketMetadataHandler(); + return new RGWBucketMetadataHandler(rados); } RGWBucketInstanceMetadataHandlerBase* RGWBucketInstanceMetaHandlerAllocator::alloc(rgw::sal::Driver* driver) @@ -3315,9 +3433,9 @@ RGWBucketInstanceMetadataHandlerBase* RGWBucketInstanceMetaHandlerAllocator::all return new RGWBucketInstanceMetadataHandler(driver); } -RGWBucketMetadataHandlerBase* RGWArchiveBucketMetaHandlerAllocator::alloc() +RGWBucketMetadataHandlerBase* RGWArchiveBucketMetaHandlerAllocator::alloc(librados::Rados& rados) { - return new RGWArchiveBucketMetadataHandler(); + return new RGWArchiveBucketMetadataHandler(rados); } RGWBucketInstanceMetadataHandlerBase* RGWArchiveBucketInstanceMetaHandlerAllocator::alloc(rgw::sal::Driver* driver) |