From 5558abb1967939ac061bbd6bb72a77c74429997e Mon Sep 17 00:00:00 2001 From: Marcus Watts Date: Fri, 24 May 2024 23:45:14 -0400 Subject: [PATCH] Fix lifecycle transition of encrypted multipart objects. Lifecycle transtion can copy objects to a different storage tier. When this happens, since the object is repacked, the original manifest is invalidated. It is necessary to store a special "parts_len" attribute to fix this. There was code in PutObj to handle this, but that was only used for multisite replication, it is not used by the lifecycle transisiton code. This fix adds similar logic to the lifecycle transition code path to make the same thing happen. Fixes: https://tracker.ceph.com/issues/23264 Signed-off-by: Marcus Watts --- src/rgw/driver/rados/rgw_rados.cc | 33 +++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/src/rgw/driver/rados/rgw_rados.cc b/src/rgw/driver/rados/rgw_rados.cc index 575e0563671..32701f6fc72 100644 --- a/src/rgw/driver/rados/rgw_rados.cc +++ b/src/rgw/driver/rados/rgw_rados.cc @@ -5422,6 +5422,35 @@ int RGWRados::copy_obj_data(RGWObjectCtx& obj_ctx, log_op ? rgw::sal::FLAG_LOG_OP : 0); } +int fixup_manifest_to_parts_len(const DoutPrefixProvider *dpp, std::map &src_attrs) { + auto iter = src_attrs.find(RGW_ATTR_MANIFEST); + if (iter == src_attrs.end()) { + return 0; + } + bufferlist &manifest_bl { iter->second }; +// manifest_bl = std::copy(iter->second); +// src_attrs.erase(iter); + + // if the source object was encrypted, preserve the part lengths from + // the original object's manifest in RGW_ATTR_CRYPT_PARTS. if the object + // already replicated and has the RGW_ATTR_CRYPT_PARTS attr, preserve it + if (src_attrs.count(RGW_ATTR_CRYPT_MODE) && + !src_attrs.count(RGW_ATTR_CRYPT_PARTS)) { + std::vector parts_len; + int r = RGWGetObj_BlockDecrypt::read_manifest_parts(dpp, manifest_bl, + parts_len); + if (r < 0) { + ldpp_dout(dpp, 4) << "failed to read part lengths from the manifest" << dendl; + return r; + } + // store the encoded part lenghts in RGW_ATTR_CRYPT_PARTS + bufferlist parts_bl; + encode(parts_len, parts_bl); + src_attrs[RGW_ATTR_CRYPT_PARTS] = std::move(parts_bl); + } + return 0; +} + int RGWRados::transition_obj(RGWObjectCtx& obj_ctx, RGWBucketInfo& bucket_info, rgw_obj obj, @@ -5448,6 +5477,10 @@ int RGWRados::transition_obj(RGWObjectCtx& obj_ctx, if (ret < 0) { return ret; } + ret = fixup_manifest_to_parts_len(dpp, attrs); + if (ret < 0) { + return ret; + } if (read_mtime != mtime) { /* raced */ -- 2.39.5