]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
crimson/os/seastore/transaction_manager: allow allocating multiple 54280/head
authorXuehan Xu <xuxuehan@qianxin.com>
Fri, 19 Jan 2024 05:26:03 +0000 (13:26 +0800)
committerXuehan Xu <xuxuehan@qianxin.com>
Mon, 5 Feb 2024 08:27:50 +0000 (16:27 +0800)
extents when rewriting data extents

Signed-off-by: Xuehan Xu <xuxuehan@qianxin.com>
src/crimson/os/seastore/lba_manager.cc
src/crimson/os/seastore/lba_manager.h
src/crimson/os/seastore/lba_manager/btree/btree_lba_manager.cc
src/crimson/os/seastore/lba_manager/btree/btree_lba_manager.h
src/crimson/os/seastore/transaction_manager.cc

index d113bbd1e957c6b96de5e992de1171224094db40..c3473bc483eba4fd2962441885f457f64fdf4c57 100644 (file)
@@ -16,7 +16,9 @@ LBAManager::update_mappings(
     return update_mapping(
       t,
       extent->get_laddr(),
+      extent->get_length(),
       extent->get_prior_paddr_and_reset(),
+      extent->get_length(),
       extent->get_paddr(),
       nullptr  // all the extents should have already been
                // added to the fixed_kv_btree
index d4d1826bcf9069a75f19a9b914b7c38679bab561..0c02e1bd61bb29f44f6a1ecf49c61a96128b5b9f 100644 (file)
@@ -191,7 +191,9 @@ public:
   virtual update_mapping_ret update_mapping(
     Transaction& t,
     laddr_t laddr,
+    extent_len_t prev_len,
     paddr_t prev_addr,
+    extent_len_t len,
     paddr_t paddr,
     LogicalCachedExtent *nextent) = 0;
 
index 1b7f927ec0fed6f9f57b0ff88948ac1a7166ff87..b9fa0685a80a0ba9719e0022f32e8ccf06650840 100644 (file)
@@ -530,7 +530,9 @@ BtreeLBAManager::update_mapping_ret
 BtreeLBAManager::update_mapping(
   Transaction& t,
   laddr_t laddr,
+  extent_len_t prev_len,
   paddr_t prev_addr,
+  extent_len_t len,
   paddr_t addr,
   LogicalCachedExtent *nextent)
 {
@@ -539,13 +541,15 @@ BtreeLBAManager::update_mapping(
   return _update_mapping(
     t,
     laddr,
-    [prev_addr, addr](
+    [prev_addr, addr, prev_len, len](
       const lba_map_val_t &in) {
       assert(!addr.is_null());
       lba_map_val_t ret = in;
       ceph_assert(in.pladdr.is_paddr());
       ceph_assert(in.pladdr.get_paddr() == prev_addr);
+      ceph_assert(in.len == prev_len);
       ret.pladdr = addr;
+      ret.len = len;
       return ret;
     },
     nextent
index 1c907f76d31139b444f50c53594a394ddcb59e90..626b9e02c0c539df067fa9b81904936f7ea425a4 100644 (file)
@@ -333,7 +333,9 @@ public:
   update_mapping_ret update_mapping(
     Transaction& t,
     laddr_t laddr,
+    extent_len_t prev_len,
     paddr_t prev_addr,
+    extent_len_t len,
     paddr_t paddr,
     LogicalCachedExtent*) final;
 
index e45224412057395f377ec95f8dfff48a03d24bab..348c43e3c8257cff683ee3c6a86d4538836364d7 100644 (file)
@@ -439,32 +439,99 @@ TransactionManager::rewrite_logical_extent(
 
   auto lextent = extent->cast<LogicalCachedExtent>();
   cache->retire_extent(t, extent);
-  auto nlextent = cache->alloc_new_extent_by_type(
-    t,
-    lextent->get_type(),
-    lextent->get_length(),
-    lextent->get_user_hint(),
-    // get target rewrite generation
-    lextent->get_rewrite_generation())->cast<LogicalCachedExtent>();
-  lextent->get_bptr().copy_out(
-    0,
-    lextent->get_length(),
-    nlextent->get_bptr().c_str());
-  nlextent->set_laddr(lextent->get_laddr());
-  nlextent->set_modify_time(lextent->get_modify_time());
-
-  DEBUGT("rewriting logical extent -- {} to {}", t, *lextent, *nlextent);
-
-  /* This update_mapping is, strictly speaking, unnecessary for delayed_alloc
-   * extents since we're going to do it again once we either do the ool write
-   * or allocate a relative inline addr.  TODO: refactor AsyncCleaner to
-   * avoid this complication. */
-  return lba_manager->update_mapping(
-    t,
-    lextent->get_laddr(),
-    lextent->get_paddr(),
-    nlextent->get_paddr(),
-    nlextent.get());
+  if (get_extent_category(lextent->get_type()) == data_category_t::METADATA) {
+    auto nlextent = cache->alloc_new_extent_by_type(
+      t,
+      lextent->get_type(),
+      lextent->get_length(),
+      lextent->get_user_hint(),
+      // get target rewrite generation
+      lextent->get_rewrite_generation())->cast<LogicalCachedExtent>();
+    lextent->get_bptr().copy_out(
+      0,
+      lextent->get_length(),
+      nlextent->get_bptr().c_str());
+    nlextent->set_laddr(lextent->get_laddr());
+    nlextent->set_modify_time(lextent->get_modify_time());
+
+    DEBUGT("rewriting logical extent -- {} to {}", t, *lextent, *nlextent);
+
+    /* This update_mapping is, strictly speaking, unnecessary for delayed_alloc
+     * extents since we're going to do it again once we either do the ool write
+     * or allocate a relative inline addr.  TODO: refactor AsyncCleaner to
+     * avoid this complication. */
+    return lba_manager->update_mapping(
+      t,
+      lextent->get_laddr(),
+      lextent->get_length(),
+      lextent->get_paddr(),
+      nlextent->get_length(),
+      nlextent->get_paddr(),
+      nlextent.get());
+  } else {
+    assert(get_extent_category(lextent->get_type()) == data_category_t::DATA);
+    auto extents = cache->alloc_new_data_extents_by_type(
+      t,
+      lextent->get_type(),
+      lextent->get_length(),
+      lextent->get_user_hint(),
+      // get target rewrite generation
+      lextent->get_rewrite_generation());
+    return seastar::do_with(
+      std::move(extents),
+      0,
+      lextent->get_length(),
+      [this, lextent, &t](auto &extents, auto &off, auto &left) {
+      return trans_intr::do_for_each(
+        extents,
+        [lextent, this, &t, &off, &left](auto &nextent) {
+        LOG_PREFIX(TransactionManager::rewrite_logical_extent);
+        bool first_extent = (off == 0);
+        ceph_assert(left >= nextent->get_length());
+        auto nlextent = nextent->template cast<LogicalCachedExtent>();
+        lextent->get_bptr().copy_out(
+          0,
+          nlextent->get_length(),
+          nlextent->get_bptr().c_str());
+        nlextent->set_laddr(lextent->get_laddr() + off);
+        nlextent->set_modify_time(lextent->get_modify_time());
+        DEBUGT("rewriting logical extent -- {} to {}", t, *lextent, *nlextent);
+
+        /* This update_mapping is, strictly speaking, unnecessary for delayed_alloc
+         * extents since we're going to do it again once we either do the ool write
+         * or allocate a relative inline addr.  TODO: refactor AsyncCleaner to
+         * avoid this complication. */
+        auto fut = base_iertr::now();
+        if (first_extent) {
+          fut = lba_manager->update_mapping(
+            t,
+            lextent->get_laddr() + off,
+            lextent->get_length(),
+            lextent->get_paddr(),
+            nlextent->get_length(),
+            nlextent->get_paddr(),
+            nlextent.get());
+        } else {
+          fut = lba_manager->alloc_extent(
+            t,
+            lextent->get_laddr() + off,
+            nlextent->get_length(),
+            nlextent->get_paddr(),
+            *nlextent
+          ).si_then([lextent, nlextent, off](auto mapping) {
+            ceph_assert(mapping->get_key() == lextent->get_laddr() + off);
+            ceph_assert(mapping->get_val() == nlextent->get_paddr());
+            return seastar::now();
+          });
+        }
+        return fut.si_then([&off, &left, nlextent] {
+          off += nlextent->get_length();
+          left -= nlextent->get_length();
+          return seastar::now();
+        });
+      });
+    });
+  }
 }
 
 TransactionManager::rewrite_extent_ret TransactionManager::rewrite_extent(