]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
RGW | fix conditional MultiWrite 67425/head
authorAli Masarwa <amasarwa@redhat.com>
Sun, 3 Aug 2025 11:00:11 +0000 (14:00 +0300)
committerPatrick Donnelly <pdonnell@ibm.com>
Thu, 19 Feb 2026 15:31:30 +0000 (10:31 -0500)
Signed-off-by: Ali Masarwa <amasarwa@redhat.com>
(cherry picked from commit 0f8d0969d50a986837d0d79134cf561af1fefad2)

17 files changed:
src/rgw/driver/d4n/rgw_sal_d4n.cc
src/rgw/driver/d4n/rgw_sal_d4n.h
src/rgw/driver/motr/rgw_sal_motr.cc
src/rgw/driver/motr/rgw_sal_motr.h
src/rgw/driver/posix/rgw_sal_posix.cc
src/rgw/driver/posix/rgw_sal_posix.h
src/rgw/driver/rados/rgw_putobj_processor.cc
src/rgw/driver/rados/rgw_sal_rados.cc
src/rgw/driver/rados/rgw_sal_rados.h
src/rgw/rgw_op.cc
src/rgw/rgw_op.h
src/rgw/rgw_rest_s3.cc
src/rgw/rgw_sal.h
src/rgw/rgw_sal_dbstore.cc
src/rgw/rgw_sal_dbstore.h
src/rgw/rgw_sal_filter.cc
src/rgw/rgw_sal_filter.h

index 257803c6d3cf8f23756e8acfa8b344e55a982e3f..bd2fbdd113656d3145b904f594307f927afa278e 100644 (file)
@@ -3044,7 +3044,9 @@ int D4NFilterMultipartUpload::complete(const DoutPrefixProvider *dpp,
                                    std::string& tag, ACLOwner& owner,
                                    uint64_t olh_epoch,
                                    rgw::sal::Object* target_obj,
-            prefix_map_t& processed_prefixes)
+            prefix_map_t& processed_prefixes,
+            const char *if_match,
+            const char *if_nomatch)
 {
   //call next->complete to complete writing the object to the backend store
   auto ret = next->complete(dpp, y, cct, part_etags, remove_objs, accounted_size,
index f844dc73d5fec46838e5feba76a3c68bd825b5bb..92595de5a05bf0304e563edafd0d77b172be92ca 100644 (file)
@@ -342,7 +342,9 @@ public:
                                    std::string& tag, ACLOwner& owner,
                                    uint64_t olh_epoch,
                                    rgw::sal::Object* target_obj,
-            prefix_map_t& processed_prefixes) override;
+            prefix_map_t& processed_prefixes,
+            const char *if_match = nullptr,
+            const char *if_nomatch = nullptr) override;
 };
 
 } } // namespace rgw::sal
index 3cb654fe41bf4df878f74d5e67b8559e0a7a843a..f156ab2d4ab1f082717309f11db73c963fa842a3 100644 (file)
@@ -2675,7 +2675,9 @@ int MotrMultipartUpload::complete(const DoutPrefixProvider *dpp,
                                   std::string& tag, ACLOwner& owner,
                                   uint64_t olh_epoch,
                                   rgw::sal::Object* target_obj,
-                                  prefix_map_t& processed_prefixes)
+                                  prefix_map_t& processed_prefixes,
+           const char *if_match,
+           const char *if_nomatch)
 {
   char final_etag[CEPH_CRYPTO_MD5_DIGESTSIZE];
   char final_etag_str[CEPH_CRYPTO_MD5_DIGESTSIZE * 2 + 16];
index 709b77c34a565642432791bd3bbb04b61d9ac0b9..cf4cf1069b04c5d7d8a915aca500971be3a6a8cd 100644 (file)
@@ -939,7 +939,9 @@ public:
                       std::string& tag, ACLOwner& owner,
                       uint64_t olh_epoch,
                       rgw::sal::Object* target_obj,
-                      prefix_map_t& processed_prefixes) override;
+                      prefix_map_t& processed_prefixes,
+           const char *if_match = nullptr,
+           const char *if_nomatch = nullptr) override;
   virtual int cleanup_orphaned_parts(const DoutPrefixProvider *dpp,
            CephContext *cct, optional_yield y,
            const rgw_obj& obj,
index 9012714f987307e9897518344d026a8c8fa7ab08..f1d9a526659767b120ade7b5da5f5e5575c4c4a3 100644 (file)
@@ -3742,7 +3742,9 @@ int POSIXMultipartUpload::complete(const DoutPrefixProvider *dpp,
                                    std::string& tag, ACLOwner& owner,
                                    uint64_t olh_epoch,
                                    rgw::sal::Object* target_obj,
-                                   prefix_map_t& processed_prefixes)
+                                   prefix_map_t& processed_prefixes,
+            const char *if_match,
+            const char *if_nomatch)
 {
   char final_etag[CEPH_CRYPTO_MD5_DIGESTSIZE];
   char final_etag_str[CEPH_CRYPTO_MD5_DIGESTSIZE * 2 + 16];
index abad8a475cb30eeab34ce5c9393d48b7c23a73fc..79a4b428f0d8ba8ee0143b2ff4232d7871f2f115 100644 (file)
@@ -906,7 +906,9 @@ public:
                       std::string& tag, ACLOwner& owner,
                       uint64_t olh_epoch,
                       rgw::sal::Object* target_obj,
-                      prefix_map_t& processed_prefixes) override;
+                      prefix_map_t& processed_prefixes,
+           const char *if_match = nullptr,
+           const char *if_nomatch = nullptr) override;
   virtual int cleanup_orphaned_parts(const DoutPrefixProvider *dpp,
                                      CephContext *cct, optional_yield y,
                                      const rgw_obj& obj,
index 645f744be4416f956e2ed7acb05ed999974205e1..c892d9c1dff4c1599f28ea8d876c69faee068c99 100644 (file)
@@ -560,6 +560,8 @@ int MultipartObjectProcessor::complete(
   obj_op.meta.delete_at = delete_at;
   obj_op.meta.zones_trace = zones_trace;
   obj_op.meta.modify_tail = true;
+  obj_op.meta.if_match = if_match;
+  obj_op.meta.if_nomatch = if_nomatch;
 
   r = obj_op.write_meta(actual_size, accounted_size, attrs, rctx,
                         writer.get_trace(), flags & rgw::sal::FLAG_LOG_OP);
@@ -791,6 +793,8 @@ int AppendObjectProcessor::complete(
   obj_op.meta.modify_tail = true;
   obj_op.meta.keep_tail = keep_tail;
   obj_op.meta.appendable = true;
+  obj_op.meta.if_match = if_match;
+  obj_op.meta.if_nomatch = if_nomatch;
   //Add the append part number
   bufferlist cur_part_num_bl;
   using ceph::encode;
index e788e05f5c3b944f6998cab8a0bdd02ae931dbcc..93d2e9c3d1067ba5740c4cf539af460dccc0a23c 100644 (file)
@@ -4127,7 +4127,9 @@ int RadosMultipartUpload::complete(const DoutPrefixProvider *dpp,
                                   std::string& tag, ACLOwner& owner,
                                   uint64_t olh_epoch,
                                   rgw::sal::Object* target_obj,
-                                  prefix_map_t& processed_prefixes)
+                                  prefix_map_t& processed_prefixes,
+           const char *if_match,
+           const char *if_nomatch)
 {
   char final_etag[CEPH_CRYPTO_MD5_DIGESTSIZE];
   char final_etag_str[CEPH_CRYPTO_MD5_DIGESTSIZE * 2 + 16];
@@ -4318,6 +4320,8 @@ int RadosMultipartUpload::complete(const DoutPrefixProvider *dpp,
   obj_op.meta.modify_tail = true;
   obj_op.meta.completeMultipart = true;
   obj_op.meta.olh_epoch = olh_epoch;
+  obj_op.meta.if_match = if_match;
+  obj_op.meta.if_nomatch = if_nomatch;
 
   const req_context rctx{dpp, y, nullptr};
   ret = obj_op.write_meta(ofs, accounted_size, attrs, rctx, get_trace());
index 6b7f5a8e7ff68cf78253cf1bad384f3b57b18685..9c5c91ed863f34b139c11817b10f9845a300274a 100644 (file)
@@ -875,7 +875,9 @@ public:
                       std::string& tag, ACLOwner& owner,
                       uint64_t olh_epoch,
                       rgw::sal::Object* target_obj,
-                      prefix_map_t& processed_prefixes) override;
+                      prefix_map_t& processed_prefixes,
+           const char *if_match = nullptr,
+           const char *if_nomatch = nullptr) override;
   virtual int cleanup_orphaned_parts(const DoutPrefixProvider *dpp,
                                      CephContext *cct, optional_yield y,
                                      const rgw_obj& obj,
index 5b0ee6a3da96e2f72441b3052686d9413e2df215..e506050c592dd568bfb948a7fd08777c9ecd4383 100644 (file)
@@ -7189,7 +7189,7 @@ void RGWCompleteMultipart::execute(optional_yield y)
   op_ret =
     upload->complete(this, y, s->cct, parts->parts, remove_objs, accounted_size,
                      compressed, cs_info, ofs, s->req_id, s->owner, olh_epoch,
-                     s->object.get(), processed_prefixes);
+                     s->object.get(), processed_prefixes, if_match, if_nomatch);
   if (op_ret < 0) {
     ldpp_dout(this, 0) << "ERROR: upload complete failed ret=" << op_ret << dendl;
     return;
index 5bb6f486ca127ba17c36c30de2ccb03d5f2bb2d0..da2373db71c545a98c66e529f2b8d90e9a8da15a 100644 (file)
@@ -1956,6 +1956,8 @@ protected:
   std::optional<rgw::cksum::Cksum> cksum;
   std::optional<std::string> armored_cksum;
   off_t ofs = 0;
+  const char *if_match{nullptr};
+  const char *if_nomatch{nullptr};
 
 public:
   RGWCompleteMultipart() {}
index 0ff827f22e62441c4a251e8b5dd3aeb1911d3201..e4040b6c575e0f7be47c1eb07bcf4a7db8c3b65d 100644 (file)
@@ -4604,6 +4604,9 @@ int RGWCompleteMultipart_ObjStore_S3::get_params(optional_yield y)
     return ret;
   }
 
+  if_match = s->info.env->get("HTTP_IF_MATCH");
+  if_nomatch = s->info.env->get("HTTP_IF_NONE_MATCH");
+
   map_qs_metadata(s, true);
 
   return do_aws4_auth_completion();
index 1991882d9d344f39f3555c8b9d6d899bb6b7ce50..11a374d70c4e0c83df4d081a5a5b50fd71592b06 100644 (file)
@@ -1527,7 +1527,9 @@ public:
                       std::string& tag, ACLOwner& owner,
                       uint64_t olh_epoch,
                       rgw::sal::Object* target_obj,
-                       prefix_map_t& processed_prefixes) = 0;
+           prefix_map_t& processed_prefixes,
+           const char *if_match = nullptr,
+           const char *if_nomatch = nullptr) = 0;
   /** Cleanup orphaned parts caused by racing condition involving part upload retry */
   virtual int cleanup_orphaned_parts(const DoutPrefixProvider *dpp,
                                      CephContext *cct, optional_yield y,
index 61fb2eb646f375a5a5bde4cfd6ad67a5c5c791a3..e2522bc3b0eaff9b075151006e25f570c58d791d 100644 (file)
@@ -924,7 +924,9 @@ namespace rgw::sal {
                                   std::string& tag, ACLOwner& owner,
                                   uint64_t olh_epoch,
                                   rgw::sal::Object* target_obj,
-                                  prefix_map_t& processed_prefixes)
+                                  prefix_map_t& processed_prefixes,
+           const char *if_match,
+           const char *if_nomatch)
   {
     char final_etag[CEPH_CRYPTO_MD5_DIGESTSIZE];
     char final_etag_str[CEPH_CRYPTO_MD5_DIGESTSIZE * 2 + 16];
index 158d4bce920d35db88d47520c0b39e696d50a34f..bfa08b7b0ceb63b48e8f324fc67fba61b328dcae 100644 (file)
@@ -461,7 +461,9 @@ protected:
                       std::string& tag, ACLOwner& owner,
                       uint64_t olh_epoch,
                       rgw::sal::Object* target_obj,
-                      prefix_map_t& processed_prefixes) override;
+                      prefix_map_t& processed_prefixes,
+           const char *if_match = nullptr,
+           const char *if_nomatch = nullptr) override;
   virtual int cleanup_orphaned_parts(const DoutPrefixProvider *dpp,
                                      CephContext *cct, optional_yield y,
                                      const rgw_obj& obj,
index 51c32d1e176f7b9b1df3cfe60c5287017c251cc4..214cb181ce0fe002e0e3d296b38a93f32afc8f1c 100644 (file)
@@ -1334,7 +1334,9 @@ int FilterMultipartUpload::complete(const DoutPrefixProvider *dpp,
                                    std::string& tag, ACLOwner& owner,
                                    uint64_t olh_epoch,
                                    rgw::sal::Object* target_obj,
-                                   prefix_map_t& processed_prefixes)
+                                   prefix_map_t& processed_prefixes,
+            const char *if_match,
+            const char *if_nomatch)
 {
   return next->complete(dpp, y, cct, part_etags, remove_objs, accounted_size,
                        compressed, cs_info, ofs, tag, owner, olh_epoch,
index f0624bdcf927698822b59834918fcbf251ebda5a..c3d0b5cb0b351ba4e556b1387342e3a7ed33356c 100644 (file)
@@ -978,7 +978,9 @@ public:
                       std::string& tag, ACLOwner& owner,
                       uint64_t olh_epoch,
                       rgw::sal::Object* target_obj,
-                      prefix_map_t& processed_prefixes) override;
+                      prefix_map_t& processed_prefixes,
+           const char *if_match = nullptr,
+           const char *if_nomatch = nullptr) override;
   virtual int cleanup_orphaned_parts(const DoutPrefixProvider *dpp,
                                      CephContext *cct, optional_yield y,
                                      const rgw_obj& obj,