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:
Yehuda Sadeh 2014-01-10 13:44:56 -08:00
parent 364f7c54fc
commit c13634e888
6 changed files with 132 additions and 11 deletions

View File

@ -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;
}

View File

@ -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

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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,