From 406e10694b1ca6f08542cbc9f9aa68de3329dc70 Mon Sep 17 00:00:00 2001 From: Yingxin Cheng Date: Fri, 14 May 2021 09:34:28 +0800 Subject: [PATCH] crimson/onode-staged-tree: handle fatal errors when call NodeExtentManager Signed-off-by: Yingxin Cheng --- .../onode_manager/staged-fltree/node.cc | 48 ++++++++++++++++++- .../staged-fltree/node_extent_accessor.h | 44 ++++++++++++++++- .../onode_manager/staged-fltree/node_layout.h | 9 ++++ .../seastore/onode_tree/test_staged_fltree.cc | 3 ++ 4 files changed, 101 insertions(+), 3 deletions(-) diff --git a/src/crimson/os/seastore/onode_manager/staged-fltree/node.cc b/src/crimson/os/seastore/onode_manager/staged-fltree/node.cc index d90ac454f55d6..a96729f4bbdf4 100644 --- a/src/crimson/os/seastore/onode_manager/staged-fltree/node.cc +++ b/src/crimson/os/seastore/onode_manager/staged-fltree/node.cc @@ -406,6 +406,12 @@ node_future> Node::load_root(context_t c, RootNodeTracker& root_tracke { LOG_PREFIX(OTree::Node::load_root); return c.nm.get_super(c.t, root_tracker + ).handle_error( + eagain_ertr::pass_further{}, + crimson::ct_error::input_output_error::handle([FNAME, c] { + ERRORT("EIO during get_super()", c.t); + ceph_abort("fatal error"); + }) ).safe_then([c, &root_tracker, FNAME](auto&& _super) { auto root_addr = _super->get_root_laddr(); assert(root_addr != L_ADDR_NULL); @@ -631,11 +637,38 @@ template node_future<> Node::fix_parent_index(context_t, Ref&&, boo node_future> Node::load( context_t c, laddr_t addr, bool expect_is_level_tail) { + LOG_PREFIX(OTree::Node::load); // NOTE: // *option1: all types of node have the same length; // option2: length is defined by node/field types; // option3: length is totally flexible; return c.nm.read_extent(c.t, addr, NODE_BLOCK_SIZE + ).handle_error( + eagain_ertr::pass_further{}, + crimson::ct_error::input_output_error::handle( + [FNAME, c, addr, expect_is_level_tail] { + ERRORT("EIO -- addr={:x}, is_level_tail={}", + c.t, addr, expect_is_level_tail); + ceph_abort("fatal error"); + }), + crimson::ct_error::invarg::handle( + [FNAME, c, addr, expect_is_level_tail] { + ERRORT("EINVAL -- addr={:x}, is_level_tail={}", + c.t, addr, expect_is_level_tail); + ceph_abort("fatal error"); + }), + crimson::ct_error::enoent::handle( + [FNAME, c, addr, expect_is_level_tail] { + ERRORT("ENOENT -- addr={:x}, is_level_tail={}", + c.t, addr, expect_is_level_tail); + ceph_abort("fatal error"); + }), + crimson::ct_error::erange::handle( + [FNAME, c, addr, expect_is_level_tail] { + ERRORT("ERANGE -- addr={:x}, is_level_tail={}", + c.t, addr, expect_is_level_tail); + ceph_abort("fatal error"); + }) ).safe_then([expect_is_level_tail](auto extent) { auto [node_type, field_type] = extent->get_types(); if (node_type == node_type_t::LEAF) { @@ -1291,6 +1324,9 @@ node_future<> InternalNode::test_clone_root( impl->test_copy_to(fresh_other.mut); auto cloned_root = fresh_other.node; return c_other.nm.get_super(c_other.t, tracker_other + ).handle_error( + eagain_ertr::pass_further{}, + crimson::ct_error::assert_all{"Invalid error during test clone"} ).safe_then([c_other, cloned_root](auto&& super_other) { cloned_root->make_root_new(c_other, std::move(super_other)); return cloned_root; @@ -1907,6 +1943,9 @@ node_future<> LeafNode::test_clone_root( impl->test_copy_to(fresh_other.mut); auto cloned_root = fresh_other.node; return c_other.nm.get_super(c_other.t, tracker_other + ).handle_error( + eagain_ertr::pass_further{}, + crimson::ct_error::assert_all{"Invalid error during test clone"} ).safe_then([c_other, cloned_root](auto&& super_other) { cloned_root->make_root_new(c_other, std::move(super_other)); }); @@ -1983,10 +2022,17 @@ node_future> LeafNode::insert_value( node_future> LeafNode::allocate_root( context_t c, RootNodeTracker& root_tracker) { + LOG_PREFIX(OTree::LeafNode::allocate_root); return LeafNode::allocate(c, field_type_t::N0, true - ).safe_then([c, &root_tracker](auto fresh_node) { + ).safe_then([c, &root_tracker, FNAME](auto fresh_node) { auto root = fresh_node.node; return c.nm.get_super(c.t, root_tracker + ).handle_error( + eagain_ertr::pass_further{}, + crimson::ct_error::input_output_error::handle([FNAME, c] { + ERRORT("EIO during get_super()", c.t); + ceph_abort("fatal error"); + }) ).safe_then([c, root](auto&& super) { root->make_root_new(c, std::move(super)); return root; diff --git a/src/crimson/os/seastore/onode_manager/staged-fltree/node_extent_accessor.h b/src/crimson/os/seastore/onode_manager/staged-fltree/node_extent_accessor.h index b72759f9afd0c..2ac67f5f619c1 100644 --- a/src/crimson/os/seastore/onode_manager/staged-fltree/node_extent_accessor.h +++ b/src/crimson/os/seastore/onode_manager/staged-fltree/node_extent_accessor.h @@ -503,6 +503,14 @@ class NodeExtentAccessorT { } assert(!extent->is_initial_pending()); return c.nm.alloc_extent(c.t, node_stage_t::EXTENT_SIZE + ).handle_error( + eagain_ertr::pass_further{}, + crimson::ct_error::input_output_error::handle( + [FNAME, c, l_to_discard = extent->get_laddr()] { + ERRORT("EIO during allocate -- node_size={}, to_discard={:x}", + c.t, node_stage_t::EXTENT_SIZE, l_to_discard); + ceph_abort("fatal error"); + }) ).safe_then([this, c, FNAME] (auto fresh_extent) { DEBUGT("update addr from {:#x} to {:#x} ...", c.t, extent->get_laddr(), fresh_extent->get_laddr()); @@ -520,15 +528,47 @@ class NodeExtentAccessorT { mut.emplace(fresh_mut); recorder = nullptr; - return c.nm.retire_extent(c.t, to_discard); + return c.nm.retire_extent(c.t, to_discard + ).handle_error( + eagain_ertr::pass_further{}, + crimson::ct_error::input_output_error::handle( + [FNAME, c, l_to_discard = to_discard->get_laddr(), + l_fresh = fresh_extent->get_laddr()] { + ERRORT("EIO during retire -- to_disgard={:x}, fresh={:x}", + c.t, l_to_discard, l_fresh); + ceph_abort("fatal error"); + }), + crimson::ct_error::enoent::handle( + [FNAME, c, l_to_discard = to_discard->get_laddr(), + l_fresh = fresh_extent->get_laddr()] { + ERRORT("ENOENT during retire -- to_disgard={:x}, fresh={:x}", + c.t, l_to_discard, l_fresh); + ceph_abort("fatal error"); + }) + ); }).safe_then([this] { return *mut; }); } ertr::future<> retire(context_t c) { + LOG_PREFIX(OTree::Extent::retire); assert(extent->is_valid()); - return c.nm.retire_extent(c.t, std::move(extent)); + auto addr = extent->get_laddr(); + return c.nm.retire_extent(c.t, std::move(extent) + ).handle_error( + eagain_ertr::pass_further{}, + crimson::ct_error::input_output_error::handle( + [FNAME, c, addr] { + ERRORT("EIO -- addr={:x}", c.t, addr); + ceph_abort("fatal error"); + }), + crimson::ct_error::enoent::handle( + [FNAME, c, addr] { + ERRORT("ENOENT -- addr={:x}", c.t, addr); + ceph_abort("fatal error"); + }) + ); } private: diff --git a/src/crimson/os/seastore/onode_manager/staged-fltree/node_layout.h b/src/crimson/os/seastore/onode_manager/staged-fltree/node_layout.h index 9c754bab1dfd4..873e665e0e31f 100644 --- a/src/crimson/os/seastore/onode_manager/staged-fltree/node_layout.h +++ b/src/crimson/os/seastore/onode_manager/staged-fltree/node_layout.h @@ -68,10 +68,19 @@ class NodeLayoutT final : public InternalNodeImpl, public LeafNodeImpl { static ertr::future allocate( context_t c, bool is_level_tail, level_t level) { + LOG_PREFIX(OTree::Layout::allocate); // NOTE: Currently, all the node types have the same size for simplicity. // But depending on the requirement, we may need to make node size // configurable by field_type_t and node_type_t, or totally flexible. return c.nm.alloc_extent(c.t, node_stage_t::EXTENT_SIZE + ).handle_error( + eagain_ertr::pass_further{}, + crimson::ct_error::input_output_error::handle( + [FNAME, c, is_level_tail, level] { + ERRORT("EIO -- node_size={}, is_level_tail={}, level={}", + c.t, node_stage_t::EXTENT_SIZE, is_level_tail, level); + ceph_abort("fatal error"); + }) ).safe_then([is_level_tail, level](auto extent) { assert(extent->is_initial_pending()); auto mut = extent->get_mutable(); diff --git a/src/test/crimson/seastore/onode_tree/test_staged_fltree.cc b/src/test/crimson/seastore/onode_tree/test_staged_fltree.cc index c621fc9df0bcf..b3762e1d32421 100644 --- a/src/test/crimson/seastore/onode_tree/test_staged_fltree.cc +++ b/src/test/crimson/seastore/onode_tree/test_staged_fltree.cc @@ -1017,6 +1017,9 @@ class DummyChildPool { DummyChildPool& pool, RootNodeTracker& root_tracker) { auto initial = create_new(keys, true, pool); return c.nm.get_super(c.t, root_tracker + ).handle_error( + eagain_ertr::pass_further{}, + crimson::ct_error::assert_all{"Invalid error during create_initial()"} ).safe_then([c, &pool, initial](auto super) { initial->make_root_new(c, std::move(super)); return initial->upgrade_root(c).safe_then([initial] { -- 2.39.5