]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
osd: Add extent_to_shard_extent interface to PGBackend.
authorAlex Ainscow <aainscow@uk.ibm.com>
Fri, 3 Oct 2025 13:24:49 +0000 (14:24 +0100)
committerAlex Ainscow <aainscow@uk.ibm.com>
Wed, 26 Nov 2025 11:28:25 +0000 (11:28 +0000)
This allows a backend to expose how an object offset/length translates to
an offset/length on a particular shard.

For Replica, this is trivial.

For EC, this means looking up the start and end offsets, then translating
this to shard address space.

Signed-off-by: Alex Ainscow <aainscow@uk.ibm.com>
src/osd/ECBackend.cc
src/osd/ECBackend.h
src/osd/ECSwitch.h
src/osd/PGBackend.h

index 6c7695c8845e110b86b7928e245a62901cfa8ea6..bf134d67591528deb1aeaddd06e2daa7a54e01e7 100644 (file)
@@ -1010,6 +1010,30 @@ int ECBackend::objects_read_sync(
   return -EOPNOTSUPP;
 }
 
+std::pair<uint64_t, uint64_t> ECBackend::extent_to_shard_extent(uint64_t off, uint64_t len) {
+  // sync reads are supported for sub-chunk reads where no reconstruct is
+  // required.
+  uint64_t chunk_size = sinfo.get_chunk_size();
+  uint64_t start_chunk = off / chunk_size;
+  // This calculation is wrong for length = 0, but it doesn't matter if these reads get sent to the primary
+  uint64_t end_chunk = (off + len - 1) / chunk_size;
+  uint64_t shard_offset, shard_len;
+  shard_id_t shard = get_parent()->whoami_shard().shard;
+  raw_shard_id_t raw_shard = sinfo.get_raw_shard(shard);
+
+  if (end_chunk == start_chunk) {
+    shard_offset = sinfo.ro_offset_to_shard_offset(off, raw_shard);
+    shard_len = len;
+  } else {
+    ECUtil::shard_extent_set_t full_read(sinfo.get_k_plus_m());
+    sinfo.ro_range_to_shard_extent_set(off, len, full_read);
+    shard_offset = full_read[shard].range_start();
+    shard_len = full_read[shard].range_end() - shard_offset;
+  }
+
+  return std::pair(shard_offset, shard_len);
+}
+
 void ECBackend::objects_read_async(
     const hobject_t &hoid,
     uint64_t object_size,
index ea8c72ddde2d93dd0da9a971e47e22043233719f..d3c490b1581f0d4fedde2a19c1eec70c358dea82 100644 (file)
@@ -138,6 +138,8 @@ class ECBackend : public ECCommon {
       ceph::buffer::list *bl
     );
 
+  std::pair<uint64_t, uint64_t> extent_to_shard_extent(uint64_t off, uint64_t len);
+
   /**
    * Async read mechanism
    *
index 8775c86625811b10710d66a0f2b7bd369da57efe..a8b133456f635dbaffcb4120e68656331e1cb20a 100644 (file)
@@ -267,6 +267,14 @@ public:
     return legacy.objects_read_sync(hoid, off, len, op_flags, bl);
   }
 
+  std::pair<uint64_t, uint64_t> extent_to_shard_extent(
+    uint64_t off, uint64_t len) override {
+    if (is_optimized()) {
+      return optimized.extent_to_shard_extent(off, len);
+    }
+    ceph_abort_msg("Extent conversion not supported in legacy EC");
+  }
+
   void objects_read_async(
     const hobject_t &hoid,
     uint64_t object_size,
index 5914f558b9aac5f543f1f1d52b05a7b2a527d189..a3110b6fe559353ffe4a5e622e07a0faf161e49e 100644 (file)
@@ -610,6 +610,11 @@ typedef std::shared_ptr<const OSDMap> OSDMapRef;
      return -EOPNOTSUPP;
    }
 
+   virtual std::pair<uint64_t, uint64_t> extent_to_shard_extent(
+       uint64_t off, uint64_t len) {
+     return std::pair(off, len);
+   }
+
    virtual void objects_read_async(
      const hobject_t &hoid,
      uint64_t object_size,