From: Yehuda Sadeh Date: Mon, 21 Nov 2016 22:10:21 +0000 (-0800) Subject: rgw: keep rgw_obj key info in rgw_obj_key field X-Git-Tag: v12.0.1~111^2~16 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=50c522ea89a756123bf74ab615138cf8478b2cee;p=ceph.git rgw: keep rgw_obj key info in rgw_obj_key field Signed-off-by: Yehuda Sadeh --- diff --git a/src/rgw/rgw_admin.cc b/src/rgw/rgw_admin.cc index 6cc3dbb97d45..553b331d35c9 100644 --- a/src/rgw/rgw_admin.cc +++ b/src/rgw/rgw_admin.cc @@ -1292,10 +1292,9 @@ int set_user_quota(int opt_cmd, RGWUser& user, RGWUserAdminOpState& op_state, in static bool bucket_object_check_filter(const string& name) { - string ns; - string obj; - string instance; - return rgw_obj::translate_oid_to_obj_in_ns(name, obj, instance, ns); + rgw_obj_key k; + string ns; /* empty namespace */ + return rgw_obj_key::oid_to_key_in_ns(name, &k, ns); } int check_min_obj_stripe_size(RGWRados *store, RGWBucketInfo& bucket_info, rgw_obj& obj, uint64_t min_stripe_size, bool *need_rewrite) @@ -5194,7 +5193,7 @@ next: } rgw_obj obj(bucket, object); if (!object_version.empty()) { - obj.set_instance(object_version); + obj.key.set_instance(object_version); } rgw_cls_bi_entry entry; @@ -5367,7 +5366,7 @@ next: } rgw_obj obj(bucket, object); - obj.set_instance(object_version); + obj.key.set_instance(object_version); bool need_rewrite = true; if (min_rewrite_stripe_size > 0) { ret = check_min_obj_stripe_size(store, bucket_info, obj, min_rewrite_stripe_size, &need_rewrite); @@ -5674,7 +5673,7 @@ next: return -ret; } rgw_obj obj(bucket, object); - obj.set_instance(object_version); + obj.key.set_instance(object_version); uint64_t obj_size; map attrs; diff --git a/src/rgw/rgw_bucket.cc b/src/rgw/rgw_bucket.cc index 5f13be24bd1d..e17be3643875 100644 --- a/src/rgw/rgw_bucket.cc +++ b/src/rgw/rgw_bucket.cc @@ -498,10 +498,9 @@ void check_bad_user_bucket_mapping(RGWRados *store, const rgw_user& user_id, static bool bucket_object_check_filter(const string& oid) { + rgw_obj_key key; string ns; - string ver; - string name; - return rgw_obj::translate_oid_to_obj_in_ns(oid, name, ns, ver); + return rgw_obj_key::oid_to_key_in_ns(oid, &key, ns); } int rgw_remove_object(RGWRados *store, RGWBucketInfo& bucket_info, rgw_bucket& bucket, rgw_obj_key& key) @@ -999,7 +998,6 @@ int RGWBucket::check_bad_index_multipart(RGWBucketAdminOpState& op_state, int max = 1000; map common_prefixes; - string ns = ""; bool is_truncated; map meta_objs; @@ -1033,10 +1031,10 @@ int RGWBucket::check_bad_index_multipart(RGWBucketAdminOpState& op_state, rgw_bucket_dir_entry& ent = *iter; rgw_obj obj(bucket, ent.key); - obj.set_ns(ns); + obj.key.ns.clear(); rgw_obj_index_key key; - obj.get_index_key(&key); + obj.key.get_index_key(&key); string oid = key.name; diff --git a/src/rgw/rgw_common.h b/src/rgw/rgw_common.h index 0608b5e1f9a4..5582e02c808d 100644 --- a/src/rgw/rgw_common.h +++ b/src/rgw/rgw_common.h @@ -1351,6 +1351,7 @@ struct rgw_obj_key { // cppcheck-suppress noExplicitConstructor rgw_obj_key(const string& n) : name(n) {} rgw_obj_key(const string& n, const string& i) : name(n), instance(i) {} + rgw_obj_key(const string& n, const string& i, const string& _ns) : name(n), instance(i), ns(_ns) {} rgw_obj_key(const rgw_obj_index_key& k) { parse_index_key(k.name, &name, &ns); @@ -1386,6 +1387,30 @@ struct rgw_obj_key { ns.clear(); } + void set(const string& n, const string& i) { + name = n; + instance = i; + ns.clear(); + } + + void set(const string& n, const string& i, const string& _ns) { + name = n; + instance = i; + ns = _ns; + } + + bool set(const rgw_obj_index_key& index_key) { + if (!parse_raw_oid(index_key.name, this)) { + return false; + } + instance = index_key.instance; + return true; + } + + void set_instance(const string& i) { + instance = i; + } + string get_index_key_name() const { if (ns.empty()) { if (name.size() < 1 || name[0] != '_') { @@ -1404,19 +1429,59 @@ struct rgw_obj_key { key->instance = instance; } - void set(const string& n, const string& i) { - name = n; - instance = i; - ns.clear(); + string get_loc() const { + /* + * For backward compatibility. Older versions used to have object locator on all objects, + * however, the name was the effective object locator. This had the same effect as not + * having object locator at all for most objects but the ones that started with underscore as + * these were escaped. + */ + if (name[0] == '_' && ns.empty()) { + return name; + } + + return string(); } bool empty() const { return name.empty(); } + + bool have_null_instance() const { + return instance == "null"; + } + + bool have_instance() const { + return !instance.empty(); + } + + bool need_to_encode_instance() const { + return have_instance() && !have_null_instance(); + } + + string get_oid() const { + if (ns.empty() && !need_to_encode_instance()) { + if (name.size() < 1 || name[0] != '_') { + return name; + } + return string("_") + name; + } + + string oid = "_"; + oid.append(ns); + if (need_to_encode_instance()) { + oid.append(string(":") + instance); + } + oid.append("_"); + oid.append(name); + return oid; + } + bool operator==(const rgw_obj_key& k) const { return (name.compare(k.name) == 0) && (instance.compare(k.instance) == 0); } + bool operator<(const rgw_obj_key& k) const { int r = name.compare(k.name); if (r == 0) { @@ -1424,9 +1489,103 @@ struct rgw_obj_key { } return (r < 0); } + bool operator<=(const rgw_obj_key& k) const { return !(k < *this); } + + static void parse_ns_field(string& ns, string& instance) { + int pos = ns.find(':'); + if (pos >= 0) { + instance = ns.substr(pos + 1); + ns = ns.substr(0, pos); + } else { + instance.clear(); + } + } + + static bool parse_raw_oid(const string& oid, rgw_obj_key *key) { + key->instance.clear(); + key->ns.clear(); + if (oid[0] != '_') { + key->name = oid; + return true; + } + + if (oid.size() >= 2 && oid[1] == '_') { + key->name = oid.substr(1); + return true; + } + + if (oid[0] != '_' || oid.size() < 3) // for namespace, min size would be 3: _x_ + return false; + + int pos = oid.find('_', 1); + if (pos <= 1) // if it starts with __, it's not in our namespace + return false; + + key->ns = oid.substr(1, pos - 1); + parse_ns_field(key->ns, key->instance); + + key->name = oid.substr(pos + 1); + return true; + } + + /** + * Translate a namespace-mangled object name to the user-facing name + * existing in the given namespace. + * + * If the object is part of the given namespace, it returns true + * and cuts down the name to the unmangled version. If it is not + * part of the given namespace, it returns false. + */ + static bool oid_to_key_in_ns(const string& oid, rgw_obj_key *key, const string& ns) { + string obj_ns; + bool ret = parse_raw_oid(oid, key); + if (!ret) { + return ret; + } + + return (ns == key->ns); + } + + /** + * Given a mangled object name and an empty namespace string, this + * function extracts the namespace into the string and sets the object + * name to be the unmangled version. + * + * It returns true after successfully doing so, or + * false if it fails. + */ + static bool strip_namespace_from_name(string& name, string& ns, string& instance) { + ns.clear(); + instance.clear(); + if (name[0] != '_') { + return true; + } + + size_t pos = name.find('_', 1); + if (pos == string::npos) { + return false; + } + + if (name[1] == '_') { + name = name.substr(1); + return true; + } + + size_t period_pos = name.find('.'); + if (period_pos < pos) { + return false; + } + + ns = name.substr(1, pos-1); + name = name.substr(pos+1, string::npos); + + parse_ns_field(ns, instance); + return true; + } + void encode(bufferlist& bl) const { ENCODE_START(2, 1, bl); ::encode(name, bl); @@ -1666,229 +1825,48 @@ WRITE_CLASS_ENCODER(RGWBucketEnt) struct rgw_obj { rgw_bucket bucket; - std::string ns; - std::string name; - std::string instance; + rgw_obj_key key; std::string placement_id; bool in_extra_data{false}; /* in-memory only member, does not serialize */ - const std::string& get_name() const { return name; } - const std::string& get_instance() const { return instance; } - // Represents the hash index source for this object once it is set (non-empty) std::string index_hash_source; rgw_obj() {} - rgw_obj(const rgw_bucket& b, const std::string& name) { - init(b, name); - } - rgw_obj(const rgw_bucket& b, const rgw_obj_key& k) { - init(b, k.name); - instance = k.instance; - } - rgw_obj(const rgw_bucket& b, const rgw_obj_index_key& k) : bucket(b) { - rgw_obj_key::parse_index_key(k.name, &name, &ns); - set_instance(k.instance); - } + rgw_obj(const rgw_bucket& b, const std::string& name) : bucket(b), key(name) {} + rgw_obj(const rgw_bucket& b, const rgw_obj_key& k) : bucket(b), key(k) {} + rgw_obj(const rgw_bucket& b, const rgw_obj_index_key& k) : bucket(b), key(k) {} + void init(const rgw_bucket& b, const std::string& name) { bucket = b; - set_name(name); + key.set(name); } - void init_ns(const rgw_bucket& b, const std::string& name, const std::string& n) { + void init(const rgw_bucket& b, const std::string& name, const string& i, const string& n) { bucket = b; - set_ns(n); - set_name(name); - } - void set_ns(const string& n) { - ns = n; - } - void set_instance(const string& i) { - instance = i; - } - - void clear_instance() { - instance.clear(); + key.set(name, i, n); } - - string get_loc() const { - /* - * For backward compatibility. Older versions used to have object locator on all objects, - * however, the name was the effective object locator. This had the same effect as not - * having object locator at all for most objects but the ones that started with underscore as - * these were escaped. - */ - if (name[0] == '_' && ns.empty()) { - return name; - } - - return string(); + void init_ns(const rgw_bucket& b, const std::string& name, const string& n) { + bucket = b; + key.name = name; + key.instance.clear(); + key.ns = n; } bool empty() const { - return name.empty(); - } - - bool have_null_instance() const { - return instance == "null"; - } - - bool have_instance() const { - return !instance.empty(); - } - - bool need_to_encode_instance() const { - return have_instance() && !have_null_instance(); - } - - void set_name(const string& n) { - name = n; + return key.empty(); } void set_key(const rgw_obj_key& k) { - set_name(k.name); - set_instance(k.instance); + key = k; } string get_oid() const { - if (ns.empty() && !need_to_encode_instance()) { - if (name.size() < 1 || name[0] != '_') { - return name; - } - return string("_") + name; - } - - string oid = "_"; - oid.append(ns); - if (need_to_encode_instance()) { - oid.append(string(":") + instance); - } - oid.append("_"); - oid.append(name); - return oid; - } - - /* - * get the object's key name as being referred to by the bucket index. - */ - string get_index_key_name() const { - if (ns.empty()) { - if (name.size() < 1 || name[0] != '_') { - return name; - } - return string("_") + name; - }; - - char buf[ns.size() + 16]; - snprintf(buf, sizeof(buf), "_%s_", ns.c_str()); - return string(buf) + name; - }; - - void get_index_key(rgw_obj_index_key *key) const { - key->name = get_index_key_name(); - key->instance = instance; - } - - static void parse_ns_field(string& ns, string& instance) { - int pos = ns.find(':'); - if (pos >= 0) { - instance = ns.substr(pos + 1); - ns = ns.substr(0, pos); - } else { - instance.clear(); - } + return key.get_oid(); } const string& get_hash_object() const { - return index_hash_source.empty() ? name : index_hash_source; - } - /** - * Translate a namespace-mangled object name to the user-facing name - * existing in the given namespace. - * - * If the object is part of the given namespace, it returns true - * and cuts down the name to the unmangled version. If it is not - * part of the given namespace, it returns false. - */ - static bool translate_oid_to_obj_in_ns(const string& oid, string& name, string& instance, string& ns) { - if (oid[0] != '_') { - if (ns.empty()) { - return true; - } - return false; - } - - string obj_ns; - bool ret = parse_raw_oid(oid, &name, &instance, &obj_ns); - if (!ret) { - return ret; - } - - return (ns == obj_ns); - } - - static bool parse_raw_oid(const string& oid, string *obj_name, string *obj_instance, string *obj_ns) { - obj_instance->clear(); - obj_ns->clear(); - if (oid[0] != '_') { - *obj_name = oid; - return true; - } - - if (oid.size() >= 2 && oid[1] == '_') { - *obj_name = oid.substr(1); - return true; - } - - if (oid[0] != '_' || oid.size() < 3) // for namespace, min size would be 3: _x_ - return false; - - int pos = oid.find('_', 1); - if (pos <= 1) // if it starts with __, it's not in our namespace - return false; - - *obj_ns = oid.substr(1, pos - 1); - parse_ns_field(*obj_ns, *obj_instance); - - *obj_name = oid.substr(pos + 1); - return true; - } - - /** - * Given a mangled object name and an empty namespace string, this - * function extracts the namespace into the string and sets the object - * name to be the unmangled version. - * - * It returns true after successfully doing so, or - * false if it fails. - */ - static bool strip_namespace_from_name(string& name, string& ns, string& instance) { - ns.clear(); - instance.clear(); - if (name[0] != '_') { - return true; - } - - size_t pos = name.find('_', 1); - if (pos == string::npos) { - return false; - } - - if (name[1] == '_') { - name = name.substr(1); - return true; - } - - size_t period_pos = name.find('.'); - if (period_pos < pos) { - return false; - } - - ns = name.substr(1, pos-1); - name = name.substr(pos+1, string::npos); - - parse_ns_field(ns, instance); - return true; + return index_hash_source.empty() ? key.name : index_hash_source; } void set_in_extra_data(bool val) { @@ -1902,9 +1880,9 @@ struct rgw_obj { void encode(bufferlist& bl) const { ENCODE_START(6, 6, bl); ::encode(bucket, bl); - ::encode(ns, bl); - ::encode(name, bl); - ::encode(instance, bl); + ::encode(key.ns, bl); + ::encode(key.name, bl); + ::encode(key.instance, bl); ::encode(placement_id, bl); ENCODE_FINISH(bl); } @@ -1914,32 +1892,32 @@ struct rgw_obj { string s; ::decode(bucket.name, bl); /* bucket.name */ ::decode(s, bl); /* loc */ - ::decode(ns, bl); - ::decode(name, bl); + ::decode(key.ns, bl); + ::decode(key.name, bl); if (struct_v >= 2) ::decode(bucket, bl); if (struct_v >= 4) - ::decode(instance, bl); - if (ns.empty() && instance.empty()) { - if (name[0] == '_') { - name = name.substr(1); + ::decode(key.instance, bl); + if (key.ns.empty() && key.instance.empty()) { + if (key.name[0] == '_') { + key.name = key.name.substr(1); } } else { if (struct_v >= 5) { - ::decode(name, bl); + ::decode(key.name, bl); } else { - ssize_t pos = name.find('_', 1); + ssize_t pos = key.name.find('_', 1); if (pos < 0) { throw buffer::error(); } - name = name.substr(pos); + key.name = key.name.substr(pos); } } } else { ::decode(bucket, bl); - ::decode(ns, bl); - ::decode(name, bl); - ::decode(instance, bl); + ::decode(key.ns, bl); + ::decode(key.name, bl); + ::decode(key.instance, bl); ::decode(placement_id, bl); } DECODE_FINISH(bl); @@ -1948,19 +1926,17 @@ struct rgw_obj { static void generate_test_instances(list& o); bool operator==(const rgw_obj& o) const { - return (name.compare(o.name) == 0) && - (bucket == o.bucket) && - (ns.compare(o.ns) == 0) && - (instance.compare(o.instance) == 0); /* should not compare placement_id */ + return (key == o.key) && + (bucket == o.bucket); } bool operator<(const rgw_obj& o) const { - int r = name.compare(o.name); + int r = key.name.compare(o.key.name); if (r == 0) { r = bucket.bucket_id.compare(o.bucket.bucket_id); /* not comparing bucket.name, if bucket_id is equal so will be bucket.name */ if (r == 0) { - r = ns.compare(o.ns); + r = key.ns.compare(o.key.ns); if (r == 0) { - r = instance.compare(o.instance); + r = key.instance.compare(o.key.instance); } } } diff --git a/src/rgw/rgw_data_sync.cc b/src/rgw/rgw_data_sync.cc index b3014068a0a9..66a3b20e46ac 100644 --- a/src/rgw/rgw_data_sync.cc +++ b/src/rgw/rgw_data_sync.cc @@ -2453,10 +2453,6 @@ class RGWBucketShardIncrementalSyncCR : public RGWCoroutine { bool updated_status{false}; const string& status_oid; - string name; - string instance; - string ns; - string cur_id; RGWDataSyncDebugLogger logger; @@ -2527,23 +2523,22 @@ int RGWBucketShardIncrementalSyncCR::operate() } inc_marker.position = cur_id; - if (!rgw_obj::parse_raw_oid(entries_iter->object, &name, &instance, &ns)) { + if (!key.set(rgw_obj_index_key(entries_iter->object))) { set_status() << "parse_raw_oid() on " << entries_iter->object << " returned false, skipping entry"; ldout(sync_env->cct, 20) << "parse_raw_oid() on " << entries_iter->object << " returned false, skipping entry" << dendl; marker_tracker.try_update_high_marker(cur_id, 0, entries_iter->timestamp); continue; } - ldout(sync_env->cct, 20) << "parsed entry: id=" << cur_id << " iter->object=" << entry->object << " iter->instance=" << entry->instance << " name=" << name << " instance=" << instance << " ns=" << ns << dendl; + ldout(sync_env->cct, 20) << "parsed entry: id=" << cur_id << " iter->object=" << entry->object << " iter->instance=" << entry->instance << " name=" << key.name << " instance=" << key.instance << " ns=" << key.ns << dendl; - if (!ns.empty()) { + if (!key.ns.empty()) { set_status() << "skipping entry in namespace: " << entry->object; ldout(sync_env->cct, 20) << "skipping entry in namespace: " << entry->object << dendl; marker_tracker.try_update_high_marker(cur_id, 0, entry->timestamp); continue; } - key = rgw_obj_key(name, entry->instance); set_status() << "got entry.id=" << cur_id << " key=" << key << " op=" << (int)entry->op; if (entry->op == CLS_RGW_OP_CANCEL) { set_status() << "canceled operation, skipping"; diff --git a/src/rgw/rgw_dencoder.cc b/src/rgw/rgw_dencoder.cc index beca1529721a..cfeae47335e7 100644 --- a/src/rgw/rgw_dencoder.cc +++ b/src/rgw/rgw_dencoder.cc @@ -159,13 +159,16 @@ void RGWObjManifest::generate_test_instances(std::list& o) void RGWObjManifest::get_implicit_location(uint64_t cur_part_id, uint64_t cur_stripe, uint64_t ofs, string *override_prefix, rgw_obj_select *location) { - string oid; + rgw_obj loc; + + string& oid = loc.key.name; + string& ns = loc.key.ns; + if (!override_prefix || override_prefix->empty()) { oid = prefix; } else { oid = *override_prefix; } - string ns; if (!cur_part_id) { if (ofs < max_head_size) { @@ -190,21 +193,15 @@ void RGWObjManifest::get_implicit_location(uint64_t cur_part_id, uint64_t cur_st } } - rgw_bucket *bucket; - - rgw_obj loc; - if (!tail_bucket.name.empty()) { - bucket = &tail_bucket; + loc.bucket = tail_bucket; } else { - bucket = &obj.bucket; + loc.bucket = obj.bucket; } - loc.init_ns(*bucket, oid, ns); - // Always overwrite instance with tail_instance // to get the right shadow object location - loc.set_instance(tail_instance); + loc.key.set_instance(tail_instance); *location = loc; } diff --git a/src/rgw/rgw_json_enc.cc b/src/rgw/rgw_json_enc.cc index ac5460b84c93..7c0b64ce229c 100644 --- a/src/rgw/rgw_json_enc.cc +++ b/src/rgw/rgw_json_enc.cc @@ -761,6 +761,7 @@ void rgw_obj_key::dump(Formatter *f) const { encode_json("name", name, f); encode_json("instance", instance, f); + encode_json("ns", ns, f); } void RGWBucketEnt::dump(Formatter *f) const @@ -798,9 +799,8 @@ void rgw_raw_obj::decode_json(JSONObj *obj) { void rgw_obj::dump(Formatter *f) const { encode_json("bucket", bucket, f); - encode_json("ns", ns, f); - encode_json("name", name, f); - encode_json("instance", instance, f); + encode_json("key", key, f); + encode_json("placement_id", placement_id, f); } void RGWDefaultSystemMetaObjInfo::dump(Formatter *f) const { diff --git a/src/rgw/rgw_op.cc b/src/rgw/rgw_op.cc index f0bc7fdff27f..7a8a58b49087 100644 --- a/src/rgw/rgw_op.cc +++ b/src/rgw/rgw_op.cc @@ -4945,7 +4945,7 @@ void RGWCompleteMultipart::execute() } rgw_obj_index_key remove_key; - src_obj.get_index_key(&remove_key); + src_obj.key.get_index_key(&remove_key); remove_objs.push_back(remove_key); @@ -5078,7 +5078,7 @@ void RGWAbortMultipart::execute() rgw_raw_obj_to_obj(s->bucket, raw_head, &head); rgw_obj_index_key key; - head.get_index_key(&key); + head.key.get_index_key(&key); remove_objs.push_back(key); } } diff --git a/src/rgw/rgw_orphan.cc b/src/rgw/rgw_orphan.cc index 73800731bc82..e706a9185fe4 100644 --- a/src/rgw/rgw_orphan.cc +++ b/src/rgw/rgw_orphan.cc @@ -24,13 +24,11 @@ static string obj_fingerprint(const string& oid, const char *force_ns = NULL) string obj_marker = oid.substr(0, pos); - string obj_name; - string obj_instance; - string obj_ns; + rgw_obj_key key; - rgw_obj::parse_raw_oid(oid.substr(pos + 1), &obj_name, &obj_instance, &obj_ns); + rgw_obj_key::parse_raw_oid(oid.substr(pos + 1), &key); - if (obj_ns.empty()) { + if (key.ns.empty()) { return oid; } @@ -38,9 +36,7 @@ static string obj_fingerprint(const string& oid, const char *force_ns = NULL) if (force_ns) { rgw_bucket b; - rgw_obj new_obj(b, obj_name); - new_obj.set_ns(force_ns); - new_obj.set_instance(obj_instance); + rgw_obj new_obj(b, key); s = obj_marker + "_" + new_obj.get_oid(); } @@ -319,13 +315,13 @@ int RGWOrphanSearch::build_all_oids_index() continue; } string stripped_oid = oid.substr(pos + 1); - string name, instance, ns; - if (!rgw_obj::parse_raw_oid(stripped_oid, &name, &instance, &ns)) { + rgw_obj_key key; + if (!rgw_obj_key::parse_raw_oid(stripped_oid, &key)) { cout << "cannot parse oid: " << oid << ", skipping" << std::endl; continue; } - if (ns.empty()) { + if (key.ns.empty()) { /* skipping head objects, we don't want to remove these as they are mutable and * cleaning them up is racy (can race with object removal and a later recreation) */ diff --git a/src/rgw/rgw_rados.cc b/src/rgw/rgw_rados.cc index cf12b75a55fa..553201b2fca8 100644 --- a/src/rgw/rgw_rados.cc +++ b/src/rgw/rgw_rados.cc @@ -2025,7 +2025,7 @@ int RGWObjManifest::generator::create_begin(CephContext *cct, RGWObjManifest *_m manifest->get_implicit_location(cur_part_id, cur_stripe, 0, NULL, &cur_obj); // Normal object which not generated through copy operation - manifest->set_tail_instance(_obj.get_instance()); + manifest->set_tail_instance(_obj.key.instance); manifest->update_iterators(); @@ -2503,7 +2503,7 @@ int RGWPutObjProcessor_Atomic::prepare(RGWRados *store, string *oid_rand) } if (!version_id.empty()) { - head_obj.set_instance(version_id); + head_obj.key.set_instance(version_id); } else if (versioned_object) { store->gen_rand_obj_instance_name(&head_obj); } @@ -5138,13 +5138,12 @@ int RGWRados::Bucket::List::list_objects(int max, vector * result->clear(); - rgw_bucket b; - rgw_obj marker_obj(b, params.marker); - rgw_obj end_marker_obj(b, params.end_marker); - rgw_obj prefix_obj; + rgw_obj_key marker_obj(params.marker.name, params.marker.instance, params.ns); + + rgw_obj_key end_marker_obj; rgw_obj_index_key cur_end_marker; if (!params.ns.empty()) { - marker_obj.set_ns(params.ns); + end_marker_obj = rgw_obj_key(params.end_marker.name, params.end_marker.instance, params.ns); end_marker_obj.set_ns(params.ns); end_marker_obj.get_index_key(&cur_end_marker); } @@ -5153,8 +5152,8 @@ int RGWRados::Bucket::List::list_objects(int max, vector * const bool cur_end_marker_valid = !params.end_marker.empty(); - prefix_obj.set_ns(params.ns); - prefix_obj.set_name(params.prefix); + rgw_obj_key prefix_obj(params.prefix); + prefix_obj.ns = params.ns; string cur_prefix = prefix_obj.get_index_key_name(); string bigger_than_delim; @@ -5200,7 +5199,11 @@ int RGWRados::Bucket::List::list_objects(int max, vector * rgw_obj_key obj(index_key); - bool valid = rgw_obj::parse_raw_oid(index_key.name, &obj.name, &obj.instance, &obj.ns); + /* note that parse_raw_oid() here will not set the correct object's instance, as + * rgw_obj_index_key encodes that separately. We don't need to set the instance because it's + * not needed for the checks here and we end up using the raw entry for the return vector + */ + bool valid = rgw_obj_key::parse_raw_oid(index_key.name, &obj); if (!valid) { ldout(cct, 0) << "ERROR: could not parse object name: " << obj.name << dendl; continue; @@ -5989,7 +5992,7 @@ int RGWRados::fix_tail_obj_locator(rgw_bucket& bucket, rgw_obj_key& key, bool fi rgw_raw_obj_to_obj(manifest.get_tail_bucket(), raw_loc, &loc); - if (loc.ns.empty()) { + if (loc.key.ns.empty()) { /* continue, we're only interested in tail objects */ continue; } @@ -6005,7 +6008,7 @@ int RGWRados::fix_tail_obj_locator(rgw_bucket& bucket, rgw_obj_key& key, bool fi } string bad_loc; - prepend_bucket_marker(bucket, loc.get_name(), bad_loc); + prepend_bucket_marker(bucket, loc.key.name, bad_loc); /* create a new ioctx with the bad locator */ librados::IoCtx src_ioctx; @@ -6446,7 +6449,7 @@ int RGWRados::Object::Write::_do_write_meta(uint64_t size, uint64_t accounted_si bool orig_exists = state->exists; uint64_t orig_size = state->accounted_size; - bool versioned_target = (meta.olh_epoch > 0 || !obj.get_instance().empty()); + bool versioned_target = (meta.olh_epoch > 0 || !obj.key.instance.empty()); bool versioned_op = (target->versioning_enabled() || is_olh || versioned_target); @@ -6502,7 +6505,7 @@ int RGWRados::Object::Write::_do_write_meta(uint64_t size, uint64_t accounted_si if (!real_clock::is_zero(meta.delete_at)) { rgw_obj_index_key obj_key; - obj.get_index_key(&obj_key); + obj.key.get_index_key(&obj_key); r = store->objexp_hint_add(meta.delete_at, obj.bucket.tenant, obj.bucket.name, obj.bucket.bucket_id, obj_key); @@ -7128,11 +7131,11 @@ int RGWRados::fetch_remote_obj(RGWObjectCtx& obj_ctx, set_mtime_weight.high_precision = high_precision_time; RGWPutObjProcessor_Atomic processor(obj_ctx, - dest_bucket_info, dest_obj.bucket, dest_obj.get_name(), + dest_bucket_info, dest_obj.bucket, dest_obj.key.name, cct->_conf->rgw_obj_stripe_size, tag, dest_bucket_info.versioning_enabled()); - const string& instance = dest_obj.get_instance(); + const string& instance = dest_obj.key.instance; if (instance != "null") { - processor.set_version_id(dest_obj.get_instance()); + processor.set_version_id(dest_obj.key.instance); } processor.set_olh_epoch(olh_epoch); int ret = processor.prepare(this, NULL); @@ -7578,7 +7581,7 @@ int RGWRados::copy_obj(RGWObjectCtx& obj_ctx, if (version_id && !version_id->empty()) { versioned_dest = true; - dest_obj.set_instance(*version_id); + dest_obj.key.set_instance(*version_id); } else if (versioned_dest) { gen_rand_obj_instance_name(&dest_obj); } @@ -7834,14 +7837,10 @@ int RGWRados::delete_bucket(RGWBucketInfo& bucket_info, RGWObjVersionTracker& ob string ns; std::map::iterator eiter; - rgw_obj_index_key obj; - string instance; for (eiter = ent_map.begin(); eiter != ent_map.end(); ++eiter) { - obj = eiter->second.key; - - /* obj.name actually contains index key that is formatted similar to oid */ + rgw_obj_key obj; - if (rgw_obj::translate_oid_to_obj_in_ns(obj.name, obj.name, instance, ns)) + if (rgw_obj_key::oid_to_key_in_ns(eiter->second.key.name, &obj, ns)) return -ENOTEMPTY; } } while (is_truncated); @@ -8194,11 +8193,11 @@ int RGWRados::Object::Delete::delete_obj() { RGWRados *store = target->get_store(); rgw_obj& src_obj = target->get_obj(); - const string& instance = src_obj.get_instance(); + const string& instance = src_obj.key.instance; rgw_obj obj = src_obj; if (instance == "null") { - obj.clear_instance(); + obj.key.instance.clear(); } bool explicit_marker_version = (!params.marker_version_id.empty()); @@ -8209,13 +8208,13 @@ int RGWRados::Object::Delete::delete_obj() if (!params.marker_version_id.empty()) { if (params.marker_version_id != "null") { - marker.set_instance(params.marker_version_id); + marker.key.set_instance(params.marker_version_id); } } else if ((params.versioning_status & BUCKET_VERSIONS_SUSPENDED) == 0) { store->gen_rand_obj_instance_name(&marker); } - result.version_id = marker.get_instance(); + result.version_id = marker.key.instance; result.delete_marker = true; struct rgw_bucket_dir_entry_meta meta; @@ -8577,7 +8576,7 @@ int RGWRados::get_system_obj_state(RGWObjectCtx *rctx, rgw_raw_obj& obj, RGWRawO int RGWRados::get_obj_state_impl(RGWObjectCtx *rctx, const rgw_obj& obj, RGWObjState **state, bool follow_olh, bool assume_noent) { - bool need_follow_olh = follow_olh && !obj.have_instance(); + bool need_follow_olh = follow_olh && obj.key.instance.empty(); RGWObjState *s = rctx->obj.get_state(obj); ldout(cct, 20) << "get_obj_state: rctx=" << (void *)rctx << " obj=" << obj << " state=" << (void *)s << " s->prefetch_data=" << s->prefetch_data << dendl; @@ -9110,7 +9109,7 @@ int RGWRados::set_attrs(void *ctx, rgw_obj& obj, ::decode(ts, bl); rgw_obj_index_key obj_key; - obj.get_index_key(&obj_key); + obj.key.get_index_key(&obj_key); objexp_hint_add(ts, bucket.tenant, bucket.name, bucket.bucket_id, obj_key); } catch (buffer::error& err) { @@ -9421,7 +9420,7 @@ int RGWRados::Bucket::UpdateIndex::complete(int64_t poolid, uint64_t epoch, } rgw_bucket_dir_entry ent; - obj.get_index_key(&ent.key); + obj.key.get_index_key(&ent.key); ent.meta.size = size; ent.meta.accounted_size = accounted_size; ent.meta.mtime = ut; @@ -10173,7 +10172,7 @@ int RGWRados::olh_init_modification_impl(RGWObjState& state, const rgw_obj& olh_ { ObjectWriteOperation op; - assert(olh_obj.get_instance().empty()); + assert(olh_obj.key.instance.empty()); bool has_tag = (state.exists && has_olh_tag(state.attrset)); @@ -10299,7 +10298,7 @@ int RGWRados::bucket_index_link_olh(RGWObjState& olh_state, const rgw_obj& obj_i return ret; } - cls_rgw_obj_key key(obj_instance.get_index_key_name(), obj_instance.get_instance()); + cls_rgw_obj_key key(obj_instance.key.get_index_key_name(), obj_instance.key.instance); ret = cls_rgw_bucket_link_olh(bs.index_ctx, bs.bucket_obj, key, olh_state.olh_tag, delete_marker, op_tag, meta, olh_epoch, unmod_since, high_precision_time, get_zone().log_data); @@ -10331,7 +10330,7 @@ int RGWRados::bucket_index_unlink_instance(const rgw_obj& obj_instance, const st return ret; } - cls_rgw_obj_key key(obj_instance.get_index_key_name(), obj_instance.get_instance()); + cls_rgw_obj_key key(obj_instance.key.get_index_key_name(), obj_instance.key.instance); ret = cls_rgw_bucket_unlink_instance(bs.index_ctx, bs.bucket_obj, key, op_tag, olh_tag, olh_epoch, get_zone().log_data); if (ret < 0) { return ret; @@ -10359,7 +10358,7 @@ int RGWRados::bucket_index_read_olh_log(RGWObjState& state, const rgw_obj& obj_i string olh_tag(state.olh_tag.c_str(), state.olh_tag.length()); - cls_rgw_obj_key key(obj_instance.get_index_key_name(), string()); + cls_rgw_obj_key key(obj_instance.key.get_index_key_name(), string()); ObjectReadOperation op; @@ -10387,7 +10386,7 @@ int RGWRados::bucket_index_trim_olh_log(RGWObjState& state, const rgw_obj& obj_i string olh_tag(state.olh_tag.c_str(), state.olh_tag.length()); - cls_rgw_obj_key key(obj_instance.get_index_key_name(), string()); + cls_rgw_obj_key key(obj_instance.key.get_index_key_name(), string()); ObjectWriteOperation op; @@ -10417,7 +10416,7 @@ int RGWRados::bucket_index_clear_olh(RGWObjState& state, const rgw_obj& obj_inst string olh_tag(state.olh_tag.c_str(), state.olh_tag.length()); - cls_rgw_obj_key key(obj_instance.get_index_key_name(), string()); + cls_rgw_obj_key key(obj_instance.key.get_index_key_name(), string()); ret = cls_rgw_clear_olh(bs.index_ctx, bs.bucket_obj, key, olh_tag); if (ret < 0) { @@ -10585,7 +10584,7 @@ int RGWRados::set_olh(RGWObjectCtx& obj_ctx, RGWBucketInfo& bucket_info, const r string op_tag; rgw_obj olh_obj = target_obj; - olh_obj.clear_instance(); + olh_obj.key.instance.clear(); RGWObjState *state = NULL; @@ -10645,7 +10644,7 @@ int RGWRados::unlink_obj_instance(RGWObjectCtx& obj_ctx, RGWBucketInfo& bucket_i string op_tag; rgw_obj olh_obj = target_obj; - olh_obj.clear_instance(); + olh_obj.key.instance.clear(); RGWObjState *state = NULL; @@ -10708,7 +10707,7 @@ void RGWRados::gen_rand_obj_instance_name(rgw_obj *target_obj) gen_rand_alphanumeric_no_underscore(cct, buf, OBJ_INSTANCE_LEN); /* don't want it to get url escaped, no underscore for instance name due to the way we encode the raw keys */ - target_obj->set_instance(buf); + target_obj->key.set_instance(buf); } static void filter_attrset(map& unfiltered_attrset, const string& check_prefix, @@ -11781,7 +11780,7 @@ int RGWRados::bi_get(rgw_bucket& bucket, rgw_obj& obj, BIIndexType index_type, r return ret; } - cls_rgw_obj_key key(obj.get_index_key_name(), obj.get_instance()); + cls_rgw_obj_key key(obj.key.get_index_key_name(), obj.key.instance); ret = cls_rgw_bi_get(bs.index_ctx, bs.bucket_obj, index_type, key, entry); if (ret < 0) @@ -11923,8 +11922,8 @@ int RGWRados::cls_obj_prepare_op(BucketShard& bs, RGWModifyOp op, string& tag, rgw_obj& obj, uint16_t bilog_flags) { ObjectWriteOperation o; - cls_rgw_obj_key key(obj.get_index_key_name(), obj.get_instance()); - cls_rgw_bucket_prepare_op(o, op, tag, key, obj.get_loc(), get_zone().log_data, bilog_flags); + cls_rgw_obj_key key(obj.key.get_index_key_name(), obj.key.instance); + cls_rgw_bucket_prepare_op(o, op, tag, key, obj.key.get_loc(), get_zone().log_data, bilog_flags); return bs.index_ctx.operate(bs.bucket_obj, &o); } @@ -11978,14 +11977,14 @@ int RGWRados::cls_obj_complete_del(BucketShard& bs, string& tag, { rgw_bucket_dir_entry ent; ent.meta.mtime = removed_mtime; - obj.get_index_key(&ent.key); + obj.key.get_index_key(&ent.key); return cls_obj_complete_op(bs, CLS_RGW_OP_DEL, tag, pool, epoch, ent, RGW_OBJ_CATEGORY_NONE, remove_objs, bilog_flags); } int RGWRados::cls_obj_complete_cancel(BucketShard& bs, string& tag, rgw_obj& obj, uint16_t bilog_flags) { rgw_bucket_dir_entry ent; - obj.get_index_key(&ent.key); + obj.key.get_index_key(&ent.key); return cls_obj_complete_op(bs, CLS_RGW_OP_CANCEL, tag, -1 /* pool id */, 0, ent, RGW_OBJ_CATEGORY_NONE, NULL, bilog_flags); } @@ -12196,11 +12195,7 @@ int RGWRados::check_disk_state(librados::IoCtx io_ctx, { uint8_t suggest_flag = (get_zone().log_data ? CEPH_RGW_DIR_SUGGEST_LOG_OP : 0); - std::string name, instance, loc, ns; - if (!rgw_obj::strip_namespace_from_name(list_state.key.name, ns, instance)) { - ldout(cct, 0) << "ERROR: got bad object name off backend: name=" << name << dendl; - return -EIO; - } + std::string loc; rgw_obj obj(bucket, list_state.key); @@ -12267,7 +12262,7 @@ int RGWRados::check_disk_state(librados::IoCtx io_ctx, rgw_obj loc; rgw_raw_obj_to_obj(manifest.get_obj().bucket, raw_loc, &loc); - if (loc.ns == RGW_OBJ_NS_MULTIPART) { + if (loc.key.ns == RGW_OBJ_NS_MULTIPART) { dout(10) << "check_disk_state(): removing manifest part from index: " << loc << dendl; r = delete_obj_index(loc); if (r < 0) { diff --git a/src/rgw/rgw_rados.h b/src/rgw/rgw_rados.h index 2977e1798bce..dfb04c7db4c4 100644 --- a/src/rgw/rgw_rados.h +++ b/src/rgw/rgw_rados.h @@ -68,7 +68,7 @@ static inline void get_obj_bucket_and_oid_loc(const rgw_obj& obj, string& oid, s { const rgw_bucket& bucket = obj.bucket; prepend_bucket_marker(bucket, obj.get_oid(), oid); - const string& loc = obj.get_loc(); + const string& loc = obj.key.get_loc(); if (!loc.empty()) { prepend_bucket_marker(bucket, loc, locator); } else { @@ -80,21 +80,15 @@ int rgw_policy_from_attrset(CephContext *cct, map& attrset, static inline bool rgw_raw_obj_to_obj(const rgw_bucket& bucket, const rgw_raw_obj& raw_obj, rgw_obj *obj) { - string name; - string instance; - string ns; - ssize_t pos = raw_obj.oid.find('_'); if (pos < 0) { return false; } - if (!rgw_obj::parse_raw_oid(raw_obj.oid.substr(pos + 1), &name, &instance, &ns)) { + if (!rgw_obj_key::parse_raw_oid(raw_obj.oid.substr(pos + 1), &obj->key)) { return false; } - - obj->init_ns(bucket, name, ns); - obj->set_instance(instance); + obj->bucket = bucket; return true; } @@ -462,7 +456,7 @@ public: if (encode_tail_bucket) { ::encode(tail_bucket, bl); } - bool encode_tail_instance = (tail_instance != obj.get_instance()); + bool encode_tail_instance = (tail_instance != obj.key.instance); ::encode(encode_tail_instance, bl); if (encode_tail_instance) { ::encode(tail_instance, bl); @@ -498,7 +492,7 @@ public: * when the explicit objs manifest was around, and it got copied. */ rgw_obj& obj_0 = objs[0].loc; - if (!obj_0.get_oid().empty() && obj_0.ns.empty()) { + if (!obj_0.get_oid().empty() && obj_0.key.ns.empty()) { objs[0].loc = obj; objs[0].size = head_size; } @@ -527,11 +521,11 @@ public: if (need_to_decode) { ::decode(tail_instance, bl); } else { - tail_instance = obj.get_instance(); + tail_instance = obj.key.instance; } } } else { // old object created before 'tail_instance' field added to manifest - tail_instance = obj.get_instance(); + tail_instance = obj.key.instance; } update_iterators(); diff --git a/src/rgw/rgw_rest_client.cc b/src/rgw/rgw_rest_client.cc index 9bbb4f7453b7..b7cda4df7e65 100644 --- a/src/rgw/rgw_rest_client.cc +++ b/src/rgw/rgw_rest_client.cc @@ -619,7 +619,7 @@ int RGWRESTStreamRWRequest::get_obj(RGWAccessKey& key, map& extr { string urlsafe_bucket, urlsafe_object; url_encode(obj.bucket.get_key(':', 0), urlsafe_bucket); - url_encode(obj.get_name(), urlsafe_object); + url_encode(obj.key.name, urlsafe_object); string resource = urlsafe_bucket + "/" + urlsafe_object; return get_resource(key, extra_headers, resource); diff --git a/src/rgw/rgw_rest_conn.cc b/src/rgw/rgw_rest_conn.cc index a96c97819ba9..f7bfb3984b62 100644 --- a/src/rgw/rgw_rest_conn.cc +++ b/src/rgw/rgw_rest_conn.cc @@ -144,8 +144,8 @@ int RGWRESTConn::get_obj(const rgw_user& uid, req_info *info /* optional */, rgw if (rgwx_stat) { params.push_back(param_pair_t(RGW_SYS_PARAM_PREFIX "stat", "true")); } - if (!obj.get_instance().empty()) { - const string& instance = obj.get_instance(); + if (!obj.key.instance.empty()) { + const string& instance = obj.key.instance; params.push_back(param_pair_t("versionId", instance)); } if (get_op) {