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"))
{
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
void dump_contents();
private:
- ExtentReader &reader; ///< ref to extent reader
ExtentPlacementManager& epm;
RootBlockRef root; ///< ref to current root
ExtentIndex extents; ///< set of live extents
) {
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()
--- /dev/null
+// -*- 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));
+ });
+ }
+};
+
+}
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));
});
}).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;
}
std::map<device_type_t, std::vector<ExtentAllocatorRef>> allocators;
+ std::vector<Device*> devices_by_id;
};
using ExtentPlacementManagerRef = std::unique_ptr<ExtentPlacementManager>;
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);
#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 {
using SegmentManagerRef = std::unique_ptr<SegmentManager>;
-class SegmentManager {
+class SegmentManager : public Device {
public:
using access_ertr = crimson::errorator<
crimson::ct_error::input_output_error,
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;
}
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;
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>(
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>(
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(
struct cache_test_t : public seastar_test_suite_t {
segment_manager::EphemeralSegmentManagerRef segment_manager;
- ExtentReaderRef reader;
ExtentPlacementManagerRef epm;
CacheRef cache;
paddr_t current;
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(
return cache->close(
).safe_then([this] {
segment_manager.reset();
- reader.reset();
epm.reset();
cache.reset();
}).handle_error(