From: Yehuda Sadeh Date: Mon, 26 Sep 2016 23:09:15 +0000 (-0700) Subject: rgw: utilities to support raw bucket index operations X-Git-Tag: v0.94.10~8^2~19 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=c381cc5d69ebec4370ee18e350b9d003e15b2770;p=ceph.git rgw: utilities to support raw bucket index operations and other related changes. Signed-off-by: Yehuda Sadeh Conflicts: src/rgw/rgw_rados.cc src/rgw/rgw_rados.h --- diff --git a/src/rgw/rgw_rados.cc b/src/rgw/rgw_rados.cc index 8132bceaf8f..9d3e055892a 100644 --- a/src/rgw/rgw_rados.cc +++ b/src/rgw/rgw_rados.cc @@ -2641,8 +2641,8 @@ void RGWRados::create_bucket_id(string *bucket_id) { 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); + char buf[zone.name.size() + 48]; + snprintf(buf, sizeof(buf), "%s.%llu.%llu", zone.name.c_str(), (long long)iid, (long long)bid); *bucket_id = buf; } @@ -2681,11 +2681,7 @@ int RGWRados::create_bucket(RGWUserInfo& owner, rgw_bucket& bucket, return r; if (!pmaster_bucket) { - uint64_t iid = instance_id(); - uint64_t bid = next_bucket_id(); - char buf[zone.name.size() + 48]; - snprintf(buf, sizeof(buf), "%s.%llu.%llu", zone.name.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; @@ -3332,6 +3328,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; +} + /** * Write/overwrite an object to the bucket storage. @@ -4665,6 +4676,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(rgw_bucket_dir_header& header, map& stats) { map::iterator iter = header.stats.begin(); @@ -7981,6 +8013,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); @@ -7990,11 +8036,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) @@ -8014,6 +8056,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); @@ -8746,6 +8811,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 93077f8cc37..0d530c30064 100644 --- a/src/rgw/rgw_rados.h +++ b/src/rgw/rgw_rados.h @@ -1183,6 +1183,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 @@ -1387,6 +1389,7 @@ public: int select_new_bucket_location(RGWUserInfo& user_info, const string& region_name, const string& rule, const std::string& bucket_name, rgw_bucket& bucket, string *pselected_rule); int set_bucket_location_by_rule(const string& location_rule, const std::string& bucket_name, rgw_bucket& bucket); + void create_bucket_id(string *bucket_id); virtual int create_bucket(RGWUserInfo& owner, rgw_bucket& bucket, const string& region_name, const string& placement_rule, @@ -1462,6 +1465,7 @@ public: 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 { @@ -2049,7 +2053,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); @@ -2060,6 +2068,7 @@ public: void shard_name(const string& prefix, unsigned max_shards, const string& key, string& name); void shard_name(const string& prefix, unsigned max_shards, const string& section, const string& key, 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 utime_t& ut, const string& section, const string& key, bufferlist& bl); int time_log_add(const string& oid, list& entries); int time_log_add(const string& oid, const utime_t& ut, const string& section, const string& key, bufferlist& bl); @@ -2191,6 +2200,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.