if (sync_stats) {
if (!bucket_name.empty()) {
- int ret = rgw_bucket_sync_user_stats(store, tenant, bucket_name);
+ RGWBucketInfo bucket_info;
+ int ret = init_bucket(tenant, bucket_name, bucket_id, bucket_info, bucket);
+ if (ret < 0) {
+ cerr << "ERROR: could not init bucket: " << cpp_strerror(-ret) << std::endl;
+ return -ret;
+ }
+ int ret = store->ctl.bucket->sync_user_stats(user_id, bucket_info);
if (ret < 0) {
cerr << "ERROR: could not sync bucket stats: " << cpp_strerror(-ret) << std::endl;
return -ret;
is_truncated, default_amount);
}
-int rgw_bucket_sync_user_stats(RGWRados *store, const rgw_user& user_id, const RGWBucketInfo& bucket_info)
-{
- string buckets_obj_id;
- rgw_get_buckets_obj(user_id, buckets_obj_id);
- rgw_raw_obj obj(store->svc.zone->get_zone_params().user_uid_pool, buckets_obj_id);
-
- return store->cls_user_sync_bucket_stats(obj, bucket_info);
-}
-
-int rgw_bucket_sync_user_stats(RGWRados *store, const string& tenant_name, const string& bucket_name)
-{
- RGWBucketInfo bucket_info;
- RGWSysObjectCtx obj_ctx = store->svc.sysobj->init_obj_ctx();
- int ret = store->get_bucket_info(obj_ctx, tenant_name, bucket_name, bucket_info, NULL, null_yield);
- if (ret < 0) {
- ldout(store->ctx(), 0) << "ERROR: could not fetch bucket info: ret=" << ret << dendl;
- return ret;
- }
-
- ret = rgw_bucket_sync_user_stats(store, bucket_info.owner, bucket_info);
- if (ret < 0) {
- ldout(store->ctx(), 0) << "ERROR: could not sync user stats for bucket " << bucket_name << ": ret=" << ret << dendl;
- return ret;
- }
-
- return 0;
-}
-
int rgw_bucket_parse_bucket_instance(const string& bucket_instance, string *target_bucket_instance, int *shard_id)
{
ssize_t pos = bucket_instance.rfind(':');
return ret;
}
- ret = rgw_bucket_sync_user_stats(store, info.owner, info);
+ ret = store->ctl.bucket->sync_user_stats(info.owner, info);
if ( ret < 0) {
dout(1) << "WARNING: failed sync user stats before bucket delete. ret=" << ret << dendl;
}
return ret;
}
- ret = rgw_bucket_sync_user_stats(store, info.owner, info);
+ ret = store->ctl.bucket->sync_user_stats(info.owner, info);
if (ret < 0) {
dout(1) << "WARNING: failed sync user stats before bucket delete. ret=" << ret << dendl;
}
struct Svc {
RGWSI_Zone *zone{nullptr};
RGWSI_Bucket *bucket{nullptr};
+ RGWSI_BucketIndex *bi{nullptr};
} svc;
RGWBucketInstanceMetadataHandler(RGWSI_Zone *zone_svc,
- RGWSI_Bucket *bucket_svc) : RGWMetadataHandler_GenericMetaBE(bucket_svc->ctx(),
- bucket_svc->get_bi_be_handler()) {
+ RGWSI_Bucket *bucket_svc,
+ RGWSI_BucketIndex *bi_svc) : RGWMetadataHandler_GenericMetaBE(bucket_svc->ctx(),
+ bucket_svc->get_bi_be_handler()) {
svc.zone = zone_svc;
svc.bucket = bucket_svc;
+ svc.bi = bi_svc;
}
string get_type() override { return "bucket.instance"; }
objv_tracker = bci.info.objv_tracker;
- int ret = store->init_bucket_index(bci.info, bci.info.num_shards);
+ int ret = handler->svc.bi->init_index(bci.info);
if (ret < 0)
return ret;
class RGWArchiveBucketInstanceMetadataHandler : public RGWBucketInstanceMetadataHandler {
public:
RGWArchiveBucketInstanceMetadataHandler(RGWSI_Zone *zone_svc,
- RGWSI_Bucket *bucket_svc) : RGWBucketInstanceMetadataHandler(zone_svc, bucket_svc) {}
+ RGWSI_Bucket *bucket_svc,
+ RGWSI_BucketIndex *bi_svc) : RGWBucketInstanceMetadataHandler(zone_svc, bucket_svc, bi_svc) {}
int do_remove(RGWSI_MetaBackend_Handler::Op *op, string& entry, RGWObjVersionTracker& objv_tracker) override {
ldout(cct, 0) << "SKIP: bucket instance removal is not allowed on archive zone: bucket.instance:" << entry << dendl;
RGWBucketCtl::RGWBucketCtl(RGWSI_Zone *zone_svc,
RGWSI_Bucket *bucket_svc,
+ RGWSI_BucketIndex *bi_svc,
RGWBucketMetadataHandler *_bm_handler,
RGWBucketInstanceMetadataHandler *_bmi_handler) : cct(zone_svc->ctx()),
bm_handler(_bm_handler),
{
svc.zone = zone_svc;
svc.bucket = bucket_svc;
+ svc.bi = bi_svc;
bucket_be_handler = bm_handler->get_be_handler();
bi_be_handler = bmi_handler->get_be_handler();
}
return svc.bucket->store_bucket_entrypoint_info(op->ctx(), meta_key, ep, false, real_time(), &attrs, &ot);
}
-int RGWBucketCtl::read_buckets_stats(map<string, RGWBucketEnt>& m)
+int RGWBucketCtl::read_bucket_stats(const rgw_bucket& bucket,
+ RGWBucketEnt *result,
+ optional_yield y)
+{
+ return bi_be_handler->call([&](RGWSI_MetaBackend_Handler::Op *op) {
+ return svc.bucket->read_bucket_stats(op->ctx(), bucket, result, y);
+ });
+}
+
+int RGWBucketCtl::read_buckets_stats(map<string, RGWBucketEnt>& m,
+ optional_yield y)
{
return bi_be_handler->call([&](RGWSI_MetaBackend_Handler::Op *op) {
- return svc.bucket->read_buckets_stats(op->ctx(), m);
+ return svc.bucket->read_buckets_stats(op->ctx(), m, y);
});
}
+int RGWBucketCtl::sync_user_stats(const rgw_user& user_id, const RGWBucketInfo& bucket_info)
+{
+ RGWBucketEnt ent;
+ int r = svc.bi->read_stats(bucket_info, &ent);
+ if (r < 0) {
+ ldout(cct, 20) << __func__ << "(): failed to read bucket stats (r=" << r << ")" << dendl;
+ return r;
+ }
+
+ return ctl.user->flush_bucket_stats(user_id, ent);
+}
+
RGWMetadataHandler *RGWBucketMetaHandlerAllocator::alloc(RGWSI_Bucket *bucket_svc,
RGWBucketCtl *bucket_ctl) {
return new RGWBucketMetadataHandler(bucket_svc, bucket_ctl);
}
RGWMetadataHandler *RGWBucketInstanceMetaHandlerAllocator::alloc(RGWSI_Zone *zone_svc,
- RGWSI_Bucket *bucket_svc) {
- return new RGWBucketInstanceMetadataHandler(zone_svc, bucket_svc);
+ RGWSI_Bucket *bucket_svc,
+ RGWSI_BucketIndex *bi_svc) {
+ return new RGWBucketInstanceMetadataHandler(zone_svc, bucket_svc, bi_svc);
}
RGWMetadataHandler *RGWArchiveBucketMetaHandlerAllocator::alloc(RGWSI_Bucket *bucket_svc,
}
RGWMetadataHandler *RGWArchiveBucketInstanceMetaHandlerAllocator::alloc(RGWSI_Zone *zone_svc,
- RGWSI_Bucket *bucket_svc) {
- return new RGWArchiveBucketInstanceMetadataHandler(zone_svc, bucket_svc);
+ RGWSI_Bucket *bucket_svc,
+ RGWSI_BucketIndex *bi_svc) {
+ return new RGWArchiveBucketInstanceMetadataHandler(zone_svc, bucket_svc, bi_svc);
}
extern void rgw_bucket_instance_key_to_oid(string& key);
extern void rgw_bucket_instance_oid_to_key(string& oid);
-extern int rgw_bucket_sync_user_stats(RGWRados *store, const rgw_user& user_id, const RGWBucketInfo& bucket_info);
-extern int rgw_bucket_sync_user_stats(RGWRados *store, const string& tenant_name, const string& bucket_name);
-
extern std::string rgw_make_bucket_entry_name(const std::string& tenant_name,
const std::string& bucket_name);
static inline void rgw_make_bucket_entry_name(const string& tenant_name,
class RGWBucketInstanceMetaHandlerAllocator {
public:
static RGWMetadataHandler *alloc(RGWSI_Zone *zone_svc,
- RGWSI_Bucket *bucket_svc);
+ RGWSI_Bucket *bucket_svc,
+ RGWSI_BucketIndex *bi_svc);
};
class RGWArchiveBucketMetaHandlerAllocator {
class RGWArchiveBucketInstanceMetaHandlerAllocator {
public:
static RGWMetadataHandler *alloc(RGWSI_Zone *zone_svc,
- RGWSI_Bucket *bucket_svc);
+ RGWSI_Bucket *bucket_svc,
+ RGWSI_BucketIndex *bi_svc);
};
extern void rgw_bucket_init(RGWMetadataManager *mm);
struct Svc {
RGWSI_Zone *zone{nullptr};
RGWSI_Bucket *bucket{nullptr};
+ RGWSI_BucketIndex *bi{nullptr};
} svc;
struct Ctl {
public:
RGWBucketCtl(RGWSI_Zone *zone_svc,
RGWSI_Bucket *bucket_svc,
+ RGWSI_BucketIndex *bi_svc,
RGWBucketMetadataHandler *_bm_handler,
RGWBucketInstanceMetadataHandler *_bmi_handler);
const rgw_bucket& bucket,
bool update_entrypoint = true);
- int read_buckets_stats(map<string, RGWBucketEnt>& m);
+ int read_buckets_stats(map<string, RGWBucketEnt>& m,
+ optional_yield y);
+
+ int read_bucket_stats(const rgw_bucket& bucket,
+ RGWBucketEnt *result,
+ optional_yield y);
+
+ /* quota related */
+ int sync_user_stats(const rgw_user& user_id, const RGWBucketInfo& bucket_info);
private:
int convert_old_bucket_info(RGWSI_MetaBackend_Handler::Op *op,
const rgw_user& user_id,
const rgw_bucket& bucket,
bool update_entrypoint);
+
};
return 0;
}
-int RGWRados::cls_user_sync_bucket_stats(rgw_raw_obj& user_obj,
- const RGWBucketInfo& bucket_info)
-{
- vector<rgw_bucket_dir_header> headers;
- int r = cls_bucket_head(bucket_info, RGW_NO_SHARD, headers);
- if (r < 0) {
- ldout(cct, 20) << "cls_bucket_header() returned " << r << dendl;
- return r;
- }
-
- cls_user_bucket_entry entry;
-
- bucket_info.bucket.convert(&entry.bucket);
-
- for (const auto& hiter : headers) {
- for (const auto& iter : hiter.stats) {
- if (RGWObjCategory::Main == iter.first ||
- RGWObjCategory::MultiMeta == iter.first) {
- const struct rgw_bucket_category_stats& header_stats = iter.second;
- entry.size += header_stats.total_size;
- entry.size_rounded += header_stats.total_size_rounded;
- entry.count += header_stats.num_entries;
- }
- }
- }
-
- list<cls_user_bucket_entry> entries;
- entries.push_back(entry);
-
- r = cls_user_update_buckets(user_obj, entries, false);
- if (r < 0) {
- ldout(cct, 20) << "cls_user_update_buckets() returned " << r << dendl;
- return r;
- }
-
- return 0;
-}
-
-int RGWRados::cls_user_get_bucket_stats(const rgw_bucket& bucket, cls_user_bucket_entry& entry)
-{
- vector<rgw_bucket_dir_header> headers;
- RGWBucketInfo bucket_info;
- auto obj_ctx = svc.sysobj->init_obj_ctx();
- int ret = get_bucket_instance_info(obj_ctx, bucket, bucket_info, NULL, NULL, null_yield);
- if (ret < 0) {
- return ret;
- }
-
- ret = cls_bucket_head(bucket_info, RGW_NO_SHARD, headers);
- if (ret < 0) {
- ldout(cct, 20) << "cls_bucket_header() returned " << ret << dendl;
- return ret;
- }
-
- bucket.convert(&entry.bucket);
-
- for (const auto& hiter : headers) {
- for (const auto& iter : hiter.stats) {
- const struct rgw_bucket_category_stats& header_stats = iter.second;
- entry.size += header_stats.total_size;
- entry.size_rounded += header_stats.total_size_rounded;
- entry.count += header_stats.num_entries;
- }
- }
-
- return 0;
-}
-
-int RGWRados::cls_user_list_buckets(rgw_raw_obj& obj,
- const string& in_marker,
- const string& end_marker,
- const int max_entries,
- list<cls_user_bucket_entry>& entries,
- string * const out_marker,
- bool * const truncated)
-{
- rgw_rados_ref ref;
- int r = get_raw_obj_ref(obj, &ref);
- if (r < 0) {
- return r;
- }
-
- librados::ObjectReadOperation op;
- int rc;
-
- cls_user_bucket_list(op, in_marker, end_marker, max_entries, entries, out_marker, truncated, &rc);
- bufferlist ibl;
- r = ref.ioctx.operate(ref.obj.oid, &op, &ibl);
- if (r < 0)
- return r;
- if (rc < 0)
- return rc;
-
- return 0;
-}
-
-int RGWRados::cls_user_update_buckets(rgw_raw_obj& obj, list<cls_user_bucket_entry>& entries, bool add)
-{
- rgw_rados_ref ref;
- int r = get_raw_obj_ref(obj, &ref);
- if (r < 0) {
- return r;
- }
-
- librados::ObjectWriteOperation op;
- cls_user_set_buckets(op, entries, add);
- r = ref.ioctx.operate(ref.obj.oid, &op);
- if (r < 0)
- return r;
-
- return 0;
-}
-
int RGWRados::complete_sync_user_stats(const rgw_user& user_id)
{
string buckets_obj_id;
return 0;
}
-int RGWRados::cls_user_remove_bucket(rgw_raw_obj& obj, const cls_user_bucket& bucket)
-{
- rgw_rados_ref ref;
- int r = get_system_obj_ref(obj, &ref);
- if (r < 0) {
- return r;
- }
-
- librados::ObjectWriteOperation op;
- ::cls_user_remove_bucket(op, bucket);
- r = ref.ioctx.operate(ref.obj.oid, &op);
- if (r < 0)
- return r;
-
- return 0;
-}
-
int RGWRados::check_bucket_shards(const RGWBucketInfo& bucket_info, const rgw_bucket& bucket,
RGWQuotaInfo& bucket_quota)
{
#include "rgw_service.h"
#include "services/svc_rados.h"
+#include "services/svc_bi_rados.h"
class RGWWatcher;
class SafeTimer;
int get_max_chunk_size(const rgw_placement_rule& placement_rule, const rgw_obj& obj, uint64_t *max_chunk_size, uint64_t *palignment = nullptr);
uint32_t get_max_bucket_shards() {
- return rgw_shards_max();
+ return RGWSI_BucketIndex_RADOS::shards_max();
}
int cls_user_get_header(const string& user_id, cls_user_header *header);
int cls_user_reset_stats(const string& user_id);
int cls_user_get_header_async(const string& user_id, RGWGetUserHeader_CB *ctx);
- int cls_user_sync_bucket_stats(rgw_raw_obj& user_obj, const RGWBucketInfo& bucket_info);
- int cls_user_list_buckets(rgw_raw_obj& obj,
- const string& in_marker,
- const string& end_marker,
- int max_entries,
- list<cls_user_bucket_entry>& entries,
- string *out_marker,
- bool *truncated);
- int cls_user_update_buckets(rgw_raw_obj& obj, list<cls_user_bucket_entry>& entries, bool add);
int cls_user_complete_stats_sync(rgw_raw_obj& obj);
int complete_sync_user_stats(const rgw_user& user_id);
- int cls_user_remove_bucket(rgw_raw_obj& obj, const cls_user_bucket& bucket);
- int cls_user_get_bucket_stats(const rgw_bucket& bucket, cls_user_bucket_entry& entry);
int check_quota(const rgw_user& bucket_owner, rgw_bucket& bucket,
RGWQuotaInfo& user_quota, RGWQuotaInfo& bucket_quota, uint64_t obj_size, bool check_size_only = false);
#include "rgw_service.h"
#include "services/svc_finisher.h"
+#include "services/svc_bi_rados.h"
#include "services/svc_bucket.h"
#include "services/svc_cls.h"
#include "services/svc_mdlog.h"
{
finisher = std::make_unique<RGWSI_Finisher>(cct);
bucket = std::make_unique<RGWSI_Bucket>(cct);
+ bi_rados = std::make_unique<RGWSI_BucketIndex_RADOS>(cct);
cls = std::make_unique<RGWSI_Cls>(cct);
mdlog = std::make_unique<RGWSI_MDLog>(cct);
meta = std::make_unique<RGWSI_Meta>(cct);
vector<RGWSI_MetaBackend *> meta_bes{meta_be_sobj.get(), meta_be_otp.get()};
finisher->init();
- bucket->init(zone.get(), sysobj.get(), sysobj_cache.get(), meta.get(), sync_modules.get());
+ bi_rados->init(zone.get(), rados.get());
+ bucket->init(zone.get(), sysobj.get(), sysobj_cache.get(),
+ bi_rados.get(), meta.get(), sync_modules.get());
cls->init(zone.get(), rados.get());
mdlog->init(zone.get(), sysobj.get());
meta->init(sysobj.get(), mdlog.get(), meta_bes);
}
finisher = _svc.finisher.get();
+ bi = _svc.bi_rados.get();
bucket = _svc.bucket.get();
cls = _svc.cls.get();
mdlog = _svc.mdlog.get();
meta.otp.reset(RGWOTPMetaHandlerAllocator::alloc(svc.zone, svc.meta_be_otp));
user.reset(new RGWUserCtl(svc.zone, svc.user, (RGWUserMetadataHandler *)meta.user.get()));
- bucket.reset(new RGWBucketCtl(svc.zone, svc.bucket,
+ bucket.reset(new RGWBucketCtl(svc.zone, svc.bucket, svc.bi,
(RGWBucketMetadataHandler *)meta.bucket.get()),
(RGWBucketInstanceMetadataHandler *)meta.bucket_instance.get());
class RGWSI_Finisher;
class RGWSI_Bucket;
+class RGWSI_BucketIndex;
+class RGWSI_BucketIndex_RADOS;
class RGWSI_Cls;
class RGWSI_MDLog;
class RGWSI_Meta;
std::unique_ptr<RGWSI_Finisher> finisher;
std::unique_ptr<RGWSI_Bucket> bucket;
+ std::unique_ptr<RGWSI_BucketIndex_RADOS> bi_rados;
std::unique_ptr<RGWSI_Cls> cls;
std::unique_ptr<RGWSI_MDLog> mdlog;
std::unique_ptr<RGWSI_Meta> meta;
RGWSI_Finisher *finisher{nullptr};
RGWSI_Bucket *bucket{nullptr};
+ RGWSI_BucketIndex *bi{nullptr};
RGWSI_Cls *cls{nullptr};
RGWSI_MDLog *mdlog{nullptr};
RGWSI_Meta *meta{nullptr};
ldout(cct, 0) << "ERROR: could not read bucket info: bucket=" << bucket_ent.bucket << " ret=" << ret << dendl;
continue;
}
- ret = rgw_bucket_sync_user_stats(store, user_id, bucket_info);
+ ret = store->ctl.bucket->sync_user_stats(user_id, bucket_info);
if (ret < 0) {
ldout(cct, 0) << "ERROR: could not sync bucket stats: ret=" << ret << dendl;
return ret;
marker = i.first;
const RGWBucketEnt& bucket_ent = i.second;
- cls_user_bucket_entry entry;
- ret = store->cls_user_get_bucket_stats(bucket_ent.bucket, entry);
+ RGWBucketEnt stats;
+ ret = store->ctl.bucket->read_bucket_stats(bucket_ent.bucket, &stats, null_yield);
if (ret < 0) {
ldout(cct, 0) << "ERROR: could not get bucket stats: ret=" << ret << dendl;
return ret;
}
+ cls_user_bucket_entry entry;
+ stats.convert(&entry);
buckets_usage_map.emplace(bucket_ent.bucket.name, entry);
}
done = (buckets.size() < max_entries);
}
if (need_stats) {
map<string, RGWBucketEnt>& m = buckets->get_buckets();
- ret = ctl.bucket->read_buckets_stats(m);
+ ret = ctl.bucket->read_buckets_stats(m, null_yield);
if (ret < 0 && ret != -ENOENT) {
ldout(svc.user->ctx(), 0) << "ERROR: could not get stats for buckets" << dendl;
return ret;
});
}
+int RGWUserCtl::flush_bucket_stats(const rgw_user& user,
+ const RGWBucketEnt& ent)
+{
+ return be_handler->call([&](RGWSI_MetaBackend_Handler::Op *op) {
+ return svc.user->flush_bucket_stats(op->ctx(), user, ent);
+ });
+}
+
RGWMetadataHandler *RGWUserMetaHandlerAllocator::alloc(RGWSI_User *user_svc) {
return new RGWUserMetadataHandler(user_svc);
}
RGWUserBuckets *buckets,
bool *is_truncated,
uint64_t default_max);
+
+ int flush_bucket_stats(const rgw_user& user,
+ const RGWBucketEnt& ent);
};
class RGWUserMetaHandlerAllocator {
#include "rgw/rgw_service.h"
+class RGWBucketInfo;
+struct RGWBucketEnt;
+
class RGWSI_BucketIndex : public RGWServiceInstance
{
public:
RGWSI_BucketIndex(CephContext *cct) : RGWServiceInstance(cct) {}
virtual ~RGWSI_BucketIndex() {}
+
+ virtual int init_index(RGWBucketInfo& bucket_info) = 0;
+ virtual int clean_index(RGWBucketInfo& bucket_info) = 0;
+
+ virtual int read_stats(const RGWBucketInfo& bucket_info,
+ RGWBucketEnt *stats) = 0;
};
static string dir_oid_prefix = ".dir.";
-RGWSI_BucketIndex_RADOS::RGWSI_BucketIndex_RADOS(CephContext *cct,
- RGWSI_Zone *zone_svc,
- RGWSI_RADOS *rados_svc) : RGWSI_BucketIndex(cct) {
+RGWSI_BucketIndex_RADOS::RGWSI_BucketIndex_RADOS(CephContext *cct) : RGWSI_BucketIndex(cct)
+{
+}
+
+void RGWSI_BucketIndex_RADOS::init(RGWSI_Zone *zone_svc,
+ RGWSI_RADOS *rados_svc)
+{
svc.zone = zone_svc;
svc.rados = rados_svc;
}
}
-int RGWSI_BucketIndex_RADOS::init_bucket_index(RGWBucketInfo& bucket_info, int num_shards)
+int RGWSI_BucketIndex_RADOS::init_index(RGWBucketInfo& bucket_info)
{
RGWSI_RADOS::Pool index_pool;
dir_oid.append(bucket_info.bucket.bucket_id);
map<int, string> bucket_objs;
- get_bucket_index_objects(dir_oid, num_shards, &bucket_objs);
+ get_bucket_index_objects(dir_oid, bucket_info.num_shards, &bucket_objs);
return CLSRGWIssueBucketIndexInit(index_pool.ioctx(),
bucket_objs,
cct->_conf->rgw_bucket_index_max_aio)();
}
-int RGWSI_BucketIndex_RADOS::clean_bucket_index(RGWBucketInfo& bucket_info, int num_shards)
+int RGWSI_BucketIndex_RADOS::clean_index(RGWBucketInfo& bucket_info)
{
RGWSI_RADOS::Pool index_pool;
dir_oid.append(bucket_info.bucket.bucket_id);
std::map<int, std::string> bucket_objs;
- get_bucket_index_objects(dir_oid, num_shards, &bucket_objs);
+ get_bucket_index_objects(dir_oid, bucket_info.num_shards, &bucket_objs);
return CLSRGWIssueBucketIndexClean(index_pool.ioctx(),
bucket_objs,
cct->_conf->rgw_bucket_index_max_aio)();
}
+int RGWSI_BucketIndex_RADOS::read_stats(const RGWBucketInfo& bucket_info,
+ RGWBucketEnt *result)
+{
+ vector<rgw_bucket_dir_header> headers;
+
+ result->bucket = bucket_info.bucket;
+ int r = cls_bucket_head(bucket_info, RGW_NO_SHARD, &headers, nullptr);
+ if (r < 0) {
+ return r;
+ }
+
+ auto hiter = headers.begin();
+ for (; hiter != headers.end(); ++hiter) {
+ RGWObjCategory category = RGWObjCategory::Main;
+ auto iter = (hiter->stats).find(category);
+ if (iter != hiter->stats.end()) {
+ struct rgw_bucket_category_stats& stats = iter->second;
+ result->count += stats.num_entries;
+ result->size += stats.total_size;
+ result->size_rounded += stats.total_size_rounded;
+ }
+ }
+
+ result->placement_rule = std::move(bucket_info.placement_rule);
+
+ return 0;
+}
+
RGWSI_RADOS *rados{nullptr};
} svc;
- RGWSI_BucketIndex_RADOS(CephContext *cct,
- RGWSI_Zone *zone_svc,
- RGWSI_RADOS *rados_svc);
+ RGWSI_BucketIndex_RADOS(CephContext *cct);
+
+ void init(RGWSI_Zone *zone_svc,
+ RGWSI_RADOS *rados_svc);
static int shards_max() {
return RGW_SHARDS_PRIME_1;
return rgw_shards_mod(sid2, num_shards);
}
- int init_bucket_index(RGWBucketInfo& bucket_info, int num_shards);
- int clean_bucket_index(RGWBucketInfo& bucket_info, int num_shards);
+ int init_index(RGWBucketInfo& bucket_info);
+ int clean_index(RGWBucketInfo& bucket_info);
+
+ int read_stats(const RGWBucketInfo& bucket_info,
+ RGWBucketEnt *stats) override;
};
#include "svc_zone.h"
#include "svc_sys_obj.h"
#include "svc_sys_obj_cache.h"
+#include "svc_bi.h"
#include "svc_meta.h"
#include "svc_meta_be_sobj.h"
#include "svc_sync_modules.h"
}
void RGWSI_Bucket::init(RGWSI_Zone *_zone_svc, RGWSI_SysObj *_sysobj_svc,
- RGWSI_SysObj_Cache *_cache_svc, RGWSI_Meta *_meta_svc,
- RGWSI_MetaBackend *_meta_be_svc, RGWSI_SyncModules *_sync_modules_svc)
+ RGWSI_SysObj_Cache *_cache_svc, RGWSI_BucketIndex *_bi,
+ RGWSI_Meta *_meta_svc, RGWSI_MetaBackend *_meta_be_svc,
+ RGWSI_SyncModules *_sync_modules_svc)
{
svc.bucket = this;
svc.zone = _zone_svc;
svc.sysobj = _sysobj_svc;
svc.cache = _cache_svc;
+ svc.bi = _bi;
svc.meta = _meta_svc;
svc.meta_be = _meta_be_svc;
svc.sync_modules = _sync_modules_svc;
return svc.meta_be->remove_entry(ctx, key, params, objv_tracker, y);
}
+int RGWSI_Bucket::read_bucket_stats(const RGWBucketInfo& bucket_info,
+ RGWBucketEnt *ent,
+ optional_yield y)
+{
+ ent->count = 0;
+ ent->size = 0;
+ ent->size_rounded = 0;
+
+ vector<rgw_bucket_dir_header> headers;
+
+ int r = svc.bi->read_stats(bucket_info, ent, y);
+ if (r < 0) {
+ ldout(cct, 0) << "ERROR: " << __func__ << "(): read_stats returned r=" << r << dendl;
+ return r;
+ }
+
+ return 0;
+}
+
+int RGWSI_Bucket::read_bucket_stats(RGWSI_MetaBackend::Context *ctx,
+ const rgw_bucket& bucket,
+ RGWBucketEnt *ent,
+ optional_yield y)
+{
+ RGWBucketInfo bucket_info;
+ int ret = read_bucket_instance_info(ctx, get_bi_meta_key(bucket),
+ &bucket_info, nullptr, nullptr,
+ y);
+ if (ret < 0) {
+ return ret;
+ }
+
+ return read_bucket_stats(bucket_info, ent, y);
+}
+
int RGWSI_Bucket::read_buckets_stats(RGWSI_MetaBackend::Context *ctx,
- map<string, RGWBucketEnt>& m)
+ map<string, RGWBucketEnt>& m,
+ optional_yield y)
{
map<string, RGWBucketEnt>::iterator iter;
for (iter = m.begin(); iter != m.end(); ++iter) {
RGWBucketEnt& ent = iter->second;
- rgw_bucket& bucket = ent.bucket;
- ent.count = 0;
- ent.size = 0;
- ent.size_rounded = 0;
-
- vector<rgw_bucket_dir_header> headers;
-
- RGWBucketInfo bucket_info;
- int ret = read_bucket_instance_info(ctx, get_bi_meta_key(bucket),
- &bucket_info, nullptr, nullptr);
- if (ret < 0) {
- return ret;
- }
-
- int r = cls_bucket_head(bucket_info, RGW_NO_SHARD, headers);
- if (r < 0)
+ int r = read_bucket_stats(ctx, ent.bucket, &ent, y);
+ if (r < 0) {
+ ldout(cct, 0) << "ERROR: " << __func__ << "(): read_bucket_stats returned r=" << r << dendl;
return r;
-
- auto hiter = headers.begin();
- for (; hiter != headers.end(); ++hiter) {
- RGWObjCategory category = main_category;
- auto iter = (hiter->stats).find(category);
- if (iter != hiter->stats.end()) {
- struct rgw_bucket_category_stats& stats = iter->second;
- ent.count += stats.num_entries;
- ent.size += stats.total_size;
- ent.size_rounded += stats.total_size_rounded;
- }
}
-
- // fill in placement_rule from the bucket instance for use in swift's
- // per-storage policy statistics
- ent.placement_rule = std::move(bucket_info.placement_rule);
}
return m.size();
map<string, bufferlist> *pattrs,
rgw_cache_entry_info *cache_info,
boost::optional<obj_version> refresh_version);
+
+ int read_bucket_stats(const RGWBucketInfo& bucket_info,
+ RGWBucketEnt *ent,
+ optional_yield y);
+
public:
struct Svc {
RGWSI_Bucket *bucket{nullptr};
+ RGWSI_BucketIndex *bi{nullptr};
RGWSI_Zone *zone{nullptr};
RGWSI_SysObj *sysobj{nullptr};
RGWSI_SysObj_Cache *cache{nullptr};
return bi_be_handler;
}
- void init(RGWSI_Zone *_zone_svc, RGWSI_SysObj *_sysobj_svc,
- RGWSI_SysObj_Cache *_cache_svc, RGWSI_Meta *_meta_svc,
+ void init(RGWSI_Zone *_zone_svc,
+ RGWSI_SysObj *_sysobj_svc,
+ RGWSI_SysObj_Cache *_cache_svc,
+ RGWSI_BucketIndex *_bi,
+ RGWSI_Meta *_meta_svc,
RGWSI_MetaBackend *_meta_be_svc,
RGWSI_SyncModules *_sync_modules);
RGWObjVersionTracker *objv_tracker,
optional_yield y);
+ int read_bucket_stats(RGWSI_MetaBackend::Context *ctx,
+ const rgw_bucket& bucket,
+ RGWBucketEnt *ent,
+ optional_yield y);
+
int read_buckets_stats(RGWSI_MetaBackend::Context *ctx,
- map<string, RGWBucketEnt>& m);
+ map<string, RGWBucketEnt>& m,
+ optional_yield y);
};
uint64_t max,
RGWUserBuckets *buckets,
bool *is_truncated) = 0;
+
+ virtual int flush_bucket_stats(RGWSI_MetaBackend::Context *ctx,
+ const rgw_user& user,
+ const RGWBucketEnt& ent) = 0;
};
return 0;
}
+int RGWSI_User_RADOS::cls_user_flush_bucket_stats(rgw_raw_obj& user_obj,
+ const RGWBucketEnt& ent)
+{
+ cls_user_bucket_entry entry;
+ ent.convert(&entry);
+
+ list<cls_user_bucket_entry> entries;
+ entries.push_back(entry);
+
+ int r = cls_user_update_buckets(user_obj, entries, false);
+ if (r < 0) {
+ ldout(cct, 20) << "cls_user_update_buckets() returned " << r << dendl;
+ return r;
+ }
+
+ return 0;
+}
+
+int RGWSI_User_RADOS::cls_user_list_buckets(rgw_raw_obj& obj,
+ const string& in_marker,
+ const string& end_marker,
+ const int max_entries,
+ list<cls_user_bucket_entry>& entries,
+ string * const out_marker,
+ bool * const truncated)
+{
+ auto rados_obj = svc.rados->obj(obj);
+ int r = rados_obj.open();
+ if (r < 0) {
+ return r;
+ }
+
+ librados::ObjectReadOperation op;
+ int rc;
+
+ cls_user_bucket_list(op, in_marker, end_marker, max_entries, entries, out_marker, truncated, &rc);
+ bufferlist ibl;
+ r = rados_obj.operate(&op, &ibl, null_yield);
+ if (r < 0)
+ return r;
+ if (rc < 0)
+ return rc;
+
+ return 0;
+}
+
int RGWSI_User_RADOS::list_buckets(RGWSI_MetaBackend::Context *ctx,
const rgw_user& user,
const string& marker,
return 0;
}
+
+int RGWSI_User_RADOS::flush_bucket_stats(RGWSI_MetaBackend::Context *ctx,
+ const rgw_user& user,
+ const RGWBucketEnt& ent)
+{
+ rgw_raw_obj obj = get_buckets_obj(user);
+
+ return cls_user_flush_bucket_stats(obj, ent);
+}
+
int cls_user_add_bucket(rgw_raw_obj& obj, const cls_user_bucket_entry& entry);
int cls_user_remove_bucket(rgw_raw_obj& obj, const cls_user_bucket& bucket);
- /* bucket stats */
+ /* quota stats */
+ int cls_user_flush_bucket_stats(rgw_raw_obj& user_obj,
+ const RGWBucketEnt& ent);
+ int cls_user_list_buckets(rgw_raw_obj& obj,
+ const string& in_marker,
+ const string& end_marker,
+ const int max_entries,
+ list<cls_user_bucket_entry>& entries,
+ string * const out_marker,
+ bool * const truncated);
int do_start() override;
public:
uint64_t max,
RGWUserBuckets *buckets,
bool *is_truncated) override;
+
+ /* quota related */
+ int flush_bucket_stats(RGWSI_MetaBackend::Context *ctx,
+ const rgw_user& user,
+ const RGWBucketEnt& ent) override;
};