From: Yehuda Sadeh Date: Wed, 23 Mar 2016 01:14:57 +0000 (-0700) Subject: rgw: convert plain object to versioned (with null version) when removing X-Git-Tag: v0.94.8~10^2 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=300c11179290d9b119ff6f310efd1cf5b559b3e1;p=ceph.git rgw: convert plain object to versioned (with null version) when removing Fixes #15243 When removing a plain null versioned object (was created prior to bucket versioning enabled), need to convert the bucket index representation to a versioned one. This is needed so that all the versioning mechanics play together. Signed-off-by: Yehuda Sadeh (cherry picked from commit c6334d430b17739fed2df2b4481ae395ef6568d9) Conflicts: src/rgw/rgw_rados.cc - hammer is missing get_zone() API from which log_data can be obtained. Needed to fall back to zone_public_config structure in bucket_index_unlink_instance() definition. - olh_tag string parameter added to bucket_index_unlink_instance() definition. src/rgw/rgw_rados.h - olh_tag string parameter added to bucket_index_unlink_instance() declaration. --- diff --git a/src/cls/rgw/cls_rgw.cc b/src/cls/rgw/cls_rgw.cc index 980884a9f099..a06b0d834213 100644 --- a/src/cls/rgw/cls_rgw.cc +++ b/src/cls/rgw/cls_rgw.cc @@ -1063,6 +1063,9 @@ public: initialized = true; } + void set_epoch(uint64_t epoch) { + instance_entry.versioned_epoch = epoch; + } int unlink_list_entry() { string list_idx; @@ -1540,12 +1543,27 @@ static int rgw_bucket_unlink_instance(cls_method_context_t hctx, bufferlist *in, return ret; } - ret = olh.init(NULL); + bool olh_found; + ret = olh.init(&olh_found); if (ret < 0) { CLS_LOG(0, "ERROR: olh.init() returned ret=%d", ret); return ret; } + if (!olh_found) { + bool instance_only = false; + cls_rgw_obj_key key(dest_key.name); + ret = convert_plain_entry_to_versioned(hctx, key, true, instance_only); + if (ret < 0) { + CLS_LOG(0, "ERROR: convert_plain_entry_to_versioned ret=%d", ret); + return ret; + } + olh.update(dest_key, false); + olh.set_tag(op.olh_tag); + + obj.set_epoch(1); + } + if (!olh.start_modify(op.olh_epoch)) { ret = obj.unlink_list_entry(); if (ret < 0) { diff --git a/src/cls/rgw/cls_rgw_client.cc b/src/cls/rgw/cls_rgw_client.cc index e6ac56b822c3..49bb840c2f98 100644 --- a/src/cls/rgw/cls_rgw_client.cc +++ b/src/cls/rgw/cls_rgw_client.cc @@ -310,13 +310,14 @@ int cls_rgw_bucket_link_olh(librados::IoCtx& io_ctx, const string& oid, const cl int cls_rgw_bucket_unlink_instance(librados::IoCtx& io_ctx, const string& oid, const cls_rgw_obj_key& key, const string& op_tag, - uint64_t olh_epoch, bool log_op) + const string& olh_tag, uint64_t olh_epoch, bool log_op) { bufferlist in, out; struct rgw_cls_unlink_instance_op call; call.key = key; call.op_tag = op_tag; call.olh_epoch = olh_epoch; + call.olh_tag = olh_tag; call.log_op = log_op; ::encode(call, in); int r = io_ctx.exec(oid, "rgw", "bucket_unlink_instance", in, out); diff --git a/src/cls/rgw/cls_rgw_client.h b/src/cls/rgw/cls_rgw_client.h index ecec679192ed..a3555e794418 100644 --- a/src/cls/rgw/cls_rgw_client.h +++ b/src/cls/rgw/cls_rgw_client.h @@ -329,7 +329,7 @@ int cls_rgw_bucket_link_olh(librados::IoCtx& io_ctx, const string& oid, const cl bool delete_marker, const string& op_tag, struct rgw_bucket_dir_entry_meta *meta, uint64_t olh_epoch, bool log_op); int cls_rgw_bucket_unlink_instance(librados::IoCtx& io_ctx, const string& oid, const cls_rgw_obj_key& key, const string& op_tag, - uint64_t olh_epoch, bool log_op); + const string& olh_tag, uint64_t olh_epoch, bool log_op); int cls_rgw_get_olh_log(librados::IoCtx& io_ctx, string& oid, librados::ObjectReadOperation& op, const cls_rgw_obj_key& olh, uint64_t ver_marker, const string& olh_tag, map > *log, bool *is_truncated); diff --git a/src/cls/rgw/cls_rgw_ops.h b/src/cls/rgw/cls_rgw_ops.h index 0a0686fbccb1..dece239f3f39 100644 --- a/src/cls/rgw/cls_rgw_ops.h +++ b/src/cls/rgw/cls_rgw_ops.h @@ -204,26 +204,31 @@ struct rgw_cls_unlink_instance_op { uint64_t olh_epoch; bool log_op; uint16_t bilog_flags; + string olh_tag; rgw_cls_unlink_instance_op() : olh_epoch(0), log_op(false), bilog_flags(0) {} void encode(bufferlist& bl) const { - ENCODE_START(1, 1, bl); + ENCODE_START(2, 1, bl); ::encode(key, bl); ::encode(op_tag, bl); ::encode(olh_epoch, bl); ::encode(log_op, bl); ::encode(bilog_flags, bl); + ::encode(olh_tag, bl); ENCODE_FINISH(bl); } void decode(bufferlist::iterator& bl) { - DECODE_START(1, bl); + DECODE_START(2, bl); ::decode(key, bl); ::decode(op_tag, bl); ::decode(olh_epoch, bl); ::decode(log_op, bl); ::decode(bilog_flags, bl); + if (struct_v >= 2) { + ::decode(olh_tag, bl); + } DECODE_FINISH(bl); } diff --git a/src/rgw/rgw_rados.cc b/src/rgw/rgw_rados.cc index 91f7ce1e0e28..654e6278a9fc 100644 --- a/src/rgw/rgw_rados.cc +++ b/src/rgw/rgw_rados.cc @@ -6479,7 +6479,7 @@ void RGWRados::bucket_index_guard_olh_op(RGWObjState& olh_state, ObjectOperation op.cmpxattr(RGW_ATTR_OLH_ID_TAG, CEPH_OSD_CMPXATTR_OP_EQ, olh_state.olh_tag); } -int RGWRados::bucket_index_unlink_instance(rgw_obj& obj_instance, const string& op_tag, uint64_t olh_epoch) +int RGWRados::bucket_index_unlink_instance(rgw_obj& obj_instance, const string& op_tag, const string& olh_tag, uint64_t olh_epoch) { rgw_rados_ref ref; rgw_bucket bucket; @@ -6496,7 +6496,7 @@ int RGWRados::bucket_index_unlink_instance(rgw_obj& obj_instance, const string& } cls_rgw_obj_key key(obj_instance.get_index_key_name(), obj_instance.get_instance()); - ret = cls_rgw_bucket_unlink_instance(bs.index_ctx, bs.bucket_obj, key, op_tag, olh_epoch, zone_public_config.log_data); + ret = cls_rgw_bucket_unlink_instance(bs.index_ctx, bs.bucket_obj, key, op_tag, olh_tag, olh_epoch, zone_public_config.log_data); if (ret < 0) { return ret; } @@ -6837,7 +6837,9 @@ int RGWRados::unlink_obj_instance(RGWObjectCtx& obj_ctx, RGWBucketInfo& bucket_i return ret; } - ret = bucket_index_unlink_instance(target_obj, op_tag, olh_epoch); + string olh_tag(state->olh_tag.c_str(), state->olh_tag.length()); + + ret = bucket_index_unlink_instance(target_obj, op_tag, olh_tag, olh_epoch); if (ret < 0) { ldout(cct, 20) << "bucket_index_link_olh() target_obj=" << target_obj << " returned " << ret << dendl; if (ret == -ECANCELED) { diff --git a/src/rgw/rgw_rados.h b/src/rgw/rgw_rados.h index 38d7c29f71a8..911ac387bfec 100644 --- a/src/rgw/rgw_rados.h +++ b/src/rgw/rgw_rados.h @@ -1945,7 +1945,7 @@ public: int bucket_index_link_olh(RGWObjState& olh_state, rgw_obj& obj_instance, bool delete_marker, const string& op_tag, struct rgw_bucket_dir_entry_meta *meta, uint64_t olh_epoch); - int bucket_index_unlink_instance(rgw_obj& obj_instance, const string& op_tag, uint64_t olh_epoch); + int bucket_index_unlink_instance(rgw_obj& obj_instance, const string& op_tag, const string& olh_tag, uint64_t olh_epoch); int bucket_index_read_olh_log(RGWObjState& state, rgw_obj& obj_instance, uint64_t ver_marker, map > *log, bool *is_truncated); int bucket_index_trim_olh_log(RGWObjState& obj_state, rgw_obj& obj_instance, uint64_t ver);