mirror of
https://github.com/ceph/ceph
synced 2025-01-20 01:51:34 +00:00
rgw: extend infrastructure to handle user stats read
Some helper functions that return data in required format for quota, add async functions. Signed-off-by: Yehuda Sadeh <yehuda@inktank.com>
This commit is contained in:
parent
364f7c54fc
commit
c13634e888
@ -5,6 +5,7 @@
|
||||
|
||||
#include "include/types.h"
|
||||
#include "cls/user/cls_user_ops.h"
|
||||
#include "cls/user/cls_user_client.h"
|
||||
#include "include/rados/librados.hpp"
|
||||
|
||||
|
||||
@ -71,8 +72,14 @@ void cls_user_bucket_list(librados::ObjectReadOperation& op,
|
||||
|
||||
class ClsUserGetHeaderCtx : public ObjectOperationCompletion {
|
||||
cls_user_header *header;
|
||||
RGWGetUserHeader_CB *ret_ctx;
|
||||
public:
|
||||
ClsUserGetHeaderCtx(cls_user_header *_h) : header(_h) {}
|
||||
ClsUserGetHeaderCtx(cls_user_header *_h, RGWGetUserHeader_CB *_ctx) : header(_h), ret_ctx(_ctx) {}
|
||||
~ClsUserGetHeaderCtx() {
|
||||
if (ret_ctx) {
|
||||
ret_ctx->put();
|
||||
}
|
||||
}
|
||||
void handle_completion(int r, bufferlist& outbl) {
|
||||
if (r >= 0) {
|
||||
cls_user_get_header_ret ret;
|
||||
@ -84,11 +91,13 @@ public:
|
||||
} catch (buffer::error& err) {
|
||||
// nothing we can do about it atm
|
||||
}
|
||||
if (ret_ctx) {
|
||||
ret_ctx->handle_response(r, ret.header);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
void cls_user_get_header(librados::ObjectReadOperation& op,
|
||||
cls_user_header *header)
|
||||
{
|
||||
@ -97,5 +106,21 @@ void cls_user_get_header(librados::ObjectReadOperation& op,
|
||||
|
||||
::encode(call, inbl);
|
||||
|
||||
op.exec("user", "get_header", inbl, new ClsUserGetHeaderCtx(header));
|
||||
op.exec("user", "get_header", inbl, new ClsUserGetHeaderCtx(header, NULL));
|
||||
}
|
||||
|
||||
int cls_user_get_header_async(IoCtx& io_ctx, string& oid, RGWGetUserHeader_CB *ctx)
|
||||
{
|
||||
bufferlist in, out;
|
||||
cls_user_get_header_op call;
|
||||
::encode(call, in);
|
||||
ObjectReadOperation op;
|
||||
op.exec("user", "get_header", in, new ClsUserGetHeaderCtx(NULL, ctx));
|
||||
AioCompletion *c = librados::Rados::aio_create_completion(NULL, NULL, NULL);
|
||||
int r = io_ctx.aio_operate(oid, c, &op, NULL);
|
||||
c->release();
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -7,6 +7,13 @@
|
||||
#include "include/types.h"
|
||||
#include "include/rados/librados.hpp"
|
||||
#include "cls_user_types.h"
|
||||
#include "common/RefCountedObj.h"
|
||||
|
||||
class RGWGetUserHeader_CB : public RefCountedObject {
|
||||
public:
|
||||
virtual ~RGWGetUserHeader_CB() {}
|
||||
virtual void handle_response(int r, cls_user_header& header) = 0;
|
||||
};
|
||||
|
||||
/*
|
||||
* user objclass
|
||||
@ -19,5 +26,6 @@ void cls_user_bucket_list(librados::ObjectReadOperation& op,
|
||||
list<cls_user_bucket_entry>& entries,
|
||||
string *out_marker, bool *truncated);
|
||||
void cls_user_get_header(librados::ObjectReadOperation& op, cls_user_header *header);
|
||||
int cls_user_get_header_async(librados::IoCtx& io_ctx, string& oid, RGWGetUserHeader_CB *ctx);
|
||||
|
||||
#endif
|
||||
|
@ -1956,12 +1956,8 @@ next:
|
||||
cerr << "ERROR: uid not specified" << std::endl;
|
||||
return EINVAL;
|
||||
}
|
||||
string buckets_obj_id;
|
||||
rgw_get_buckets_obj(user_id, buckets_obj_id);
|
||||
rgw_obj obj(store->zone.user_uid_pool, buckets_obj_id);
|
||||
|
||||
cls_user_header header;
|
||||
int ret = store->cls_user_get_header(obj, &header);
|
||||
int ret = store->cls_user_get_header(user_id, &header);
|
||||
if (ret < 0) {
|
||||
cerr << "ERROR: can't read user header: " << cpp_strerror(-ret) << std::endl;
|
||||
return -ret;
|
||||
|
@ -791,7 +791,7 @@ struct RGWStorageStats
|
||||
uint64_t num_kb_rounded;
|
||||
uint64_t num_objects;
|
||||
|
||||
RGWStorageStats() : num_kb(0), num_kb_rounded(0), num_objects(0) {}
|
||||
RGWStorageStats() : category(RGW_OBJ_CATEGORY_NONE), num_kb(0), num_kb_rounded(0), num_objects(0) {}
|
||||
};
|
||||
|
||||
struct req_state;
|
||||
|
@ -4708,6 +4708,55 @@ int RGWRados::get_bucket_stats_async(rgw_bucket& bucket, RGWGetBucketStats_CB *c
|
||||
return 0;
|
||||
}
|
||||
|
||||
class RGWGetUserStatsContext : public RGWGetUserHeader_CB {
|
||||
RGWGetUserStats_CB *cb;
|
||||
|
||||
public:
|
||||
RGWGetUserStatsContext(RGWGetUserStats_CB *_cb) : cb(_cb) {}
|
||||
void handle_response(int r, cls_user_header& header) {
|
||||
if (r >= 0) {
|
||||
RGWStorageStats stats;
|
||||
|
||||
stats.num_kb = header.total_bytes;
|
||||
stats.num_kb_rounded = header.total_bytes_rounded;
|
||||
stats.num_objects = header.total_entries;
|
||||
|
||||
cb->set_response(stats);
|
||||
}
|
||||
|
||||
cb->handle_response(r);
|
||||
|
||||
cb->put();
|
||||
}
|
||||
};
|
||||
|
||||
int RGWRados::get_bucket_stats(const string& user, RGWStorageStats& stats)
|
||||
{
|
||||
cls_user_header header;
|
||||
int r = cls_user_get_header(user, &header);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
stats.num_kb = header.total_bytes;
|
||||
stats.num_kb_rounded = header.total_bytes_rounded;
|
||||
stats.num_objects = header.total_entries;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int RGWRados::get_user_stats_async(const string& user, RGWGetUserStats_CB *ctx)
|
||||
{
|
||||
RGWGetUserStatsContext *get_ctx = new RGWGetUserStatsContext(ctx);
|
||||
int r = cls_user_get_header_async(user, get_ctx);
|
||||
if (r < 0) {
|
||||
ctx->put();
|
||||
delete get_ctx;
|
||||
return r;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void RGWRados::get_bucket_instance_entry(rgw_bucket& bucket, string& entry)
|
||||
{
|
||||
entry = bucket.name + ":" + bucket.bucket_id;
|
||||
@ -5605,8 +5654,12 @@ int RGWRados::cls_bucket_head_async(rgw_bucket& bucket, RGWGetDirHeader_CB *ctx)
|
||||
return 0;
|
||||
}
|
||||
|
||||
int RGWRados::cls_user_get_header(rgw_obj& obj, cls_user_header *header)
|
||||
int RGWRados::cls_user_get_header(const string& user_id, cls_user_header *header)
|
||||
{
|
||||
string buckets_obj_id;
|
||||
rgw_get_buckets_obj(user_id, buckets_obj_id);
|
||||
rgw_obj obj(zone.user_uid_pool, buckets_obj_id);
|
||||
|
||||
librados::IoCtx io_ctx;
|
||||
rgw_bucket bucket;
|
||||
std::string oid, key;
|
||||
@ -5625,6 +5678,27 @@ int RGWRados::cls_user_get_header(rgw_obj& obj, cls_user_header *header)
|
||||
return 0;
|
||||
}
|
||||
|
||||
int RGWRados::cls_user_get_header_async(const string& user_id, RGWGetUserHeader_CB *ctx)
|
||||
{
|
||||
string buckets_obj_id;
|
||||
rgw_get_buckets_obj(user_id, buckets_obj_id);
|
||||
rgw_obj obj(zone.user_uid_pool, buckets_obj_id);
|
||||
|
||||
librados::IoCtx io_ctx;
|
||||
rgw_bucket bucket;
|
||||
std::string oid, key;
|
||||
get_obj_bucket_and_oid_key(obj, bucket, oid, key);
|
||||
int r = open_bucket_data_ctx(bucket, io_ctx);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = ::cls_user_get_header_async(io_ctx, oid, ctx);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int RGWRados::cls_user_sync_bucket_stats(rgw_obj& user_obj, rgw_bucket& bucket)
|
||||
{
|
||||
rgw_bucket_dir_header header;
|
||||
|
@ -789,7 +789,21 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
class RGWGetUserStats_CB : public RefCountedObject {
|
||||
protected:
|
||||
string user;
|
||||
RGWStorageStats stats;
|
||||
public:
|
||||
RGWGetUserStats_CB(const string& _user) : user(_user) {}
|
||||
virtual ~RGWGetUserStats_CB() {}
|
||||
virtual void handle_response(int r) = 0;
|
||||
virtual void set_response(RGWStorageStats& _stats) {
|
||||
stats = _stats;
|
||||
}
|
||||
};
|
||||
|
||||
class RGWGetDirHeader_CB;
|
||||
class RGWGetUserHeader_CB;
|
||||
|
||||
|
||||
class RGWRados
|
||||
@ -1328,9 +1342,12 @@ public:
|
||||
}
|
||||
|
||||
int decode_policy(bufferlist& bl, ACLOwner *owner);
|
||||
int get_bucket_stats(const string& user, RGWStorageStats& stats);
|
||||
int get_bucket_stats(rgw_bucket& bucket, uint64_t *bucket_ver, uint64_t *master_ver, map<RGWObjCategory, RGWStorageStats>& stats,
|
||||
string *max_marker);
|
||||
int get_bucket_stats_async(rgw_bucket& bucket, RGWGetBucketStats_CB *cb);
|
||||
int get_user_stats(const string& user, RGWStorageStats& stats);
|
||||
int get_user_stats_async(const string& user, RGWGetUserStats_CB *cb);
|
||||
void get_bucket_instance_obj(rgw_bucket& bucket, rgw_obj& obj);
|
||||
void get_bucket_instance_entry(rgw_bucket& bucket, string& entry);
|
||||
void get_bucket_meta_oid(rgw_bucket& bucket, string& oid);
|
||||
@ -1419,7 +1436,8 @@ public:
|
||||
int bucket_rebuild_index(rgw_bucket& bucket);
|
||||
int remove_objs_from_index(rgw_bucket& bucket, list<string>& oid_list);
|
||||
|
||||
int cls_user_get_header(rgw_obj& obj, cls_user_header *header);
|
||||
int cls_user_get_header(const string& user_id, cls_user_header *header);
|
||||
int cls_user_get_header_async(const string& user_id, RGWGetUserHeader_CB *ctx);
|
||||
int cls_user_sync_bucket_stats(rgw_obj& user_obj, rgw_bucket& bucket);
|
||||
int cls_user_list_buckets(rgw_obj& obj,
|
||||
const string& in_marker, int max_entries,
|
||||
|
Loading…
Reference in New Issue
Block a user