From 39dc94089f1c9f6b3b82cf8622b0b30dd6d5f388 Mon Sep 17 00:00:00 2001 From: Ali Masarwa Date: Sun, 3 Aug 2025 14:00:11 +0300 Subject: [PATCH] RGW | fix conditional MultiWrite Signed-off-by: Ali Masarwa (cherry picked from commit 0f8d0969d50a986837d0d79134cf561af1fefad2) --- src/rgw/driver/d4n/rgw_sal_d4n.cc | 4 +++- src/rgw/driver/d4n/rgw_sal_d4n.h | 4 +++- src/rgw/driver/motr/rgw_sal_motr.cc | 4 +++- src/rgw/driver/motr/rgw_sal_motr.h | 4 +++- src/rgw/driver/posix/rgw_sal_posix.cc | 4 +++- src/rgw/driver/posix/rgw_sal_posix.h | 4 +++- src/rgw/driver/rados/rgw_putobj_processor.cc | 4 ++++ src/rgw/driver/rados/rgw_sal_rados.cc | 6 +++++- src/rgw/driver/rados/rgw_sal_rados.h | 4 +++- src/rgw/rgw_op.cc | 2 +- src/rgw/rgw_op.h | 2 ++ src/rgw/rgw_rest_s3.cc | 3 +++ src/rgw/rgw_sal.h | 4 +++- src/rgw/rgw_sal_dbstore.cc | 4 +++- src/rgw/rgw_sal_dbstore.h | 4 +++- src/rgw/rgw_sal_filter.cc | 4 +++- src/rgw/rgw_sal_filter.h | 4 +++- 17 files changed, 51 insertions(+), 14 deletions(-) diff --git a/src/rgw/driver/d4n/rgw_sal_d4n.cc b/src/rgw/driver/d4n/rgw_sal_d4n.cc index 257803c6d3cf..bd2fbdd11365 100644 --- a/src/rgw/driver/d4n/rgw_sal_d4n.cc +++ b/src/rgw/driver/d4n/rgw_sal_d4n.cc @@ -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, diff --git a/src/rgw/driver/d4n/rgw_sal_d4n.h b/src/rgw/driver/d4n/rgw_sal_d4n.h index f844dc73d5fe..92595de5a05b 100644 --- a/src/rgw/driver/d4n/rgw_sal_d4n.h +++ b/src/rgw/driver/d4n/rgw_sal_d4n.h @@ -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 diff --git a/src/rgw/driver/motr/rgw_sal_motr.cc b/src/rgw/driver/motr/rgw_sal_motr.cc index 3cb654fe41bf..f156ab2d4ab1 100644 --- a/src/rgw/driver/motr/rgw_sal_motr.cc +++ b/src/rgw/driver/motr/rgw_sal_motr.cc @@ -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]; diff --git a/src/rgw/driver/motr/rgw_sal_motr.h b/src/rgw/driver/motr/rgw_sal_motr.h index 709b77c34a56..cf4cf1069b04 100644 --- a/src/rgw/driver/motr/rgw_sal_motr.h +++ b/src/rgw/driver/motr/rgw_sal_motr.h @@ -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, diff --git a/src/rgw/driver/posix/rgw_sal_posix.cc b/src/rgw/driver/posix/rgw_sal_posix.cc index 9012714f9873..f1d9a5266597 100644 --- a/src/rgw/driver/posix/rgw_sal_posix.cc +++ b/src/rgw/driver/posix/rgw_sal_posix.cc @@ -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]; diff --git a/src/rgw/driver/posix/rgw_sal_posix.h b/src/rgw/driver/posix/rgw_sal_posix.h index abad8a475cb3..79a4b428f0d8 100644 --- a/src/rgw/driver/posix/rgw_sal_posix.h +++ b/src/rgw/driver/posix/rgw_sal_posix.h @@ -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, diff --git a/src/rgw/driver/rados/rgw_putobj_processor.cc b/src/rgw/driver/rados/rgw_putobj_processor.cc index 645f744be441..c892d9c1dff4 100644 --- a/src/rgw/driver/rados/rgw_putobj_processor.cc +++ b/src/rgw/driver/rados/rgw_putobj_processor.cc @@ -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; diff --git a/src/rgw/driver/rados/rgw_sal_rados.cc b/src/rgw/driver/rados/rgw_sal_rados.cc index e788e05f5c3b..93d2e9c3d106 100644 --- a/src/rgw/driver/rados/rgw_sal_rados.cc +++ b/src/rgw/driver/rados/rgw_sal_rados.cc @@ -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()); diff --git a/src/rgw/driver/rados/rgw_sal_rados.h b/src/rgw/driver/rados/rgw_sal_rados.h index 6b7f5a8e7ff6..9c5c91ed863f 100644 --- a/src/rgw/driver/rados/rgw_sal_rados.h +++ b/src/rgw/driver/rados/rgw_sal_rados.h @@ -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, diff --git a/src/rgw/rgw_op.cc b/src/rgw/rgw_op.cc index 5b0ee6a3da96..e506050c592d 100644 --- a/src/rgw/rgw_op.cc +++ b/src/rgw/rgw_op.cc @@ -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; diff --git a/src/rgw/rgw_op.h b/src/rgw/rgw_op.h index 5bb6f486ca12..da2373db71c5 100644 --- a/src/rgw/rgw_op.h +++ b/src/rgw/rgw_op.h @@ -1956,6 +1956,8 @@ protected: std::optional cksum; std::optional armored_cksum; off_t ofs = 0; + const char *if_match{nullptr}; + const char *if_nomatch{nullptr}; public: RGWCompleteMultipart() {} diff --git a/src/rgw/rgw_rest_s3.cc b/src/rgw/rgw_rest_s3.cc index 0ff827f22e62..e4040b6c575e 100644 --- a/src/rgw/rgw_rest_s3.cc +++ b/src/rgw/rgw_rest_s3.cc @@ -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(); diff --git a/src/rgw/rgw_sal.h b/src/rgw/rgw_sal.h index 1991882d9d34..11a374d70c4e 100644 --- a/src/rgw/rgw_sal.h +++ b/src/rgw/rgw_sal.h @@ -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, diff --git a/src/rgw/rgw_sal_dbstore.cc b/src/rgw/rgw_sal_dbstore.cc index 61fb2eb646f3..e2522bc3b0ea 100644 --- a/src/rgw/rgw_sal_dbstore.cc +++ b/src/rgw/rgw_sal_dbstore.cc @@ -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]; diff --git a/src/rgw/rgw_sal_dbstore.h b/src/rgw/rgw_sal_dbstore.h index 158d4bce920d..bfa08b7b0ceb 100644 --- a/src/rgw/rgw_sal_dbstore.h +++ b/src/rgw/rgw_sal_dbstore.h @@ -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, diff --git a/src/rgw/rgw_sal_filter.cc b/src/rgw/rgw_sal_filter.cc index 51c32d1e176f..214cb181ce0f 100644 --- a/src/rgw/rgw_sal_filter.cc +++ b/src/rgw/rgw_sal_filter.cc @@ -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, diff --git a/src/rgw/rgw_sal_filter.h b/src/rgw/rgw_sal_filter.h index f0624bdcf927..c3d0b5cb0b35 100644 --- a/src/rgw/rgw_sal_filter.h +++ b/src/rgw/rgw_sal_filter.h @@ -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, -- 2.47.3