From 0f8d0969d50a986837d0d79134cf561af1fefad2 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 --- 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 1b118726f1e5b..6c6700d7f1a68 100644 --- a/src/rgw/driver/d4n/rgw_sal_d4n.cc +++ b/src/rgw/driver/d4n/rgw_sal_d4n.cc @@ -2891,7 +2891,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 1478aa5f40f49..473a03a42608f 100644 --- a/src/rgw/driver/d4n/rgw_sal_d4n.h +++ b/src/rgw/driver/d4n/rgw_sal_d4n.h @@ -355,7 +355,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 3cb654fe41bf4..f156ab2d4ab1f 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 709b77c34a565..cf4cf1069b04c 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 b309d0b203fbd..9fe4fe3d0ca9b 100644 --- a/src/rgw/driver/posix/rgw_sal_posix.cc +++ b/src/rgw/driver/posix/rgw_sal_posix.cc @@ -3918,7 +3918,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 fe664574d2d1b..f9193eb4aa361 100644 --- a/src/rgw/driver/posix/rgw_sal_posix.h +++ b/src/rgw/driver/posix/rgw_sal_posix.h @@ -1284,7 +1284,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 645f744be4416..c892d9c1dff4c 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 6c74ccde9c97b..de0d37f046ccc 100644 --- a/src/rgw/driver/rados/rgw_sal_rados.cc +++ b/src/rgw/driver/rados/rgw_sal_rados.cc @@ -4149,7 +4149,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]; @@ -4340,6 +4342,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 eb48cc31634cd..4ab9141e18b85 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 36fc34961e595..8a7af75f920c3 100644 --- a/src/rgw/rgw_op.cc +++ b/src/rgw/rgw_op.cc @@ -7197,7 +7197,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 85f283551eef6..f3068fe555123 100644 --- a/src/rgw/rgw_op.h +++ b/src/rgw/rgw_op.h @@ -2015,6 +2015,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 73bd030bbaa63..df17c2d12773b 100644 --- a/src/rgw/rgw_rest_s3.cc +++ b/src/rgw/rgw_rest_s3.cc @@ -4668,6 +4668,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 42626160c13e4..2d6d1bed276b3 100644 --- a/src/rgw/rgw_sal.h +++ b/src/rgw/rgw_sal.h @@ -1530,7 +1530,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 3b456b46366f1..2bb397c35a585 100644 --- a/src/rgw/rgw_sal_dbstore.cc +++ b/src/rgw/rgw_sal_dbstore.cc @@ -926,7 +926,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 1fa10e0c70b92..c676b77cf7433 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 99c5168fddea9..2dbaa49d1af2d 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 8607712f6f107..086e8bc733a2c 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.39.5