From 926f859032e3ee7f4c6ade3a4687177944d5806c Mon Sep 17 00:00:00 2001 From: "J. Eric Ivancich" Date: Tue, 1 Jun 2021 15:17:23 -0400 Subject: [PATCH] rgw: completion of multipart upload leaves delete marker The multipart upload meta object is deleted when the multipart upload is completed. When the bucket is versioned, it needs to be deleted from the bucket index rather than go through versioning delete process that adds a delete marker to the bucket index rather than simply removing it from the bucket index. Signed-off-by: J. Eric Ivancich (cherry picked from commit 9ab7c18c4039f7b7283da3182807641d99b01ca7) Conflicts: src/rgw/rgw_op.cc : adapted to significant Zipper mods src/rgw/rgw_rados.cc : adapted to significant Zipper mods src/rgw/rgw_rados.h : adapted to significant Zipper mods src/rgw/rgw_sal.h : adapted to significant Zipper mods src/rgw/rgw_sal_rados.cc : adapted to significant Zipper mods src/rgw/rgw_sal_rados.h : adapted to significant Zipper mods --- src/rgw/rgw_op.cc | 21 +++++++++++++++------ src/rgw/rgw_rados.cc | 2 +- src/rgw/rgw_rados.h | 6 +++--- src/rgw/rgw_sal.h | 4 +++- src/rgw/rgw_sal_rados.cc | 14 ++++++++++++-- src/rgw/rgw_sal_rados.h | 4 +++- 6 files changed, 37 insertions(+), 14 deletions(-) diff --git a/src/rgw/rgw_op.cc b/src/rgw/rgw_op.cc index 2165da1607a6..ab658154c174 100644 --- a/src/rgw/rgw_op.cc +++ b/src/rgw/rgw_op.cc @@ -6077,6 +6077,7 @@ void RGWCompleteMultipart::execute(optional_yield y) accounted_size += obj_part.accounted_size; } } while (truncated); + hash.Final((unsigned char *)final_etag); buf_to_hex((unsigned char *)final_etag, sizeof(final_etag), final_etag_str); @@ -6122,17 +6123,24 @@ void RGWCompleteMultipart::execute(optional_yield y) obj_op->params.completeMultipart = true; obj_op->params.olh_epoch = olh_epoch; obj_op->params.attrs = &attrs; + op_ret = obj_op->prepare(s->yield); - if (op_ret < 0) + if (op_ret < 0) { return; + } op_ret = obj_op->write_meta(this, ofs, accounted_size, s->yield); - if (op_ret < 0) + if (op_ret < 0) { return; + } - // remove the upload obj + // remove the upload meta object string version_id; - int r = meta_obj->delete_object(this, s->obj_ctx, ACLOwner(), ACLOwner(), ceph::real_time(), false, 0, version_id, null_yield); + + // remove the upload meta object ; the meta object is not versioned + // when the bucket is, as that would add an unneeded delete marker + int r = meta_obj->delete_object(this, s->obj_ctx, ACLOwner(), ACLOwner(), ceph::real_time(), false, 0, + version_id, null_yield, true /* prevent versioning*/ ); if (r >= 0) { /* serializer's exclusive lock is released */ serializer->clear_locked(); @@ -6146,7 +6154,7 @@ void RGWCompleteMultipart::execute(optional_yield y) ldpp_dout(this, 1) << "ERROR: publishing notification failed, with error: " << ret << dendl; // too late to rollback operation, hence op_ret is not set here } -} +} // RGWCompleteMultipart::execute void RGWCompleteMultipart::complete() { @@ -6602,7 +6610,8 @@ bool RGWBulkDelete::Deleter::delete_single(const acct_path_t& path, optional_yie std::unique_ptr obj = bucket->get_object(path.obj_key); obj->set_atomic(s->obj_ctx); - ret = obj->delete_object(dpp, s->obj_ctx, bowner, bucket_owner, ceph::real_time(), false, 0, version_id, s->yield); + ret = obj->delete_object(dpp, s->obj_ctx, bowner, bucket_owner, ceph::real_time(), false, 0, + version_id, s->yield); if (ret < 0) { goto delop_fail; } diff --git a/src/rgw/rgw_rados.cc b/src/rgw/rgw_rados.cc index fbd6e8133121..67b89c9c9aa9 100644 --- a/src/rgw/rgw_rados.cc +++ b/src/rgw/rgw_rados.cc @@ -5199,7 +5199,7 @@ int RGWRados::delete_obj(const DoutPrefixProvider *dpp, RGWObjectCtx& obj_ctx, const RGWBucketInfo& bucket_info, const rgw_obj& obj, - int versioning_status, + int versioning_status, // versioning flags in enum RGWBucketFlags uint16_t bilog_flags, const real_time& expiration_time, rgw_zone_set *zones_trace) diff --git a/src/rgw/rgw_rados.h b/src/rgw/rgw_rados.h index 1f0ba1d72b05..b971edb0386b 100644 --- a/src/rgw/rgw_rados.h +++ b/src/rgw/rgw_rados.h @@ -846,8 +846,8 @@ public: struct DeleteParams { rgw_user bucket_owner; - int versioning_status; - ACLOwner obj_owner; /* needed for creation of deletion marker */ + int versioning_status; // versioning flags in enum RGWBucketFlags + ACLOwner obj_owner; // needed for creation of deletion marker uint64_t olh_epoch; string marker_version_id; uint32_t bilog_flags; @@ -1236,7 +1236,7 @@ public: RGWObjectCtx& obj_ctx, const RGWBucketInfo& bucket_owner, const rgw_obj& src_obj, - int versioning_status, + int versioning_status, // versioning flags in enum RGWBucketFlags uint16_t bilog_flags = 0, const ceph::real_time& expiration_time = ceph::real_time(), rgw_zone_set *zones_trace = nullptr); diff --git a/src/rgw/rgw_sal.h b/src/rgw/rgw_sal.h index 7af83d6c03a1..156bc8522688 100644 --- a/src/rgw/rgw_sal.h +++ b/src/rgw/rgw_sal.h @@ -448,7 +448,9 @@ class RGWObject { virtual int delete_object(const DoutPrefixProvider *dpp, RGWObjectCtx* obj_ctx, ACLOwner obj_owner, ACLOwner bucket_owner, ceph::real_time unmod_since, bool high_precision_time, uint64_t epoch, - std::string& version_id, optional_yield y) = 0; + std::string& version_id, + optional_yield y, + bool prevent_versioning = false) = 0; virtual int copy_object(RGWObjectCtx& obj_ctx, RGWUser* user, req_info *info, const rgw_zone_id& source_zone, rgw::sal::RGWObject* dest_object, rgw::sal::RGWBucket* dest_bucket, diff --git a/src/rgw/rgw_sal_rados.cc b/src/rgw/rgw_sal_rados.cc index 353c7808b33d..5f07e7379b81 100644 --- a/src/rgw/rgw_sal_rados.cc +++ b/src/rgw/rgw_sal_rados.cc @@ -693,7 +693,16 @@ int RGWRadosObject::RadosReadOp::get_attr(const DoutPrefixProvider *dpp, const c return parent_op.get_attr(dpp, name, dest, y); } -int RGWRadosObject::delete_object(const DoutPrefixProvider *dpp, RGWObjectCtx* obj_ctx, ACLOwner obj_owner, ACLOwner bucket_owner, ceph::real_time unmod_since, bool high_precision_time, uint64_t epoch, string& version_id, optional_yield y) +int RGWRadosObject::delete_object(const DoutPrefixProvider *dpp, + RGWObjectCtx* obj_ctx, + ACLOwner obj_owner, + ACLOwner bucket_owner, + ceph::real_time unmod_since, + bool high_precision_time, + uint64_t epoch, + std::string& version_id, + optional_yield y, + bool prevent_versioning) { int ret = 0; RGWRados::Object del_target(store->getRados(), bucket->get_info(), *obj_ctx, get_obj()); @@ -702,7 +711,8 @@ int RGWRadosObject::delete_object(const DoutPrefixProvider *dpp, RGWObjectCtx* o del_op.params.olh_epoch = epoch; del_op.params.marker_version_id = version_id; del_op.params.bucket_owner = bucket_owner.get_id(); - del_op.params.versioning_status = bucket->get_info().versioning_status(); + del_op.params.versioning_status = + prevent_versioning ? 0 : bucket->get_info().versioning_status(); del_op.params.obj_owner = obj_owner; del_op.params.unmod_since = unmod_since; del_op.params.high_precision_time = high_precision_time; diff --git a/src/rgw/rgw_sal_rados.h b/src/rgw/rgw_sal_rados.h index e5edafeea050..7ea8fb443da1 100644 --- a/src/rgw/rgw_sal_rados.h +++ b/src/rgw/rgw_sal_rados.h @@ -102,7 +102,9 @@ class RGWRadosObject : public RGWObject { virtual int delete_object(const DoutPrefixProvider *dpp, RGWObjectCtx* obj_ctx, ACLOwner obj_owner, ACLOwner bucket_owner, ceph::real_time unmod_since, bool high_precision_time, uint64_t epoch, - std::string& version_id,optional_yield y) override; + std::string& version_id, + optional_yield y, + bool prevent_versioning) override; virtual int copy_object(RGWObjectCtx& obj_ctx, RGWUser* user, req_info *info, const rgw_zone_id& source_zone, rgw::sal::RGWObject* dest_object, rgw::sal::RGWBucket* dest_bucket, -- 2.47.3