]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
crimson: fix split_pin_left assert_aligned
authorchunmei-liu <chunmei.liu@intel.com>
Fri, 21 Jan 2022 16:22:59 +0000 (08:22 -0800)
committerchunmei-liu <chunmei.liu@intel.com>
Wed, 26 Jan 2022 00:14:20 +0000 (16:14 -0800)
hint passed to lba alloc_extent may not be block size aligned
in a certain case, this hint insert lba tree as key, so make
laddr in lba tree is not aligned.

Signed-off-by: chunmei-liu <chunmei.liu@intel.com>
src/crimson/os/seastore/lba_manager/btree/btree_lba_manager.cc
src/crimson/os/seastore/onode.h
src/crimson/os/seastore/onode_manager/staged-fltree/tree_utils.h
src/crimson/os/seastore/seastore.cc
src/crimson/os/seastore/seastore_types.cc
src/crimson/os/seastore/seastore_types.h
src/test/crimson/seastore/onode_tree/test_fltree_onode_manager.cc

index c9b9ee865b324a8c6759c0817d4fa5aefd218467..b699a5ed88fda6fa4e203c07897e250871df75b5 100644 (file)
@@ -126,6 +126,7 @@ BtreeLBAManager::alloc_extent(
   extent_len_t len,
   paddr_t addr)
 {
+  ceph_assert(is_aligned(hint, (uint64_t)segment_manager.get_block_size()));
   struct state_t {
     laddr_t last_end;
 
index c9c31c3a0b512533cbaef07365029026adb22147..0d8be372776ae2836cba84f1f9e98b741e38dea2 100644 (file)
@@ -66,11 +66,12 @@ public:
   virtual onode_layout_t &get_mutable_layout(Transaction &t) = 0;
   virtual ~Onode() = default;
 
-  laddr_t get_metadata_hint() const {
+  laddr_t get_metadata_hint(uint64_t block_size) const {
     assert(default_metadata_offset);
     assert(default_metadata_range);
+    uint64_t range_blocks = default_metadata_range / block_size;
     return get_hint() + default_metadata_offset +
-      ((uint32_t)std::rand() % default_metadata_range);
+      (((uint32_t)std::rand() % range_blocks) * block_size);
   }
   laddr_t get_data_hint() const {
     return get_hint();
index e061cf8c53daee2f15e015b6dd63f859cfcd1258..ad60f5c6e2d4d34aba678d7dd215efd96f03d272 100644 (file)
@@ -196,13 +196,14 @@ class KVPool {
 
   static KVPool create_range(
       const std::pair<index_t, index_t>& range_i,
-      const std::vector<size_t>& value_sizes) {
+      const std::vector<size_t>& value_sizes,
+      const uint64_t block_size) {
     kv_vector_t kvs;
     std::random_device rd;
     for (index_t i = range_i.first; i < range_i.second; ++i) {
       auto value_size = value_sizes[rd() % value_sizes.size()];
       kvs.emplace_back(
-          kv_t{make_oid(i), ValueItem::create(value_size, i)}
+          kv_t{make_oid(i), ValueItem::create(value_size, i, block_size)}
       );
     }
     return KVPool(std::move(kvs));
index 1a89fa79a44a40bc3c946b43290812ca36956f0c..2702e4973097036487249a0a9345fd2c3472acdf 100644 (file)
@@ -517,7 +517,8 @@ SeaStore::get_attr_errorator::future<ceph::bufferlist> SeaStore::get_attr(
       }
       return _omap_get_value(
         t,
-        layout.xattr_root.get(onode.get_metadata_hint()),
+        layout.xattr_root.get(
+          onode.get_metadata_hint(segment_manager->get_block_size())),
         name);
     }
   ).handle_error(crimson::ct_error::input_output_error::handle([FNAME] {
@@ -616,7 +617,7 @@ SeaStore::omap_get_values(
     op_type_t::OMAP_GET_VALUES,
     [this, keys](auto &t, auto &onode) {
       omap_root_t omap_root = onode.get_layout().omap_root.get(
-       onode.get_metadata_hint());
+       onode.get_metadata_hint(segment_manager->get_block_size()));
       return _omap_get_values(
        t,
        std::move(omap_root),
@@ -694,7 +695,8 @@ SeaStore::_omap_list_ret SeaStore::_omap_list(
   const std::optional<std::string>& start,
   OMapManager::omap_list_config_t config) const
 {
-  auto root = omap_root.get(onode.get_metadata_hint());
+  auto root = omap_root.get(
+    onode.get_metadata_hint(segment_manager->get_block_size()));
   if (root.is_null()) {
     return seastar::make_ready_future<_omap_list_bare_ret>(
       true, omap_values_t{}
@@ -1109,13 +1111,13 @@ SeaStore::_omap_set_kvs(
 {
   return seastar::do_with(
     BtreeOMapManager(*transaction_manager),
-    omap_root.get(onode->get_metadata_hint()),
+    omap_root.get(onode->get_metadata_hint(segment_manager->get_block_size())),
     [&, keys=std::move(kvs)](auto &omap_manager, auto &root) {
       tm_iertr::future<> maybe_create_root =
         !root.is_null() ?
         tm_iertr::now() :
         omap_manager.initialize_omap(
-          t, onode->get_metadata_hint()
+          t, onode->get_metadata_hint(segment_manager->get_block_size())
         ).si_then([&root](auto new_root) {
           root = new_root;
         });
@@ -1166,13 +1168,15 @@ SeaStore::tm_ret SeaStore::_omap_rmkeys(
 {
   LOG_PREFIX(SeaStore::_omap_rmkeys);
   DEBUGT("{} {} keys", *ctx.transaction, *onode, keys.size());
-  auto omap_root = onode->get_layout().omap_root.get(onode->get_metadata_hint());
+  auto omap_root = onode->get_layout().omap_root.get(
+    onode->get_metadata_hint(segment_manager->get_block_size()));
   if (omap_root.is_null()) {
     return seastar::now();
   } else {
     return seastar::do_with(
       BtreeOMapManager(*transaction_manager),
-      onode->get_layout().omap_root.get(onode->get_metadata_hint()),
+      onode->get_layout().omap_root.get(
+        onode->get_metadata_hint(segment_manager->get_block_size())),
       std::move(keys),
       [&ctx, &onode](
        auto &omap_manager,
index f738870544cf61c76818e98f47708c43363a0771..f25ce7cce3485bd7e39ec8b25195038f56928fa4 100644 (file)
@@ -14,6 +14,11 @@ seastar::logger& journal_logger() {
 
 namespace crimson::os::seastore {
 
+bool is_aligned(uint64_t offset, uint64_t alignment)
+{
+  return (offset % alignment) == 0;
+}
+
 std::ostream& operator<<(std::ostream& out, const seastore_meta_t& meta)
 {
   return out << meta.seastore_id;
index db7c907a29a987e405f8606f49c5e8e0e9a96ad7..c42345076840ace86f6d5323ae66bd4e70920212 100644 (file)
@@ -38,6 +38,8 @@ struct seastore_meta_t {
   }
 };
 
+bool is_aligned(uint64_t offset, uint64_t alignment);
+
 std::ostream& operator<<(std::ostream& out, const seastore_meta_t& meta);
 
 // identifies a specific physical device within seastore
index c91e13e511b2700eed3412018867346502090ac1..047e695a4100ab3ae87387a9d033d4ae19201b77 100644 (file)
@@ -26,20 +26,22 @@ namespace {
 struct onode_item_t {
   uint32_t size;
   uint64_t id;
+  uint64_t block_size;
   uint32_t cnt_modify = 0;
 
   void initialize(Transaction& t, Onode& value) const {
     auto& layout = value.get_mutable_layout(t);
     layout.size = size;
-    layout.omap_root.update(omap_root_t(id, cnt_modify, value.get_metadata_hint()));
+    layout.omap_root.update(omap_root_t(id, cnt_modify,
+      value.get_metadata_hint(block_size)));
     validate(value);
   }
 
   void validate(Onode& value) const {
     auto& layout = value.get_layout();
     ceph_assert(laddr_t(layout.size) == laddr_t{size});
-    ceph_assert(layout.omap_root.get(value.get_metadata_hint()).addr == id);
-    ceph_assert(layout.omap_root.get(value.get_metadata_hint()).depth == cnt_modify);
+    ceph_assert(layout.omap_root.get(value.get_metadata_hint(block_size)).addr == id);
+    ceph_assert(layout.omap_root.get(value.get_metadata_hint(block_size)).depth == cnt_modify);
   }
 
   void modify(Transaction& t, Onode& value) {
@@ -48,9 +50,9 @@ struct onode_item_t {
     initialize(t, value);
   }
 
-  static onode_item_t create(std::size_t size, std::size_t id) {
+  static onode_item_t create(std::size_t size, std::size_t id, uint64_t block_size) {
     ceph_assert(size <= std::numeric_limits<uint32_t>::max());
-    return {(uint32_t)size, id};
+    return {(uint32_t)size, id, block_size};
   }
 };
 
@@ -239,7 +241,8 @@ struct fltree_onode_manager_test_t
 TEST_F(fltree_onode_manager_test_t, 1_single)
 {
   run_async([this] {
-    auto pool = KVPool<onode_item_t>::create_range({0, 1}, {128, 256});
+    uint64_t block_size = tm->get_block_size();
+    auto pool = KVPool<onode_item_t>::create_range({0, 1}, {128, 256}, block_size);
     auto iter = pool.begin();
     with_onode_write(iter, [](auto& t, auto& onode, auto& item) {
       item.initialize(t, onode);
@@ -266,8 +269,9 @@ TEST_F(fltree_onode_manager_test_t, 1_single)
 TEST_F(fltree_onode_manager_test_t, 2_synthetic)
 {
   run_async([this] {
+    uint64_t block_size = tm->get_block_size();
     auto pool = KVPool<onode_item_t>::create_range(
-        {0, 100}, {32, 64, 128, 256, 512});
+        {0, 100}, {32, 64, 128, 256, 512}, block_size);
     auto start = pool.begin();
     auto end = pool.end();
     with_onodes_write(start, end,