]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
crimson/os/seastore/transaction_manager: replace read_extents, expose pins
authorSamuel Just <sjust@redhat.com>
Sat, 27 Mar 2021 06:10:08 +0000 (23:10 -0700)
committerSamuel Just <sjust@redhat.com>
Sun, 18 Apr 2021 07:30:42 +0000 (00:30 -0700)
read_extents in all except one case was used to read a known single extent
-- replace those users with read_extent.  store-nbd uses read_extents as
intended, but other users will need to be able to deal with zero mappings.

Signed-off-by: Samuel Just <sjust@redhat.com>
src/crimson/os/seastore/collection_manager/flat_collection_manager.cc
src/crimson/os/seastore/omap_manager/btree/omap_btree_node_impl.cc
src/crimson/os/seastore/onode_manager/staged-fltree/node_extent_manager/seastore.h
src/crimson/os/seastore/transaction_manager.h
src/crimson/tools/store-nbd.cc
src/test/crimson/seastore/test_transaction_manager.cc

index 08cf84ffa335814eccd0f80910dfe83f91f083cc..40c66487788783cb9a997f2adbdaba352fa07d18 100644 (file)
@@ -47,13 +47,11 @@ FlatCollectionManager::get_coll_root(const coll_root_t &coll_root, Transaction &
   logger().debug("FlatCollectionManager: {}", __func__);
   assert(coll_root.get_location() != L_ADDR_NULL);
   auto cc = get_coll_context(t);
-  return cc.tm.read_extents<CollectionNode>(
+  return cc.tm.read_extent<CollectionNode>(
     cc.t,
     coll_root.get_location(),
     coll_root.get_size()
-  ).safe_then([](auto&& extents) {
-    assert(extents.size() == 1);
-    [[maybe_unused]] auto [laddr, e] = extents.front();
+  ).safe_then([](auto&& e) {
     return get_root_ertr::make_ready_future<CollectionNodeRef>(std::move(e));
   });
 }
index 59d8050a21241c562f26fe52aa6257f2174a8c0e..c325dc4845f97c4af7e212d9d8c70603100bf2f3 100644 (file)
@@ -603,25 +603,21 @@ omap_load_extent(omap_context_t oc, laddr_t laddr, depth_t depth)
 {
   ceph_assert(depth > 0);
   if (depth > 1) {
-    return oc.tm.read_extents<OMapInnerNode>(oc.t, laddr, OMAP_BLOCK_SIZE
+    return oc.tm.read_extent<OMapInnerNode>(oc.t, laddr, OMAP_BLOCK_SIZE
     ).handle_error(
       omap_load_extent_ertr::pass_further{},
       crimson::ct_error::assert_all{ "Invalid error in omap_load_extent" }
     ).safe_then(
-      [](auto&& extents) {
-      assert(extents.size() == 1);
-      [[maybe_unused]] auto [laddr, e] = extents.front();
+      [](auto&& e) {
       return seastar::make_ready_future<OMapNodeRef>(std::move(e));
     });
   } else {
-    return oc.tm.read_extents<OMapLeafNode>(oc.t, laddr, OMAP_BLOCK_SIZE
+    return oc.tm.read_extent<OMapLeafNode>(oc.t, laddr, OMAP_BLOCK_SIZE
     ).handle_error(
       omap_load_extent_ertr::pass_further{},
       crimson::ct_error::assert_all{ "Invalid error in omap_load_extent" }
     ).safe_then(
-      [](auto&& extents) {
-      assert(extents.size() == 1);
-      [[maybe_unused]] auto [laddr, e] = extents.front();
+      [](auto&& e) {
       return seastar::make_ready_future<OMapNodeRef>(std::move(e));
     });
   }
index f80b99fabe008023f1173e6196e3d03be34c47f9..4b584372d1d5296d54cc04c301b7353335e282b6 100644 (file)
@@ -75,10 +75,8 @@ class SeastoreNodeExtentManager final: public NodeExtentManager {
   tm_future<NodeExtentRef> read_extent(
       Transaction& t, laddr_t addr, extent_len_t len) override {
     logger().debug("OTree::Seastore: reading {}B at {:#x} ...", len, addr);
-    return tm.read_extents<SeastoreNodeExtent>(t, addr, len
-    ).safe_then([addr, len](auto&& extents) {
-      assert(extents.size() == 1);
-      [[maybe_unused]] auto [laddr, e] = extents.front();
+    return tm.read_extent<SeastoreNodeExtent>(t, addr, len
+    ).safe_then([addr, len](auto&& e) {
       logger().trace("OTree::Seastore: read {}B at {:#x}",
                      e->get_length(), e->get_laddr());
       assert(e->get_laddr() == addr);
index 93a24c8109f5760dc83f92b927c405328efa2079..cc62376116265e68f4ce4fa0b401fe29fe272196 100644 (file)
@@ -96,64 +96,91 @@ public:
   }
 
   /**
-   * Read extents corresponding to specified lba range
+   * get_pins
+   *
+   * Get logical pins overlapping offset~length
    */
-  using read_extent_ertr = LBAManager::get_mapping_ertr::extend_ertr<
+  using get_pins_ertr = LBAManager::get_mapping_ertr;
+  using get_pins_ret = get_pins_ertr::future<lba_pin_list_t>;
+  get_pins_ret get_pins(
+    Transaction &t,
+    laddr_t offset,
+    extent_len_t length) {
+    return lba_manager->get_mapping(
+      t, offset, length);
+  }
+
+  /**
+   * pin_to_extent
+   *
+   * Get extent mapped at pin.
+   */
+  using pin_to_extent_ertr = get_pins_ertr::extend_ertr<
     SegmentManager::read_ertr>;
   template <typename T>
-  using read_extent_ret = read_extent_ertr::future<lextent_list_t<T>>;
+  using pin_to_extent_ret = pin_to_extent_ertr::future<
+    TCachedExtentRef<T>>;
   template <typename T>
-  read_extent_ret<T> read_extents(
+  pin_to_extent_ret<T> pin_to_extent(
+    Transaction &t,
+    LBAPinRef pin) {
+    using ret = pin_to_extent_ret<T>;
+    crimson::get_logger(ceph_subsys_filestore).debug(
+      "pin_to_extent: getting extent {}",
+      *pin);
+    return cache->get_extent<T>(
+      t,
+      pin->get_paddr(),
+      pin->get_length()
+    ).safe_then([this, pin=std::move(pin)](auto ref) mutable -> ret {
+      if (!ref->has_pin()) {
+       if (pin->has_been_invalidated() || ref->has_been_invalidated()) {
+         return crimson::ct_error::eagain::make();
+       } else {
+         ref->set_pin(std::move(pin));
+         lba_manager->add_pin(ref->get_pin());
+       }
+      }
+      crimson::get_logger(ceph_subsys_filestore).debug(
+       "pin_to_extent: got extent {}",
+       *ref);
+      return pin_to_extent_ret<T>(
+       pin_to_extent_ertr::ready_future_marker{},
+       std::move(ref));
+    });
+  }
+
+  /**
+   * read_extent
+   *
+   * Read extent of type T at offset~length
+   */
+  using read_extent_ertr = get_pins_ertr::extend_ertr<
+    SegmentManager::read_ertr>;
+  template <typename T>
+  using read_extent_ret = read_extent_ertr::future<
+    TCachedExtentRef<T>>;
+  template <typename T>
+  read_extent_ret<T> read_extent(
     Transaction &t,
     laddr_t offset,
-    extent_len_t length)
-  {
-    std::unique_ptr<lextent_list_t<T>> ret =
-      std::make_unique<lextent_list_t<T>>();
-    auto &ret_ref = *ret;
-    std::unique_ptr<lba_pin_list_t> pin_list =
-      std::make_unique<lba_pin_list_t>();
-    auto &pin_list_ref = *pin_list;
-    return lba_manager->get_mapping(
+    extent_len_t length) {
+    return get_pins(
       t, offset, length
-    ).safe_then([this, &t, &pin_list_ref, &ret_ref](auto pins) {
-      crimson::get_logger(ceph_subsys_filestore).debug(
-       "read_extents: mappings {}",
-       pins);
-      pins.swap(pin_list_ref);
-      return crimson::do_for_each(
-       pin_list_ref.begin(),
-       pin_list_ref.end(),
-       [this, &t, &ret_ref](auto &pin) {
-         crimson::get_logger(ceph_subsys_filestore).debug(
-           "read_extents: get_extent {}~{}",
-           pin->get_paddr(),
-           pin->get_length());
-         return cache->get_extent<T>(
-           t,
-           pin->get_paddr(),
-           pin->get_length()
-         ).safe_then([this, &pin, &ret_ref](auto ref) mutable
-                     -> read_extent_ertr::future<> {
-           if (!ref->has_pin()) {
-             if (pin->has_been_invalidated() || ref->has_been_invalidated()) {
-               return crimson::ct_error::eagain::make();
-             } else {
-               ref->set_pin(std::move(pin));
-               lba_manager->add_pin(ref->get_pin());
-             }
-           }
-           ret_ref.push_back(std::make_pair(ref->get_laddr(), ref));
-           crimson::get_logger(ceph_subsys_filestore).debug(
-             "read_extents: got extent {}",
-             *ref);
-           return read_extent_ertr::now();
-         });
-       });
-    }).safe_then([ret=std::move(ret), pin_list=std::move(pin_list)]() mutable {
-      return read_extent_ret<T>(
-       read_extent_ertr::ready_future_marker{},
-       std::move(*ret));
+    ).safe_then([this, &t, offset, length](auto pins) {
+      if (pins.size() != 1) {
+       auto &logger = crimson::get_logger(ceph_subsys_filestore);
+       logger.error(
+         "TransactionManager::read_extent offset {} len {} got {} extents:",
+         offset,
+         length,
+         pins.size());
+       for (auto &i: pins) {
+         logger.error("\t{}", *i);
+       }
+       ceph_assert(0 == "Should be impossible");
+      }
+      return pin_to_extent<T>(t, std::move(pins.front()));
     });
   }
 
index 3aa3d7968b9d2923bf2eb69d77eab93fa28b21c0..38c4a49c495e027cc40161fdc6202d52a6cd46ec 100644 (file)
@@ -556,6 +556,44 @@ public:
     );
   }
 
+  auto read_extents(
+    Transaction &t,
+    laddr_t offset,
+    extent_len_t length) {
+    return seastar::do_with(
+      lba_pin_list_t(),
+      lextent_list_t<TestBlock>(),
+      [this, &t, offset, length](auto &pins, auto &ret) {
+       return tm->get_pins(
+         t, offset, length
+       ).safe_then([this, &t, &pins, &ret](auto _pins) {
+         _pins.swap(pins);
+         logger().debug("read_extents: mappings {}", pins);
+         return crimson::do_for_each(
+           pins.begin(),
+           pins.end(),
+           [this, &t, &ret](auto &&pin) {
+             logger().debug(
+               "read_extents: get_extent {}~{}",
+               pin->get_paddr(),
+               pin->get_length());
+             return tm->pin_to_extent<TestBlock>(
+               t,
+               std::move(pin)
+             ).safe_then([this, &ret](auto ref) mutable {
+               ret.push_back(std::make_pair(ref->get_laddr(), ref));
+               logger().debug(
+                 "read_extents: got extent {}",
+                 *ref);
+               return seastar::now();
+             });
+           }).safe_then([&ret] {
+             return std::move(ret);
+           });
+       });
+      });
+  }
+
   seastar::future<bufferlist> read(
     off_t offset,
     size_t size) final {
@@ -568,7 +606,7 @@ public:
       return seastar::do_with(
        tm->create_transaction(),
        [=, &blret](auto &t) {
-         return tm->read_extents<TestBlock>(*t, offset, size
+         return read_extents(*t, offset, size
          ).safe_then([=, &blret](auto ext_list) mutable {
            size_t cur = offset;
            for (auto &i: ext_list) {
index 745efae1ef6977336c46b7d33a5b9a36470138d7..93a8b222a3fd2e996e1caf2843038570e03ab112 100644 (file)
@@ -424,13 +424,9 @@ struct transaction_manager_test_t :
     ceph_assert(test_mappings.contains(addr, t.mapping_delta));
     ceph_assert(test_mappings.get(addr, t.mapping_delta).desc.len == len);
 
-    auto ret_list = tm->read_extents<TestBlock>(
+    auto ext = tm->read_extent<TestBlock>(
       *t.t, addr, len
     ).unsafe_get0();
-    EXPECT_EQ(ret_list.size(), 1);
-    auto &ext = ret_list.begin()->second;
-    auto &laddr = ret_list.begin()->first;
-    EXPECT_EQ(addr, laddr);
     EXPECT_EQ(addr, ext->get_laddr());
     return ext;
   }