]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph-ci.git/commitdiff
rgw/d4n: implementation of load_obj_state() and exists()
authorPritha Srivastava <prsrivas@redhat.com>
Thu, 6 Feb 2025 13:44:35 +0000 (19:14 +0530)
committerPritha Srivastava <prsrivas@redhat.com>
Mon, 21 Apr 2025 05:52:08 +0000 (11:22 +0530)
for D4NFilterObject.

Signed-off-by: Pritha Srivastava <prsrivas@redhat.com>
src/rgw/driver/d4n/rgw_sal_d4n.cc
src/rgw/driver/d4n/rgw_sal_d4n.h

index 7ba7ea40618b8d0c2a0da4c97035a6e92ceeaa00..257803c6d3cf8f23756e8acfa8b344e55a982e3f 100644 (file)
@@ -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<D4NFilterObject*>(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);
index db5fc08a006faabd76576ed721799e7e9c7f3f63..f844dc73d5fec46838e5feba76a3c68bd825b5bb 100644 (file)
@@ -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 {