]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
crimson/os/seastore/lba_manager: allow cloning part of the mapping
authorXuehan Xu <xuxuehan@qianxin.com>
Mon, 21 Apr 2025 04:26:52 +0000 (12:26 +0800)
committerXuehan Xu <xuxuehan@qianxin.com>
Sun, 28 Sep 2025 06:48:59 +0000 (14:48 +0800)
Signed-off-by: Xuehan Xu <xuxuehan@qianxin.com>
src/crimson/os/seastore/lba/btree_lba_manager.cc
src/crimson/os/seastore/lba/btree_lba_manager.h
src/crimson/os/seastore/lba_manager.h
src/crimson/os/seastore/transaction_manager.h
src/test/crimson/seastore/test_transaction_manager.cc

index d58e61318f783b5e4611f4105853a79ac06aa71e..13f35ef765871c79b05630cbeee6ed2bce514c47 100644 (file)
@@ -427,17 +427,21 @@ BtreeLBAManager::clone_mapping(
   LBAMapping pos,
   LBAMapping mapping,
   laddr_t laddr,
+  extent_len_t offset,
+  extent_len_t len,
   bool updateref)
 {
   LOG_PREFIX(BtreeLBAManager::clone_mapping);
   assert(pos.is_viewable());
   assert(mapping.is_viewable());
-  DEBUGT("pos={}, mapping={}, laddr={}, updateref={}",
-    t, pos, mapping, laddr, updateref);
+  DEBUGT("pos={}, mapping={}, laddr={}, {}~{} updateref={}",
+    t, pos, mapping, laddr, offset, len, updateref);
+  assert(offset + len <= mapping.get_length());
   struct state_t {
     LBAMapping pos;
     LBAMapping mapping;
     laddr_t laddr;
+    extent_len_t offset;
     extent_len_t len;
   };
   auto c = get_context(t);
@@ -464,11 +468,10 @@ BtreeLBAManager::clone_mapping(
       return update_refcount_iertr::make_ready_future<
        LBAMapping>(std::move(mapping));
     }
-  }).si_then([c, this, pos=std::move(pos),
-                     laddr](auto mapping) mutable {
-    auto len = mapping.get_length();
+  }).si_then([c, this, pos=std::move(pos), len,
+             offset, laddr](auto mapping) mutable {
     return seastar::do_with(
-      state_t{std::move(pos), std::move(mapping), laddr, len},
+      state_t{std::move(pos), std::move(mapping), laddr, offset, len},
       [this, c](auto &state) {
       return with_btree<LBABtree>(
        cache,
@@ -479,17 +482,15 @@ BtreeLBAManager::clone_mapping(
        ).si_then([&state, c, &btree]() mutable {
          auto &cursor = state.pos.get_effective_cursor();
          assert(state.laddr + state.len <= cursor.key);
+          auto inter_key = state.mapping.is_indirect()
+            ? state.mapping.get_intermediate_key()
+            : state.mapping.get_key();
+          inter_key = (inter_key + state.offset).checked_to_laddr();
          return btree.insert(
            c,
            btree.make_partial_iter(c, cursor),
            state.laddr,
-           lba_map_val_t{
-             state.len,
-             state.mapping.is_indirect()
-               ? state.mapping.get_intermediate_key()
-               : state.mapping.get_key(),
-             EXTENT_DEFAULT_REF_COUNT,
-             0});
+            lba_map_val_t{state.len, inter_key, EXTENT_DEFAULT_REF_COUNT, 0});
        }).si_then([c, &state](auto p) {
          auto &[iter, inserted] = p;
          auto &leaf_node = *iter.get_leaf_node();
index e91dc10270686de53118992c1a3ae9203a4c8a6f..33b6ea87ce069212ea135fec70c0068ef75d555e 100644 (file)
@@ -105,6 +105,8 @@ public:
     LBAMapping pos,
     LBAMapping mapping,
     laddr_t laddr,
+    extent_len_t offset,
+    extent_len_t len,
     bool updateref) final;
 
 #ifdef UNIT_TESTS_BUILT
index c551e5ea21f3cefb58e0fa6512e445c6539da34f..1b1d37bfdc1bd18bc67cac5d209da5fe699e7aa6 100644 (file)
@@ -117,15 +117,19 @@ public:
   using clone_mapping_iertr = alloc_extent_iertr;
   using clone_mapping_ret = clone_mapping_iertr::future<clone_mapping_ret_t>;
   /*
-   * Clones "mapping" at the position "pos" with new laddr "laddr", if updateref
-   * is true, update the refcount of the mapping "mapping"
+   * Clones (part of) "mapping" at the position "pos" with the new lba key "laddr".
    */
   virtual clone_mapping_ret clone_mapping(
     Transaction &t,
-    LBAMapping pos,
-    LBAMapping mapping,
-    laddr_t laddr,
-    bool updateref) = 0;
+    LBAMapping pos,            // the destined position
+    LBAMapping mapping,                // the mapping to be cloned
+    laddr_t laddr,             // the new lba key of the cloned mapping
+    extent_len_t offset,       // the offset of the part to be cloned,
+                               // relative to the start of the mapping.
+    extent_len_t len,          // the length of the part to be cloned
+    bool updateref             // whether to update the refcount of the
+                               // direct mapping
+  ) = 0;
 
   virtual alloc_extent_ret reserve_region(
     Transaction &t,
index 40868c09adcdc82f72233bbc33c970863c2fbb1f..1080d3491822de8b7d6452e8458e21249914b506 100644 (file)
@@ -584,6 +584,8 @@ public:
     LBAMapping pos,
     LBAMapping mapping,
     laddr_t hint,
+    extent_len_t offset,
+    extent_len_t len,
     bool updateref) {
     LOG_PREFIX(TransactionManager::clone_pin);
     SUBDEBUGT(seastore_tm, "{} clone to hint {} ... pos={}, updateref={}",
@@ -591,17 +593,20 @@ public:
     return seastar::do_with(
       std::move(pos),
       std::move(mapping),
-      [FNAME, this, &t, hint, updateref](auto &pos, auto &mapping) {
+      [offset, len, FNAME, this, &t, hint, updateref](auto &pos, auto &mapping) {
       return pos.refresh(
       ).si_then([&pos, &mapping](auto m) {
        pos = std::move(m);
        return mapping.refresh();
-      }).si_then([FNAME, this, &pos, &t, hint, updateref](auto mapping) {
+      }).si_then([offset, len, FNAME, this, &pos,
+                 &t, hint, updateref](auto mapping) {
        return lba_manager->clone_mapping(
          t,
          std::move(pos),
          std::move(mapping),
          hint,
+         offset,
+         len,
          updateref
        ).si_then([FNAME, &t](auto ret) {
          SUBDEBUGT(seastore_tm, "cloned as {}", t, ret.cloned_mapping);
@@ -664,9 +669,11 @@ public:
        if (mapping.is_real()) {
          ret = true;
        }
+       auto len = mapping.get_length();
        return clone_pin(
          t, std::move(pos), std::move(mapping),
-         (base + offset).checked_to_laddr(), updateref
+         (base + offset).checked_to_laddr(),
+         0, len, updateref
        ).si_then([&offset, &pos, &mapping](auto ret) {
          offset += ret.cloned_mapping.get_length();
          return ret.cloned_mapping.next(
index 59ec6ec60c0a8765e2251b20f0874da9fd93e2cd..ec1e19c31481e3dc41159086aa0e52e98c0d6340 100644 (file)
@@ -708,11 +708,14 @@ struct transaction_manager_test_t :
     laddr_t offset) {
     auto key = mapping.get_key();
     auto pin = with_trans_intr(*(t.t), [&](auto &trans) {
+      auto len = mapping.get_length();
       return tm->clone_pin(
        trans,
        std::move(pos),
        std::move(mapping),
        offset,
+       0,
+       len,
        true);
     }).unsafe_get().cloned_mapping;
     EXPECT_EQ(offset, pin.get_key());