From 23aa65f62ae760f1a60f1a979b97a8458a7f6f78 Mon Sep 17 00:00:00 2001 From: Yehuda Sadeh Date: Fri, 6 Dec 2013 15:22:37 -0800 Subject: [PATCH] rgw: replace user bucket listing with objclass call instead of directly accessing the omap operation Signed-off-by: Yehuda Sadeh --- src/rgw/Makefile.am | 1 + src/rgw/rgw_bucket.cc | 29 +++++++++++++++++------------ src/rgw/rgw_bucket.h | 1 + src/rgw/rgw_common.h | 16 ++++++++++++++++ src/rgw/rgw_rados.cc | 25 +++++++++++++++++++++++++ src/rgw/rgw_rados.h | 5 +++++ 6 files changed, 65 insertions(+), 12 deletions(-) diff --git a/src/rgw/Makefile.am b/src/rgw/Makefile.am index b92c35e08d61f..bf32d8fdc34b7 100644 --- a/src/rgw/Makefile.am +++ b/src/rgw/Makefile.am @@ -41,6 +41,7 @@ LIBRGW_DEPS += \ libcls_rgw_client.la \ libcls_log_client.a \ libcls_statelog_client.a \ + libcls_user_client.a \ libcls_replica_log_client.a \ libcls_lock_client.la \ libcls_refcount_client.la \ diff --git a/src/rgw/rgw_bucket.cc b/src/rgw/rgw_bucket.cc index 31afebe9ea33d..6fd86c3e948ec 100644 --- a/src/rgw/rgw_bucket.cc +++ b/src/rgw/rgw_bucket.cc @@ -17,6 +17,8 @@ // until everything is moved from rgw_common #include "rgw_common.h" +#include "cls/user/cls_user_types.h" + #define dout_subsys ceph_subsys_rgw #define BUCKET_TAG_TIMEOUT 30 @@ -47,21 +49,24 @@ int rgw_read_user_buckets(RGWRados *store, string user_id, RGWUserBuckets& bucke bufferlist bl; rgw_obj obj(store->zone.user_uid_pool, buckets_obj_id); bufferlist header; - map m; + list entries; - ret = store->omap_get_vals(obj, header, marker, max, m); - if (ret == -ENOENT) - ret = 0; + bool truncated; + string m = marker; - if (ret < 0) - return ret; + do { + ret = store->cls_user_list_buckets(obj, m, max, entries, &m, &truncated); + if (ret == -ENOENT) + ret = 0; - for (map::iterator q = m.begin(); q != m.end(); ++q) { - bufferlist::iterator iter = q->second.begin(); - RGWBucketEnt bucket; - ::decode(bucket, iter); - buckets.add(bucket); - } + if (ret < 0) + return ret; + + for (list::iterator q = entries.begin(); q != entries.end(); ++q) { + RGWBucketEnt e(*q); + buckets.add(e); + } + } while (truncated); if (need_stats) { map& m = buckets.get_buckets(); diff --git a/src/rgw/rgw_bucket.h b/src/rgw/rgw_bucket.h index 47795403dc6c0..607c53d40c12e 100644 --- a/src/rgw/rgw_bucket.h +++ b/src/rgw/rgw_bucket.h @@ -33,6 +33,7 @@ extern int rgw_bucket_instance_remove_entry(RGWRados *store, string& entry, RGWO extern int rgw_bucket_delete_bucket_obj(RGWRados *store, string& bucket_name, RGWObjVersionTracker& objv_tracker); + /** * Store a list of the user's buckets, with associated functinos. */ diff --git a/src/rgw/rgw_common.h b/src/rgw/rgw_common.h index 3f9fa17e08bf5..97bd87984f391 100644 --- a/src/rgw/rgw_common.h +++ b/src/rgw/rgw_common.h @@ -31,6 +31,7 @@ #include "rgw_cors.h" #include "rgw_quota.h" #include "cls/version/cls_version_types.h" +#include "cls/user/cls_user_types.h" #include "include/rados/librados.hpp" using namespace std; @@ -560,6 +561,13 @@ struct rgw_bucket { */ rgw_bucket() { } + rgw_bucket(const cls_user_bucket& b) { + name = b.name; + data_pool = b.data_pool; + index_pool = b.index_pool; + marker = b.marker; + bucket_id = b.bucket_id; + } rgw_bucket(const char *n) : name(n) { assert(*n == '.'); // only rgw private buckets should be initialized without pool data_pool = index_pool = n; @@ -901,6 +909,14 @@ struct RGWBucketEnt { RGWBucketEnt() : size(0), size_rounded(0), creation_time(0), count(0) {} + RGWBucketEnt(const cls_user_bucket_entry& e) { + bucket = e.bucket; + size = e.size; + size_rounded = e.size_rounded; + creation_time = e.creation_time; + count = e.count; + } + void encode(bufferlist& bl) const { ENCODE_START(5, 5, bl); uint64_t s = size; diff --git a/src/rgw/rgw_rados.cc b/src/rgw/rgw_rados.cc index 37eacc0533ae5..06a3de62cc602 100644 --- a/src/rgw/rgw_rados.cc +++ b/src/rgw/rgw_rados.cc @@ -22,6 +22,7 @@ #include "cls/log/cls_log_client.h" #include "cls/statelog/cls_statelog_client.h" #include "cls/lock/cls_lock_client.h" +#include "cls/user/cls_user_client.h" #include "rgw_tools.h" @@ -5586,6 +5587,30 @@ int RGWRados::cls_bucket_head_async(rgw_bucket& bucket, RGWGetDirHeader_CB *ctx) return 0; } +int RGWRados::cls_user_list_buckets(rgw_obj& obj, + const string& in_marker, int max_entries, + list& entries, + string *out_marker, bool *truncated) +{ + bufferlist bl; + 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; + + librados::ObjectReadOperation op; + cls_user_bucket_list(op, in_marker, max_entries, entries, out_marker, truncated); + bufferlist ibl; + r = io_ctx.operate(oid, &op, &ibl); + if (r < 0) + return r; + + return 0; +} + int RGWRados::check_quota(rgw_bucket& bucket, RGWQuotaInfo& quota_info, uint64_t obj_size) { return quota_handler->check_quota(bucket, quota_info, 1, obj_size); diff --git a/src/rgw/rgw_rados.h b/src/rgw/rgw_rados.h index 476572ce3f6c9..62a619efcd18e 100644 --- a/src/rgw/rgw_rados.h +++ b/src/rgw/rgw_rados.h @@ -1410,6 +1410,11 @@ public: int bucket_rebuild_index(rgw_bucket& bucket); int remove_objs_from_index(rgw_bucket& bucket, list& oid_list); + int cls_user_list_buckets(rgw_obj& obj, + const string& in_marker, int max_entries, + list& entries, + string *out_marker, bool *truncated); + int check_quota(rgw_bucket& bucket, RGWQuotaInfo& quota_info, uint64_t obj_size); string unique_id(uint64_t unique_num) { -- 2.39.5