]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
crimson/os/seastore/transaction_manager: implement alloc_remapped_extent
authorXinyu Huang <xinyu.huang@intel.com>
Fri, 21 Apr 2023 15:10:49 +0000 (15:10 +0000)
committerXinyu Huang <xinyu.huang@intel.com>
Tue, 4 Jul 2023 09:07:13 +0000 (17:07 +0800)
Signed-off-by: Xinyu Huang <xinyu.huang@intel.com>
src/crimson/os/seastore/cache.h
src/crimson/os/seastore/cached_extent.h
src/crimson/os/seastore/transaction_manager.h

index 153d7c3c96ca32ec8ab6ccbe41a3c75c4fa60926..2f7346fe3583be11bf5d89985fb958fd1603753b 100644 (file)
@@ -895,6 +895,48 @@ public:
     return ret;
   }
 
+  /**
+   * alloc_remapped_extent
+   *
+   * Allocates an EXIST_CLEAN extent. Use the buffer to fill the new extent
+   * if buffer exists.
+   */
+  template <typename T>
+  TCachedExtentRef<T> alloc_remapped_extent(
+    Transaction &t,
+    laddr_t remap_laddr,
+    paddr_t remap_paddr,
+    extent_len_t remap_length,
+    laddr_t original_laddr,
+    std::optional<ceph::bufferptr> &&original_bptr) {
+    LOG_PREFIX(Cache::alloc_remapped_extent);
+    SUBTRACET(seastore_cache, "allocate {} {}B, hint={}",
+              t, T::TYPE, remap_length, remap_laddr);
+    assert(remap_laddr >= original_laddr);
+    TCachedExtentRef<T> ext;
+    if (original_bptr.has_value()) {
+      // shallow copy the buffer from original extent
+      auto nbp = ceph::bufferptr(
+        *original_bptr,
+        remap_laddr - original_laddr,
+        remap_length);
+      // ExtentPlacementManager::alloc_new_extent will make a new
+      // (relative/temp) paddr, so make extent directly
+      ext = CachedExtent::make_cached_extent_ref<T>(std::move(nbp));
+    } else {
+      ext = CachedExtent::make_placeholder_cached_extent_ref<T>(remap_length);
+    }
+
+    ext->init(CachedExtent::extent_state_t::EXIST_CLEAN,
+             remap_paddr,
+             PLACEMENT_HINT_NULL,
+             NULL_GENERATION,
+              t.get_trans_id());
+
+    t.add_fresh_extent(ext);
+    return ext;
+  }
+
   /**
    * alloc_new_extent
    *
index 25ae023b2fab8ebbe8c2f84fd2d83f0c19e75359..26efa453dd75e0b74b0a5a759ccd221b6f2bef50 100644 (file)
@@ -748,6 +748,12 @@ protected:
     return new T(std::forward<Args>(args)...);
   }
 
+  template <typename T>
+  static TCachedExtentRef<T> make_placeholder_cached_extent_ref(
+    extent_len_t length) {
+    return new T(length);
+  }
+
   void reset_prior_instance() {
     prior_instance.reset();
   }
index 80b292203fedf8eae13bf9b9223593905d031065..420d3da6f9d98df6909f5548cd7f51c736508f98 100644 (file)
@@ -683,6 +683,55 @@ private:
     });
   }
 
+  /**
+   * alloc_remapped_extent
+   *
+   * Allocates a new extent at given remap_paddr that must be absolute and
+   * use the buffer to fill the new extent if buffer exists. Otherwise, will
+   * not read disk to fill the new extent.
+   * Returns the new extent.
+   *
+   * Should make sure the end laddr of remap extent <= the end laddr of
+   * original extent when using this method.
+   */
+  using alloc_remapped_extent_iertr =
+    alloc_extent_iertr::extend_ertr<Device::read_ertr>;
+  using alloc_remapped_extent_ret =
+    alloc_remapped_extent_iertr::future<LBAMappingRef>;
+  template <typename T>
+  alloc_remapped_extent_ret alloc_remapped_extent(
+    Transaction &t,
+    laddr_t remap_laddr,
+    paddr_t remap_paddr,
+    extent_len_t remap_length,
+    laddr_t original_laddr,
+    std::optional<ceph::bufferptr> &&original_bptr) {
+    LOG_PREFIX(TransactionManager::alloc_remapped_extent);
+    SUBDEBUG(seastore_tm, "alloc remapped extent: remap_laddr: {}, "
+      "remap_paddr: {}, remap_length: {}, has data in cache: {} ",
+      remap_laddr, remap_paddr, remap_length,
+      original_bptr.has_value() ? "true":"false");
+    auto ext = cache->alloc_remapped_extent<T>(
+      t,
+      remap_laddr,
+      remap_paddr,
+      remap_length,
+      original_laddr,
+      std::move(original_bptr));
+    return lba_manager->alloc_extent(
+      t,
+      remap_laddr,
+      remap_length,
+      remap_paddr,
+      ext.get()
+    ).si_then([remap_laddr, remap_length, remap_paddr](auto &&ref) {
+      assert(ref->get_key() == remap_laddr);
+      assert(ref->get_val() == remap_paddr);
+      assert(ref->get_length() == remap_length);
+      return alloc_remapped_extent_iertr::make_ready_future
+        <LBAMappingRef>(std::move(ref));
+    });
+  }
 
 public:
   // Testing interfaces