From a19ef011db0fd565688588d9b9967ebf547b4151 Mon Sep 17 00:00:00 2001 From: Yehuda Sadeh Date: Thu, 13 Mar 2014 11:25:24 -0700 Subject: [PATCH] rgw: manifest hold the actual bucket used for tail objects Fixes: 7703 Object can be copied between different buckets, so we need to keep track of which bucket is used for naming the tail parts. The new manifest requires that because older manifest just held all the tail objects (each containing the appropriate bucket internally). Signed-off-by: Yehuda Sadeh --- src/rgw/rgw_json_enc.cc | 1 + src/rgw/rgw_rados.cc | 15 +++++++++++++-- src/rgw/rgw_rados.h | 22 ++++++++++++++++++---- 3 files changed, 32 insertions(+), 6 deletions(-) diff --git a/src/rgw/rgw_json_enc.cc b/src/rgw/rgw_json_enc.cc index ec27bf8a06632..81ec599fc9708 100644 --- a/src/rgw/rgw_json_enc.cc +++ b/src/rgw/rgw_json_enc.cc @@ -65,6 +65,7 @@ void RGWObjManifest::dump(Formatter *f) const ::encode_json("head_size", head_size, f); ::encode_json("max_head_size", max_head_size, f); ::encode_json("prefix", prefix, f); + ::encode_json("tail_bucket", tail_bucket, f); ::encode_json("rules", rules, f); } diff --git a/src/rgw/rgw_rados.cc b/src/rgw/rgw_rados.cc index 89e7ec0a1e4eb..cb82e05e225df 100644 --- a/src/rgw/rgw_rados.cc +++ b/src/rgw/rgw_rados.cc @@ -714,6 +714,7 @@ int RGWObjManifest::generator::create_begin(CephContext *cct, RGWObjManifest *_m manifest = _m; bucket = _b; + manifest->set_tail_bucket(_b); manifest->set_head(_h); last_ofs = 0; @@ -823,9 +824,15 @@ void RGWObjManifest::get_implicit_location(uint64_t cur_part_id, uint64_t cur_st } } - rgw_bucket bucket = head_obj.bucket; + rgw_bucket *bucket; - location->init_ns(bucket, oid, ns); + if (!tail_bucket.name.empty()) { + bucket = &tail_bucket; + } else { + bucket = &head_obj.bucket; + } + + location->init_ns(*bucket, oid, ns); } RGWObjManifest::obj_iterator RGWObjManifest::obj_find(uint64_t ofs) @@ -3245,6 +3252,10 @@ set_err_state: if (!copy_itself) { manifest = astate->manifest; + rgw_bucket& tail_bucket = manifest.get_tail_bucket(); + if (tail_bucket.name.empty()) { + manifest.set_tail_bucket(src_obj.bucket); + } for (; miter != astate->manifest.obj_end(); ++miter) { ObjectWriteOperation op; cls_refcount_get(op, tag, true); diff --git a/src/rgw/rgw_rados.h b/src/rgw/rgw_rados.h index cab38be48d47c..f6a810e0e1ebf 100644 --- a/src/rgw/rgw_rados.h +++ b/src/rgw/rgw_rados.h @@ -144,8 +144,6 @@ struct RGWObjManifestRule { RGWObjManifestRule(uint32_t _start_part_num, uint64_t _start_ofs, uint64_t _part_size, uint64_t _stripe_max_size) : start_part_num(_start_part_num), start_ofs(_start_ofs), part_size(_part_size), stripe_max_size(_stripe_max_size) {} - void get_obj_name(const string& prefix, uint64_t ofs, string *name); - void encode(bufferlist& bl) const { ENCODE_START(1, 1, bl); ::encode(start_part_num, bl); @@ -179,6 +177,8 @@ protected: uint64_t max_head_size; string prefix; + rgw_bucket tail_bucket; /* might be different than the original bucket, + as object might have been copied across buckets */ map rules; void convert_to_explicit(); @@ -204,6 +204,7 @@ public: head_size = rhs.head_size; max_head_size = rhs.max_head_size; prefix = rhs.prefix; + tail_bucket = rhs.tail_bucket; rules = rhs.rules; begin_iter.set_manifest(this); @@ -238,7 +239,7 @@ public: } void encode(bufferlist& bl) const { - ENCODE_START(3, 3, bl); + ENCODE_START(4, 3, bl); ::encode(obj_size, bl); ::encode(objs, bl); ::encode(explicit_objs, bl); @@ -247,11 +248,12 @@ public: ::encode(max_head_size, bl); ::encode(prefix, bl); ::encode(rules, bl); + ::encode(tail_bucket, bl); ENCODE_FINISH(bl); } void decode(bufferlist::iterator& bl) { - DECODE_START_LEGACY_COMPAT_LEN_32(3, 2, 2, bl); + DECODE_START_LEGACY_COMPAT_LEN_32(4, 2, 2, bl); ::decode(obj_size, bl); ::decode(objs, bl); if (struct_v >= 3) { @@ -265,6 +267,10 @@ public: explicit_objs = true; } + if (struct_v >= 4) { + ::decode(tail_bucket, bl); + } + update_iterators(); DECODE_FINISH(bl); } @@ -301,6 +307,14 @@ public: return head_obj; } + void set_tail_bucket(const rgw_bucket& _b) { + tail_bucket = _b; + } + + rgw_bucket& get_tail_bucket() { + return tail_bucket; + } + void set_prefix(const string& _p) { prefix = _p; } -- 2.39.5