]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
osd: replace get_obc() with maybe_load_obc() in EC recovery
authorRadoslaw Zarzynski <rzarzyns@redhat.com>
Thu, 9 May 2024 19:09:50 +0000 (19:09 +0000)
committerAlex Ainscow <aainscow@uk.ibm.com>
Wed, 17 Sep 2025 08:43:26 +0000 (09:43 +0100)
Signed-off-by: Radoslaw Zarzynski <rzarzyns@redhat.com>
(cherry picked from commit 266773625f997ff6a1fda82b201e023948a5c081)

src/osd/ECBackend.cc
src/osd/ECBackend.h
src/osd/ECCommon.h
src/osd/ECListener.h

index 51f785af7e430cffe9d2d5a5a6dc874bc6dd0c3a..3dfaf62bca35269116dbe5c108c5d5cdc8e7b8b0 100644 (file)
@@ -353,28 +353,12 @@ void ECCommon::RecoveryBackend::handle_recovery_read_complete(
 
   if (res.attrs) {
     op.xattrs.swap(*(res.attrs));
-
-    if (!op.obc) {
-      // attrs only reference the origin bufferlist (decode from
-      // ECSubReadReply message) whose size is much greater than attrs
-      // in recovery. If obc cache it (get_obc maybe cache the attr),
-      // this causes the whole origin bufferlist would not be free
-      // until obc is evicted from obc cache. So rebuild the
-      // bufferlist before cache it.
-      for (map<string, bufferlist>::iterator it = op.xattrs.begin();
-           it != op.xattrs.end();
-           ++it) {
-        it->second.rebuild();
-      }
-      // Need to remove ECUtil::get_hinfo_key() since it should not leak out
-      // of the backend (see bug #12983)
-      map<string, bufferlist, less<>> sanitized_attrs(op.xattrs);
-      sanitized_attrs.erase(ECUtil::get_hinfo_key());
-      op.obc = get_parent()->get_obc(hoid, sanitized_attrs);
-      ceph_assert(op.obc);
-      op.recovery_info.size = op.obc->obs.oi.size;
-      op.recovery_info.oi = op.obc->obs.oi;
-
+    const auto empty_obc = !op.obc;
+    maybe_load_obc(op.xattrs, op);
+#ifdef WITH_CRIMSON
+    ceph_assert(hoid == op.hoid);
+#endif
+    if (empty_obc) {
       update_object_size_after_read(op.recovery_info.size, res, req);
     }
   }
@@ -404,6 +388,33 @@ void ECCommon::RecoveryBackend::handle_recovery_read_complete(
   continue_recovery_op(op, m);
 }
 
+void ECBackend::ECRecoveryBackend::maybe_load_obc(
+  const std::map<std::string, ceph::bufferlist, std::less<>>& raw_attrs,
+  RecoveryOp &op)
+{
+  if (!op.obc) {
+    // attrs only reference the origin bufferlist (decode from
+    // ECSubReadReply message) whose size is much greater than attrs
+    // in recovery. If obc cache it (get_obc maybe cache the attr),
+    // this causes the whole origin bufferlist would not be free
+    // until obc is evicted from obc cache. So rebuild the
+    // bufferlist before cache it.
+    for (map<string, bufferlist>::iterator it = op.xattrs.begin();
+         it != op.xattrs.end();
+         ++it) {
+      it->second.rebuild();
+    }
+    // Need to remove ECUtil::get_hinfo_key() since it should not leak out
+    // of the backend (see bug #12983)
+    map<string, bufferlist, less<>> sanitized_attrs(op.xattrs);
+    sanitized_attrs.erase(ECUtil::get_hinfo_key());
+    op.obc = get_parent()->get_obc(op.hoid, sanitized_attrs);
+    ceph_assert(op.obc);
+    op.recovery_info.size = op.obc->obs.oi.size;
+    op.recovery_info.oi = op.obc->obs.oi;
+  }
+}
+
 struct SendPushReplies : public Context {
   PGBackend::Listener *l;
   epoch_t epoch;
index 4881043dcb22a7c7f0aabd0a555af4b295e2342b..0f15094a56dceacc7ee89eaa9bbfd942102217f6 100644 (file)
@@ -204,6 +204,10 @@ class ECBackend : public ECCommon {
         ceph::os::Transaction &&txn,
         std::map<int, MOSDPGPushReply*> replies) override;
 
+    void maybe_load_obc(
+      const std::map<std::string, ceph::bufferlist, std::less<>>& raw_attrs,
+      RecoveryOp &op) final;
+
     PGBackend::Listener *get_parent() const { return parent; }
 
    private:
index 66fbfde7398c9e5d62e4710dac56d3bb0d081244..cc84944a1d46e93dce66c13c211ae1cee72661a8 100644 (file)
@@ -761,6 +761,9 @@ struct ECCommon {
     virtual void commit_txn_send_replies(
         ceph::os::Transaction &&txn,
         std::map<int, MOSDPGPushReply*> replies) = 0;
+    virtual void maybe_load_obc(
+      const std::map<std::string, ceph::bufferlist, std::less<>> &raw_attrs,
+      RecoveryOp &op) = 0;
     void dispatch_recovery_messages(RecoveryMessages &m, int priority);
 
     RecoveryBackend::RecoveryOp recover_object(
index fd9e37a682fe42350d3dcdd342e170a02baa01b6..a8f02e30af0804f01d5f51f7bc43ac4dedd0f74a 100644 (file)
@@ -87,9 +87,11 @@ struct ECListener {
 
   virtual bool pg_is_repair() const = 0;
 
-     virtual ObjectContextRef get_obc(
-       const hobject_t &hoid,
-       const std::map<std::string, ceph::buffer::list, std::less<>> &attrs) = 0;
+#ifndef WITH_CRIMSON
+  virtual ObjectContextRef get_obc(
+    const hobject_t &hoid,
+    const std::map<std::string, ceph::buffer::list, std::less<>> &attrs) = 0;
+#endif
 
      virtual bool check_failsafe_full() = 0;
      virtual hobject_t get_temp_recovery_object(const hobject_t& target,