From: Samuel Just Date: Tue, 2 Mar 2021 20:35:06 +0000 (-0800) Subject: crimson/os/seastore/onode_manager: introduce FLTreeOnodeManager X-Git-Tag: v17.1.0~2678^2~8 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=4355f33131ce1dbe13c8e990250d05f5a07ac34c;p=ceph.git crimson/os/seastore/onode_manager: introduce FLTreeOnodeManager Adjusts OnodeManager interface and introduces FLTreeOnodeManager implementation. Signed-off-by: Samuel Just --- diff --git a/src/crimson/os/seastore/onode.cc b/src/crimson/os/seastore/onode.cc index a8b925b7014..a3e2483b20f 100644 --- a/src/crimson/os/seastore/onode.cc +++ b/src/crimson/os/seastore/onode.cc @@ -6,38 +6,12 @@ namespace crimson::os::seastore { -size_t Onode::size() const -{ - return ceph::encoded_sizeof(*this); -} - -void Onode::encode(void* buffer, size_t len) -{ - struct [[gnu::packed]] encoded_t { - uint8_t struct_v; - uint8_t struct_compat; - uint32_t struct_len; - uint32_t len; - char data[]; - }; - auto p = reinterpret_cast(buffer); - assert(std::numeric_limits::max() >= size()); - assert(len >= size()); - p->struct_v = 1; - p->struct_compat = 1; - p->struct_len = sizeof(encoded_t) + payload.size(); - p->len = payload.size(); - std::memcpy(p->data, payload.data(), payload.size()); -} - -bool operator==(const Onode& lhs, const Onode& rhs) -{ - return lhs.get() == rhs.get(); -} - std::ostream& operator<<(std::ostream &out, const Onode &rhs) { - return out << rhs.get(); + auto &layout = rhs.get_layout(); + return out << "Onode(" + << "size=" << static_cast(layout.size) + << ")"; } } diff --git a/src/crimson/os/seastore/onode.h b/src/crimson/os/seastore/onode.h index 4d778302881..08ad754fb40 100644 --- a/src/crimson/os/seastore/onode.h +++ b/src/crimson/os/seastore/onode.h @@ -12,37 +12,34 @@ #include "include/buffer.h" #include "include/denc.h" +#include "crimson/os/seastore/transaction.h" + namespace crimson::os::seastore { -// in-memory onode, in addition to the stuff that should be persisted to disk, -// it may contain intrusive hooks for LRU, rw locks etc +struct __attribute__((packed)) onode_layout_t { + ceph_le32 size = init_le32(0); + omap_root_le_t omap_root; +} __attribute__((packed)); + +/** + * Onode + * + * Interface manipulated by seastore. OnodeManager implementations should + * return objects derived from this interface with layout referencing + * internal representation of onode_layout_t. + */ class Onode : public boost::intrusive_ref_counter< Onode, boost::thread_unsafe_counter> { public: - Onode(std::string_view s) - : payload{s} - {} - size_t size() const; - const std::string& get() const { - return payload; - } - void encode(void* buffer, size_t len); - DENC(Onode, v, p) { - DENC_START(1, 1, p); - denc(v.payload, p); - DENC_FINISH(p); - } - -private: - // dummy payload - std::string payload; + + virtual const onode_layout_t &get_layout() const = 0; + virtual onode_layout_t &get_mutable_layout(Transaction &t) = 0; + virtual ~Onode() = default; }; -bool operator==(const Onode& lhs, const Onode& rhs); + std::ostream& operator<<(std::ostream &out, const Onode &rhs); using OnodeRef = boost::intrusive_ptr; } - -WRITE_CLASS_DENC(crimson::os::seastore::Onode) diff --git a/src/crimson/os/seastore/onode_manager.h b/src/crimson/os/seastore/onode_manager.h index 0a03b7fdf7c..ea46df991d4 100644 --- a/src/crimson/os/seastore/onode_manager.h +++ b/src/crimson/os/seastore/onode_manager.h @@ -21,26 +21,46 @@ namespace crimson::os::seastore { class OnodeManager { + using base_ertr = TransactionManager::base_ertr; public: - using open_ertr = crimson::errorator< - crimson::ct_error::input_output_error>; - virtual open_ertr::future get_or_create_onode( + using mkfs_ertr = TransactionManager::mkfs_ertr; + using mkfs_ret = mkfs_ertr::future<>; + virtual mkfs_ret mkfs(Transaction &t) = 0; + + using get_onode_ertr = base_ertr::extend< + crimson::ct_error::enoent>; + using get_onode_ret = get_onode_ertr::future< + OnodeRef>; + virtual get_onode_ret get_onode( + Transaction &trans, + const ghobject_t &hoid) { + return seastar::make_ready_future(); + } + + using get_or_create_onode_ertr = base_ertr; + using get_or_create_onode_ret = get_or_create_onode_ertr::future< + OnodeRef>; + virtual get_or_create_onode_ret get_or_create_onode( Transaction &trans, const ghobject_t &hoid) { - return open_ertr::make_ready_future(); + return seastar::make_ready_future(); } - virtual open_ertr::future> get_or_create_onodes( + + using get_or_create_onodes_ertr = base_ertr; + using get_or_create_onodes_ret = get_or_create_onodes_ertr::future< + std::vector>; + virtual get_or_create_onodes_ret get_or_create_onodes( Transaction &trans, const std::vector &hoids) { - return open_ertr::make_ready_future>(); + return seastar::make_ready_future>(); } - using write_ertr= crimson::errorator< - crimson::ct_error::input_output_error>; - virtual write_ertr::future<> write_dirty( + using write_dirty_ertr = base_ertr; + using write_dirty_ret = write_dirty_ertr::future<>; + virtual write_dirty_ret write_dirty( Transaction &trans, const std::vector &onodes) { - return write_ertr::now(); + return seastar::now(); } virtual ~OnodeManager() {} }; diff --git a/src/crimson/os/seastore/onode_manager/staged-fltree/fltree_onode_manager.cc b/src/crimson/os/seastore/onode_manager/staged-fltree/fltree_onode_manager.cc new file mode 100644 index 00000000000..6fd7fee5fe8 --- /dev/null +++ b/src/crimson/os/seastore/onode_manager/staged-fltree/fltree_onode_manager.cc @@ -0,0 +1,121 @@ +// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:nil -*- +// vim: ts=8 sw=2 smarttab + +#include "crimson/os/seastore/onode_manager/staged-fltree/fltree_onode_manager.h" + +namespace { +[[maybe_unused]] seastar::logger& logger() { + return crimson::get_logger(ceph_subsys_test); +} +} + +namespace crimson::os::seastore::onode { + +FLTreeOnodeManager::get_onode_ret FLTreeOnodeManager::get_onode( + Transaction &trans, + const ghobject_t &hoid) { + return tree.find( + trans, hoid + ).safe_then([this, &trans, &hoid](auto cursor) + -> get_onode_ret { + if (cursor == tree.end()) { + logger().debug( + "FLTreeOnodeManager::{}: no entry for {}", + __func__, + hoid); + return crimson::ct_error::enoent::make(); + } + auto val = OnodeRef(new FLTreeOnode(cursor.value())); + return seastar::make_ready_future( + val + ); + }).handle_error( + get_onode_ertr::pass_further{}, + crimson::ct_error::assert_all{ + "Invalid error in FLTreeOnodeManager::get_onode" + } + ); +} + +FLTreeOnodeManager::get_or_create_onode_ret +FLTreeOnodeManager::get_or_create_onode( + Transaction &trans, + const ghobject_t &hoid) { + return tree.insert( + trans, hoid, + OnodeTree::tree_value_config_t{sizeof(onode_layout_t)} + ).safe_then([this, &trans, &hoid](auto p) + -> get_or_create_onode_ret { + auto [cursor, created] = std::move(p); + auto val = OnodeRef(new FLTreeOnode(cursor.value())); + if (created) { + logger().debug( + "FLTreeOnodeManager::{}: created onode for entry for {}", + __func__, + hoid); + val->get_mutable_layout(trans) = onode_layout_t{}; + } + return seastar::make_ready_future( + val + ); + }).handle_error( + get_or_create_onode_ertr::pass_further{}, + crimson::ct_error::assert_all{ + "Invalid error in FLTreeOnodeManager::get_or_create_onode" + } + ); +} + +FLTreeOnodeManager::get_or_create_onodes_ret +FLTreeOnodeManager::get_or_create_onodes( + Transaction &trans, + const std::vector &hoids) { + return seastar::do_with( + std::vector(), + [this, &hoids, &trans](auto &ret) { + ret.reserve(hoids.size()); + return crimson::do_for_each( + hoids, + [this, &trans, &ret](auto &hoid) { + return get_or_create_onode(trans, hoid + ).safe_then([this, &ret](auto &&onoderef) { + ret.push_back(std::move(onoderef)); + }); + }).safe_then([&ret] { + return std::move(ret); + }); + }); +} + +FLTreeOnodeManager::write_dirty_ret FLTreeOnodeManager::write_dirty( + Transaction &trans, + const std::vector &onodes) { + return crimson::do_for_each( + onodes, + [this, &trans](auto &onode) -> OnodeTree::btree_future<> { + auto &flonode = static_cast(*onode); + switch (flonode.status) { + case FLTreeOnode::status_t::MUTATED: { + flonode.populate_recorder(trans); + return seastar::now(); + } + case FLTreeOnode::status_t::DELETED: { + return tree.erase(trans, flonode).safe_then([](auto) {}); + } + case FLTreeOnode::status_t::STABLE: { + return seastar::now(); + } + default: + __builtin_unreachable(); + } + }).handle_error( + write_dirty_ertr::pass_further{}, + crimson::ct_error::assert_all{ + "Invalid error in FLTreeOnodeManager::write_dirty" + } + ); +} + +FLTreeOnodeManager::~FLTreeOnodeManager() {} + +} diff --git a/src/crimson/os/seastore/onode_manager/staged-fltree/fltree_onode_manager.h b/src/crimson/os/seastore/onode_manager/staged-fltree/fltree_onode_manager.h new file mode 100644 index 00000000000..f7e180e1b63 --- /dev/null +++ b/src/crimson/os/seastore/onode_manager/staged-fltree/fltree_onode_manager.h @@ -0,0 +1,108 @@ +// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:nil -*- +// vim: ts=8 sw=2 smarttab + +#pragma once + +#include "crimson/os/seastore/onode_manager.h" +#include "crimson/os/seastore/onode_manager/staged-fltree/node_extent_manager/seastore.h" +#include "crimson/os/seastore/onode_manager/staged-fltree/value.h" +#include "crimson/os/seastore/onode_manager/staged-fltree/tree.h" + +namespace crimson::os::seastore::onode { + +struct FLTreeOnode : Onode, Value { + static constexpr value_magic_t HEADER_MAGIC = value_magic_t::ONODE; + + enum class status_t { + STABLE, + MUTATED, + DELETED + } status = status_t::STABLE; + + FLTreeOnode(FLTreeOnode&&) = default; + FLTreeOnode& operator=(FLTreeOnode&&) = delete; + + FLTreeOnode(const FLTreeOnode&) = default; + FLTreeOnode& operator=(const FLTreeOnode&) = delete; + + template + FLTreeOnode(T&&... args) : Value(std::forward(args)...) {} + + struct Recorder : public ValueDeltaRecorder { + Recorder(bufferlist &bl) : ValueDeltaRecorder(bl) {} + + value_magic_t get_header_magic() const final { + return value_magic_t::ONODE; + } + + void apply_value_delta( + ceph::bufferlist::const_iterator&, + NodeExtentMutable&, + laddr_t) final { + // TODO + } + }; + + const onode_layout_t &get_layout() const final { + return *read_payload(); + } + + onode_layout_t &get_mutable_layout(Transaction &t) final { + auto p = prepare_mutate_payload< + onode_layout_t, + Recorder>(t); + status = status_t::MUTATED; + return *reinterpret_cast(p.first.get_write()); + }; + + void populate_recorder(Transaction &t) { + auto p = prepare_mutate_payload< + onode_layout_t, + Recorder>(t); + status = status_t::STABLE; + // TODO: fill in recorder + } + + ~FLTreeOnode() final {} +}; + +using OnodeTree = Btree; + +class FLTreeOnodeManager : public crimson::os::seastore::OnodeManager { + OnodeTree tree; + +public: + FLTreeOnodeManager(TransactionManager &tm) : + tree(std::make_unique( + tm, laddr_t{})) {} + + mkfs_ret mkfs(Transaction &t) { + return tree.mkfs(t + ).handle_error( + mkfs_ertr::pass_further{}, + crimson::ct_error::assert_all{ + "Invalid error in FLTreeOnodeManager::mkfs" + } + ); + } + + get_onode_ret get_onode( + Transaction &trans, + const ghobject_t &hoid) final; + + get_or_create_onode_ret get_or_create_onode( + Transaction &trans, + const ghobject_t &hoid) final; + + get_or_create_onodes_ret get_or_create_onodes( + Transaction &trans, + const std::vector &hoids) final; + + write_dirty_ret write_dirty( + Transaction &trans, + const std::vector &onodes) final; + + ~FLTreeOnodeManager(); +}; + +} diff --git a/src/crimson/os/seastore/onode_manager/staged-fltree/tree.h b/src/crimson/os/seastore/onode_manager/staged-fltree/tree.h index d722cfc05f3..1045c9b724c 100644 --- a/src/crimson/os/seastore/onode_manager/staged-fltree/tree.h +++ b/src/crimson/os/seastore/onode_manager/staged-fltree/tree.h @@ -240,13 +240,19 @@ class Btree { return btree_ertr::make_ready_future(0u); } - btree_future erase(Cursor& pos) { + btree_future erase(Transaction &t, Cursor& pos) { // TODO return btree_ertr::make_ready_future( Cursor::make_end(this)); } - btree_future erase(Cursor& first, Cursor& last) { + btree_future erase(Transaction &t, Cursor& first, Cursor& last) { + // TODO + return btree_ertr::make_ready_future( + Cursor::make_end(this)); + } + + btree_future erase(Transaction &t, Value &value) { // TODO return btree_ertr::make_ready_future( Cursor::make_end(this));