From 9b64d6868424d6ba0726b3cb0e19cb8f7cb0c05c Mon Sep 17 00:00:00 2001 From: Pritha Srivastava Date: Thu, 6 Feb 2025 19:14:35 +0530 Subject: [PATCH] rgw/d4n: implementation of load_obj_state() and exists() for D4NFilterObject. Signed-off-by: Pritha Srivastava --- src/rgw/driver/d4n/rgw_sal_d4n.cc | 36 ++++++++++++++++++++++++++++++- src/rgw/driver/d4n/rgw_sal_d4n.h | 7 ++++++ 2 files changed, 42 insertions(+), 1 deletion(-) diff --git a/src/rgw/driver/d4n/rgw_sal_d4n.cc b/src/rgw/driver/d4n/rgw_sal_d4n.cc index 7ba7ea40618..257803c6d3c 100644 --- a/src/rgw/driver/d4n/rgw_sal_d4n.cc +++ b/src/rgw/driver/d4n/rgw_sal_d4n.cc @@ -799,6 +799,31 @@ int D4NFilterObject::copy_object(const ACLOwner& owner, return 0; } +int D4NFilterObject::load_obj_state(const DoutPrefixProvider *dpp, optional_yield y, + bool follow_olh) +{ + if (load_from_store) { + return next->load_obj_state(dpp, y, follow_olh); + } + bool has_instance = false; + if (!this->get_instance().empty()) { + has_instance = true; + } + int ret = get_obj_attrs_from_cache(dpp, y); + if (ret) { + /* clearing instance if not present in object before + calling get_obj_attrs_from_cache as it incorrectly + causes delete obj to be invoked for an instance + even though a simple delete request has been issued + (after load_obj_state is invoked) */ + if (!has_instance) { + this->clear_instance(); + } + return 0; + } + return next->load_obj_state(dpp, y, follow_olh); +} + int D4NFilterObject::set_obj_attrs(const DoutPrefixProvider* dpp, Attrs* setattrs, Attrs* delattrs, optional_yield y, uint32_t flags) { @@ -915,7 +940,9 @@ int D4NFilterObject::get_obj_attrs_from_cache(const DoutPrefixProvider* dpp, opt } }//end-if }//end-for - this->set_instance(instance); //set this only after setting object state else it won't take effect + if (!instance.empty()) { + this->set_instance(instance); //set this only after setting object state else it won't take effect + } attrs.erase(RGW_CACHE_ATTR_MTIME); attrs.erase(RGW_CACHE_ATTR_OBJECT_SIZE); attrs.erase(RGW_CACHE_ATTR_ACCOUNTED_SIZE); @@ -1412,6 +1439,7 @@ bool D4NFilterObject::check_head_exists_in_cache_get_oid(const DoutPrefixProvide } std::string key = head_oid_in_cache; this->driver->get_policy_driver()->get_cache_policy()->update(dpp, key, 0, 0, version, block.cacheObj.dirty, rgw::d4n::RefCount::DECR, y); + this->exists_in_cache = true; } else { found_in_cache = false; } @@ -2948,6 +2976,9 @@ int D4NFilterWriter::complete(size_t accounted_size, const std::string& etag, ldpp_dout(dpp, 0) << "D4NFilterWriter::" << __func__ << "(): writing to backend store failed, ret=" << ret << dendl; return ret; } + /* we want to always load latest object state from store + to avoid reading stale state in case of object overwrites. */ + object->set_load_obj_from_store(true); object->load_obj_state(dpp, y); attrs = object->get_attrs(); object->set_attrs_from_obj_state(dpp, y, attrs, dirty); @@ -3025,6 +3056,9 @@ int D4NFilterMultipartUpload::complete(const DoutPrefixProvider *dpp, //Cache only the head object for multipart objects D4NFilterObject* d4n_target_obj = dynamic_cast(target_obj); + /* we want to always load latest object state from store + to avoid reading stale state in case of object overwrites. */ + d4n_target_obj->set_load_obj_from_store(true); d4n_target_obj->load_obj_state(dpp, y); rgw::sal::Attrs attrs = d4n_target_obj->get_attrs(); d4n_target_obj->set_attrs_from_obj_state(dpp, y, attrs); diff --git a/src/rgw/driver/d4n/rgw_sal_d4n.h b/src/rgw/driver/d4n/rgw_sal_d4n.h index db5fc08a006..f844dc73d5f 100644 --- a/src/rgw/driver/d4n/rgw_sal_d4n.h +++ b/src/rgw/driver/d4n/rgw_sal_d4n.h @@ -134,6 +134,8 @@ class D4NFilterObject : public FilterObject { rgw::sal::Bucket* dest_bucket{nullptr}; //for copy-object bool multipart{false}; bool delete_marker{false}; + bool exists_in_cache{false}; + bool load_from_store{false}; public: struct D4NFilterReadOp : FilterReadOp { @@ -245,6 +247,8 @@ class D4NFilterObject : public FilterObject { optional_yield y) override; virtual const std::string &get_name() const override { return next->get_name(); } + virtual int load_obj_state(const DoutPrefixProvider *dpp, optional_yield y, + bool follow_olh = true) override; virtual int set_obj_attrs(const DoutPrefixProvider* dpp, Attrs* setattrs, Attrs* delattrs, optional_yield y, uint32_t flags) override; virtual int get_obj_attrs(optional_yield y, const DoutPrefixProvider* dpp, @@ -277,6 +281,9 @@ class D4NFilterObject : public FilterObject { int set_attr_crypt_parts(const DoutPrefixProvider* dpp, optional_yield y, rgw::sal::Attrs& attrs); int create_delete_marker(const DoutPrefixProvider* dpp, optional_yield y); bool is_delete_marker() { return delete_marker; } + bool exists(void) override { if (exists_in_cache) { return true;} return next->exists(); }; + bool load_obj_from_store() { return load_from_store; } + void set_load_obj_from_store(bool load_from_store) { this->load_from_store = load_from_store; } }; class D4NFilterWriter : public FilterWriter { -- 2.39.5