From 8a04c0a61bc71291da4e4241bc5e6f5acc731a05 Mon Sep 17 00:00:00 2001 From: Guang Yang Date: Mon, 3 Nov 2014 12:56:06 +0000 Subject: [PATCH] Fix the multipart uploads functional test failures due to bucket index sharding. Signed-off-by: Guang Yang --- src/rgw/rgw_common.h | 6 +++++ src/rgw/rgw_op.cc | 6 +++++ src/rgw/rgw_rados.cc | 59 ++++++++++++++++++++++---------------------- src/rgw/rgw_rados.h | 20 +++++++-------- 4 files changed, 51 insertions(+), 40 deletions(-) diff --git a/src/rgw/rgw_common.h b/src/rgw/rgw_common.h index 0769f91a037bb..22af8cbd553aa 100644 --- a/src/rgw/rgw_common.h +++ b/src/rgw/rgw_common.h @@ -1048,6 +1048,9 @@ public: bool in_extra_data; /* in-memory only member, does not serialize */ + // Represents the hash index source for this object once it is set (non-empty) + std::string index_hash_source; + rgw_obj() : in_extra_data(false) {} rgw_obj(const char *b, const char *o) : in_extra_data(false) { rgw_bucket _b(b); @@ -1146,6 +1149,9 @@ public: return orig_key; } + string& get_hash_object() { + return index_hash_source.empty() ? object : index_hash_source; + } /** * Translate a namespace-mangled object name to the user-facing name * existing in the given namespace. diff --git a/src/rgw/rgw_op.cc b/src/rgw/rgw_op.cc index 0319a56982da4..124511026d7a8 100644 --- a/src/rgw/rgw_op.cc +++ b/src/rgw/rgw_op.cc @@ -1453,6 +1453,7 @@ int RGWPutObjProcessor_Multipart::prepare(RGWRados *store, void *obj_ctx, string } head_obj = manifest_gen.get_cur_obj(); + head_obj.index_hash_source = obj_str; cur_obj = head_obj; add_obj(cur_obj); @@ -2526,6 +2527,7 @@ void RGWInitMultipart::execute() obj.init_ns(s->bucket, tmp_obj_name, mp_ns); // the meta object will be indexed with 0 size, we c obj.set_in_extra_data(true); + obj.index_hash_source = s->object_str; ret = store->put_obj_meta(s->obj_ctx, obj, 0, NULL, attrs, RGW_OBJ_CATEGORY_MULTIMETA, PUT_OBJ_CREATE_EXCL, s->owner.get_id()); } while (ret == -EEXIST); } @@ -2734,6 +2736,7 @@ void RGWCompleteMultipart::execute() meta_obj.init_ns(s->bucket, meta_oid, mp_ns); meta_obj.set_in_extra_data(true); + meta_obj.index_hash_source = s->object_str; ret = get_obj_attrs(store, s, meta_obj, attrs, NULL, NULL); if (ret < 0) { @@ -2885,6 +2888,7 @@ void RGWAbortMultipart::execute() string oid = mp.get_part(obj_iter->second.num); rgw_obj obj; obj.init_ns(s->bucket, oid, mp_ns); + obj.index_hash_source = s->object_str; ret = store->delete_obj(s->obj_ctx, owner, obj); if (ret < 0 && ret != -ENOENT) return; @@ -2893,6 +2897,7 @@ void RGWAbortMultipart::execute() RGWObjManifest::obj_iterator oiter; for (oiter = manifest.obj_begin(); oiter != manifest.obj_end(); ++oiter) { rgw_obj loc = oiter.get_location(); + loc.index_hash_source = s->object_str; ret = store->delete_obj(s->obj_ctx, owner, loc); if (ret < 0 && ret != -ENOENT) return; @@ -2904,6 +2909,7 @@ void RGWAbortMultipart::execute() // and also remove the metadata obj meta_obj.init_ns(s->bucket, meta_oid, mp_ns); meta_obj.set_in_extra_data(true); + meta_obj.index_hash_source = s->object_str; ret = store->delete_obj(s->obj_ctx, owner, meta_obj); if (ret == -ENOENT) { ret = -ERR_NO_SUCH_BUCKET; diff --git a/src/rgw/rgw_rados.cc b/src/rgw/rgw_rados.cc index 914e24342506d..a485954e2d53f 100644 --- a/src/rgw/rgw_rados.cc +++ b/src/rgw/rgw_rados.cc @@ -2971,8 +2971,8 @@ int RGWRados::put_obj_meta_impl(void *ctx, rgw_obj& obj, uint64_t size, ldout(cct, 0) << "ERROR: complete_atomic_overwrite returned r=" << r << dendl; } - r = complete_update_index(bucket, obj.object, index_tag, poolid, epoch, size, - ut, etag, content_type, &acl_bl, category, remove_objs); + r = complete_update_index(bucket, obj, index_tag, poolid, epoch, size, + ut, etag, content_type, &acl_bl, category, remove_objs); if (r < 0) goto done_cancel; @@ -2988,7 +2988,7 @@ int RGWRados::put_obj_meta_impl(void *ctx, rgw_obj& obj, uint64_t size, return 0; done_cancel: - int ret = complete_update_index_cancel(bucket, obj.object, index_tag); + int ret = complete_update_index_cancel(bucket, obj, index_tag); if (ret < 0) { ldout(cct, 0) << "ERROR: complete_update_index_cancel() returned ret=" << ret << dendl; } @@ -3985,9 +3985,9 @@ int RGWRados::delete_obj_impl(void *ctx, const string& bucket_owner, rgw_obj& ob int64_t poolid = ref.ioctx.get_id(); if (r >= 0 || r == -ENOENT) { uint64_t epoch = ref.ioctx.get_last_version(); - r = complete_update_index_del(bucket, obj.object, tag, poolid, epoch); + r = complete_update_index_del(bucket, obj, tag, poolid, epoch); } else { - int ret = complete_update_index_cancel(bucket, obj.object, tag); + int ret = complete_update_index_cancel(bucket, obj, tag); if (ret < 0) { ldout(cct, 0) << "ERROR: complete_update_index_cancel returned ret=" << ret << dendl; } @@ -4046,7 +4046,7 @@ int RGWRados::delete_obj_index(rgw_obj& obj) get_obj_bucket_and_oid_key(obj, bucket, oid, key); string tag; - int r = complete_update_index_del(bucket, obj.object, tag, -1 /* pool */, 0); + int r = complete_update_index_del(bucket, obj, tag, -1 /* pool */, 0); return r; } @@ -4622,13 +4622,12 @@ int RGWRados::prepare_update_index(RGWObjState *state, rgw_bucket& bucket, append_rand_alpha(cct, tag, tag, 32); } } - ret = cls_obj_prepare_op(bucket, op, tag, - obj.object, obj.key); + ret = cls_obj_prepare_op(bucket, op, tag, obj.object, obj.key, obj.get_hash_object()); return ret; } -int RGWRados::complete_update_index(rgw_bucket& bucket, string& oid, string& tag, int64_t poolid, uint64_t epoch, uint64_t size, +int RGWRados::complete_update_index(rgw_bucket& bucket, rgw_obj& oid, string& tag, int64_t poolid, uint64_t epoch, uint64_t size, utime_t& ut, string& etag, string& content_type, bufferlist *acl_bl, RGWObjCategory category, list *remove_objs) { @@ -4636,7 +4635,7 @@ int RGWRados::complete_update_index(rgw_bucket& bucket, string& oid, string& tag return 0; RGWObjEnt ent; - ent.name = oid; + ent.name = oid.object; ent.size = size; ent.mtime = ut; ent.etag = etag; @@ -4651,7 +4650,7 @@ int RGWRados::complete_update_index(rgw_bucket& bucket, string& oid, string& tag ent.owner_display_name = owner.get_display_name(); ent.content_type = content_type; - int ret = cls_obj_complete_add(bucket, tag, poolid, epoch, ent, category, remove_objs); + int ret = cls_obj_complete_add(bucket, tag, poolid, epoch, ent, category, remove_objs, oid.get_hash_object()); return ret; } @@ -4770,10 +4769,10 @@ done: if (update_index) { if (ret >= 0) { - ret = complete_update_index(bucket, dst_obj.object, tag, poolid, epoch, size, + ret = complete_update_index(bucket, dst_obj, tag, poolid, epoch, size, ut, etag, content_type, &acl_bl, category, NULL); } else { - int r = complete_update_index_cancel(bucket, dst_obj.object, tag); + int r = complete_update_index_cancel(bucket, dst_obj, tag); if (r < 0) { ldout(cct, 0) << "ERROR: comlete_update_index_cancel() returned r=" << r << dendl; } @@ -6243,11 +6242,11 @@ int RGWRados::cls_rgw_init_index(librados::IoCtx& index_ctx, librados::ObjectWri } int RGWRados::cls_obj_prepare_op(rgw_bucket& bucket, RGWModifyOp op, string& tag, - string& name, string& locator) + string& name, string& locator, const string& index_hash_object) { librados::IoCtx index_ctx; string bucket_obj; - int ret = open_bucket_index_shard(bucket, index_ctx, name, &bucket_obj); + int ret = open_bucket_index_shard(bucket, index_ctx, index_hash_object, &bucket_obj); ldout(cct, 20) << " bucket index object: " << bucket_obj << dendl; if (ret < 0) return ret; @@ -6261,11 +6260,11 @@ int RGWRados::cls_obj_prepare_op(rgw_bucket& bucket, RGWModifyOp op, string& tag int RGWRados::cls_obj_complete_op(rgw_bucket& bucket, RGWModifyOp op, string& tag, int64_t pool, uint64_t epoch, RGWObjEnt& ent, RGWObjCategory category, - list *remove_objs) + list *remove_objs, const string& index_hash_object) { librados::IoCtx index_ctx; string bucket_obj; - int ret = open_bucket_index_shard(bucket, index_ctx, ent.name, &bucket_obj); + int ret = open_bucket_index_shard(bucket, index_ctx, index_hash_object, &bucket_obj); ldout(cct, 20) << " bucket index object: " << bucket_obj << dendl; if (ret < 0) return ret; @@ -6294,25 +6293,25 @@ int RGWRados::cls_obj_complete_op(rgw_bucket& bucket, RGWModifyOp op, string& ta int RGWRados::cls_obj_complete_add(rgw_bucket& bucket, string& tag, int64_t pool, uint64_t epoch, RGWObjEnt& ent, RGWObjCategory category, - list *remove_objs) + list *remove_obj, const string& index_hash_object) { - return cls_obj_complete_op(bucket, CLS_RGW_OP_ADD, tag, pool, epoch, ent, category, remove_objs); + return cls_obj_complete_op(bucket, CLS_RGW_OP_ADD, tag, pool, epoch, ent, category, remove_obj, index_hash_object); } int RGWRados::cls_obj_complete_del(rgw_bucket& bucket, string& tag, int64_t pool, uint64_t epoch, - string& name) + string& name, const string& index_hash_object) { RGWObjEnt ent; ent.name = name; - return cls_obj_complete_op(bucket, CLS_RGW_OP_DEL, tag, pool, epoch, ent, RGW_OBJ_CATEGORY_NONE, NULL); + return cls_obj_complete_op(bucket, CLS_RGW_OP_DEL, tag, pool, epoch, ent, RGW_OBJ_CATEGORY_NONE, NULL, index_hash_object); } -int RGWRados::cls_obj_complete_cancel(rgw_bucket& bucket, string& tag, string& name) +int RGWRados::cls_obj_complete_cancel(rgw_bucket& bucket, string& tag, string& name, const string& index_hash_object) { RGWObjEnt ent; ent.name = name; - return cls_obj_complete_op(bucket, CLS_RGW_OP_ADD, tag, -1 /* pool id */, 0, ent, RGW_OBJ_CATEGORY_NONE, NULL); + return cls_obj_complete_op(bucket, CLS_RGW_OP_ADD, tag, -1 /* pool id */, 0, ent, RGW_OBJ_CATEGORY_NONE, NULL, index_hash_object); } int RGWRados::cls_obj_set_bucket_tag_timeout(rgw_bucket& bucket, uint64_t timeout) @@ -6392,15 +6391,15 @@ int RGWRados::cls_bucket_list(rgw_bucket& bucket, const string& start, const str librados::IoCtx sub_ctx; sub_ctx.dup(index_ctx); r = check_disk_state(sub_ctx, bucket, dirent, e, updates[vnames[pos]]); - if (r < 0) { - if (r == -ENOENT) - continue; - else + if (r < 0 && r != -ENOENT) { return r; } } - m[e.name] = e; - ldout(cct, 10) << "RGWRados::cls_bucket_list: got " << e.name << dendl; + if (r >= 0) { + m[e.name] = e; + ldout(cct, 10) << "RGWRados::cls_bucket_list: got " << e.name << dendl; + ++count; + } // Refresh the candidates map candidates.erase(candidates.begin()); @@ -6408,7 +6407,6 @@ int RGWRados::cls_bucket_list(rgw_bucket& bucket, const string& start, const str if (vcurrents[pos] != vends[pos]) { candidates[vcurrents[pos]->second.name] = pos; } - ++count; } // Suggest updates if there is any @@ -6431,6 +6429,7 @@ int RGWRados::cls_bucket_list(rgw_bucket& bucket, const string& start, const str } if (m.size()) *last_entry = m.rbegin()->first; + return 0; } diff --git a/src/rgw/rgw_rados.h b/src/rgw/rgw_rados.h index b501fa450b2b0..819f494925bd3 100644 --- a/src/rgw/rgw_rados.h +++ b/src/rgw/rgw_rados.h @@ -1845,12 +1845,12 @@ public: int cls_rgw_init_index(librados::IoCtx& io_ctx, librados::ObjectWriteOperation& op, string& oid); int cls_obj_prepare_op(rgw_bucket& bucket, RGWModifyOp op, string& tag, - string& name, string& locator); + string& name, string& locator, const string& index_hash_object); int cls_obj_complete_op(rgw_bucket& bucket, RGWModifyOp op, string& tag, int64_t pool, uint64_t epoch, - RGWObjEnt& ent, RGWObjCategory category, list *remove_objs); - int cls_obj_complete_add(rgw_bucket& bucket, string& tag, int64_t pool, uint64_t epoch, RGWObjEnt& ent, RGWObjCategory category, list *remove_objs); - int cls_obj_complete_del(rgw_bucket& bucket, string& tag, int64_t pool, uint64_t epoch, string& name); - int cls_obj_complete_cancel(rgw_bucket& bucket, string& tag, string& name); + RGWObjEnt& ent, RGWObjCategory category, list *remove_objs, const string& index_hash_object); + int cls_obj_complete_add(rgw_bucket& bucket, string& tag, int64_t pool, uint64_t epoch, RGWObjEnt& ent, RGWObjCategory category, list *remove_objs, const string& index_hash_object); + int cls_obj_complete_del(rgw_bucket& bucket, string& tag, int64_t pool, uint64_t epoch, string& name, const string& index_hash_object); + int cls_obj_complete_cancel(rgw_bucket& bucket, string& tag, string& name, const string& index_hash_object); int cls_obj_set_bucket_tag_timeout(rgw_bucket& bucket, uint64_t timeout); int cls_bucket_list(rgw_bucket& bucket, const string& start, const string& prefix, uint32_t hint_num, map& m, bool *is_truncated, string *last_entry, @@ -1859,20 +1859,20 @@ public: int cls_bucket_head_async(rgw_bucket& bucket, RGWGetDirHeader_CB *ctx, int *num_aio); int prepare_update_index(RGWObjState *state, rgw_bucket& bucket, RGWModifyOp op, rgw_obj& oid, string& tag); - int complete_update_index(rgw_bucket& bucket, string& oid, string& tag, int64_t poolid, uint64_t epoch, uint64_t size, + int complete_update_index(rgw_bucket& bucket, rgw_obj& oid, string& tag, int64_t poolid, uint64_t epoch, uint64_t size, utime_t& ut, string& etag, string& content_type, bufferlist *acl_bl, RGWObjCategory category, list *remove_objs); - int complete_update_index_del(rgw_bucket& bucket, string& oid, string& tag, int64_t pool, uint64_t epoch) { + int complete_update_index_del(rgw_bucket& bucket, rgw_obj& oid, string& tag, int64_t pool, uint64_t epoch) { if (bucket_is_system(bucket)) return 0; - return cls_obj_complete_del(bucket, tag, pool, epoch, oid); + return cls_obj_complete_del(bucket, tag, pool, epoch, oid.object, oid.get_hash_object()); } - int complete_update_index_cancel(rgw_bucket& bucket, string& oid, string& tag) { + int complete_update_index_cancel(rgw_bucket& bucket, rgw_obj& oid, string& tag) { if (bucket_is_system(bucket)) return 0; - return cls_obj_complete_cancel(bucket, tag, oid); + return cls_obj_complete_cancel(bucket, tag, oid.object, oid.get_hash_object()); } int list_bi_log_entries(rgw_bucket& bucket, string& marker, uint32_t max, std::list& result, bool *truncated); int trim_bi_log_entries(rgw_bucket& bucket, string& marker, string& end_marker); -- 2.39.5