#include "crimson/os/seastore/onode_manager/staged-fltree/stages/node_stage_layout.h"
namespace {
-
-seastar::logger& logger() {
- return crimson::get_logger(ceph_subsys_filestore);
+LOG_PREFIX(OTree::Seastore);
}
-}
+SET_SUBSYS(seastore_onode);
namespace crimson::os::seastore::onode {
-static DeltaRecorderURef create_recorder(
- node_type_t node_type, field_type_t field_type) {
+static DeltaRecorderURef create_replay_recorder(
+ node_type_t node_type, field_type_t field_type)
+{
if (node_type == node_type_t::LEAF) {
if (field_type == field_type_t::N0) {
- return DeltaRecorderT<node_fields_0_t, node_type_t::LEAF>::create();
+ return DeltaRecorderT<node_fields_0_t, node_type_t::LEAF>::create_for_replay();
} else if (field_type == field_type_t::N1) {
- return DeltaRecorderT<node_fields_1_t, node_type_t::LEAF>::create();
+ return DeltaRecorderT<node_fields_1_t, node_type_t::LEAF>::create_for_replay();
} else if (field_type == field_type_t::N2) {
- return DeltaRecorderT<node_fields_2_t, node_type_t::LEAF>::create();
+ return DeltaRecorderT<node_fields_2_t, node_type_t::LEAF>::create_for_replay();
} else if (field_type == field_type_t::N3) {
- return DeltaRecorderT<leaf_fields_3_t, node_type_t::LEAF>::create();
+ return DeltaRecorderT<leaf_fields_3_t, node_type_t::LEAF>::create_for_replay();
} else {
ceph_abort("impossible path");
}
} else if (node_type == node_type_t::INTERNAL) {
if (field_type == field_type_t::N0) {
- return DeltaRecorderT<node_fields_0_t, node_type_t::INTERNAL>::create();
+ return DeltaRecorderT<node_fields_0_t, node_type_t::INTERNAL>::create_for_replay();
} else if (field_type == field_type_t::N1) {
- return DeltaRecorderT<node_fields_1_t, node_type_t::INTERNAL>::create();
+ return DeltaRecorderT<node_fields_1_t, node_type_t::INTERNAL>::create_for_replay();
} else if (field_type == field_type_t::N2) {
- return DeltaRecorderT<node_fields_2_t, node_type_t::INTERNAL>::create();
+ return DeltaRecorderT<node_fields_2_t, node_type_t::INTERNAL>::create_for_replay();
} else if (field_type == field_type_t::N3) {
- return DeltaRecorderT<internal_fields_3_t, node_type_t::INTERNAL>::create();
+ return DeltaRecorderT<internal_fields_3_t, node_type_t::INTERNAL>::create_for_replay();
} else {
ceph_abort("impossible path");
}
}
}
-void SeastoreSuper::write_root_laddr(context_t c, laddr_t addr) {
- logger().info("OTree::Seastore: update root {:#x} ...", addr);
- root_addr = addr;
- auto nm = static_cast<SeastoreNodeExtentManager*>(&c.nm);
- nm->get_tm().write_onode_root(c.t, addr);
-}
-
NodeExtentRef SeastoreNodeExtent::mutate(
- context_t c, DeltaRecorderURef&& _recorder) {
- logger().debug("OTree::Seastore: mutate {:#x} ...", get_laddr());
- auto nm = static_cast<SeastoreNodeExtentManager*>(&c.nm);
- auto extent = nm->get_tm().get_mutable_extent(c.t, this);
+ context_t c, DeltaRecorderURef&& _recorder)
+{
+ DEBUGT("mutate {} ...", c.t, *this);
+ auto p_handle = static_cast<TransactionManagerHandle*>(&c.nm);
+ auto extent = p_handle->tm.get_mutable_extent(c.t, this);
auto ret = extent->cast<SeastoreNodeExtent>();
+ // A replayed extent may already have an empty recorder, we discard it for
+ // simplicity.
assert(!ret->recorder || ret->recorder->is_empty());
ret->recorder = std::move(_recorder);
return ret;
}
-void SeastoreNodeExtent::apply_delta(const ceph::bufferlist& bl) {
- logger().debug("OTree::Seastore: replay {:#x} ...", get_laddr());
+void SeastoreNodeExtent::apply_delta(const ceph::bufferlist& bl)
+{
+ DEBUG("replay {} ...", *this);
if (!recorder) {
- auto [node_type, field_type] = get_types();
- recorder = create_recorder(node_type, field_type);
+ auto header = get_header();
+ auto field_type = header.get_field_type();
+ if (!field_type.has_value()) {
+ ERROR("replay got invalid node -- {}", *this);
+ ceph_abort("fatal error");
+ }
+ auto node_type = header.get_node_type();
+ recorder = create_replay_recorder(node_type, *field_type);
} else {
#ifndef NDEBUG
- auto [node_type, field_type] = get_types();
- assert(recorder->node_type() == node_type);
- assert(recorder->field_type() == field_type);
+ auto header = get_header();
+ assert(recorder->node_type() == header.get_node_type());
+ assert(recorder->field_type() == *header.get_field_type());
#endif
}
- assert(is_clean());
- auto node = do_get_mutable();
+ auto mut = do_get_mutable();
auto p = bl.cbegin();
while (p != bl.end()) {
- recorder->apply_delta(p, node);
+ recorder->apply_delta(p, mut, *this);
}
+ DEBUG("relay done!");
}
}