From b01e732f3d597670f4f781be3db81786e63d5053 Mon Sep 17 00:00:00 2001 From: Yehuda Sadeh Date: Mon, 26 Sep 2016 16:09:15 -0700 Subject: [PATCH] rgw: utilities to support raw bucket index operations and other related changes. Signed-off-by: Yehuda Sadeh --- src/rgw/rgw_rados.cc | 123 +++++++++++++++++++++++++++++++++++++++---- src/rgw/rgw_rados.h | 12 +++++ 2 files changed, 125 insertions(+), 10 deletions(-) diff --git a/src/rgw/rgw_rados.cc b/src/rgw/rgw_rados.cc index 3e1229ed0eca1..e5cebb6483510 100644 --- a/src/rgw/rgw_rados.cc +++ b/src/rgw/rgw_rados.cc @@ -5321,11 +5321,7 @@ int RGWRados::create_bucket(RGWUserInfo& owner, rgw_bucket& bucket, return ret; if (!pmaster_bucket) { - uint64_t iid = instance_id(); - uint64_t bid = next_bucket_id(); - char buf[get_zone_params().get_id().size() + 48]; - snprintf(buf, sizeof(buf), "%s.%llu.%llu", get_zone_params().get_id().c_str(), (long long)iid, (long long)bid); - bucket.marker = buf; + create_bucket_id(&bucket.marker); bucket.bucket_id = bucket.marker; } else { bucket.marker = pmaster_bucket->marker; @@ -6000,6 +5996,21 @@ int RGWRados::BucketShard::init(rgw_bucket& _bucket, rgw_obj& obj) return 0; } +int RGWRados::BucketShard::init(rgw_bucket& _bucket, int sid) +{ + bucket = _bucket; + shard_id = sid; + + int ret = store->open_bucket_index_shard(bucket, index_ctx, shard_id, &bucket_obj); + if (ret < 0) { + ldout(store->ctx(), 0) << "ERROR: open_bucket_index_shard() returned ret=" << ret << dendl; + return ret; + } + ldout(store->ctx(), 20) << " bucket index object: " << bucket_obj << dendl; + + return 0; +} + /* Execute @handler on last item in bucket listing for bucket specified * in @bucket_info. @obj_prefix and @obj_delim narrow down the listing @@ -7894,6 +7905,27 @@ int RGWRados::open_bucket_index_shard(rgw_bucket& bucket, librados::IoCtx& index return 0; } +int RGWRados::open_bucket_index_shard(rgw_bucket& bucket, librados::IoCtx& index_ctx, + int shard_id, string *bucket_obj) +{ + string bucket_oid_base; + int ret = open_bucket_index_base(bucket, index_ctx, bucket_oid_base); + if (ret < 0) + return ret; + + RGWObjectCtx obj_ctx(this); + + // Get the bucket info + RGWBucketInfo binfo; + ret = get_bucket_instance_info(obj_ctx, bucket, binfo, NULL, NULL); + if (ret < 0) + return ret; + + get_bucket_index_object(bucket_oid_base, binfo.num_shards, + shard_id, bucket_obj); + return 0; +} + static void accumulate_raw_stats(const rgw_bucket_dir_header& header, map& stats) { @@ -11545,6 +11577,20 @@ int RGWRados::bi_get(rgw_bucket& bucket, rgw_obj& obj, BIIndexType index_type, r return 0; } +void RGWRados::bi_put(ObjectWriteOperation& op, BucketShard& bs, rgw_cls_bi_entry& entry) +{ + cls_rgw_bi_put(op, bs.bucket_obj, entry); +} + +int RGWRados::bi_put(BucketShard& bs, rgw_cls_bi_entry& entry) +{ + int ret = cls_rgw_bi_put(bs.index_ctx, bs.bucket_obj, entry); + if (ret < 0) + return ret; + + return 0; +} + int RGWRados::bi_put(rgw_bucket& bucket, rgw_obj& obj, rgw_cls_bi_entry& entry) { BucketShard bs(this); @@ -11554,11 +11600,7 @@ int RGWRados::bi_put(rgw_bucket& bucket, rgw_obj& obj, rgw_cls_bi_entry& entry) return ret; } - ret = cls_rgw_bi_put(bs.index_ctx, bs.bucket_obj, entry); - if (ret < 0) - return ret; - - return 0; + return bi_put(bs, entry); } int RGWRados::bi_list(rgw_bucket& bucket, const string& obj_name, const string& marker, uint32_t max, list *entries, bool *is_truncated) @@ -11578,6 +11620,29 @@ int RGWRados::bi_list(rgw_bucket& bucket, const string& obj_name, const string& return 0; } +int RGWRados::bi_list(BucketShard& bs, const string& marker, uint32_t max, list *entries, bool *is_truncated) +{ + string filter_prefix; + + int ret = cls_rgw_bi_list(bs.index_ctx, bs.bucket_obj, filter_prefix, marker, max, entries, is_truncated); + if (ret < 0) + return ret; + + return 0; +} + +int RGWRados::bi_list(rgw_bucket& bucket, int shard_id, const string& marker, uint32_t max, list *entries, bool *is_truncated) +{ + BucketShard bs(this); + int ret = bs.init(bucket, shard_id); + if (ret < 0) { + ldout(cct, 5) << "bs.init() returned ret=" << ret << dendl; + return ret; + } + + return bi_list(bs, marker, max, entries, is_truncated); +} + int RGWRados::gc_operate(string& oid, librados::ObjectWriteOperation *op) { return gc_pool_ctx.operate(oid, op); @@ -12333,6 +12398,44 @@ void RGWRados::get_bucket_instance_ids(RGWBucketInfo& bucket_info, int shard_id, } } +int RGWRados::get_target_shard_id(const RGWBucketInfo& bucket_info, const string& obj_key, + int *shard_id) +{ + int r = 0; + switch (bucket_info.bucket_index_shard_hash_type) { + case RGWBucketInfo::MOD: + if (!bucket_info.num_shards) { + if (shard_id) { + *shard_id = -1; + } + } else { + uint32_t sid = ceph_str_hash_linux(obj_key.c_str(), obj_key.size()); + uint32_t sid2 = sid ^ ((sid & 0xFF) << 24); + sid = sid2 % MAX_BUCKET_INDEX_SHARDS_PRIME % bucket_info.num_shards; + if (shard_id) { + *shard_id = (int)sid; + } + } + break; + default: + r = -ENOTSUP; + } + return r; +} + +void RGWRados::get_bucket_index_object(const string& bucket_oid_base, uint32_t num_shards, + int shard_id, string *bucket_obj) +{ + if (!num_shards) { + // By default with no sharding, we use the bucket oid as itself + (*bucket_obj) = bucket_oid_base; + } else { + char buf[bucket_oid_base.size() + 32]; + snprintf(buf, sizeof(buf), "%s.%d", bucket_oid_base.c_str(), shard_id); + (*bucket_obj) = buf; + } +} + int RGWRados::get_bucket_index_object(const string& bucket_oid_base, const string& obj_key, uint32_t num_shards, RGWBucketInfo::BIShardsHashType hash_type, string *bucket_obj, int *shard_id) { diff --git a/src/rgw/rgw_rados.h b/src/rgw/rgw_rados.h index b2092a160ac09..d228b370c928c 100644 --- a/src/rgw/rgw_rados.h +++ b/src/rgw/rgw_rados.h @@ -1819,6 +1819,8 @@ class RGWRados string& bucket_oid_base); int open_bucket_index_shard(rgw_bucket& bucket, librados::IoCtx& index_ctx, const string& obj_key, string *bucket_obj, int *shard_id); + int open_bucket_index_shard(rgw_bucket& bucket, librados::IoCtx& index_ctx, + int shard_id, string *bucket_obj); int open_bucket_index(rgw_bucket& bucket, librados::IoCtx& index_ctx, map& bucket_objs, int shard_id = -1, map *bucket_instance_ids = NULL); template @@ -2160,6 +2162,7 @@ public: RGWZonePlacementInfo *rule_info); int set_bucket_location_by_rule(const string& location_rule, const string& tenant_name, const string& bucket_name, rgw_bucket& bucket, RGWZonePlacementInfo *rule_info); + void create_bucket_id(string *bucket_id); virtual int create_bucket(RGWUserInfo& owner, rgw_bucket& bucket, const string& zonegroup_id, const string& placement_rule, @@ -2242,6 +2245,7 @@ public: explicit BucketShard(RGWRados *_store) : store(_store), shard_id(-1) {} int init(rgw_bucket& _bucket, rgw_obj& obj); + int init(rgw_bucket& _bucket, int sid); }; class Object { @@ -2923,7 +2927,11 @@ public: int bi_get_instance(rgw_obj& obj, rgw_bucket_dir_entry *dirent); int bi_get(rgw_bucket& bucket, rgw_obj& obj, BIIndexType index_type, rgw_cls_bi_entry *entry); + void bi_put(librados::ObjectWriteOperation& op, BucketShard& bs, rgw_cls_bi_entry& entry); + int bi_put(BucketShard& bs, rgw_cls_bi_entry& entry); int bi_put(rgw_bucket& bucket, rgw_obj& obj, rgw_cls_bi_entry& entry); + int bi_list(rgw_bucket& bucket, int shard_id, const string& marker, uint32_t max, list *entries, bool *is_truncated); + int bi_list(BucketShard& bs, const string& marker, uint32_t max, list *entries, bool *is_truncated); int bi_list(rgw_bucket& bucket, const string& obj_name, const string& marker, uint32_t max, list *entries, bool *is_truncated); @@ -2936,6 +2944,7 @@ public: void shard_name(const string& prefix, unsigned max_shards, const string& key, string& name, int *shard_id); void shard_name(const string& prefix, unsigned max_shards, const string& section, const string& key, string& name); void shard_name(const string& prefix, unsigned shard_id, string& name); + int get_target_shard_id(const RGWBucketInfo& bucket_info, const string& obj_key, int *shard_id); void time_log_prepare_entry(cls_log_entry& entry, const ceph::real_time& ut, const string& section, const string& key, bufferlist& bl); int time_log_add_init(librados::IoCtx& io_ctx); int time_log_add(const string& oid, list& entries, @@ -3108,6 +3117,9 @@ public: int get_bucket_index_object(const string& bucket_oid_base, const string& obj_key, uint32_t num_shards, RGWBucketInfo::BIShardsHashType hash_type, string *bucket_obj, int *shard); + void get_bucket_index_object(const string& bucket_oid_base, uint32_t num_shards, + int shard_id, string *bucket_obj); + /** * Check the actual on-disk state of the object specified * by list_state, and fill in the time and size of object. -- 2.39.5