/** write an object to the storage device in the appropriate pool
with the given stats */
virtual int put_obj_meta(void *ctx, std::string& id, rgw_obj& obj, uint64_t size, time_t *mtime,
- map<std::string, bufferlist>& attrs, string& category, bool exclusive) = 0;
+ map<std::string, bufferlist>& attrs, RGWObjCategory category, bool exclusive) = 0;
virtual int put_obj_data(void *ctx, std::string& id, rgw_obj& obj, const char *data,
off_t ofs, size_t len) = 0;
virtual int aio_put_obj_data(void *ctx, std::string& id, rgw_obj& obj, const char *data,
time_t *mtime, map<std::string, bufferlist>& attrs) {
int ret = put_obj_data(ctx, id, obj, data, -1, len);
if (ret >= 0) {
- string category;
- ret = put_obj_meta(ctx, id, obj, len, mtime, attrs, category, false);
+ ret = put_obj_meta(ctx, id, obj, len, mtime, attrs, RGW_OBJ_CATEGORY_NONE, false);
}
return ret;
}
const char *if_match,
const char *if_nomatch,
map<std::string, bufferlist>& attrs,
- string& category,
+ RGWObjCategory category,
struct rgw_err *err) = 0;
/**
* Delete a bucket.
rgw_obj& src_obj, off_t src_ofs,
uint64_t size, time_t *pmtime,
map<string, bufferlist> attrs,
- string& category) {
+ RGWObjCategory category) {
RGWCloneRangeInfo info;
vector<RGWCloneRangeInfo> v;
info.src = src_obj;
virtual int clone_objs(void *ctx, rgw_obj& dst_obj,
vector<RGWCloneRangeInfo>& ranges,
map<string, bufferlist> attrs,
- string& category,
+ RGWObjCategory category,
time_t *pmtime,
bool truncate_dest,
bool exclusive) { return -ENOTSUP; }
// the upper layer to schedule this operation.. e.g., log intent in intent log
virtual void set_intent_cb(void *ctx, int (*cb)(void *user_ctx, rgw_obj& obj, RGWIntentEvent intent)) {}
- virtual int get_bucket_stats(rgw_bucket& bucket, map<string, RGWBucketStats>& stats) { return -ENOTSUP; }
+ virtual int get_bucket_stats(rgw_bucket& bucket, map<RGWObjCategory, RGWBucketStats>& stats) { return -ENOTSUP; }
};
class RGWStoreManager {
cerr << "either bucket or bucket-id needs to be specified" << std::endl;
return usage();
}
- map<string, RGWBucketStats> stats;
+ map<RGWObjCategory, RGWBucketStats> stats;
int ret = rgwstore->get_bucket_stats(bucket, stats);
if (ret < 0) {
cerr << "error getting bucket stats ret=" << ret << std::endl;
return ret;
}
- map<string, RGWBucketStats>::iterator iter;
+ map<RGWObjCategory, RGWBucketStats>::iterator iter;
formatter->reset();
formatter->open_object_section("stats");
formatter->dump_string("bucket", bucket.name.c_str());
for (iter = stats.begin(); iter != stats.end(); ++iter) {
RGWBucketStats& s = iter->second;
formatter->open_object_section("category");
- const char *cat_name = (iter->first.size() ? iter->first.c_str() : "");
+ const char *cat_name = rgw_obj_category_name(iter->first);
formatter->dump_string("name", cat_name);
formatter->dump_format("size_kb", "%lld", s.num_kb);
formatter->dump_format("num_objects", "%lld", s.num_objects);
- formatter->dump_format("num_object_clones", "%lld", s.num_object_clones);
- formatter->dump_format("num_object_copies", "%lld", s.num_object_copies);
- formatter->dump_format("num_objects_missing_on_primary", "%lld", s.num_objects_missing_on_primary);
- formatter->dump_format("num_objects_unfound", "%lld", s.num_objects_unfound);
- formatter->dump_format("num_objects_degraded", "%lld", s.num_objects_degraded);
- formatter->dump_format("num_read_kb", "%lld", s.num_rd_kb);
- formatter->dump_format("num_write_kb", "%lld", s.num_wr_kb);
formatter->close_section();
formatter->flush(cout);
}
using namespace ceph::crypto;
-string rgw_obj_category_main = "rgw.main";
-string rgw_obj_category_shadow = "rgw.shadow";
-string rgw_obj_category_multimeta = "rgw.multimeta";
-string rgw_obj_category_none;
-
rgw_err::
rgw_err()
{
using ceph::crypto::MD5;
-extern string rgw_obj_category_main;
-extern string rgw_obj_category_shadow;
-extern string rgw_obj_category_multimeta;
-extern string rgw_obj_category_none;
-
#define RGW_ROOT_BUCKET ".rgw"
#define RGW_CONTROL_BUCKET ".rgw.control"
DEL_POOL,
};
+enum RGWObjCategory {
+ RGW_OBJ_CATEGORY_NONE = 0,
+ RGW_OBJ_CATEGORY_MAIN = 1,
+ RGW_OBJ_CATEGORY_SHADOW = 2,
+ RGW_OBJ_CATEGORY_MULTIMETA = 3,
+};
+
/** Store error returns for output at a different point in the program */
struct rgw_err {
rgw_err();
struct RGWBucketStats
{
- string pool_name;
- string category;
+ RGWObjCategory category;
uint64_t num_kb;
uint64_t num_objects;
- uint64_t num_object_clones;
- uint64_t num_object_copies; // num_objects * num_replicas
- uint64_t num_objects_missing_on_primary;
- uint64_t num_objects_unfound;
- uint64_t num_objects_degraded;
- uint64_t num_rd_kb;
- uint64_t num_wr_kb;
};
struct req_state;
dest.append(buf);
}
+static inline const char *rgw_obj_category_name(RGWObjCategory category)
+{
+ switch (category) {
+ case RGW_OBJ_CATEGORY_NONE:
+ return "rgw.none";
+ case RGW_OBJ_CATEGORY_MAIN:
+ return "rgw.main";
+ case RGW_OBJ_CATEGORY_SHADOW:
+ return "rgw.shadow";
+ case RGW_OBJ_CATEGORY_MULTIMETA:
+ return "rgw.multimeta";
+ }
+
+ return "unknown";
+}
+
/** */
extern int parse_time(const char *time_str, time_t *time);
/** Check if a user has a permission on that ACL */
int RGWFS::put_obj_meta(void *ctx, std::string& id, rgw_obj& obj,
uint64_t size, time_t *mtime, map<string, bufferlist>& attrs,
- string& category, bool exclusive)
+ RGWObjCategory category, bool exclusive)
{
rgw_bucket& bucket = obj.bucket;
std::string& oid = obj.object;
const char *if_match,
const char *if_nomatch,
map<string, bufferlist>& attrs,
- string& category,
+ RGWObjCategory category,
struct rgw_err *err)
{
int ret;
int create_bucket(std::string& id, rgw_bucket& bucket, map<std::string, bufferlist>& attrs, bool create_pool, bool assign_marker, bool exclusive, uint64_t auid=0);
int put_obj_meta(void *ctx, std::string& id, rgw_obj& obj, uint64_t size, time_t *mtime,
- map<std::string, bufferlist>& attrs, string& category, bool exclusive);
+ map<std::string, bufferlist>& attrs, RGWObjCategory category, bool exclusive);
int put_obj_data(void *ctx, std::string& id, rgw_obj& obj, const char *data,
off_t ofs, size_t size);
int copy_obj(void *ctx, std::string& id, rgw_obj& dest_obj,
const char *if_match,
const char *if_nomatch,
map<std::string, bufferlist>& attrs,
- string& category,
+ RGWObjCategory category,
struct rgw_err *err);
int delete_bucket(std::string& id, rgw_bucket& bucket, bool remove_pool);
int delete_obj(void *ctx, std::string& id, rgw_obj& obj, bool sync);
if (!multipart) {
rgw_obj dst_obj(s->bucket, s->object_str);
rgwstore->set_atomic(s->obj_ctx, dst_obj);
- ret = rgwstore->clone_obj(s->obj_ctx, dst_obj, 0, obj, 0, s->obj_size, NULL, attrs, rgw_obj_category_main);
+ ret = rgwstore->clone_obj(s->obj_ctx, dst_obj, 0, obj, 0, s->obj_size, NULL, attrs, RGW_OBJ_CATEGORY_MAIN);
if (ret < 0)
goto done_err;
if (created_obj) {
goto done;
}
} else {
- ret = rgwstore->put_obj_meta(s->obj_ctx, s->user.user_id, obj, s->obj_size, NULL, attrs, rgw_obj_category_main, false);
+ ret = rgwstore->put_obj_meta(s->obj_ctx, s->user.user_id, obj, s->obj_size, NULL, attrs, RGW_OBJ_CATEGORY_MAIN, false);
if (ret < 0)
goto done_err;
unmod_ptr,
if_match,
if_nomatch,
- attrs, rgw_obj_category_main, &s->err);
+ attrs, RGW_OBJ_CATEGORY_MAIN, &s->err);
done:
send_response();
obj.init(s->bucket, tmp_obj_name, s->object_str, mp_ns);
// the meta object will be indexed with 0 size, we c
- ret = rgwstore->put_obj_meta(s->obj_ctx, s->user.user_id, obj, 0, NULL, attrs, rgw_obj_category_multimeta, true);
+ ret = rgwstore->put_obj_meta(s->obj_ctx, s->user.user_id, obj, 0, NULL, attrs, RGW_OBJ_CATEGORY_MULTIMETA, true);
} while (ret == -EEXIST);
done:
send_response();
target_obj.init(s->bucket, s->object_str);
rgwstore->set_atomic(s->obj_ctx, target_obj);
- ret = rgwstore->put_obj_meta(s->obj_ctx, s->user.user_id, target_obj, 0, NULL, attrs, rgw_obj_category_main, false);
+ ret = rgwstore->put_obj_meta(s->obj_ctx, s->user.user_id, target_obj, 0, NULL, attrs, RGW_OBJ_CATEGORY_MAIN, false);
if (ret < 0)
goto done;
ofs += obj_iter->second.size;
}
- ret = rgwstore->clone_objs(s->obj_ctx, target_obj, ranges, attrs, rgw_obj_category_main, NULL, true, false);
+ ret = rgwstore->clone_objs(s->obj_ctx, target_obj, ranges, attrs, RGW_OBJ_CATEGORY_MAIN, NULL, true, false);
if (ret < 0)
goto done;
static string bucket_marker_ver_oid = ".rgw.bucket-marker-ver";
static string dir_oid_prefix = ".dir.";
-static string shadow_category = "rgw.shadow";
-static string main_category = "rgw.main";
+static RGWObjCategory shadow_category = RGW_OBJ_CATEGORY_SHADOW;
+static RGWObjCategory main_category = RGW_OBJ_CATEGORY_MAIN;
class RGWWatcher : public librados::WatchCtx {
RGWRados *rados;
* Returns: 0 on success, -ERR# otherwise.
*/
int RGWRados::put_obj_meta(void *ctx, std::string& id, rgw_obj& obj, uint64_t size,
- time_t *mtime, map<string, bufferlist>& attrs, string& category, bool exclusive)
+ time_t *mtime, map<string, bufferlist>& attrs, RGWObjCategory category, bool exclusive)
{
rgw_bucket bucket;
std::string oid;
ObjectWriteOperation op;
- if (category.size())
- op.create(exclusive, category);
- else
- op.create(exclusive);
+ op.create(exclusive);
string etag;
bufferlist acl_bl;
uint64_t epoch = io_ctx.get_last_version();
- uint8_t index_category = 0;
utime_t ut = ceph_clock_now(g_ceph_context);
r = complete_update_index(bucket, obj.object, tag, epoch, size,
- ut, etag, &acl_bl, index_category);
+ ut, etag, &acl_bl, category);
if (mtime) {
r = io_ctx.stat(oid, NULL, mtime);
const char *if_match,
const char *if_nomatch,
map<string, bufferlist>& attrs, /* in/out */
- string& category,
+ RGWObjCategory category,
struct rgw_err *err)
{
int ret, r;
}
int RGWRados::complete_update_index(rgw_bucket& bucket, string& oid, string& tag, uint64_t epoch, uint64_t size,
- utime_t& ut, string& etag, bufferlist *acl_bl, uint8_t category)
+ utime_t& ut, string& etag, bufferlist *acl_bl, RGWObjCategory category)
{
if (bucket.marker.empty())
return 0;
int RGWRados::clone_objs_impl(void *ctx, rgw_obj& dst_obj,
vector<RGWCloneRangeInfo>& ranges,
map<string, bufferlist> attrs,
- string& category,
+ RGWObjCategory category,
time_t *pmtime,
bool truncate_dest,
bool exclusive,
op.set_op_flags(OP_FAILOK); // don't fail if object didn't exist
}
- if (category.size())
- op.create(exclusive, category);
- else
- op.create(exclusive);
+ op.create(exclusive);
map<string, bufferlist>::iterator iter;
atomic_write_finish(state, ret);
if (ret >= 0) {
- uint8_t category = 0;
ret = complete_update_index(bucket, dst_obj.object, tag, epoch, size,
ut, etag, &acl_bl, category);
}
int RGWRados::clone_objs(void *ctx, rgw_obj& dst_obj,
vector<RGWCloneRangeInfo>& ranges,
map<string, bufferlist> attrs,
- string& category,
+ RGWObjCategory category,
time_t *pmtime,
bool truncate_dest,
bool exclusive,
return 0;
}
-int RGWRados::get_bucket_stats(rgw_bucket& bucket, map<string, RGWBucketStats>& stats)
+int RGWRados::get_bucket_stats(rgw_bucket& bucket, map<RGWObjCategory, RGWBucketStats>& stats)
{
- list<string> vec;
-
- string pool_name = bucket.pool;
-
- if (pool_name.empty())
- pool_name = bucket.name;
-
- if (pool_name.empty())
- return -EINVAL;
-
- vec.push_back(pool_name.c_str());
-
- vector<string>::iterator cat_iter;
- map<string, map<string, pool_stat_t> > pool_stats;
- string empty_category;
- int ret = rados->get_pool_stats(vec, empty_category, pool_stats);
- if (ret < 0)
- return ret;
-
- map<string, bool> cats_map;
- vector<string>::iterator iter;
+ rgw_bucket_dir_header header;
+ int r = cls_bucket_head(bucket, header);
+ if (r < 0)
+ return r;
- for (map<string, librados::stats_map>::iterator c = pool_stats.begin(); c != pool_stats.end(); ++c) {
- const string& pool_name = c->first;
- stats_map& m = c->second;
- for (stats_map::iterator i = m.begin(); i != m.end(); ++i) {
- string cat = (i->first.size() ? i->first.c_str() : empty_category);
-
- RGWBucketStats& s = stats[cat];
- pool_stat_t& ps = i->second;
- s.pool_name = pool_name;
- s.category = cat;
- s.num_kb = ps.num_kb;
- s.num_objects = ps.num_objects;
- s.num_object_clones = ps.num_object_clones;
- s.num_object_copies = ps.num_object_copies;
- s.num_objects_missing_on_primary = ps.num_objects_missing_on_primary;
- s.num_objects_unfound = ps.num_objects_unfound;
- s.num_objects_degraded = ps.num_objects_degraded;
- s.num_rd_kb = ps.num_rd_kb;
- s.num_wr_kb = ps.num_wr_kb;
- }
+ stats.clear();
+ map<uint8_t, struct rgw_bucket_category_stats>::iterator iter = header.stats.begin();
+ for (; iter != header.stats.end(); ++iter) {
+ RGWObjCategory category = (RGWObjCategory)iter->first;
+ RGWBucketStats& s = stats[category];
+ struct rgw_bucket_category_stats& stats = iter->second;
+ s.category = (RGWObjCategory)iter->first;
+ s.num_kb = (stats.total_size_rounded + 1023 / 1024);
+ s.num_objects = stats.num_entries;
}
+
return 0;
}
}
int RGWRados::update_containers_stats(map<string, RGWBucketEnt>& m)
{
- int count = 0;
-
map<string, RGWBucketEnt>::iterator iter;
- list<string> pools_list;
for (iter = m.begin(); iter != m.end(); ++iter) {
RGWBucketEnt& ent = iter->second;
rgw_bucket& bucket = ent.bucket;
ent.count = 0;
ent.size = 0;
- uint8_t category = 0;
- map<uint8_t, struct rgw_bucket_category_stats>::iterator iter = header.stats.find(category);
+ RGWObjCategory category = main_category;
+ map<uint8_t, struct rgw_bucket_category_stats>::iterator iter = header.stats.find((uint8_t)category);
if (iter != header.stats.end()) {
struct rgw_bucket_category_stats& stats = iter->second;
ent.count = stats.num_entries;
ent.size = stats.total_size_rounded;
}
}
- map<std::string,librados::stats_map> sm;
- int r = rados->get_pool_stats(pools_list, rgw_obj_category_main, sm);
- if (r < 0)
- return r;
- map<string, librados::stats_map>::iterator miter;
-
- for (miter = sm.begin(), iter = m.begin(); miter != sm.end(), iter != m.end(); ++iter, ++miter) {
- stats_map stats = miter->second;
- stats_map::iterator stats_iter = stats.begin();
- if (stats_iter == stats.end())
- continue;
-
- string bucket_name = miter->first;
- RGWBucketEnt& ent = iter->second;
- if (bucket_name.compare(ent.bucket.name) != 0)
- continue;
-
- pool_stat_t stat = stats_iter->second;
- ent.count = stat.num_objects;
- ent.size = stat.num_bytes;
- count++;
- }
-
- return count;
+ return m.size();
}
int RGWRados::append_async(rgw_obj& obj, size_t size, bufferlist& bl)
return r;
}
-int RGWRados::cls_obj_complete_op(rgw_bucket& bucket, uint8_t op, string& tag, uint64_t epoch, RGWObjEnt& ent, uint8_t category)
+int RGWRados::cls_obj_complete_op(rgw_bucket& bucket, uint8_t op, string& tag, uint64_t epoch, RGWObjEnt& ent, RGWObjCategory category)
{
if (bucket.marker.empty()) {
if (bucket.name[0] == '.')
return r;
}
-int RGWRados::cls_obj_complete_add(rgw_bucket& bucket, string& tag, uint64_t epoch, RGWObjEnt& ent, uint8_t category)
+int RGWRados::cls_obj_complete_add(rgw_bucket& bucket, string& tag, uint64_t epoch, RGWObjEnt& ent, RGWObjCategory category)
{
return cls_obj_complete_op(bucket, CLS_RGW_OP_ADD, tag, epoch, ent, category);
}
{
RGWObjEnt ent;
ent.name = name;
- return cls_obj_complete_op(bucket, CLS_RGW_OP_DEL, tag, epoch, ent, 0);
+ return cls_obj_complete_op(bucket, CLS_RGW_OP_DEL, tag, epoch, ent, RGW_OBJ_CATEGORY_NONE);
}
int RGWRados::cls_bucket_list(rgw_bucket& bucket, string start, uint32_t num, map<string, RGWObjEnt>& m, bool *is_truncated)
int clone_objs_impl(void *ctx, rgw_obj& dst_obj,
vector<RGWCloneRangeInfo>& ranges,
map<string, bufferlist> attrs,
- string& category,
+ RGWObjCategory category,
time_t *pmtime,
bool truncate_dest,
bool exclusive,
/** Write/overwrite an object to the bucket storage. */
virtual int put_obj_meta(void *ctx, std::string& id, rgw_obj& obj, uint64_t size, time_t *mtime,
- map<std::string, bufferlist>& attrs, string& category, bool exclusive);
+ map<std::string, bufferlist>& attrs, RGWObjCategory category, bool exclusive);
virtual int put_obj_data(void *ctx, std::string& id, rgw_obj& obj, const char *data,
off_t ofs, size_t len);
virtual int aio_put_obj_data(void *ctx, std::string& id, rgw_obj& obj, const char *data,
virtual int clone_objs(void *ctx, rgw_obj& dst_obj,
vector<RGWCloneRangeInfo>& ranges,
map<string, bufferlist> attrs,
- string& category,
+ RGWObjCategory category,
time_t *pmtime, bool truncate_dest, bool exclusive) {
return clone_objs(ctx, dst_obj, ranges, attrs, category, pmtime, truncate_dest, exclusive, NULL);
}
int clone_objs(void *ctx, rgw_obj& dst_obj,
vector<RGWCloneRangeInfo>& ranges,
map<string, bufferlist> attrs,
- string& category,
+ RGWObjCategory category,
time_t *pmtime,
bool truncate_dest,
bool exclusive,
int clone_obj_cond(void *ctx, rgw_obj& dst_obj, off_t dst_ofs,
rgw_obj& src_obj, off_t src_ofs,
uint64_t size, map<string, bufferlist> attrs,
- string& category,
+ RGWObjCategory category,
time_t *pmtime,
bool truncate_dest,
bool exclusive,
const char *if_match,
const char *if_nomatch,
map<std::string, bufferlist>& attrs,
- string& category,
+ RGWObjCategory category,
struct rgw_err *err);
/** delete a bucket*/
virtual int delete_bucket(std::string& id, rgw_bucket& bucket, bool remove_pool);
}
int decode_policy(bufferlist& bl, ACLOwner *owner);
- int get_bucket_stats(rgw_bucket& bucket, map<string, RGWBucketStats>& stats);
+ int get_bucket_stats(rgw_bucket& bucket, map<RGWObjCategory, RGWBucketStats>& stats);
int cls_rgw_init_index(rgw_bucket& bucket, string& oid);
int cls_obj_prepare_op(rgw_bucket& bucket, uint8_t op, string& tag, string& name);
int cls_obj_complete_op(rgw_bucket& bucket, uint8_t op, string& tag, uint64_t epoch,
- RGWObjEnt& ent, uint8_t category);
- int cls_obj_complete_add(rgw_bucket& bucket, string& tag, uint64_t epoch, RGWObjEnt& ent, uint8_t category);
+ RGWObjEnt& ent, RGWObjCategory category);
+ int cls_obj_complete_add(rgw_bucket& bucket, string& tag, uint64_t epoch, RGWObjEnt& ent, RGWObjCategory category);
int cls_obj_complete_del(rgw_bucket& bucket, string& tag, uint64_t epoch, string& name);
int cls_bucket_list(rgw_bucket& bucket, string start, uint32_t num, map<string, RGWObjEnt>& m, bool *is_truncated);
int cls_bucket_head(rgw_bucket& bucket, struct rgw_bucket_dir_header& header);
int prepare_update_index(RGWObjState *state, rgw_bucket& bucket, string& oid, string& tag);
int complete_update_index(rgw_bucket& bucket, string& oid, string& tag, uint64_t epoch, uint64_t size,
- utime_t& ut, string& etag, bufferlist *acl_bl, uint8_t category);
+ utime_t& ut, string& etag, bufferlist *acl_bl, RGWObjCategory category);
int complete_update_index_del(rgw_bucket& bucket, string& oid, string& tag, uint64_t epoch) {
return cls_obj_complete_del(bucket, tag, epoch, oid);
}