]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
crimson/os/seastore: introduce the generic Device class
authorYingxin Cheng <yingxin.cheng@intel.com>
Mon, 21 Mar 2022 07:47:16 +0000 (15:47 +0800)
committerYingxin Cheng <yingxin.cheng@intel.com>
Wed, 6 Apr 2022 02:29:46 +0000 (10:29 +0800)
Implement the read interface of Device and integrate it with EPM, so
that Cache doesn't need to depend on the segment specific ExtentReader
class.

Signed-off-by: Yingxin Cheng <yingxin.cheng@intel.com>
src/crimson/os/seastore/cache.cc
src/crimson/os/seastore/cache.h
src/crimson/os/seastore/device.h [new file with mode: 0644]
src/crimson/os/seastore/extent_placement_manager.h
src/crimson/os/seastore/extent_reader.h
src/crimson/os/seastore/segment_manager.h
src/crimson/os/seastore/transaction_manager.cc
src/crimson/os/seastore/transaction_manager.h
src/test/crimson/seastore/test_btree_lba_manager.cc
src/test/crimson/seastore/test_seastore_cache.cc

index c3d0c3fc9c36cc7708f11dc5f0a2a86514ff0c24..50c2a9b72eccef77fce24732a4504da0d0a77ebc 100644 (file)
@@ -27,10 +27,8 @@ SET_SUBSYS(seastore_cache);
 namespace crimson::os::seastore {
 
 Cache::Cache(
-  ExtentReader &reader,
   ExtentPlacementManager &epm)
-  : reader(reader),
-    epm(epm),
+  : epm(epm),
     lru(crimson::common::get_conf<Option::size_t>(
          "seastore_cache_lru_size"))
 {
index b2f5b213aceabc81fa4c917d44cbcc91dc30bca7..789e5fa7a85774c5e5e81f64763e374883708ace 100644 (file)
@@ -100,7 +100,7 @@ public:
     crimson::ct_error::input_output_error>;
   using base_iertr = trans_iertr<base_ertr>;
 
-  Cache(ExtentReader &reader, ExtentPlacementManager &epm);
+  Cache(ExtentPlacementManager &epm);
   ~Cache();
 
   /// Creates empty transaction by source
@@ -739,7 +739,6 @@ public:
   void dump_contents();
 
 private:
-  ExtentReader &reader;                   ///< ref to extent reader
   ExtentPlacementManager& epm;
   RootBlockRef root;               ///< ref to current root
   ExtentIndex extents;             ///< set of live extents
@@ -1020,7 +1019,7 @@ private:
   ) {
     assert(extent->state == CachedExtent::extent_state_t::CLEAN_PENDING);
     extent->set_io_wait();
-    return reader.read(
+    return epm.read(
       extent->get_paddr(),
       extent->get_length(),
       extent->get_bptr()
diff --git a/src/crimson/os/seastore/device.h b/src/crimson/os/seastore/device.h
new file mode 100644 (file)
index 0000000..bc050a0
--- /dev/null
@@ -0,0 +1,46 @@
+// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:nil -*-
+// vim: ts=8 sw=2 smarttab
+
+#pragma once
+
+#include <memory>
+
+#include "include/buffer_fwd.h"
+
+#include "crimson/common/errorator.h"
+
+namespace crimson::os::seastore {
+
+/**
+ * Device
+ *
+ * Represents a general device regardless of the underlying medium.
+ */
+class Device {
+public:
+  virtual device_id_t get_device_id() const = 0;
+
+  using read_ertr = crimson::errorator<
+    crimson::ct_error::input_output_error,
+    crimson::ct_error::invarg,
+    crimson::ct_error::enoent,
+    crimson::ct_error::erange>;
+  virtual read_ertr::future<> read(
+    paddr_t addr,
+    size_t len,
+    ceph::bufferptr &out) = 0;
+
+  read_ertr::future<ceph::bufferptr> read(
+    paddr_t addr,
+    size_t len
+  ) {
+    auto ptrref = std::make_unique<ceph::bufferptr>(
+      buffer::create_page_aligned(len));
+    return read(addr, len, *ptrref
+    ).safe_then([ptrref=std::move(ptrref)]() mutable {
+      return read_ertr::make_ready_future<bufferptr>(std::move(*ptrref));
+    });
+  }
+};
+
+}
index fcf1375e3bd848953df8eed57b07d920538a91f8..e7dddf3534152d8b2b12620798964ce6c80042e9 100644 (file)
@@ -171,7 +171,15 @@ private:
 
 class ExtentPlacementManager {
 public:
-  ExtentPlacementManager() = default;
+  ExtentPlacementManager() {
+    devices_by_id.resize(DEVICE_ID_MAX, nullptr);
+  }
+
+  void add_device(Device* device) {
+    auto device_id = device->get_device_id();
+    ceph_assert(devices_by_id[device_id] == nullptr);
+    devices_by_id[device_id] = device;
+  }
 
   void add_allocator(device_type_t type, ExtentAllocatorRef&& allocator) {
     allocators[type].emplace_back(std::move(allocator));
@@ -270,9 +278,21 @@ public:
       });
     }).safe_then([this] {
       allocators.clear();
+      devices_by_id.clear();
+      devices_by_id.resize(DEVICE_ID_MAX, nullptr);
     });
   }
 
+  using read_ertr = Device::read_ertr;
+  read_ertr::future<> read(
+    paddr_t addr,
+    size_t len,
+    ceph::bufferptr &out
+  ) {
+    assert(devices_by_id[addr.get_device_id()] != nullptr);
+    return devices_by_id[addr.get_device_id()]->read(addr, len, out);
+  }
+
 private:
   device_type_t get_allocator_type(placement_hint_t hint) {
     return device_type_t::SEGMENTED;
@@ -286,6 +306,7 @@ private:
   }
 
   std::map<device_type_t, std::vector<ExtentAllocatorRef>> allocators;
+  std::vector<Device*> devices_by_id;
 };
 using ExtentPlacementManagerRef = std::unique_ptr<ExtentPlacementManager>;
 
index 1016f50f238461573047cd779a4990a80fdfc00f..4d77dbe6ef8137cff41342587f75ac943a7a6f58 100644 (file)
@@ -85,14 +85,6 @@ public:
     segment_managers[segment_manager->get_device_id()] = segment_manager;
   }
 
-  read_ertr::future<> read(
-    paddr_t addr,
-    size_t len,
-    ceph::bufferptr &out) {
-    assert(segment_managers[addr.get_device_id()]);
-    return segment_managers[addr.get_device_id()]->read(addr, len, out);
-  }
-
   void reset() {
     segment_managers.clear();
     segment_managers.resize(DEVICE_ID_MAX, nullptr);
index 235a9d1cad505992c3a55c3e71eb7e25a028e544..644aaa71444a86608704c8d96f054897116c4309 100644 (file)
 #include <boost/iterator/counting_iterator.hpp>
 #include <seastar/core/future.hh>
 
-#include "include/ceph_assert.h"
-#include "crimson/os/seastore/seastore_types.h"
 #include "include/buffer_fwd.h"
+#include "include/ceph_assert.h"
+
 #include "crimson/common/config_proxy.h"
+#include "crimson/os/seastore/seastore_types.h"
 #include "crimson/osd/exceptions.h"
+#include "device.h"
 
 namespace crimson::os::seastore {
 
@@ -178,7 +180,7 @@ class SegmentManager;
 
 using SegmentManagerRef = std::unique_ptr<SegmentManager>;
 
-class SegmentManager {
+class SegmentManager : public Device {
 public:
   using access_ertr = crimson::errorator<
     crimson::ct_error::input_output_error,
@@ -210,26 +212,6 @@ public:
     crimson::ct_error::enoent>;
   virtual release_ertr::future<> release(segment_id_t id) = 0;
 
-  using read_ertr = crimson::errorator<
-    crimson::ct_error::input_output_error,
-    crimson::ct_error::invarg,
-    crimson::ct_error::enoent,
-    crimson::ct_error::erange>;
-  virtual read_ertr::future<> read(
-    paddr_t addr,
-    size_t len,
-    ceph::bufferptr &out) = 0;
-  read_ertr::future<ceph::bufferptr> read(
-    paddr_t addr,
-    size_t len) {
-    auto ptrref = std::make_unique<ceph::bufferptr>(
-      buffer::create_page_aligned(len));
-    return read(addr, len, *ptrref).safe_then(
-      [ptrref=std::move(ptrref)]() mutable {
-       return read_ertr::make_ready_future<bufferptr>(std::move(*ptrref));
-      });
-  }
-
   /* Methods for discovering device geometry, segmentid set, etc */
   virtual size_t get_size() const = 0;
   virtual seastore_off_t get_block_size() const = 0;
@@ -245,8 +227,6 @@ public:
   }
   virtual const seastore_meta_t &get_meta() const = 0;
 
-  virtual device_id_t get_device_id() const = 0;
-
   virtual secondary_device_set_t& get_secondary_devices() = 0;
 
   virtual device_spec_t get_device_spec() const = 0;
index a01652601d0c1e52a87418f7d38f2fd2dcce39bd..237e90966d24aaa0660d2640e7a5690d3d312584 100644 (file)
@@ -567,7 +567,7 @@ TransactionManagerRef make_transaction_manager(
     detailed);
   auto journal = journal::make_segmented(sm, scanner_ref, *segment_cleaner);
   auto epm = std::make_unique<ExtentPlacementManager>();
-  auto cache = std::make_unique<Cache>(scanner_ref, *epm);
+  auto cache = std::make_unique<Cache>(*epm);
   auto lba_manager = lba_manager::create_lba_manager(sm, *cache);
 
   return std::make_unique<TransactionManager>(
index b54e44751225de624ffeb32f71d5a3ded0a1dc70..34171b63f98a7481f9ccb00f13ec03b7dab229f4 100644 (file)
@@ -545,6 +545,7 @@ public:
     LOG_PREFIX(TransactionManager::add_segment_manager);
     SUBDEBUG(seastore_tm, "adding segment manager {}", sm->get_device_id());
     scanner.add_segment_manager(sm);
+    epm->add_device(sm);
     epm->add_allocator(
       device_type_t::SEGMENTED,
       std::make_unique<SegmentedAllocator>(
index c36936c5024ed46751c66f52243d92f7d7975309..79bbce63c6aa92671e2a8582b3b9bccd9f3852a7 100644 (file)
@@ -103,11 +103,12 @@ struct btree_test_base :
     journal = journal::make_segmented(
       *segment_manager, scanner_ref, *this);
     epm.reset(new ExtentPlacementManager());
-    cache.reset(new Cache(scanner_ref, *epm));
+    cache.reset(new Cache(*epm));
 
     block_size = segment_manager->get_block_size();
     next = segment_id_t{segment_manager->get_device_id(), 0};
     scanner_ref.add_segment_manager(segment_manager.get());
+    epm->add_device(segment_manager.get());
     journal->set_write_pipeline(&pipeline);
 
     return segment_manager->init(
index 979883be44f35236cba19d4d7d5559568409e659..94efc4fd48db4f0b3637e95bacf99fc98c9eedbe 100644 (file)
@@ -21,7 +21,6 @@ namespace {
 
 struct cache_test_t : public seastar_test_suite_t {
   segment_manager::EphemeralSegmentManagerRef segment_manager;
-  ExtentReaderRef reader;
   ExtentPlacementManagerRef epm;
   CacheRef cache;
   paddr_t current;
@@ -84,11 +83,10 @@ struct cache_test_t : public seastar_test_suite_t {
 
   seastar::future<> set_up_fut() final {
     segment_manager = segment_manager::create_test_ephemeral();
-    reader.reset(new ExtentReader());
     epm.reset(new ExtentPlacementManager());
-    cache.reset(new Cache(*reader, *epm));
+    cache.reset(new Cache(*epm));
     current = paddr_t::make_seg_paddr(segment_id_t(segment_manager->get_device_id(), 0), 0);
-    reader->add_segment_manager(segment_manager.get());
+    epm->add_device(segment_manager.get());
     return segment_manager->init(
     ).safe_then([this] {
       return seastar::do_with(
@@ -113,7 +111,6 @@ struct cache_test_t : public seastar_test_suite_t {
     return cache->close(
     ).safe_then([this] {
       segment_manager.reset();
-      reader.reset();
       epm.reset();
       cache.reset();
     }).handle_error(