]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
crimson/seastore: support sparse_read
authorchunmei-liu <chunmei.liu@intel.com>
Mon, 7 Feb 2022 22:34:33 +0000 (14:34 -0800)
committerchunmei-liu <chunmei.liu@intel.com>
Thu, 17 Feb 2022 15:57:57 +0000 (07:57 -0800)
add fiemap and readv functions.

Signed-off-by: chunmei-liu <chunmei.liu@intel.com>
src/crimson/os/seastore/object_data_handler.cc
src/crimson/os/seastore/object_data_handler.h
src/crimson/os/seastore/seastore.cc
src/crimson/os/seastore/seastore.h

index 4e5a55b0d0ad46f363f171f81f0842ec73fcca5c..624229979159a6bf28a83f7a091e016c9b2e5faa 100644 (file)
@@ -551,6 +551,60 @@ ObjectDataHandler::read_ret ObjectDataHandler::read(
     });
 }
 
+ObjectDataHandler::fiemap_ret ObjectDataHandler::fiemap(
+  context_t ctx,
+  objaddr_t obj_offset,
+  extent_len_t len)
+{
+  return seastar::do_with(
+    std::map<uint64_t, uint64_t>(),
+    [ctx, obj_offset, len](auto &ret) {
+    return with_object_data(
+      ctx,
+      [ctx, obj_offset, len, &ret](const auto &object_data) {
+      LOG_PREFIX(ObjectDataHandler::fiemap);
+      DEBUGT(
+       "{}~{}, reservation {}~{}",
+        ctx.t,
+        obj_offset,
+        len,
+        object_data.get_reserved_data_base(),
+        object_data.get_reserved_data_len());
+      /* Assumption: callers ensure that onode size is <= reserved
+       * size and that len is adjusted here prior to call */
+      ceph_assert(!object_data.is_null());
+      ceph_assert((obj_offset + len) <= object_data.get_reserved_data_len());
+      ceph_assert(len > 0);
+      laddr_t loffset =
+        object_data.get_reserved_data_base() + obj_offset;
+      return ctx.tm.get_pins(
+        ctx.t,
+        loffset,
+        len
+      ).si_then([loffset, len, &object_data, &ret](auto &&pins) {
+       ceph_assert(pins.size() >= 1);
+        ceph_assert((*pins.begin())->get_laddr() <= loffset);
+       for (auto &&i: pins) {
+         if (!(i->get_paddr().is_zero())) {
+           auto ret_left = std::max(i->get_laddr(), loffset);
+           auto ret_right = std::min(
+             i->get_laddr() + i->get_length(),
+             loffset + len);
+           assert(ret_right > ret_left);
+           ret.emplace(
+             std::make_pair(
+               ret_left - object_data.get_reserved_data_base(),
+               ret_right - ret_left
+             ));
+         }
+       }
+      });
+    }).si_then([&ret] {
+      return std::move(ret);
+    });
+  });
+}
+
 ObjectDataHandler::truncate_ret ObjectDataHandler::truncate(
   context_t ctx,
   objaddr_t offset)
index c397245125cf89ac51287a6b63eb7009b24921cf..dd91f343623b33eaeb45cd75d3bf22abe5557645 100644 (file)
@@ -74,6 +74,14 @@ public:
     objaddr_t offset,
     extent_len_t len);
 
+  /// sparse read data, get range interval in [offset, offset + len)
+  using fiemap_iertr = base_iertr;
+  using fiemap_ret = fiemap_iertr::future<std::map<uint64_t, uint64_t>>;
+  fiemap_ret fiemap(
+    context_t ctx,
+    objaddr_t offset,
+    extent_len_t len);
+
   /// Clears data past offset
   using truncate_iertr = base_iertr;
   using truncate_ret = truncate_iertr::future<>;
index 2702e4973097036487249a0a9345fd2c3472acdf..0323f81e956e6404b99550cd3de1fe72910b5347 100644 (file)
@@ -484,6 +484,22 @@ SeaStore::read_errorator::future<ceph::bufferlist> SeaStore::readv(
   interval_set<uint64_t>& m,
   uint32_t op_flags)
 {
+  return seastar::do_with(
+    ceph::bufferlist{},
+    [=, &oid, &m](auto &ret) {
+    return crimson::do_for_each(
+      m,
+      [=, &oid, &ret](auto &p) {
+      return read(
+       ch, oid, p.first, p.second, op_flags
+       ).safe_then([&ret](auto bl) {
+        ret.claim_append(bl);
+      });
+    }).safe_then([&ret] {
+      return read_errorator::make_ready_future<ceph::bufferlist>
+        (std::move(ret));
+    });
+  });
   return read_errorator::make_ready_future<ceph::bufferlist>();
 }
 
@@ -853,13 +869,53 @@ seastar::future<FuturizedStore::OmapIteratorRef> SeaStore::get_omap_iterator(
   });
 }
 
+SeaStore::_fiemap_ret SeaStore::_fiemap(
+  Transaction &t,
+  Onode &onode,
+  uint64_t off,
+  uint64_t len) const
+{
+  return seastar::do_with(
+    ObjectDataHandler(max_object_size),
+    [=, &t, &onode] (auto &objhandler) {
+    return objhandler.fiemap(
+      ObjectDataHandler::context_t{
+        *transaction_manager,
+        t,
+        onode,
+      },
+      off,
+      len);
+  });
+}
 seastar::future<std::map<uint64_t, uint64_t>> SeaStore::fiemap(
   CollectionRef ch,
   const ghobject_t& oid,
   uint64_t off,
   uint64_t len)
 {
-  return seastar::make_ready_future<std::map<uint64_t, uint64_t>>();
+  LOG_PREFIX(SeaStore::fiemap);
+  DEBUG("oid: {}, off: {}, len: {} ", oid, off, len);
+  return repeat_with_onode<std::map<uint64_t, uint64_t>>(
+    ch,
+    oid,
+    Transaction::src_t::READ,
+    "fiemap_read",
+    op_type_t::READ,
+    [=](auto &t, auto &onode) -> _fiemap_ret {
+    size_t size = onode.get_layout().size;
+    if (off >= size) {
+      INFOT("fiemap offset is over onode size!", t);
+      return seastar::make_ready_future<std::map<uint64_t, uint64_t>>();
+    }
+    size_t adjust_len = (len == 0) ?
+      size - off:
+      std::min(size - off, len);
+    return _fiemap(t, onode, off, adjust_len);
+  }).handle_error(
+    crimson::ct_error::assert_all{
+      "Invalid error in SeaStore::fiemap"
+  });
 }
 
 void SeaStore::on_error(ceph::os::Transaction &t) {
index 93e34c28801e3898d4ac64a71c85ce5cf6b6e1a1..358370ae59e221d1e603b3b45b9e16298100c535 100644 (file)
@@ -22,6 +22,7 @@
 #include "crimson/os/seastore/onode_manager.h"
 #include "crimson/os/seastore/omap_manager.h"
 #include "crimson/os/seastore/collection_manager.h"
+#include "crimson/os/seastore/object_data_handler.h"
 
 namespace crimson::os::seastore {
 
@@ -269,6 +270,13 @@ private:
     });
   }
 
+  using _fiemap_ret = ObjectDataHandler::fiemap_ret;
+  _fiemap_ret _fiemap(
+    Transaction &t,
+    Onode &onode,
+    uint64_t off,
+    uint64_t len) const;
+
   using _omap_get_value_iertr = OMapManager::base_iertr::extend<
     crimson::ct_error::enodata
     >;