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
*
});
}
+ /**
+ * 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