]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
crimson/onode-staged-tree: handle fatal errors when call NodeExtentManager
authorYingxin Cheng <yingxin.cheng@intel.com>
Fri, 14 May 2021 01:34:28 +0000 (09:34 +0800)
committerYingxin Cheng <yingxin.cheng@intel.com>
Fri, 21 May 2021 06:47:38 +0000 (14:47 +0800)
Signed-off-by: Yingxin Cheng <yingxin.cheng@intel.com>
src/crimson/os/seastore/onode_manager/staged-fltree/node.cc
src/crimson/os/seastore/onode_manager/staged-fltree/node_extent_accessor.h
src/crimson/os/seastore/onode_manager/staged-fltree/node_layout.h
src/test/crimson/seastore/onode_tree/test_staged_fltree.cc

index d90ac454f55d6847cf58512e208cee114907c873..a96729f4bbdf4f611efdcdecc459abdb8c2916f5 100644 (file)
@@ -406,6 +406,12 @@ node_future<Ref<Node>> 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<false>(context_t, Ref<Node>&&, boo
 node_future<Ref<Node>> 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<Ref<tree_cursor_t>> LeafNode::insert_value(
 node_future<Ref<LeafNode>> 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;
index b72759f9afd0c9480f7836203abf86588ed4c1c6..2ac67f5f619c1ea22f7f714cc15ea35457c3222d 100644 (file)
@@ -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:
index 9c754bab1dfd49bbfe4122d0fb357c0dede5f338..873e665e0e31f09200e2969b2c65b14ea3d9cbc9 100644 (file)
@@ -68,10 +68,19 @@ class NodeLayoutT final : public InternalNodeImpl, public LeafNodeImpl {
 
   static ertr::future<typename parent_t::fresh_impl_t> 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();
index c621fc9df0bcff9f21793e185643503e03f59bc3..b3762e1d324212906ea4611fd0f415a60f8e4436 100644 (file)
@@ -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] {