]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
crimson/os/seastore/onode_manager: introduce FLTreeOnodeManager
authorSamuel Just <sjust@redhat.com>
Tue, 2 Mar 2021 20:35:06 +0000 (12:35 -0800)
committerSamuel Just <sjust@redhat.com>
Wed, 10 Mar 2021 06:35:45 +0000 (22:35 -0800)
Adjusts OnodeManager interface and introduces FLTreeOnodeManager
implementation.

Signed-off-by: Samuel Just <sjust@redhat.com>
src/crimson/os/seastore/onode.cc
src/crimson/os/seastore/onode.h
src/crimson/os/seastore/onode_manager.h
src/crimson/os/seastore/onode_manager/staged-fltree/fltree_onode_manager.cc [new file with mode: 0644]
src/crimson/os/seastore/onode_manager/staged-fltree/fltree_onode_manager.h [new file with mode: 0644]
src/crimson/os/seastore/onode_manager/staged-fltree/tree.h

index a8b925b7014884cd657c69485ba6a9a399949298..a3e2483b20f42554a7dda0c1747f81ba91792b7f 100644 (file)
@@ -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<encoded_t*>(buffer);
-  assert(std::numeric_limits<uint16_t>::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<uint32_t>(layout.size)
+            << ")";
 }
 
 }
index 4d778302881ba6a90b7bb6b2cf68f03870a0d625..08ad754fb407d2b4685ebfede117a74cf2ae4c0b 100644 (file)
 #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<Onode>;
 }
-
-WRITE_CLASS_DENC(crimson::os::seastore::Onode)
index 0a03b7fdf7cd804c6a757765c3ce40920df9539c..ea46df991d4215df5077f53dd89f9f1b60da270a 100644 (file)
 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<OnodeRef> 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<OnodeRef>();
+  }
+
+  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<OnodeRef>();
+    return seastar::make_ready_future<OnodeRef>();
   }
-  virtual open_ertr::future<std::vector<OnodeRef>> 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<OnodeRef>>;
+  virtual get_or_create_onodes_ret get_or_create_onodes(
     Transaction &trans,
     const std::vector<ghobject_t> &hoids) {
-    return open_ertr::make_ready_future<std::vector<OnodeRef>>();
+    return seastar::make_ready_future<std::vector<OnodeRef>>();
   }
 
-  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<OnodeRef> &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 (file)
index 0000000..6fd7fee
--- /dev/null
@@ -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<OnodeRef>(
+      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<OnodeRef>(
+      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<ghobject_t> &hoids) {
+  return seastar::do_with(
+    std::vector<OnodeRef>(),
+    [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<OnodeRef> &onodes) {
+  return crimson::do_for_each(
+    onodes,
+    [this, &trans](auto &onode) -> OnodeTree::btree_future<> {
+      auto &flonode = static_cast<FLTreeOnode&>(*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 (file)
index 0000000..f7e180e
--- /dev/null
@@ -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 <typename... T>
+  FLTreeOnode(T&&... args) : Value(std::forward<T>(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>();
+  }
+
+  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<onode_layout_t*>(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<FLTreeOnode>;
+
+class FLTreeOnodeManager : public crimson::os::seastore::OnodeManager {
+  OnodeTree tree;
+
+public:
+  FLTreeOnodeManager(TransactionManager &tm) :
+    tree(std::make_unique<SeastoreNodeExtentManager>(
+          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<ghobject_t> &hoids) final;
+
+  write_dirty_ret write_dirty(
+    Transaction &trans,
+    const std::vector<OnodeRef> &onodes) final;
+
+  ~FLTreeOnodeManager();
+};
+
+}
index d722cfc05f336cbbc1e37dadeb691ecd6b7031a0..1045c9b724c5eff0f6a5ead12f02192cea4b4509 100644 (file)
@@ -240,13 +240,19 @@ class Btree {
     return btree_ertr::make_ready_future<size_t>(0u);
   }
 
-  btree_future<Cursor> erase(Cursor& pos) {
+  btree_future<Cursor> erase(Transaction &t, Cursor& pos) {
     // TODO
     return btree_ertr::make_ready_future<Cursor>(
         Cursor::make_end(this));
   }
 
-  btree_future<Cursor> erase(Cursor& first, Cursor& last) {
+  btree_future<Cursor> erase(Transaction &t, Cursor& first, Cursor& last) {
+    // TODO
+    return btree_ertr::make_ready_future<Cursor>(
+        Cursor::make_end(this));
+  }
+
+  btree_future<Cursor> erase(Transaction &t, Value &value) {
     // TODO
     return btree_ertr::make_ready_future<Cursor>(
         Cursor::make_end(this));