c.t, addr, expect_is_level_tail);
ceph_abort("fatal error");
})
- ).safe_then([FNAME, c, expect_is_level_tail](auto extent) {
- auto [node_type, field_type] = extent->get_types();
+ ).safe_then([FNAME, c, addr, expect_is_level_tail](auto extent) {
+ auto header = extent->get_header();
+ auto field_type = header.get_field_type();
+ if (!field_type) {
+ ERRORT("load addr={:x}, is_level_tail={} error, "
+ "got invalid header -- {}",
+ c.t, addr, expect_is_level_tail, extent);
+ ceph_abort("fatal error");
+ }
+ if (header.get_is_level_tail() != expect_is_level_tail) {
+ ERRORT("load addr={:x}, is_level_tail={} error, "
+ "is_level_tail mismatch -- {}",
+ c.t, addr, expect_is_level_tail, extent);
+ ceph_abort("fatal error");
+ }
+
+ auto node_type = header.get_node_type();
if (node_type == node_type_t::LEAF) {
if (extent->get_length() != c.vb.get_leaf_node_size()) {
- ERRORT("leaf length mismatch -- {}", c.t, extent);
+ ERRORT("load addr={:x}, is_level_tail={} error, "
+ "leaf length mismatch -- {}",
+ c.t, addr, expect_is_level_tail, extent);
ceph_abort("fatal error");
}
- auto impl = LeafNodeImpl::load(extent, field_type, expect_is_level_tail);
+ auto impl = LeafNodeImpl::load(extent, *field_type);
return Ref<Node>(new LeafNode(impl.get(), std::move(impl)));
} else if (node_type == node_type_t::INTERNAL) {
if (extent->get_length() != c.vb.get_internal_node_size()) {
- ERRORT("internal length mismatch -- {}", c.t, extent);
+ ERRORT("load addr={:x}, is_level_tail={} error, "
+ "internal length mismatch -- {}",
+ c.t, addr, expect_is_level_tail, extent);
ceph_abort("fatal error");
}
- auto impl = InternalNodeImpl::load(extent, field_type, expect_is_level_tail);
+ auto impl = InternalNodeImpl::load(extent, *field_type);
return Ref<Node>(new InternalNode(impl.get(), std::move(impl)));
} else {
ceph_abort("impossible path");
).safe_then([this, position, c, FNAME] (auto child) {
TRACET("loaded child untracked {}",
c.t, child->get_name());
+ if (child->level() + 1 != level()) {
+ ERRORT("loaded child {} error from parent {} at pos({}), level mismatch",
+ c.t, child->get_name(), get_name(), position);
+ ceph_abort("fatal error");
+ }
child->as_child(position, this);
return child;
});
#include "node_extent_manager/dummy.h"
#include "node_extent_manager/seastore.h"
-#include "stages/node_stage_layout.h"
namespace crimson::os::seastore::onode {
-std::pair<node_type_t, field_type_t> NodeExtent::get_types() const
-{
- const auto header = reinterpret_cast<const node_header_t*>(get_read());
- auto node_type = header->get_node_type();
- auto field_type = header->get_field_type();
- if (!field_type.has_value()) {
- throw std::runtime_error("load failed: bad field type");
- }
- return {node_type, *field_type};
-}
-
NodeExtentManagerURef NodeExtentManager::create_dummy(bool is_sync)
{
if (is_sync) {
#include "crimson/os/seastore/transaction_manager.h"
#include "fwd.h"
-#include "super.h"
#include "node_extent_mutable.h"
#include "node_types.h"
+#include "stages/node_stage_layout.h"
+#include "super.h"
/**
* node_extent_manager.h
class NodeExtent : public LogicalCachedExtent {
public:
virtual ~NodeExtent() = default;
- std::pair<node_type_t, field_type_t> get_types() const;
+ const node_header_t& get_header() const {
+ return *reinterpret_cast<const node_header_t*>(get_read());
+ }
const char* get_read() const {
return get_bptr().c_str();
}
{
DEBUG("replay {:#x} ...", get_laddr());
if (!recorder) {
- auto [node_type, field_type] = get_types();
- recorder = create_replay_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
}
auto node = do_get_mutable();
}
InternalNodeImplURef InternalNodeImpl::load(
- NodeExtentRef extent, field_type_t type, bool expect_is_level_tail)
+ NodeExtentRef extent, field_type_t type)
{
if (type == field_type_t::N0) {
- return InternalNode0::load(extent, expect_is_level_tail);
+ return InternalNode0::load(extent);
} else if (type == field_type_t::N1) {
- return InternalNode1::load(extent, expect_is_level_tail);
+ return InternalNode1::load(extent);
} else if (type == field_type_t::N2) {
- return InternalNode2::load(extent, expect_is_level_tail);
+ return InternalNode2::load(extent);
} else if (type == field_type_t::N3) {
- return InternalNode3::load(extent, expect_is_level_tail);
+ return InternalNode3::load(extent);
} else {
ceph_abort("impossible path");
}
}
LeafNodeImplURef LeafNodeImpl::load(
- NodeExtentRef extent, field_type_t type, bool expect_is_level_tail)
+ NodeExtentRef extent, field_type_t type)
{
if (type == field_type_t::N0) {
- return LeafNode0::load(extent, expect_is_level_tail);
+ return LeafNode0::load(extent);
} else if (type == field_type_t::N1) {
- return LeafNode1::load(extent, expect_is_level_tail);
+ return LeafNode1::load(extent);
} else if (type == field_type_t::N2) {
- return LeafNode2::load(extent, expect_is_level_tail);
+ return LeafNode2::load(extent);
} else if (type == field_type_t::N3) {
- return LeafNode3::load(extent, expect_is_level_tail);
+ return LeafNode3::load(extent);
} else {
ceph_abort("impossible path");
}
};
static eagain_future<fresh_impl_t> allocate(context_t, field_type_t, bool, level_t);
- static InternalNodeImplURef load(NodeExtentRef, field_type_t, bool);
+ static InternalNodeImplURef load(NodeExtentRef, field_type_t);
protected:
InternalNodeImpl() = default;
};
static eagain_future<fresh_impl_t> allocate(context_t, field_type_t, bool);
- static LeafNodeImplURef load(NodeExtentRef, field_type_t, bool);
+ static LeafNodeImplURef load(NodeExtentRef, field_type_t);
protected:
LeafNodeImpl() = default;
NodeLayoutT& operator=(NodeLayoutT&&) = delete;
~NodeLayoutT() override = default;
- static URef load(NodeExtentRef extent, bool expect_is_level_tail) {
+ static URef load(NodeExtentRef extent) {
std::unique_ptr<NodeLayoutT> ret(new NodeLayoutT(extent));
- assert(ret->is_level_tail() == expect_is_level_tail);
return ret;
}