]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph-ci.git/commitdiff
Fix lifecycle transition of encrypted multipart objects.
authorMarcus Watts <mwatts@redhat.com>
Sat, 25 May 2024 03:45:14 +0000 (23:45 -0400)
committerThomas Serlin <tserlin@redhat.com>
Mon, 22 Sep 2025 19:18:18 +0000 (15:18 -0400)
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 <mwatts@redhat.com>
(cherry picked from commit 60ddd17d2753b769ba2f5ebde60eb7753649d73f)

Resolves: rhbz#2300284

src/rgw/driver/rados/rgw_rados.cc

index adeb7e1da776496d8f6c342e821745a39b03c749..4e886f1bbf3ec16249188e5df9f2465658475840 100644 (file)
@@ -5371,6 +5371,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<std::string, ceph::buffer::list> &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<size_t> 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,
@@ -5397,6 +5426,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 */